File indexing completed on 2026-05-03 08:13:29
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CXX03___FORMAT_FORMATTER_TUPLE_H
0011 #define _LIBCPP___CXX03___FORMAT_FORMATTER_TUPLE_H
0012
0013 #include <__cxx03/__algorithm/ranges_copy.h>
0014 #include <__cxx03/__chrono/statically_widen.h>
0015 #include <__cxx03/__config>
0016 #include <__cxx03/__format/buffer.h>
0017 #include <__cxx03/__format/concepts.h>
0018 #include <__cxx03/__format/format_context.h>
0019 #include <__cxx03/__format/format_error.h>
0020 #include <__cxx03/__format/format_parse_context.h>
0021 #include <__cxx03/__format/formatter.h>
0022 #include <__cxx03/__format/formatter_output.h>
0023 #include <__cxx03/__format/parser_std_format_spec.h>
0024 #include <__cxx03/__type_traits/remove_cvref.h>
0025 #include <__cxx03/__utility/integer_sequence.h>
0026 #include <__cxx03/__utility/pair.h>
0027 #include <__cxx03/string_view>
0028 #include <__cxx03/tuple>
0029
0030 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0031 # pragma GCC system_header
0032 #endif
0033
0034 _LIBCPP_BEGIN_NAMESPACE_STD
0035
0036 #if _LIBCPP_STD_VER >= 23
0037
0038 template <__fmt_char_type _CharT, class _Tuple, formattable<_CharT>... _Args>
0039 struct _LIBCPP_TEMPLATE_VIS __formatter_tuple {
0040 _LIBCPP_HIDE_FROM_ABI constexpr void set_separator(basic_string_view<_CharT> __separator) noexcept {
0041 __separator_ = __separator;
0042 }
0043 _LIBCPP_HIDE_FROM_ABI constexpr void
0044 set_brackets(basic_string_view<_CharT> __opening_bracket, basic_string_view<_CharT> __closing_bracket) noexcept {
0045 __opening_bracket_ = __opening_bracket;
0046 __closing_bracket_ = __closing_bracket;
0047 }
0048
0049 template <class _ParseContext>
0050 _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) {
0051 auto __begin = __parser_.__parse(__ctx, __format_spec::__fields_tuple);
0052
0053 auto __end = __ctx.end();
0054
0055 if (__parser_.__clear_brackets_)
0056 set_brackets({}, {});
0057 else if (__begin != __end && *__begin == _CharT('m')) {
0058 if constexpr (sizeof...(_Args) == 2) {
0059 set_separator(_LIBCPP_STATICALLY_WIDEN(_CharT, ": "));
0060 set_brackets({}, {});
0061 ++__begin;
0062 } else
0063 std::__throw_format_error("Type m requires a pair or a tuple with two elements");
0064 }
0065
0066 if (__begin != __end && *__begin != _CharT('}'))
0067 std::__throw_format_error("The format specifier should consume the input or end with a '}'");
0068
0069 __ctx.advance_to(__begin);
0070
0071
0072
0073
0074 std::__for_each_index_sequence(make_index_sequence<sizeof...(_Args)>(), [&]<size_t _Index> {
0075 auto& __formatter = std::get<_Index>(__underlying_);
0076 __formatter.parse(__ctx);
0077
0078
0079
0080 std::__set_debug_format(__formatter);
0081 });
0082
0083 return __begin;
0084 }
0085
0086 template <class _FormatContext>
0087 typename _FormatContext::iterator _LIBCPP_HIDE_FROM_ABI
0088 format(conditional_t<(formattable<const _Args, _CharT> && ...), const _Tuple&, _Tuple&> __tuple,
0089 _FormatContext& __ctx) const {
0090 __format_spec::__parsed_specifications<_CharT> __specs = __parser_.__get_parsed_std_specifications(__ctx);
0091
0092 if (!__specs.__has_width())
0093 return __format_tuple(__tuple, __ctx);
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 __format::__retarget_buffer<_CharT> __buffer{8 * tuple_size_v<_Tuple>};
0108 basic_format_context<typename __format::__retarget_buffer<_CharT>::__iterator, _CharT> __c{
0109 __buffer.__make_output_iterator(), __ctx};
0110
0111 __format_tuple(__tuple, __c);
0112
0113 return __formatter::__write_string_no_precision(basic_string_view{__buffer.__view()}, __ctx.out(), __specs);
0114 }
0115
0116 template <class _FormatContext>
0117 _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator __format_tuple(auto&& __tuple, _FormatContext& __ctx) const {
0118 __ctx.advance_to(std::ranges::copy(__opening_bracket_, __ctx.out()).out);
0119
0120 std::__for_each_index_sequence(make_index_sequence<sizeof...(_Args)>(), [&]<size_t _Index> {
0121 if constexpr (_Index)
0122 __ctx.advance_to(std::ranges::copy(__separator_, __ctx.out()).out);
0123 __ctx.advance_to(std::get<_Index>(__underlying_).format(std::get<_Index>(__tuple), __ctx));
0124 });
0125
0126 return std::ranges::copy(__closing_bracket_, __ctx.out()).out;
0127 }
0128
0129 __format_spec::__parser<_CharT> __parser_{.__alignment_ = __format_spec::__alignment::__left};
0130
0131 private:
0132 tuple<formatter<remove_cvref_t<_Args>, _CharT>...> __underlying_;
0133 basic_string_view<_CharT> __separator_ = _LIBCPP_STATICALLY_WIDEN(_CharT, ", ");
0134 basic_string_view<_CharT> __opening_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, "(");
0135 basic_string_view<_CharT> __closing_bracket_ = _LIBCPP_STATICALLY_WIDEN(_CharT, ")");
0136 };
0137
0138 template <__fmt_char_type _CharT, formattable<_CharT>... _Args>
0139 struct _LIBCPP_TEMPLATE_VIS formatter<pair<_Args...>, _CharT>
0140 : public __formatter_tuple<_CharT, pair<_Args...>, _Args...> {};
0141
0142 template <__fmt_char_type _CharT, formattable<_CharT>... _Args>
0143 struct _LIBCPP_TEMPLATE_VIS formatter<tuple<_Args...>, _CharT>
0144 : public __formatter_tuple<_CharT, tuple<_Args...>, _Args...> {};
0145
0146 #endif
0147
0148 _LIBCPP_END_NAMESPACE_STD
0149
0150 #endif