Add extern templates for format_float

Fixes #413.
This commit is contained in:
Jonathan Müller 2016-11-05 20:59:05 +01:00
parent 49ccb2e449
commit 6c0125785b

View File

@ -255,6 +255,21 @@ typedef __int64 intmax_t;
(!defined(FMT_ICC_VERSION) || FMT_ICC_VERSION >= 1500) (!defined(FMT_ICC_VERSION) || FMT_ICC_VERSION >= 1500)
#endif #endif
#ifndef FMT_USE_EXTERN_TEMPLATES
// Clang doesn't have a feature check for extern templates so we check
// for variadic templates which were introduced in the same version.
// For GCC according to cppreference.com they were introduced in 3.3.
# define FMT_USE_EXTERN_TEMPLATES \
((__clang__ && FMT_USE_VARIADIC_TEMPLATES) || \
FMT_GCC_VERSION >= 303)
#endif
#ifdef FMT_HEADER_ONLY
// If header only do not use extern templates.
# undef FMT_USE_EXTERN_TEMPLATES
# define FMT_USE_EXTERN_TEMPLATES 0
#endif
#ifndef FMT_ASSERT #ifndef FMT_ASSERT
# define FMT_ASSERT(condition, message) assert((condition) && message) # define FMT_ASSERT(condition, message) assert((condition) && message)
#endif #endif
@ -812,6 +827,15 @@ class CharTraits<char> : public BasicCharTraits<char> {
const char *format, unsigned width, int precision, T value); const char *format, unsigned width, int precision, T value);
}; };
#if FMT_USE_EXTERN_TEMPLATES
extern template int CharTraits<char>::format_float<double>
(char *buffer, std::size_t size,
const char* format, unsigned width, int precision, double value);
extern template int CharTraits<char>::format_float<long double
(char *buffer, std::size_t size,
const char* format, unsigned width, int precision, long double value);
#endif
template <> template <>
class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> { class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> {
public: public:
@ -823,6 +847,15 @@ class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> {
const wchar_t *format, unsigned width, int precision, T value); const wchar_t *format, unsigned width, int precision, T value);
}; };
#if FMT_USE_EXTERN_TEMPLATES
extern template int CharTraits<wchar_t>::format_float<double>
(wchar_t *buffer, std::size_t size,
const wchar_t* format, unsigned width, int precision, double value);
extern template int CharTraits<wchar_t>::format_float<long double>
(wchar_t *buffer, std::size_t size,
const wchar_t* format, unsigned width, int precision, long double value);
#endif
// Checks if a number is negative - used to avoid warnings. // Checks if a number is negative - used to avoid warnings.
template <bool IsSigned> template <bool IsSigned>
struct SignChecker { struct SignChecker {
@ -869,13 +902,7 @@ struct FMT_API BasicData {
static const char DIGITS[]; static const char DIGITS[];
}; };
#ifndef FMT_USE_EXTERN_TEMPLATES #if FMT_USE_EXTERN_TEMPLATES
// Clang doesn't have a feature check for extern templates so we check
// for variadic templates which were introduced in the same version.
# define FMT_USE_EXTERN_TEMPLATES (__clang__ && FMT_USE_VARIADIC_TEMPLATES)
#endif
#if FMT_USE_EXTERN_TEMPLATES && !defined(FMT_HEADER_ONLY)
extern template struct BasicData<void>; extern template struct BasicData<void>;
#endif #endif