From 5466373a1173e19f9f448908a4b70f410873f1b9 Mon Sep 17 00:00:00 2001 From: Daniela Engert Date: Fri, 14 May 2021 15:02:45 +0200 Subject: [PATCH] Do *not* export namespace `detail` Introduce `FMT_BEGIN_DETAIL_NAMESPACE` and `FMT_END_DETAIL_NAMESPACE` for `namespace detail` sections embedded in that part of the code that contains all declarations that are exported from the module, i.e. which is enclosed by `FMT_MODULE_EXPORT_BEGIN` and `FMT_MODULE_EXPORT_END`. Given a correct implementation of C++20 modules, neither the name `fmt::detail` nor any of its contents will become visible outside of the module. --- include/fmt/chrono.h | 12 +++++----- include/fmt/color.h | 14 +++++------ include/fmt/core.h | 56 ++++++++++++++++++++++---------------------- include/fmt/format.h | 7 +++--- src/fmt.cc | 6 +++++ 5 files changed, 49 insertions(+), 46 deletions(-) diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index 65a6e6f2..e26e5190 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -382,9 +382,8 @@ inline std::tm gmtime( return gmtime(std::chrono::system_clock::to_time_t(time_point)); } -FMT_MODULE_EXPORT_END +FMT_BEGIN_DETAIL_NAMESPACE -namespace detail { inline size_t strftime(char* str, size_t count, const char* format, const std::tm* time) { // Assign to a pointer to suppress GCCs -Wformat-nonliteral @@ -403,9 +402,8 @@ inline size_t strftime(wchar_t* str, size_t count, const wchar_t* format, wcsftime = std::wcsftime; return wcsftime(str, count, format, time); } -} // namespace detail -FMT_MODULE_EXPORT_BEGIN +FMT_END_DETAIL_NAMESPACE template struct formatter, @@ -458,7 +456,8 @@ template struct formatter { basic_string_view specs; }; -namespace detail { +FMT_BEGIN_DETAIL_NAMESPACE + template FMT_CONSTEXPR const char* get_units() { return nullptr; } @@ -1078,7 +1077,8 @@ struct chrono_formatter { out = format_duration_unit(out); } }; -} // namespace detail + +FMT_END_DETAIL_NAMESPACE template struct formatter, Char> { diff --git a/include/fmt/color.h b/include/fmt/color.h index f2e1a798..8cddbfe1 100644 --- a/include/fmt/color.h +++ b/include/fmt/color.h @@ -206,8 +206,7 @@ struct rgb { uint8_t b; }; -FMT_MODULE_EXPORT_END -namespace detail { +FMT_BEGIN_DETAIL_NAMESPACE // color is a struct of either a rgb color or a terminal color. struct color_type { @@ -230,8 +229,8 @@ struct color_type { uint32_t rgb_color; } value; }; -} // namespace detail -FMT_MODULE_EXPORT_BEGIN + +FMT_END_DETAIL_NAMESPACE /** A text style consisting of foreground and background colors and emphasis. */ class text_style { @@ -370,8 +369,7 @@ FMT_CONSTEXPR inline text_style operator|(emphasis lhs, return text_style(lhs) | rhs; } -FMT_MODULE_EXPORT_END -namespace detail { +FMT_BEGIN_DETAIL_NAMESPACE template struct ansi_color_escape { FMT_CONSTEXPR ansi_color_escape(detail::color_type text_color, @@ -512,8 +510,8 @@ void vformat_to(buffer& buf, const text_style& ts, detail::vformat_to(buf, format_str, args); if (has_style) detail::reset_color(buf); } -} // namespace detail -FMT_MODULE_EXPORT_BEGIN + +FMT_END_DETAIL_NAMESPACE template > void vprint(std::FILE* f, const text_style& ts, const S& format, diff --git a/include/fmt/core.h b/include/fmt/core.h index 399b70e7..293d8242 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -241,6 +241,14 @@ #ifndef FMT_MODULE_EXPORT_END # define FMT_MODULE_EXPORT_END #endif +#ifndef FMT_BEGIN_DETAIL_NAMESPACE +# define FMT_BEGIN_DETAIL_NAMESPACE \ + namespace detail { +#endif +#ifndef FMT_END_DETAIL_NAMESPACE +# define FMT_END_DETAIL_NAMESPACE \ + } +#endif #if !defined(FMT_HEADER_ONLY) && defined(_WIN32) # define FMT_CLASS_API FMT_MSC_WARNING(suppress : 4275) @@ -317,8 +325,6 @@ template using type_identity_t = typename type_identity::type; struct monostate {}; -FMT_MODULE_EXPORT_END - // An enable_if helper to be used in template parameters which results in much // shorter symbols: https://godbolt.org/z/sWw4vP. Extra parentheses are needed // to workaround a bug in MSVC 2019 (see #1140 and #1186). @@ -328,7 +334,7 @@ FMT_MODULE_EXPORT_END # define FMT_ENABLE_IF(...) enable_if_t<(__VA_ARGS__), int> = 0 #endif -namespace detail { +FMT_BEGIN_DETAIL_NAMESPACE constexpr FMT_INLINE bool is_constant_evaluated() FMT_NOEXCEPT { #ifdef __cpp_lib_is_constant_evaluated @@ -393,7 +399,8 @@ template constexpr bool is_unicode() { return FMT_UNICODE || sizeof(Char) != 1 || (sizeof(micro) == 3 && micro[0] == 0xC2 && micro[1] == 0xB5); } -} // namespace detail + +FMT_END_DETAIL_NAMESPACE /** An implementation of ``std::basic_string_view`` for pre-C++17. It provides a @@ -402,8 +409,6 @@ template constexpr bool is_unicode() { compiled with a different ``-std`` option than the client code (which is not recommended). */ -FMT_MODULE_EXPORT_BEGIN - template class basic_string_view { private: const Char* data_; @@ -552,8 +557,8 @@ constexpr basic_string_view to_string_view(const S& s) { return s; } -FMT_MODULE_EXPORT_END -namespace detail { +FMT_BEGIN_DETAIL_NAMESPACE + void to_string_view(...); using fmt::v7::to_string_view; @@ -589,8 +594,8 @@ struct error_handler { // This function is intentionally not constexpr to give a compile-time error. FMT_NORETURN FMT_API void on_error(const char* message); }; -} // namespace detail -FMT_MODULE_EXPORT_BEGIN + +FMT_END_DETAIL_NAMESPACE /** String's character type. */ template using char_t = typename detail::char_t_impl::type; @@ -700,8 +705,7 @@ template struct is_contiguous : std::false_type {}; template struct is_contiguous> : std::true_type {}; -FMT_MODULE_EXPORT_END -namespace detail { +FMT_BEGIN_DETAIL_NAMESPACE // Extracts a reference to the container from back_insert_iterator. template @@ -1320,8 +1324,8 @@ 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 }; -} // namespace detail -FMT_MODULE_EXPORT_BEGIN + +FMT_END_DETAIL_NAMESPACE // A formatting argument. It is a trivially copyable/constructible type to // allow storage in basic_memory_buffer. @@ -1431,8 +1435,7 @@ FMT_CONSTEXPR_DECL FMT_INLINE auto visit_format_arg( return vis(monostate()); } -FMT_MODULE_EXPORT_END -namespace detail { +FMT_BEGIN_DETAIL_NAMESPACE #if FMT_GCC_VERSION && FMT_GCC_VERSION < 500 // A workaround for gcc 4.8 to make void_t work in a SFINAE context. @@ -1517,8 +1520,8 @@ template make_arg(const T& value) { return make_arg(value); } -} // namespace detail -FMT_MODULE_EXPORT_BEGIN + +FMT_END_DETAIL_NAMESPACE // Formatting context. template class basic_format_context { @@ -1576,14 +1579,10 @@ using buffer_context = using format_context = buffer_context; using wformat_context = buffer_context; -FMT_MODULE_EXPORT_END - // Workaround an alias issue: https://stackoverflow.com/q/62767544/471164. #define FMT_BUFFER_CONTEXT(Char) \ basic_format_context, Char> -FMT_MODULE_EXPORT_BEGIN - template using is_formattable = bool_constant< !std::is_same>().map( @@ -1827,7 +1826,8 @@ enum type { none, minus, plus, space }; } using sign_t = sign::type; -namespace detail { +FMT_BEGIN_DETAIL_NAMESPACE + void throw_format_error(const char* message); // Workaround an array initialization issue in gcc 4.8. @@ -1853,7 +1853,8 @@ template struct fill_t { return data_[index]; } }; -} // namespace detail + +FMT_END_DETAIL_NAMESPACE // Format specifiers for built-in and string types. template struct basic_format_specs { @@ -1878,8 +1879,7 @@ template struct basic_format_specs { using format_specs = basic_format_specs; -FMT_MODULE_EXPORT_END -namespace detail { +FMT_BEGIN_DETAIL_NAMESPACE enum class arg_id_kind { none, index, name }; @@ -2583,8 +2583,8 @@ FMT_API void vprint_mojibake(std::FILE*, string_view, format_args); #ifndef _WIN32 inline void vprint_mojibake(std::FILE*, string_view, format_args) {} #endif -} // namespace detail -FMT_MODULE_EXPORT_BEGIN + +FMT_END_DETAIL_NAMESPACE /** Formats a string and writes the output to ``out``. */ // GCC 8 and earlier cannot handle std::back_insert_iterator with diff --git a/include/fmt/format.h b/include/fmt/format.h index 722e4e13..a6dbd819 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -802,8 +802,7 @@ class FMT_API format_error : public std::runtime_error { ~format_error() FMT_NOEXCEPT FMT_OVERRIDE FMT_MSC_DEFAULT; }; -FMT_MODULE_EXPORT_END -namespace detail { +FMT_BEGIN_DETAIL_NAMESPACE inline void throw_format_error(const char* message) { FMT_THROW(format_error(message)); @@ -2534,8 +2533,8 @@ FMT_API void format_error_code(buffer& out, int error_code, FMT_API void report_error(format_func func, int error_code, const char* message) FMT_NOEXCEPT; -} // namespace detail -FMT_MODULE_EXPORT_BEGIN + +FMT_END_DETAIL_NAMESPACE template using arg_formatter FMT_DEPRECATED_ALIAS = diff --git a/src/fmt.cc b/src/fmt.cc index a3af12d1..b0d805da 100644 --- a/src/fmt.cc +++ b/src/fmt.cc @@ -70,6 +70,12 @@ export module fmt; #define FMT_MODULE_EXPORT export #define FMT_MODULE_EXPORT_BEGIN export { #define FMT_MODULE_EXPORT_END } +#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