diff --git a/mdbx.h++ b/mdbx.h++ index ba403bca..6426f3fa 100644 --- a/mdbx.h++ +++ b/mdbx.h++ @@ -107,6 +107,16 @@ #include #endif +#if !defined(_MSC_VER) || defined(__clang__) +/* adequate compilers */ +#define MDBX_EXTERN_API_TEMPLATE(API_ATTRIBUTES, API_TYPENAME) extern template class API_ATTRIBUTES API_TYPENAME +#define MDBX_INSTALL_API_TEMPLATE(API_ATTRIBUTES, API_TYPENAME) template class API_TYPENAME +#else +/* stupid microsoft showing off */ +#define MDBX_EXTERN_API_TEMPLATE(API_ATTRIBUTES, API_TYPENAME) extern template class API_TYPENAME +#define MDBX_INSTALL_API_TEMPLATE(API_ATTRIBUTES, API_TYPENAME) template class API_ATTRIBUTES API_TYPENAME +#endif + #if __cplusplus >= 201103L #include #include @@ -1500,8 +1510,7 @@ public: private: friend class txn; - struct silo; - using swap_alloc = allocation_aware_details::swap_alloc; + using swap_alloc = allocation_aware_details::swap_alloc; struct silo /* Empty Base Class Optimization */ : public allocator_type { MDBX_CXX20_CONSTEXPR const allocator_type &get_allocator() const noexcept { return *this; } MDBX_CXX20_CONSTEXPR allocator_type &get_allocator() noexcept { return *this; } @@ -2729,6 +2738,12 @@ inline string make_string(const PRODUCER &producer, const ALLOCATOR & return result; } +MDBX_EXTERN_API_TEMPLATE(LIBMDBX_API_TYPE, buffer); + +#if defined(__cpp_lib_memory_resource) && __cpp_lib_memory_resource >= 201603L && _GLIBCXX_USE_CXX11_ABI +MDBX_EXTERN_API_TEMPLATE(LIBMDBX_API_TYPE, buffer); +#endif /* __cpp_lib_memory_resource >= 201603L */ + /// \brief Combines data slice with boolean flag to represent result of certain /// operations. struct value_result { @@ -2854,9 +2869,13 @@ template struct buffer_pair_spec operator pair() const noexcept { return pair(key, value); } }; +/// \brief Combines pair of buffers for key and value to hold an operands for certain operations. template using buffer_pair = buffer_pair_spec; +/// \brief Default pair of buffers. +using default_buffer_pair = buffer_pair; + /// end of cxx_data @} //------------------------------------------------------------------------------ diff --git a/src/mdbx.c++ b/src/mdbx.c++ index 7b4d8aa1..565c79e9 100644 --- a/src/mdbx.c++ +++ b/src/mdbx.c++ @@ -1162,12 +1162,32 @@ bool from_base64::is_erroneous() const noexcept { //------------------------------------------------------------------------------ -template class LIBMDBX_API_TYPE buffer; +#if defined(_MSC_VER) +#pragma warning(push) +/* warning C4251: 'mdbx::buffer<...>::silo_': + * struct 'mdbx::buffer<..>::silo' needs to have dll-interface to be used by clients of class 'mdbx::buffer<...>' + * + * Microsoft не хочет признавать ошибки и пересматривать приятные решения, поэтому MSVC продолжает кошмарить + * и стращать разработчиков предупреждениями, тем самым перекладывая ответственность на их плечи. + * + * В данном случае предупреждение выдаётся из-за инстанцирования std::string::allocator_type::pointer и + * std::pmr::string::allocator_type::pointer внутри mdbx::buffer<..>::silo. А так как эти типы являются частью + * стандартной библиотеки C++ они всегда будут доступны и без необходимости их инстанцирования и экспорта из libmdbx. + * + * Поэтому нет других вариантов как заглушить это предупреждение и еще раз плюнуть в сторону microsoft. */ +#pragma warning(disable : 4251) +#endif /* MSVC */ + +MDBX_INSTALL_API_TEMPLATE(LIBMDBX_API_TYPE, buffer); #if defined(__cpp_lib_memory_resource) && __cpp_lib_memory_resource >= 201603L && _GLIBCXX_USE_CXX11_ABI -template class LIBMDBX_API_TYPE buffer; +MDBX_INSTALL_API_TEMPLATE(LIBMDBX_API_TYPE, buffer); #endif /* __cpp_lib_memory_resource >= 201603L */ +#if defined(_MSC_VER) +#pragma warning(pop) +#endif /* MSVC */ + //------------------------------------------------------------------------------ static inline MDBX_env_flags_t mode2flags(env::mode mode) {