diff options
Diffstat (limited to 'include/fmt/std.h')
-rw-r--r-- | include/fmt/std.h | 82 |
1 files changed, 69 insertions, 13 deletions
diff --git a/include/fmt/std.h b/include/fmt/std.h index 4d1f97d2..7cff1159 100644 --- a/include/fmt/std.h +++ b/include/fmt/std.h @@ -38,6 +38,10 @@ # endif #endif +#if FMT_CPLUSPLUS > 201703L && FMT_HAS_INCLUDE(<source_location>) +# include <source_location> +#endif + // GCC 4 does not support FMT_HAS_INCLUDE. #if FMT_HAS_INCLUDE(<cxxabi.h>) || defined(__GLIBCXX__) # include <cxxabi.h> @@ -59,13 +63,31 @@ # endif #endif -#ifdef __cpp_lib_filesystem +// For older Xcode versions, __cpp_lib_xxx flags are inaccurately defined. +#ifndef FMT_CPP_LIB_FILESYSTEM +# ifdef __cpp_lib_filesystem +# define FMT_CPP_LIB_FILESYSTEM __cpp_lib_filesystem +# else +# define FMT_CPP_LIB_FILESYSTEM 0 +# endif +#endif + +#ifndef FMT_CPP_LIB_VARIANT +# ifdef __cpp_lib_variant +# define FMT_CPP_LIB_VARIANT __cpp_lib_variant +# else +# define FMT_CPP_LIB_VARIANT 0 +# endif +#endif + +#if FMT_CPP_LIB_FILESYSTEM FMT_BEGIN_NAMESPACE namespace detail { -template <typename Char, typename PathChar> auto get_path_string( - const std::filesystem::path& p, const std::basic_string<PathChar>& native) { +template <typename Char, typename PathChar> +auto get_path_string(const std::filesystem::path& p, + const std::basic_string<PathChar>& native) { if constexpr (std::is_same_v<Char, char> && std::is_same_v<PathChar, wchar_t>) return to_utf8<wchar_t>(native, to_utf8_error_policy::replace); else @@ -76,7 +98,8 @@ template <typename Char, typename PathChar> void write_escaped_path(basic_memory_buffer<Char>& quoted, const std::filesystem::path& p, const std::basic_string<PathChar>& native) { - if constexpr (std::is_same_v<Char, char> && std::is_same_v<PathChar, wchar_t>) { + if constexpr (std::is_same_v<Char, char> && + std::is_same_v<PathChar, wchar_t>) { auto buf = basic_memory_buffer<wchar_t>(); write_escaped_string<wchar_t>(std::back_inserter(buf), native); bool valid = to_utf8<wchar_t>::convert(quoted, {buf.data(), buf.size()}); @@ -97,6 +120,7 @@ template <typename Char> struct formatter<std::filesystem::path, Char> { format_specs<Char> specs_; detail::arg_ref<Char> width_ref_; bool debug_ = false; + char path_type_ = 0; public: FMT_CONSTEXPR void set_debug_format(bool set = true) { debug_ = set; } @@ -113,27 +137,34 @@ template <typename Char> struct formatter<std::filesystem::path, Char> { debug_ = true; ++it; } + if (it != end && (*it == 'g')) path_type_ = *it++; return it; } template <typename FormatContext> auto format(const std::filesystem::path& p, FormatContext& ctx) const { auto specs = specs_; +# ifdef _WIN32 + auto path_string = !path_type_ ? p.native() : p.generic_wstring(); +# else + auto path_string = !path_type_ ? p.native() : p.generic_string(); +# endif + detail::handle_dynamic_spec<detail::width_checker>(specs.width, width_ref_, ctx); if (!debug_) { - auto s = detail::get_path_string<Char>(p, p.native()); + auto s = detail::get_path_string<Char>(p, path_string); return detail::write(ctx.out(), basic_string_view<Char>(s), specs); } auto quoted = basic_memory_buffer<Char>(); - detail::write_escaped_path(quoted, p, p.native()); + detail::write_escaped_path(quoted, p, path_string); return detail::write(ctx.out(), basic_string_view<Char>(quoted.data(), quoted.size()), specs); } }; FMT_END_NAMESPACE -#endif +#endif // FMT_CPP_LIB_FILESYSTEM FMT_BEGIN_NAMESPACE FMT_EXPORT @@ -145,7 +176,7 @@ struct formatter<std::bitset<N>, Char> : nested_formatter<string_view> { const std::bitset<N>& bs; template <typename OutputIt> - FMT_CONSTEXPR OutputIt operator()(OutputIt out) { + FMT_CONSTEXPR auto operator()(OutputIt out) -> OutputIt { for (auto pos = N; pos > 0; --pos) { out = detail::write<Char>(out, bs[pos - 1] ? Char('1') : Char('0')); } @@ -197,7 +228,7 @@ struct formatter<std::optional<T>, Char, } template <typename FormatContext> - auto format(std::optional<T> const& opt, FormatContext& ctx) const + auto format(const std::optional<T>& opt, FormatContext& ctx) const -> decltype(ctx.out()) { if (!opt) return detail::write<Char>(ctx.out(), none); @@ -211,7 +242,32 @@ struct formatter<std::optional<T>, Char, FMT_END_NAMESPACE #endif // __cpp_lib_optional -#ifdef __cpp_lib_variant +#ifdef __cpp_lib_source_location +FMT_BEGIN_NAMESPACE +FMT_EXPORT +template <> struct formatter<std::source_location> { + template <typename ParseContext> FMT_CONSTEXPR auto parse(ParseContext& ctx) { + return ctx.begin(); + } + + template <typename FormatContext> + auto format(const std::source_location& loc, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto out = ctx.out(); + out = detail::write(out, loc.file_name()); + out = detail::write(out, ':'); + out = detail::write<char>(out, loc.line()); + out = detail::write(out, ':'); + out = detail::write<char>(out, loc.column()); + out = detail::write(out, ": "); + out = detail::write(out, loc.function_name()); + return out; + } +}; +FMT_END_NAMESPACE +#endif + +#if FMT_CPP_LIB_VARIANT FMT_BEGIN_NAMESPACE namespace detail { @@ -302,7 +358,7 @@ struct formatter< } }; FMT_END_NAMESPACE -#endif // __cpp_lib_variant +#endif // FMT_CPP_LIB_VARIANT FMT_BEGIN_NAMESPACE FMT_EXPORT @@ -326,7 +382,7 @@ template <typename Char> struct formatter<std::error_code, Char> { FMT_EXPORT template <typename T, typename Char> struct formatter< - T, Char, + T, Char, // DEPRECATED! Mixing code unit types. typename std::enable_if<std::is_base_of<std::exception, T>::value>::type> { private: bool with_typename_ = false; @@ -357,7 +413,7 @@ struct formatter< # ifdef FMT_HAS_ABI_CXA_DEMANGLE int status = 0; std::size_t size = 0; - std::unique_ptr<char, decltype(&std::free)> demangled_name_ptr( + std::unique_ptr<char, void (*)(void*)> demangled_name_ptr( abi::__cxa_demangle(ti.name(), nullptr, &size, &status), &std::free); string_view demangled_name_view; |