From 9ff3b97779037f89348960b5151342d7a04bb355 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Sat, 7 Sep 2013 10:15:08 -0700 Subject: [PATCH] Move more code from header to source. --- format.cc | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- format.h | 72 -------------------------------------- 2 files changed, 100 insertions(+), 75 deletions(-) diff --git a/format.cc b/format.cc index 13f9cf23..1bf20b18 100644 --- a/format.cc +++ b/format.cc @@ -34,6 +34,81 @@ #include "format.h" #include +#include + +namespace { + +#ifndef _MSC_VER + +inline int SignBit(double value) { + // When compiled in C++11 mode signbit is no longer a macro but a function + // defined in namespace std and the macro is undefined. + using namespace std; + return signbit(value); +} + +inline int IsInf(double x) { +#ifdef isinf + return isinf(x); +#else + return std::isinf(x); +#endif +} + +#define FMT_SNPRINTF snprintf + +#else + +inline int SignBit(double value) { + if (value < 0) return 1; + if (value == value) return 0; + int dec = 0, sign = 0; + char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail. + _ecvt_s(buffer, sizeof(buffer), value, 0, &dec, &sign); + return sign; +} + +inline int IsInf(double x) { return !_finite(x); } + +#define FMT_SNPRINTF sprintf_s + +#endif // _MSC_VER + +template +struct CharTraits; + +template <> +struct CharTraits { + template + static int FormatFloat(char *buffer, std::size_t size, + const char *format, unsigned width, int precision, T value) { + if (width == 0) { + return precision < 0 ? + FMT_SNPRINTF(buffer, size, format, value) : + FMT_SNPRINTF(buffer, size, format, precision, value); + } + return precision < 0 ? + FMT_SNPRINTF(buffer, size, format, width, value) : + FMT_SNPRINTF(buffer, size, format, width, precision, value); + } +}; + +template <> +struct CharTraits { + template + static int FormatFloat(wchar_t *buffer, std::size_t size, + const wchar_t *format, unsigned width, int precision, T value) { + if (width == 0) { + return precision < 0 ? + swprintf(buffer, size, format, value) : + swprintf(buffer, size, format, precision, value); + } + return precision < 0 ? + swprintf(buffer, size, format, width, value) : + swprintf(buffer, size, format, width, precision, value); + } +}; +} const char fmt::internal::DIGITS[] = "0001020304050607080910111213141516171819" @@ -156,7 +231,7 @@ void fmt::BasicWriter::FormatDouble( char sign = 0; // Use SignBit instead of value < 0 because the latter is always // false for NaN. - if (internal::SignBit(value)) { + if (SignBit(value)) { sign = '-'; value = -value; } else if (spec.sign_flag()) { @@ -178,7 +253,7 @@ void fmt::BasicWriter::FormatDouble( return; } - if (internal::IsInf(value)) { + if (IsInf(value)) { // Format infinity ourselves because sprintf's output is not consistent // across platforms. std::size_t size = 4; @@ -231,7 +306,7 @@ void fmt::BasicWriter::FormatDouble( for (;;) { std::size_t size = buffer_.capacity() - offset; Char *start = &buffer_[offset]; - int n = internal::CharTraits::FormatFloat( + int n = CharTraits::FormatFloat( start, size, format, width_for_sprintf, precision, value); if (n >= 0 && offset + n < buffer_.capacity()) { if (sign) { @@ -568,44 +643,66 @@ void fmt::BasicFormatter::DoFormat() { writer.buffer_.append(start, s); } +// Explicit instantiations for char. + template void fmt::BasicWriter::FormatDouble( double value, const FormatSpec &spec, int precision); + template void fmt::BasicWriter::FormatDouble( long double value, const FormatSpec &spec, int precision); + template fmt::BasicWriter::CharPtr fmt::BasicWriter::FillPadding( CharPtr buffer, unsigned total_size, std::size_t content_size, char fill); + template void fmt::BasicWriter::FormatDecimal( CharPtr buffer, uint64_t value, unsigned num_digits); + template fmt::BasicWriter::CharPtr fmt::BasicWriter::PrepareFilledBuffer( unsigned size, const AlignSpec &spec, char sign); + template void fmt::BasicFormatter::ReportError( const char *s, StringRef message) const; + template unsigned fmt::BasicFormatter::ParseUInt(const char *&s) const; + template const fmt::BasicFormatter::Arg &fmt::BasicFormatter::ParseArgIndex(const char *&s); + template void fmt::BasicFormatter::CheckSign( const char *&s, const Arg &arg); + template void fmt::BasicFormatter::DoFormat(); +// Explicit instantiations for wchar_t. + template void fmt::BasicWriter::FormatDouble( double value, const FormatSpec &spec, int precision); + template void fmt::BasicWriter::FormatDouble( long double value, const FormatSpec &spec, int precision); + template fmt::BasicWriter::CharPtr fmt::BasicWriter::FillPadding( CharPtr buffer, unsigned total_size, std::size_t content_size, char fill); + template void fmt::BasicWriter::FormatDecimal( CharPtr buffer, uint64_t value, unsigned num_digits); + template fmt::BasicWriter::CharPtr fmt::BasicWriter::PrepareFilledBuffer( unsigned size, const AlignSpec &spec, char sign); + template void fmt::BasicFormatter::ReportError( const wchar_t *s, StringRef message) const; + template unsigned fmt::BasicFormatter::ParseUInt( const wchar_t *&s) const; + template const fmt::BasicFormatter::Arg &fmt::BasicFormatter::ParseArgIndex(const wchar_t *&s); + template void fmt::BasicFormatter::CheckSign( const wchar_t *&s, const Arg &arg); + template void fmt::BasicFormatter::DoFormat(); diff --git a/format.h b/format.h index 7b934007..d93a2623 100644 --- a/format.h +++ b/format.h @@ -32,7 +32,6 @@ #include #include -#include #include #include #include @@ -69,77 +68,6 @@ template inline T *CheckPtr(T *ptr, std::size_t) { return ptr; } #endif -#ifndef _MSC_VER - -inline int SignBit(double value) { - // When compiled in C++11 mode signbit is no longer a macro but a function - // defined in namespace std and the macro is undefined. - using namespace std; - return signbit(value); -} - -inline int IsInf(double x) { -#ifdef isinf - return isinf(x); -#else - return std::isinf(x); -#endif -} - -#define FMT_SNPRINTF snprintf - -#else - -inline int SignBit(double value) { - if (value < 0) return 1; - if (value == value) return 0; - int dec = 0, sign = 0; - char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail. - _ecvt_s(buffer, sizeof(buffer), value, 0, &dec, &sign); - return sign; -} - -inline int IsInf(double x) { return !_finite(x); } - -#define FMT_SNPRINTF sprintf_s - -#endif // _MSC_VER - -template -struct CharTraits; - -template <> -struct CharTraits { - template - static int FormatFloat(char *buffer, std::size_t size, - const char *format, unsigned width, int precision, T value) { - if (width == 0) { - return precision < 0 ? - FMT_SNPRINTF(buffer, size, format, value) : - FMT_SNPRINTF(buffer, size, format, precision, value); - } - return precision < 0 ? - FMT_SNPRINTF(buffer, size, format, width, value) : - FMT_SNPRINTF(buffer, size, format, width, precision, value); - } -}; - -template <> -struct CharTraits { - template - static int FormatFloat(wchar_t *buffer, std::size_t size, - const wchar_t *format, unsigned width, int precision, T value) { - if (width == 0) { - return precision < 0 ? - swprintf(buffer, size, format, value) : - swprintf(buffer, size, format, precision, value); - } - return precision < 0 ? - swprintf(buffer, size, format, width, value) : - swprintf(buffer, size, format, width, precision, value); - } -}; - // A simple array for POD types with the first SIZE elements stored in // the object itself. It supports a subset of std::vector's operations. template