diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index dc780b4b..714c1014 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -460,7 +460,7 @@ auto write(OutputIt out, const std::tm& time, const std::locale& loc, } // namespace detail -FMT_EXPORT_BEGIN +FMT_BEGIN_EXPORT /** Converts given time since epoch as ``std::time_t`` value into calendar time, @@ -2288,7 +2288,7 @@ template struct formatter { } }; -FMT_EXPORT_END +FMT_END_EXPORT FMT_END_NAMESPACE #endif // FMT_CHRONO_H_ diff --git a/include/fmt/color.h b/include/fmt/color.h index dbb2cefb..d175448a 100644 --- a/include/fmt/color.h +++ b/include/fmt/color.h @@ -11,7 +11,7 @@ #include "format.h" FMT_BEGIN_NAMESPACE -FMT_EXPORT_BEGIN +FMT_BEGIN_EXPORT enum class color : uint32_t { alice_blue = 0xF0F8FF, // rgb(240,248,255) @@ -627,7 +627,7 @@ FMT_CONSTEXPR auto styled(const T& value, text_style ts) return detail::styled_arg>{value, ts}; } -FMT_EXPORT_END +FMT_END_EXPORT FMT_END_NAMESPACE #endif // FMT_COLOR_H_ diff --git a/include/fmt/compile.h b/include/fmt/compile.h index 1180eab9..38e02dfa 100644 --- a/include/fmt/compile.h +++ b/include/fmt/compile.h @@ -497,7 +497,7 @@ constexpr auto compile(S format_str) { #endif // defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) } // namespace detail -FMT_EXPORT_BEGIN +FMT_BEGIN_EXPORT #if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) @@ -601,7 +601,7 @@ template constexpr auto operator""_cf() { } // namespace literals #endif -FMT_EXPORT_END +FMT_END_EXPORT FMT_END_NAMESPACE #endif // FMT_COMPILE_H_ diff --git a/include/fmt/core.h b/include/fmt/core.h index 19bc46c8..08c8cd16 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -183,21 +183,17 @@ #ifndef FMT_MODULE_EXPORT # define FMT_MODULE_EXPORT -# define FMT_EXPORT_BEGIN -# define FMT_EXPORT_END -# define FMT_BEGIN_DETAIL_NAMESPACE namespace detail { -# define FMT_END_DETAIL_NAMESPACE } +# define FMT_BEGIN_EXPORT +# define FMT_END_EXPORT #endif #if !defined(FMT_HEADER_ONLY) && defined(_WIN32) -# define FMT_CLASS_API FMT_MSC_WARNING(suppress : 4275) # ifdef FMT_LIB_EXPORT # define FMT_API __declspec(dllexport) # elif defined(FMT_SHARED) # define FMT_API __declspec(dllimport) # endif #else -# define FMT_CLASS_API # if defined(FMT_LIB_EXPORT) || defined(FMT_SHARED) # if defined(__GNUC__) || defined(__clang__) # define FMT_API __attribute__((visibility("default"))) @@ -262,7 +258,6 @@ FMT_GCC_PRAGMA("GCC optimize(\"Og\")") #endif FMT_BEGIN_NAMESPACE -FMT_EXPORT_BEGIN // Implementations of enable_if_t and other metafunctions for older systems. template @@ -300,8 +295,7 @@ inline auto format_as(std::byte b) -> unsigned char { } #endif -FMT_BEGIN_DETAIL_NAMESPACE - +namespace detail { // Suppresses "unused variable" warnings with the method described in // https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/. // (void)var does not work on many Intel compilers. @@ -391,7 +385,7 @@ FMT_CONSTEXPR inline auto is_utf8() -> bool { return FMT_UNICODE || (sizeof(section) == 3 && uchar(section[0]) == 0xC2 && uchar(section[1]) == 0xA7); } -FMT_END_DETAIL_NAMESPACE +} // namespace detail /** An implementation of ``std::basic_string_view`` for pre-C++17. It provides a @@ -508,7 +502,7 @@ using string_view = basic_string_view; template struct is_char : std::false_type {}; template <> struct is_char : std::true_type {}; -FMT_BEGIN_DETAIL_NAMESPACE +namespace detail { // A base class for compile-time strings. struct compile_string {}; @@ -640,7 +634,7 @@ struct error_handler { throw_format_error(message); } }; -FMT_END_DETAIL_NAMESPACE +} // namespace detail /** String's character type. */ template using char_t = typename detail::char_t_impl::type; @@ -719,7 +713,7 @@ template class basic_format_parse_context { using format_parse_context = basic_format_parse_context; -FMT_BEGIN_DETAIL_NAMESPACE +namespace detail { // A parse context with extra data used only in compile-time checks. template class compile_parse_context : public basic_format_parse_context { @@ -757,7 +751,7 @@ class compile_parse_context : public basic_format_parse_context { #endif } }; -FMT_END_DETAIL_NAMESPACE +} // namespace detail template FMT_CONSTEXPR void basic_format_parse_context::do_check_arg_id(int id) { @@ -805,7 +799,7 @@ struct is_contiguous> : std::true_type {}; class appender; -FMT_BEGIN_DETAIL_NAMESPACE +namespace detail { template constexpr auto has_const_formatter_impl(T*) @@ -1481,8 +1475,7 @@ enum { packed_arg_bits = 4 }; enum { max_packed_args = 62 / packed_arg_bits }; enum : unsigned long long { is_unpacked_bit = 1ULL << 63 }; enum : unsigned long long { has_named_args_bit = 1ULL << 62 }; - -FMT_END_DETAIL_NAMESPACE +} // namespace detail // An output iterator that appends to a buffer. // It is used to reduce symbol sizes for the common case. @@ -1601,7 +1594,7 @@ FMT_CONSTEXPR FMT_INLINE auto visit_format_arg( return vis(monostate()); } -FMT_BEGIN_DETAIL_NAMESPACE +namespace detail { template auto copy_str(InputIt begin, InputIt end, appender out) -> appender { @@ -1716,7 +1709,7 @@ template basic_format_arg { return make_arg(value); } -FMT_END_DETAIL_NAMESPACE +} // namespace detail // Formatting context. template class basic_format_context { @@ -2005,7 +1998,7 @@ enum type FMT_ENUM_UNDERLYING_TYPE(unsigned char){none, minus, plus, space}; } using sign_t = sign::type; -FMT_BEGIN_DETAIL_NAMESPACE +namespace detail { // Workaround an array initialization issue in gcc 4.8. template struct fill_t { @@ -2030,7 +2023,7 @@ template struct fill_t { return data_[index]; } }; -FMT_END_DETAIL_NAMESPACE +} // namespace detail enum class presentation_type : unsigned char { none, @@ -2075,7 +2068,7 @@ template struct format_specs { localized(false) {} }; -FMT_BEGIN_DETAIL_NAMESPACE +namespace detail { enum class arg_id_kind { none, index, name }; @@ -2687,7 +2680,9 @@ FMT_API void vprint_mojibake(std::FILE*, string_view, format_args); #ifndef _WIN32 inline void vprint_mojibake(std::FILE*, string_view, format_args) {} #endif -FMT_END_DETAIL_NAMESPACE +} // namespace detail + +FMT_BEGIN_EXPORT // A formatter specialization for natively supported types. template @@ -2940,7 +2935,7 @@ FMT_INLINE void println(format_string fmt, T&&... args) { return fmt::println(stdout, fmt, std::forward(args)...); } -FMT_EXPORT_END +FMT_END_EXPORT FMT_GCC_PRAGMA("GCC pop_options") FMT_END_NAMESPACE diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index fc8fbb3f..2bda1c56 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -144,10 +144,6 @@ FMT_API FMT_FUNC auto format_facet::do_put( } #endif -#if !FMT_MSC_VERSION -FMT_API FMT_FUNC format_error::~format_error() noexcept = default; -#endif - FMT_FUNC std::system_error vsystem_error(int error_code, string_view format_str, format_args args) { auto ec = std::error_code(error_code, std::generic_category()); diff --git a/include/fmt/format.h b/include/fmt/format.h index 44a834fe..d94da7cb 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -48,6 +48,11 @@ #include "core.h" +#ifndef FMT_BEGIN_DETAIL_NAMESPACE +# define FMT_BEGIN_DETAIL_NAMESPACE namespace detail { +# define FMT_END_DETAIL_NAMESPACE } +#endif + #if FMT_HAS_CPP17_ATTRIBUTE(fallthrough) # define FMT_FALLTHROUGH [[fallthrough]] #elif defined(__clang__) @@ -97,12 +102,6 @@ # define FMT_NOINLINE #endif -#if FMT_MSC_VERSION -# define FMT_MSC_DEFAULT = default -#else -# define FMT_MSC_DEFAULT -#endif - #ifndef FMT_THROW # if FMT_EXCEPTIONS # if FMT_MSC_VERSION || defined(__NVCC__) @@ -893,7 +892,7 @@ template struct is_locale> : std::true_type {}; } // namespace detail -FMT_EXPORT_BEGIN +FMT_BEGIN_EXPORT // The number of characters to store in the basic_memory_buffer object itself // to avoid dynamic memory allocation. @@ -936,7 +935,27 @@ class basic_memory_buffer final : public detail::buffer { } protected: - FMT_CONSTEXPR20 void grow(size_t size) override; + FMT_CONSTEXPR20 void grow(size_t size) override { + detail::abort_fuzzing_if(size > 5000); + const size_t max_size = std::allocator_traits::max_size(alloc_); + size_t old_capacity = this->capacity(); + size_t new_capacity = old_capacity + old_capacity / 2; + if (size > new_capacity) + new_capacity = size; + else if (new_capacity > max_size) + new_capacity = size > max_size ? size : max_size; + T* old_data = this->data(); + T* new_data = + std::allocator_traits::allocate(alloc_, new_capacity); + // The following code doesn't throw, so the raw pointer above doesn't leak. + std::uninitialized_copy(old_data, old_data + this->size(), + detail::make_checked(new_data, new_capacity)); + this->set(new_data, new_capacity); + // deallocate must not throw according to the standard, but even if it does, + // the buffer already uses the new storage and will deallocate it in + // destructor. + if (old_data != store_) alloc_.deallocate(old_data, old_capacity); + } public: using value_type = T; @@ -1013,30 +1032,6 @@ class basic_memory_buffer final : public detail::buffer { } }; -template -FMT_CONSTEXPR20 void basic_memory_buffer::grow( - size_t size) { - detail::abort_fuzzing_if(size > 5000); - const size_t max_size = std::allocator_traits::max_size(alloc_); - size_t old_capacity = this->capacity(); - size_t new_capacity = old_capacity + old_capacity / 2; - if (size > new_capacity) - new_capacity = size; - else if (new_capacity > max_size) - new_capacity = size > max_size ? size : max_size; - T* old_data = this->data(); - T* new_data = - std::allocator_traits::allocate(alloc_, new_capacity); - // The following code doesn't throw, so the raw pointer above doesn't leak. - std::uninitialized_copy(old_data, old_data + this->size(), - detail::make_checked(new_data, new_capacity)); - this->set(new_data, new_capacity); - // deallocate must not throw according to the standard, but even if it does, - // the buffer already uses the new storage and will deallocate it in - // destructor. - if (old_data != store_) alloc_.deallocate(old_data, old_capacity); -} - using memory_buffer = basic_memory_buffer; template @@ -1050,16 +1045,15 @@ FMT_API bool write_console(std::FILE* f, string_view text); FMT_API void print(std::FILE*, string_view); } // namespace detail +// Suppress a misleading warning in older versions of clang. +#if FMT_CLANG_VERSION +# pragma clang diagnostic ignored "-Wweak-vtables" +#endif + /** An error reported from a formatting function. */ -FMT_CLASS_API class FMT_API format_error : public std::runtime_error { public: using std::runtime_error::runtime_error; - format_error(const format_error&) = default; - format_error& operator=(const format_error&) = default; - format_error(format_error&&) = default; - format_error& operator=(format_error&&) = default; - ~format_error() noexcept override FMT_MSC_DEFAULT; }; namespace detail_exported { @@ -4235,26 +4229,6 @@ class format_int { auto str() const -> std::string { return std::string(str_, size()); } }; -template -template -FMT_CONSTEXPR FMT_INLINE auto -formatter::value != - detail::type::custom_type>>::format(const T& val, - FormatContext& ctx) - const -> decltype(ctx.out()) { - if (specs_.width_ref.kind != detail::arg_id_kind::none || - specs_.precision_ref.kind != detail::arg_id_kind::none) { - auto specs = specs_; - detail::handle_dynamic_spec(specs.width, - specs.width_ref, ctx); - detail::handle_dynamic_spec( - specs.precision, specs.precision_ref, ctx); - return detail::write(ctx.out(), val, specs, ctx.locale()); - } - return detail::write(ctx.out(), val, specs_, ctx.locale()); -} - template struct formatter::value>> : private formatter> { @@ -4678,7 +4652,28 @@ FMT_NODISCARD FMT_INLINE auto formatted_size(const Locale& loc, return buf.count(); } -FMT_EXPORT_END +FMT_END_EXPORT + +template +template +FMT_CONSTEXPR FMT_INLINE auto +formatter::value != + detail::type::custom_type>>::format(const T& val, + FormatContext& ctx) + const -> decltype(ctx.out()) { + if (specs_.width_ref.kind != detail::arg_id_kind::none || + specs_.precision_ref.kind != detail::arg_id_kind::none) { + auto specs = specs_; + detail::handle_dynamic_spec(specs.width, + specs.width_ref, ctx); + detail::handle_dynamic_spec( + specs.precision, specs.precision_ref, ctx); + return detail::write(ctx.out(), val, specs, ctx.locale()); + } + return detail::write(ctx.out(), val, specs_, ctx.locale()); +} + FMT_END_NAMESPACE #ifdef FMT_HEADER_ONLY diff --git a/include/fmt/os.h b/include/fmt/os.h index 97d9d25d..dea86557 100644 --- a/include/fmt/os.h +++ b/include/fmt/os.h @@ -71,7 +71,7 @@ #define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1) FMT_BEGIN_NAMESPACE -FMT_EXPORT_BEGIN +FMT_BEGIN_EXPORT /** \rst @@ -465,7 +465,7 @@ inline ostream output_file(cstring_view path, T... params) { } #endif // FMT_USE_FCNTL -FMT_EXPORT_END +FMT_END_EXPORT FMT_END_NAMESPACE #endif // FMT_OS_H_ diff --git a/include/fmt/printf.h b/include/fmt/printf.h index bcb2dd3e..25e93bb3 100644 --- a/include/fmt/printf.h +++ b/include/fmt/printf.h @@ -14,7 +14,7 @@ #include "format.h" FMT_BEGIN_NAMESPACE -FMT_EXPORT_BEGIN +FMT_BEGIN_EXPORT template struct printf_formatter { printf_formatter() = delete; }; @@ -673,7 +673,7 @@ inline auto printf(const S& fmt, const T&... args) -> int { fmt::make_format_args>>(args...)); } -FMT_EXPORT_END +FMT_END_EXPORT FMT_END_NAMESPACE #endif // FMT_PRINTF_H_ diff --git a/include/fmt/ranges.h b/include/fmt/ranges.h index 211bc84b..266b9e1b 100644 --- a/include/fmt/ranges.h +++ b/include/fmt/ranges.h @@ -683,7 +683,7 @@ struct formatter list, string_view sep) return join(std::begin(list), std::end(list), sep); } -FMT_EXPORT_END +FMT_END_EXPORT FMT_END_NAMESPACE #endif // FMT_RANGES_H_ diff --git a/include/fmt/xchar.h b/include/fmt/xchar.h index 360ab759..d7b2fa47 100644 --- a/include/fmt/xchar.h +++ b/include/fmt/xchar.h @@ -37,7 +37,7 @@ inline auto write_loc(std::back_insert_iterator> out, } } // namespace detail -FMT_EXPORT_BEGIN +FMT_BEGIN_EXPORT using wstring_view = basic_string_view; using wformat_parse_context = basic_format_parse_context; @@ -253,7 +253,7 @@ template void println(wformat_string fmt, T&&... args) { template inline auto to_wstring(const T& value) -> std::wstring { return format(FMT_STRING(L"{}"), value); } -FMT_EXPORT_END +FMT_END_EXPORT FMT_END_NAMESPACE #endif // FMT_XCHAR_H_ diff --git a/src/fmt.cc b/src/fmt.cc index d09c4855..05351439 100644 --- a/src/fmt.cc +++ b/src/fmt.cc @@ -1,9 +1,5 @@ module; -#if !defined(WIN32_LEAN_AND_MEAN) && defined(_WIN32) -# define WIN32_LEAN_AND_MEAN -#endif - // Put all implementation-provided headers into the global module fragment // to prevent attachment to this module. #include @@ -54,22 +50,23 @@ module; # endif #endif #ifdef _WIN32 +# define WIN32_LEAN_AND_MEAN # include #endif export module fmt; #define FMT_MODULE_EXPORT export -#define FMT_EXPORT_BEGIN export { -#define FMT_EXPORT_END } +#define FMT_BEGIN_EXPORT export { +#define FMT_END_EXPORT } #define FMT_BEGIN_DETAIL_NAMESPACE \ } \ namespace detail { #define FMT_END_DETAIL_NAMESPACE \ } \ export { -// all library-provided declarations and definitions -// must be in the module purview to be exported +// All library-provided declarations and definitions must be in the module +// purview to be exported. #include "fmt/args.h" #include "fmt/chrono.h" #include "fmt/color.h" diff --git a/src/os.cc b/src/os.cc index 959502c6..f530d7a5 100644 --- a/src/os.cc +++ b/src/os.cc @@ -372,22 +372,22 @@ file file::open_windows_file(wcstring_view path, int oflag) { } # endif -#if !defined(__MSDOS__) +# if !defined(__MSDOS__) long getpagesize() { -# ifdef _WIN32 +# ifdef _WIN32 SYSTEM_INFO si; GetSystemInfo(&si); return si.dwPageSize; -# else +# else long size = FMT_POSIX_CALL(sysconf(_SC_PAGESIZE)); if (size < 0) FMT_THROW(system_error(errno, FMT_STRING("cannot get memory page size"))); return size; -# endif +# endif } -#endif +# endif -FMT_BEGIN_DETAIL_NAMESPACE +namespace detail { void file_buffer::grow(size_t) { if (this->size() == this->capacity()) flush(); @@ -410,8 +410,7 @@ file_buffer::~file_buffer() { flush(); delete[] data(); } - -FMT_END_DETAIL_NAMESPACE +} // namespace detail ostream::~ostream() = default; #endif // FMT_USE_FCNTL