mirror of
https://github.com/fmtlib/fmt.git
synced 2024-11-08 20:30:06 +00:00
Fix DLL visibility of explicit instantiation "declaration" of internal::basic_data<void> in header format.h and the explicit instantiation "definition" in format.cc (#1134)
* Update format.cc As the explicit instantiation *declaration* of `internal::basic_data<void>` in format.h, this explicit instantiation *definition* should mirror FMT_API also. * Mirror visibility of explicit instantiation declaration explicit instantiation declaration of internal::basic_data<void> should mirror visibility of FMT_API * Eliminate `__declspec(dllexport)` designation on extern template internal::basic_data<> when `extern` affected during exporting phase. * Add `FMT_EXTERN_TEMPLATE_API` for designate DLL export `extern template` When exporting DLL, do not designate `__declspec(dllexport)` any template that has any explicit class template declaration a.k.a. `extern template`. Instead, designate `__declspec(dllexport)` at single point where we have explicit class template definition a.k.a. normal instantiation without `extern` Note: this is a c++11 feature. * Delete whole `FMT_USE_EXTERN_TEMPLATES` block and its condition 1. Remove whole `FMT_USE_EXTERN_TEMPLATES` block (trailing `FMT_UDL_TEMPLATE` block) ```` #ifndef FMT_USE_EXTERN_TEMPLATES # ifndef FMT_HEADER_ONLY # define FMT_USE_EXTERN_TEMPLATES \ ((FMT_CLANG_VERSION >= 209 && __cplusplus >= 201103L) || \ (FMT_GCC_VERSION >= 303 && FMT_HAS_GXX_CXX11)) # else # define FMT_USE_EXTERN_TEMPLATES 0 # endif #endif ```` 2. Delete `FMT_USE_EXTERN_TEMPLATES` condition, only condition, that trailing basic_data class template definition. ```` #if FMT_USE_EXTERN_TEMPLATES extern template struct basic_data<void>; #endif ```` 3. Replace `FMT_API` with new `FMT_EXTERN_TEMPLATE_API` added in `core.h` for sake of extern template of `basic_data<void>` * Add `#define FMT_EXTERN extern` only when not `FMT_HEADER_ONLY` * Replace `extern` on basic_data<void> with the `FMT_EXTERN` condition in core.h * replace misspelled if !define() with ifndef
This commit is contained in:
parent
4a4d72f917
commit
29c10fbf6e
@ -189,11 +189,21 @@
|
|||||||
# define FMT_API __declspec(dllexport)
|
# define FMT_API __declspec(dllexport)
|
||||||
# elif defined(FMT_SHARED)
|
# elif defined(FMT_SHARED)
|
||||||
# define FMT_API __declspec(dllimport)
|
# define FMT_API __declspec(dllimport)
|
||||||
|
# define FMT_EXTERN_TEMPLATE_API FMT_API
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef FMT_API
|
#ifndef FMT_API
|
||||||
# define FMT_API
|
# define FMT_API
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef FMT_EXTERN_TEMPLATE_API
|
||||||
|
# define FMT_EXTERN_TEMPLATE_API
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FMT_HEADER_ONLY
|
||||||
|
# define FMT_EXTERN extern
|
||||||
|
#else
|
||||||
|
# define FMT_EXTERN
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef FMT_ASSERT
|
#ifndef FMT_ASSERT
|
||||||
# define FMT_ASSERT(condition, message) assert((condition) && message)
|
# define FMT_ASSERT(condition, message) assert((condition) && message)
|
||||||
|
@ -159,16 +159,6 @@ FMT_END_NAMESPACE
|
|||||||
# define FMT_UDL_TEMPLATE 0
|
# define FMT_UDL_TEMPLATE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FMT_USE_EXTERN_TEMPLATES
|
|
||||||
# ifndef FMT_HEADER_ONLY
|
|
||||||
# define FMT_USE_EXTERN_TEMPLATES \
|
|
||||||
((FMT_CLANG_VERSION >= 209 && __cplusplus >= 201103L) || \
|
|
||||||
(FMT_GCC_VERSION >= 303 && FMT_HAS_GXX_CXX11))
|
|
||||||
# else
|
|
||||||
# define FMT_USE_EXTERN_TEMPLATES 0
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if FMT_HAS_GXX_CXX11 || FMT_HAS_FEATURE(cxx_trailing_return) || \
|
#if FMT_HAS_GXX_CXX11 || FMT_HAS_FEATURE(cxx_trailing_return) || \
|
||||||
FMT_MSC_VER >= 1600
|
FMT_MSC_VER >= 1600
|
||||||
# define FMT_USE_TRAILING_RETURN 1
|
# define FMT_USE_TRAILING_RETURN 1
|
||||||
@ -712,7 +702,7 @@ template <typename T> struct int_traits {
|
|||||||
|
|
||||||
// Static data is placed in this class template to allow header-only
|
// Static data is placed in this class template to allow header-only
|
||||||
// configuration.
|
// configuration.
|
||||||
template <typename T = void> struct FMT_API basic_data {
|
template <typename T = void> struct FMT_EXTERN_TEMPLATE_API basic_data {
|
||||||
static const uint64_t POWERS_OF_10_64[];
|
static const uint64_t POWERS_OF_10_64[];
|
||||||
static const uint32_t ZERO_OR_POWERS_OF_10_32[];
|
static const uint32_t ZERO_OR_POWERS_OF_10_32[];
|
||||||
static const uint64_t ZERO_OR_POWERS_OF_10_64[];
|
static const uint64_t ZERO_OR_POWERS_OF_10_64[];
|
||||||
@ -726,9 +716,7 @@ template <typename T = void> struct FMT_API basic_data {
|
|||||||
static const wchar_t WRESET_COLOR[5];
|
static const wchar_t WRESET_COLOR[5];
|
||||||
};
|
};
|
||||||
|
|
||||||
#if FMT_USE_EXTERN_TEMPLATES
|
FMT_EXTERN template struct basic_data<void>;
|
||||||
extern template struct basic_data<void>;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// This is a struct rather than a typedef to avoid shadowing warnings in gcc.
|
// This is a struct rather than a typedef to avoid shadowing warnings in gcc.
|
||||||
struct data : basic_data<> {};
|
struct data : basic_data<> {};
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "fmt/format-inl.h"
|
#include "fmt/format-inl.h"
|
||||||
|
|
||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
template struct internal::basic_data<void>;
|
template struct FMT_API internal::basic_data<void>;
|
||||||
|
|
||||||
// Workaround a bug in MSVC2013 that prevents instantiation of grisu_format.
|
// Workaround a bug in MSVC2013 that prevents instantiation of grisu_format.
|
||||||
bool (*instantiate_grisu_format)(double, internal::buffer<char>&, int, unsigned,
|
bool (*instantiate_grisu_format)(double, internal::buffer<char>&, int, unsigned,
|
||||||
|
Loading…
Reference in New Issue
Block a user