2323# include < type_traits>
2424# include < typeinfo>
2525# include < utility>
26- # include < vector>
2726
2827// Check FMT_CPLUSPLUS to suppress a bogus warning in MSVC.
2928# if FMT_CPLUSPLUS >= 201703L
7978# endif
8079#endif
8180
82- #if FMT_CPP_LIB_FILESYSTEM
8381FMT_BEGIN_NAMESPACE
84-
8582namespace detail {
8683
84+ #if FMT_CPP_LIB_FILESYSTEM
85+
8786template <typename Char, typename PathChar>
8887auto get_path_string (const std::filesystem::path& p,
8988 const std::basic_string<PathChar>& native) {
@@ -111,8 +110,136 @@ void write_escaped_path(basic_memory_buffer<Char>& quoted,
111110 }
112111}
113112
113+ #endif // FMT_CPP_LIB_FILESYSTEM
114+
115+ #if defined(__cpp_lib_expected) || FMT_CPP_LIB_VARIANT
116+ template <typename Char, typename OutputIt, typename T>
117+ auto write_escaped_alternative (OutputIt out, const T& v) -> OutputIt {
118+ if constexpr (has_to_string_view<T>::value)
119+ return write_escaped_string<Char>(out, detail::to_string_view (v));
120+ if constexpr (std::is_same_v<T, Char>) return write_escaped_char (out, v);
121+ return write<Char>(out, v);
122+ }
123+ #endif
124+
125+ #if FMT_CPP_LIB_VARIANT
126+
127+ template <typename T>
128+ using variant_index_sequence =
129+ std::make_index_sequence<std::variant_size<T>::value>;
130+
131+ template <typename > struct is_variant_like_ : std::false_type {};
132+ template <typename ... Types>
133+ struct is_variant_like_ <std::variant<Types...>> : std::true_type {};
134+
135+ // formattable element check.
136+ template <typename T, typename C> class is_variant_formattable_ {
137+ template <std::size_t ... Is>
138+ static std::conjunction<
139+ is_formattable<std::variant_alternative_t <Is, T>, C>...>
140+ check (std::index_sequence<Is...>);
141+
142+ public:
143+ static constexpr const bool value =
144+ decltype (check(variant_index_sequence<T>{}))::value;
145+ };
146+
147+ #endif // FMT_CPP_LIB_VARIANT
148+
149+ #if FMT_USE_RTTI
150+ template <typename Char, typename OutputIt>
151+ auto write_demangled_name (OutputIt out, const std::type_info& ti) -> OutputIt {
152+ # ifdef FMT_HAS_ABI_CXA_DEMANGLE
153+ int status = 0 ;
154+ std::size_t size = 0 ;
155+ std::unique_ptr<char , void (*)(void *)> demangled_name_ptr (
156+ abi::__cxa_demangle (ti.name (), nullptr , &size, &status), &std::free);
157+
158+ string_view demangled_name_view;
159+ if (demangled_name_ptr) {
160+ demangled_name_view = demangled_name_ptr.get ();
161+
162+ // Normalization of stdlib inline namespace names.
163+ // libc++ inline namespaces.
164+ // std::__1::* -> std::*
165+ // std::__1::__fs::* -> std::*
166+ // libstdc++ inline namespaces.
167+ // std::__cxx11::* -> std::*
168+ // std::filesystem::__cxx11::* -> std::filesystem::*
169+ if (demangled_name_view.starts_with (" std::" )) {
170+ char * begin = demangled_name_ptr.get ();
171+ char * to = begin + 5 ; // std::
172+ for (char *from = to, *end = begin + demangled_name_view.size ();
173+ from < end;) {
174+ // This is safe, because demangled_name is NUL-terminated.
175+ if (from[0 ] == ' _' && from[1 ] == ' _' ) {
176+ char * next = from + 1 ;
177+ while (next < end && *next != ' :' ) next++;
178+ if (next[0 ] == ' :' && next[1 ] == ' :' ) {
179+ from = next + 2 ;
180+ continue ;
181+ }
182+ }
183+ *to++ = *from++;
184+ }
185+ demangled_name_view = {begin, detail::to_unsigned (to - begin)};
186+ }
187+ } else {
188+ demangled_name_view = string_view (ti.name ());
189+ }
190+ return detail::write_bytes<Char>(out, demangled_name_view);
191+ # elif FMT_MSC_VERSION
192+ const string_view demangled_name (ti.name ());
193+ for (std::size_t i = 0 ; i < demangled_name.size (); ++i) {
194+ auto sub = demangled_name;
195+ sub.remove_prefix (i);
196+ if (sub.starts_with (" enum " )) {
197+ i += 4 ;
198+ continue ;
199+ }
200+ if (sub.starts_with (" class " ) || sub.starts_with (" union " )) {
201+ i += 5 ;
202+ continue ;
203+ }
204+ if (sub.starts_with (" struct " )) {
205+ i += 6 ;
206+ continue ;
207+ }
208+ if (*sub.begin () != ' ' ) *out++ = *sub.begin ();
209+ }
210+ return out;
211+ # else
212+ return detail::write_bytes<Char>(out, string_view (ti.name ()));
213+ # endif
214+ }
215+ #endif // FMT_USE_RTTI
216+
217+ template <typename T, typename Enable = void >
218+ struct has_flip : std::false_type {};
219+
220+ template <typename T>
221+ struct has_flip <T, void_t <decltype (std::declval<T>().flip())>>
222+ : std::true_type {};
223+
224+ template <typename T> struct is_bit_reference_like {
225+ static constexpr const bool value =
226+ std::is_convertible<T, bool >::value &&
227+ std::is_nothrow_assignable<T, bool >::value && has_flip<T>::value;
228+ };
229+
230+ // Workaround for libc++ incompatibility with C++ standard.
231+ // According to the Standard, `bitset::operator[] const` returns bool.
232+ #ifdef _LIBCPP_VERSION
233+ template <typename C>
234+ struct is_bit_reference_like <std::__bit_const_reference<C>> {
235+ static constexpr const bool value = true ;
236+ };
237+ #endif
238+
114239} // namespace detail
115240
241+ #if FMT_CPP_LIB_FILESYSTEM
242+
116243template <typename Char> struct formatter <std::filesystem::path, Char> {
117244 private:
118245 format_specs specs_;
@@ -177,10 +304,8 @@ class path : public std::filesystem::path {
177304 auto generic_system_string () const -> std::string { return generic_string (); }
178305};
179306
180- FMT_END_NAMESPACE
181307#endif // FMT_CPP_LIB_FILESYSTEM
182308
183- FMT_BEGIN_NAMESPACE
184309template <std::size_t N, typename Char>
185310struct formatter <std::bitset<N>, Char>
186311 : nested_formatter<basic_string_view<Char>, Char> {
@@ -209,10 +334,8 @@ struct formatter<std::bitset<N>, Char>
209334
210335template <typename Char>
211336struct formatter <std::thread::id, Char> : basic_ostream_formatter<Char> {};
212- FMT_END_NAMESPACE
213337
214338#ifdef __cpp_lib_optional
215- FMT_BEGIN_NAMESPACE
216339template <typename T, typename Char>
217340struct formatter <std::optional<T>, Char,
218341 std::enable_if_t <is_formattable<T, Char>::value>> {
@@ -251,30 +374,9 @@ struct formatter<std::optional<T>, Char,
251374 return detail::write (out, ' )' );
252375 }
253376};
254- FMT_END_NAMESPACE
255377#endif // __cpp_lib_optional
256378
257- #if defined(__cpp_lib_expected) || FMT_CPP_LIB_VARIANT
258-
259- FMT_BEGIN_NAMESPACE
260- namespace detail {
261-
262- template <typename Char, typename OutputIt, typename T>
263- auto write_escaped_alternative (OutputIt out, const T& v) -> OutputIt {
264- if constexpr (has_to_string_view<T>::value)
265- return write_escaped_string<Char>(out, detail::to_string_view (v));
266- if constexpr (std::is_same_v<T, Char>) return write_escaped_char (out, v);
267- return write<Char>(out, v);
268- }
269-
270- } // namespace detail
271-
272- FMT_END_NAMESPACE
273- #endif
274-
275379#ifdef __cpp_lib_expected
276- FMT_BEGIN_NAMESPACE
277-
278380template <typename T, typename E, typename Char>
279381struct formatter <std::expected<T, E>, Char,
280382 std::enable_if_t <(std::is_void<T>::value ||
@@ -301,11 +403,9 @@ struct formatter<std::expected<T, E>, Char,
301403 return out;
302404 }
303405};
304- FMT_END_NAMESPACE
305406#endif // __cpp_lib_expected
306407
307408#ifdef __cpp_lib_source_location
308- FMT_BEGIN_NAMESPACE
309409template <> struct formatter <std::source_location> {
310410 FMT_CONSTEXPR auto parse (parse_context<>& ctx) { return ctx.begin (); }
311411
@@ -323,34 +423,9 @@ template <> struct formatter<std::source_location> {
323423 return out;
324424 }
325425};
326- FMT_END_NAMESPACE
327426#endif
328427
329428#if FMT_CPP_LIB_VARIANT
330- FMT_BEGIN_NAMESPACE
331- namespace detail {
332-
333- template <typename T>
334- using variant_index_sequence =
335- std::make_index_sequence<std::variant_size<T>::value>;
336-
337- template <typename > struct is_variant_like_ : std::false_type {};
338- template <typename ... Types>
339- struct is_variant_like_ <std::variant<Types...>> : std::true_type {};
340-
341- // formattable element check.
342- template <typename T, typename C> class is_variant_formattable_ {
343- template <std::size_t ... Is>
344- static std::conjunction<
345- is_formattable<std::variant_alternative_t <Is, T>, C>...>
346- check (std::index_sequence<Is...>);
347-
348- public:
349- static constexpr const bool value =
350- decltype (check(variant_index_sequence<T>{}))::value;
351- };
352-
353- } // namespace detail
354429
355430template <typename T> struct is_variant_like {
356431 static constexpr const bool value = detail::is_variant_like_<T>::value;
@@ -402,10 +477,9 @@ struct formatter<
402477 return out;
403478 }
404479};
405- FMT_END_NAMESPACE
480+
406481#endif // FMT_CPP_LIB_VARIANT
407482
408- FMT_BEGIN_NAMESPACE
409483template <> struct formatter <std::error_code> {
410484 private:
411485 format_specs specs_;
@@ -459,76 +533,6 @@ template <> struct formatter<std::error_code> {
459533};
460534
461535#if FMT_USE_RTTI
462- namespace detail {
463-
464- template <typename Char, typename OutputIt>
465- auto write_demangled_name (OutputIt out, const std::type_info& ti) -> OutputIt {
466- # ifdef FMT_HAS_ABI_CXA_DEMANGLE
467- int status = 0 ;
468- std::size_t size = 0 ;
469- std::unique_ptr<char , void (*)(void *)> demangled_name_ptr (
470- abi::__cxa_demangle (ti.name (), nullptr , &size, &status), &std::free);
471-
472- string_view demangled_name_view;
473- if (demangled_name_ptr) {
474- demangled_name_view = demangled_name_ptr.get ();
475-
476- // Normalization of stdlib inline namespace names.
477- // libc++ inline namespaces.
478- // std::__1::* -> std::*
479- // std::__1::__fs::* -> std::*
480- // libstdc++ inline namespaces.
481- // std::__cxx11::* -> std::*
482- // std::filesystem::__cxx11::* -> std::filesystem::*
483- if (demangled_name_view.starts_with (" std::" )) {
484- char * begin = demangled_name_ptr.get ();
485- char * to = begin + 5 ; // std::
486- for (char *from = to, *end = begin + demangled_name_view.size ();
487- from < end;) {
488- // This is safe, because demangled_name is NUL-terminated.
489- if (from[0 ] == ' _' && from[1 ] == ' _' ) {
490- char * next = from + 1 ;
491- while (next < end && *next != ' :' ) next++;
492- if (next[0 ] == ' :' && next[1 ] == ' :' ) {
493- from = next + 2 ;
494- continue ;
495- }
496- }
497- *to++ = *from++;
498- }
499- demangled_name_view = {begin, detail::to_unsigned (to - begin)};
500- }
501- } else {
502- demangled_name_view = string_view (ti.name ());
503- }
504- return detail::write_bytes<Char>(out, demangled_name_view);
505- # elif FMT_MSC_VERSION
506- const string_view demangled_name (ti.name ());
507- for (std::size_t i = 0 ; i < demangled_name.size (); ++i) {
508- auto sub = demangled_name;
509- sub.remove_prefix (i);
510- if (sub.starts_with (" enum " )) {
511- i += 4 ;
512- continue ;
513- }
514- if (sub.starts_with (" class " ) || sub.starts_with (" union " )) {
515- i += 5 ;
516- continue ;
517- }
518- if (sub.starts_with (" struct " )) {
519- i += 6 ;
520- continue ;
521- }
522- if (*sub.begin () != ' ' ) *out++ = *sub.begin ();
523- }
524- return out;
525- # else
526- return detail::write_bytes<Char>(out, string_view (ti.name ()));
527- # endif
528- }
529-
530- } // namespace detail
531-
532536template <typename Char>
533537struct formatter <std::type_info, Char // DEPRECATED! Mixing code unit types.
534538 > {
@@ -543,7 +547,7 @@ struct formatter<std::type_info, Char // DEPRECATED! Mixing code unit types.
543547 return detail::write_demangled_name<Char>(ctx.out (), ti);
544548 }
545549};
546- #endif
550+ #endif // FMT_USE_RTTI
547551
548552template <typename T, typename Char>
549553struct formatter <
@@ -579,34 +583,6 @@ struct formatter<
579583 }
580584};
581585
582- namespace detail {
583-
584- template <typename T, typename Enable = void >
585- struct has_flip : std::false_type {};
586-
587- template <typename T>
588- struct has_flip <T, void_t <decltype (std::declval<T>().flip())>>
589- : std::true_type {};
590-
591- template <typename T> struct is_bit_reference_like {
592- static constexpr const bool value =
593- std::is_convertible<T, bool >::value &&
594- std::is_nothrow_assignable<T, bool >::value && has_flip<T>::value;
595- };
596-
597- #ifdef _LIBCPP_VERSION
598-
599- // Workaround for libc++ incompatibility with C++ standard.
600- // According to the Standard, `bitset::operator[] const` returns bool.
601- template <typename C>
602- struct is_bit_reference_like <std::__bit_const_reference<C>> {
603- static constexpr const bool value = true ;
604- };
605-
606- #endif
607-
608- } // namespace detail
609-
610586// We can't use std::vector<bool, Allocator>::reference and
611587// std::bitset<N>::reference because the compiler can't deduce Allocator and N
612588// in partial specialization.
@@ -725,4 +701,5 @@ struct formatter<std::reference_wrapper<T>, Char,
725701};
726702
727703FMT_END_NAMESPACE
704+
728705#endif // FMT_STD_H_
0 commit comments