File indexing completed on 2026-05-03 08:13:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___FORMAT_RANGE_DEFAULT_FORMATTER_H
0011 #define _LIBCPP___FORMAT_RANGE_DEFAULT_FORMATTER_H
0012
0013 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0014 # pragma GCC system_header
0015 #endif
0016
0017 #include <__algorithm/ranges_copy.h>
0018 #include <__chrono/statically_widen.h>
0019 #include <__concepts/same_as.h>
0020 #include <__config>
0021 #include <__format/concepts.h>
0022 #include <__format/formatter.h>
0023 #include <__format/range_formatter.h>
0024 #include <__iterator/back_insert_iterator.h>
0025 #include <__ranges/concepts.h>
0026 #include <__ranges/data.h>
0027 #include <__ranges/from_range.h>
0028 #include <__ranges/size.h>
0029 #include <__type_traits/conditional.h>
0030 #include <__type_traits/remove_cvref.h>
0031 #include <__utility/pair.h>
0032 #include <string_view>
0033
0034 _LIBCPP_BEGIN_NAMESPACE_STD
0035
0036 #if _LIBCPP_STD_VER >= 23
0037
0038 template <class _Rp, class _CharT>
0039 concept __const_formattable_range =
0040 ranges::input_range<const _Rp> && formattable<ranges::range_reference_t<const _Rp>, _CharT>;
0041
0042 template <class _Rp, class _CharT>
0043 using __fmt_maybe_const _LIBCPP_NODEBUG = conditional_t<__const_formattable_range<_Rp, _CharT>, const _Rp, _Rp>;
0044
0045 _LIBCPP_DIAGNOSTIC_PUSH
0046 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wshadow")
0047 _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wshadow")
0048
0049 enum class range_format { disabled, map, set, sequence, string, debug_string };
0050 _LIBCPP_DIAGNOSTIC_POP
0051
0052
0053
0054 template <class _Rp>
0055 struct _LIBCPP_TEMPLATE_VIS __instantiated_the_primary_template_of_format_kind;
0056
0057 template <class _Rp>
0058 constexpr range_format format_kind = [] {
0059
0060
0061 static_assert(sizeof(_Rp) != sizeof(_Rp), "create a template specialization of format_kind for your type");
0062 return range_format::disabled;
0063 }();
0064
0065 template <ranges::input_range _Rp>
0066 requires same_as<_Rp, remove_cvref_t<_Rp>>
0067 inline constexpr range_format format_kind<_Rp> = [] {
0068
0069
0070
0071
0072 if constexpr (same_as<remove_cvref_t<ranges::range_reference_t<_Rp>>, _Rp>)
0073 return range_format::disabled;
0074
0075 else if constexpr (requires { typename _Rp::key_type; }) {
0076
0077 if constexpr (requires { typename _Rp::mapped_type; } &&
0078
0079
0080 __fmt_pair_like<remove_cvref_t<ranges::range_reference_t<_Rp>>>)
0081 return range_format::map;
0082 else
0083
0084 return range_format::set;
0085 } else
0086
0087 return range_format::sequence;
0088 }();
0089
0090 template <range_format _Kp, ranges::input_range _Rp, class _CharT>
0091 struct _LIBCPP_TEMPLATE_VIS __range_default_formatter;
0092
0093
0094
0095 template <ranges::input_range _Rp, class _CharT>
0096 struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::sequence, _Rp, _CharT> {
0097 private:
0098 using __maybe_const_r _LIBCPP_NODEBUG = __fmt_maybe_const<_Rp, _CharT>;
0099 range_formatter<remove_cvref_t<ranges::range_reference_t<__maybe_const_r>>, _CharT> __underlying_;
0100
0101 public:
0102 _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) noexcept {
0103 __underlying_.set_separator(__separator);
0104 }
0105 _LIBCPP_HIDE_FROM_ABI constexpr void
0106 set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) noexcept {
0107 __underlying_.set_brackets(__opening_bracket, __closing_bracket);
0108 }
0109
0110 template <class _ParseContext>
0111 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0112 return __underlying_.parse(__ctx);
0113 }
0114
0115 template <class _FormatContext>
0116 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
0117 format(__maybe_const_r& __range, _FormatContext& __ctx) const {
0118 return __underlying_.format(__range, __ctx);
0119 }
0120 };
0121
0122 template <ranges::input_range _Rp, class _CharT>
0123 struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::map, _Rp, _CharT> {
0124 private:
0125 using __maybe_const_map _LIBCPP_NODEBUG = __fmt_maybe_const<_Rp, _CharT>;
0126 using __element_type _LIBCPP_NODEBUG = remove_cvref_t<ranges::range_reference_t<__maybe_const_map>>;
0127 range_formatter<__element_type, _CharT> __underlying_;
0128
0129 public:
0130 _LIBCPP_HIDE_FROM_ABI constexpr __range_default_formatter()
0131 requires(__fmt_pair_like<__element_type>)
0132 {
0133 __underlying_.set_brackets(_LIBCPP_STATICALLY_WIDEN(_CharT, "{"), _LIBCPP_STATICALLY_WIDEN(_CharT, "}"));
0134 __underlying_.underlying().set_brackets({}, {});
0135 __underlying_.underlying().set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ": "));
0136 }
0137
0138 template <class _ParseContext>
0139 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0140 return __underlying_.parse(__ctx);
0141 }
0142
0143 template <class _FormatContext>
0144 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
0145 format(__maybe_const_map& __range, _FormatContext& __ctx) const {
0146 return __underlying_.format(__range, __ctx);
0147 }
0148 };
0149
0150 template <ranges::input_range _Rp, class _CharT>
0151 struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<range_format::set, _Rp, _CharT> {
0152 private:
0153 using __maybe_const_set _LIBCPP_NODEBUG = __fmt_maybe_const<_Rp, _CharT>;
0154 using __element_type _LIBCPP_NODEBUG = remove_cvref_t<ranges::range_reference_t<__maybe_const_set>>;
0155 range_formatter<__element_type, _CharT> __underlying_;
0156
0157 public:
0158 _LIBCPP_HIDE_FROM_ABI constexpr __range_default_formatter() {
0159 __underlying_.set_brackets(_LIBCPP_STATICALLY_WIDEN(_CharT, "{"), _LIBCPP_STATICALLY_WIDEN(_CharT, "}"));
0160 }
0161
0162 template <class _ParseContext>
0163 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0164 return __underlying_.parse(__ctx);
0165 }
0166
0167 template <class _FormatContext>
0168 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
0169 format(__maybe_const_set& __range, _FormatContext& __ctx) const {
0170 return __underlying_.format(__range, __ctx);
0171 }
0172 };
0173
0174 template <range_format _Kp, ranges::input_range _Rp, class _CharT>
0175 requires(_Kp == range_format::string || _Kp == range_format::debug_string)
0176 struct _LIBCPP_TEMPLATE_VIS __range_default_formatter<_Kp, _Rp, _CharT> {
0177 private:
0178
0179
0180
0181
0182 formatter<basic_string_view<_CharT>, _CharT> __underlying_;
0183
0184 public:
0185 template <class _ParseContext>
0186 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0187 typename _ParseContext::iterator __i = __underlying_.parse(__ctx);
0188 if constexpr (_Kp == range_format::debug_string)
0189 __underlying_.set_debug_format();
0190 return __i;
0191 }
0192
0193 template <class _FormatContext>
0194 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator
0195 format(conditional_t<ranges::input_range<const _Rp>, const _Rp&, _Rp&> __range, _FormatContext& __ctx) const {
0196
0197
0198
0199 if constexpr (ranges::contiguous_range<_Rp> && std::ranges::sized_range<_Rp>)
0200 return __underlying_.format(basic_string_view<_CharT>{ranges::data(__range), ranges::size(__range)}, __ctx);
0201 else
0202 return __underlying_.format(basic_string<_CharT>{from_range, __range}, __ctx);
0203 }
0204 };
0205
0206 template <ranges::input_range _Rp, class _CharT>
0207 requires(format_kind<_Rp> != range_format::disabled && formattable<ranges::range_reference_t<_Rp>, _CharT>)
0208 struct _LIBCPP_TEMPLATE_VIS formatter<_Rp, _CharT> : __range_default_formatter<format_kind<_Rp>, _Rp, _CharT> {};
0209
0210 #endif
0211
0212 _LIBCPP_END_NAMESPACE_STD
0213
0214 #endif