aboutsummaryrefslogtreecommitdiff
path: root/include/fmt/std.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/fmt/std.h')
-rw-r--r--include/fmt/std.h82
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;