Module linkage fixes for shared build (#4169)

* Mark some in-class defined member functions as explicitly inline/constexpr, to avoid missing external symbols when using fmt module with shared build due to modules not defaulting to implicit inline.

* Switch constexpr to inline for context::arg(string_view).
NOTE: Looks as if basic_format_args::get(string_view) could probably be made constexpr instead, but sticking with minimal change approach.

* Work around apparent non-conformance of older MSVC compilers.

* Switch format_int::str() from constexpr to inline to satisfy libstdc++ std::string constexpr limitations.

* Replace usages of macros for constexpr/inline with keywords.

* Fix for locations requiring C++14 constexpr.

* Further minor constexpr tweaks.

* Apply clang format
This commit is contained in:
Cameron Angus
2024-09-26 07:53:55 -07:00
committed by GitHub
parent 891c9a73ae
commit 96dca569a1
5 changed files with 63 additions and 58 deletions
+19 -17
View File
@@ -540,24 +540,24 @@ inline auto localtime(std::time_t time) -> std::tm {
std::time_t time_;
std::tm tm_;
dispatcher(std::time_t t) : time_(t) {}
inline dispatcher(std::time_t t) : time_(t) {}
auto run() -> bool {
inline auto run() -> bool {
using namespace fmt::detail;
return handle(localtime_r(&time_, &tm_));
}
auto handle(std::tm* tm) -> bool { return tm != nullptr; }
inline auto handle(std::tm* tm) -> bool { return tm != nullptr; }
auto handle(detail::null<>) -> bool {
inline auto handle(detail::null<>) -> bool {
using namespace fmt::detail;
return fallback(localtime_s(&tm_, &time_));
}
auto fallback(int res) -> bool { return res == 0; }
inline auto fallback(int res) -> bool { return res == 0; }
#if !FMT_MSC_VERSION
auto fallback(detail::null<>) -> bool {
inline auto fallback(detail::null<>) -> bool {
using namespace fmt::detail;
std::tm* tm = std::localtime(&time_);
if (tm) tm_ = *tm;
@@ -591,24 +591,24 @@ inline auto gmtime(std::time_t time) -> std::tm {
std::time_t time_;
std::tm tm_;
dispatcher(std::time_t t) : time_(t) {}
inline dispatcher(std::time_t t) : time_(t) {}
auto run() -> bool {
inline auto run() -> bool {
using namespace fmt::detail;
return handle(gmtime_r(&time_, &tm_));
}
auto handle(std::tm* tm) -> bool { return tm != nullptr; }
inline auto handle(std::tm* tm) -> bool { return tm != nullptr; }
auto handle(detail::null<>) -> bool {
inline auto handle(detail::null<>) -> bool {
using namespace fmt::detail;
return fallback(gmtime_s(&tm_, &time_));
}
auto fallback(int res) -> bool { return res == 0; }
inline auto fallback(int res) -> bool { return res == 0; }
#if !FMT_MSC_VERSION
auto fallback(detail::null<>) -> bool {
inline auto fallback(detail::null<>) -> bool {
std::tm* tm = std::gmtime(&time_);
if (tm) tm_ = *tm;
return tm != nullptr;
@@ -912,7 +912,9 @@ template <typename Derived> struct null_chrono_spec_handler {
};
struct tm_format_checker : null_chrono_spec_handler<tm_format_checker> {
FMT_NORETURN void unsupported() { FMT_THROW(format_error("no format")); }
FMT_NORETURN inline void unsupported() {
FMT_THROW(format_error("no format"));
}
template <typename Char>
FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
@@ -1572,7 +1574,7 @@ class tm_writer {
struct chrono_format_checker : null_chrono_spec_handler<chrono_format_checker> {
bool has_precision_integral = false;
FMT_NORETURN void unsupported() { FMT_THROW(format_error("no date")); }
FMT_NORETURN inline void unsupported() { FMT_THROW(format_error("no date")); }
template <typename Char>
FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
@@ -1693,14 +1695,14 @@ class get_locale {
bool has_locale_ = false;
public:
get_locale(bool localized, locale_ref loc) : has_locale_(localized) {
inline get_locale(bool localized, locale_ref loc) : has_locale_(localized) {
if (localized)
::new (&locale_) std::locale(loc.template get<std::locale>());
}
~get_locale() {
inline ~get_locale() {
if (has_locale_) locale_.~locale();
}
operator const std::locale&() const {
inline operator const std::locale&() const {
return has_locale_ ? locale_ : get_classic_locale();
}
};