Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-03 08:13:28

0001 // -*- C++ -*-
0002 //===----------------------------------------------------------------------===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009 
0010 #ifndef _LIBCPP___CXX03___FORMAT_FORMAT_CONTEXT_H
0011 #define _LIBCPP___CXX03___FORMAT_FORMAT_CONTEXT_H
0012 
0013 #include <__cxx03/__concepts/same_as.h>
0014 #include <__cxx03/__config>
0015 #include <__cxx03/__format/buffer.h>
0016 #include <__cxx03/__format/format_arg.h>
0017 #include <__cxx03/__format/format_arg_store.h>
0018 #include <__cxx03/__format/format_args.h>
0019 #include <__cxx03/__format/format_error.h>
0020 #include <__cxx03/__fwd/format.h>
0021 #include <__cxx03/__iterator/back_insert_iterator.h>
0022 #include <__cxx03/__iterator/concepts.h>
0023 #include <__cxx03/__memory/addressof.h>
0024 #include <__cxx03/__utility/move.h>
0025 #include <__cxx03/__variant/monostate.h>
0026 #include <__cxx03/cstddef>
0027 
0028 #ifndef _LIBCPP_HAS_NO_LOCALIZATION
0029 #  include <__cxx03/__locale>
0030 #  include <__cxx03/optional>
0031 #endif
0032 
0033 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0034 #  pragma GCC system_header
0035 #endif
0036 
0037 _LIBCPP_PUSH_MACROS
0038 #include <__cxx03/__undef_macros>
0039 
0040 _LIBCPP_BEGIN_NAMESPACE_STD
0041 
0042 #if _LIBCPP_STD_VER >= 20
0043 
0044 template <class _OutIt, class _CharT>
0045   requires output_iterator<_OutIt, const _CharT&>
0046 class _LIBCPP_TEMPLATE_VIS basic_format_context;
0047 
0048 #  ifndef _LIBCPP_HAS_NO_LOCALIZATION
0049 /**
0050  * Helper to create a basic_format_context.
0051  *
0052  * This is needed since the constructor is private.
0053  */
0054 template <class _OutIt, class _CharT>
0055 _LIBCPP_HIDE_FROM_ABI basic_format_context<_OutIt, _CharT>
0056 __format_context_create(_OutIt __out_it,
0057                         basic_format_args<basic_format_context<_OutIt, _CharT>> __args,
0058                         optional<std::locale>&& __loc = nullopt) {
0059   return std::basic_format_context(std::move(__out_it), __args, std::move(__loc));
0060 }
0061 #  else
0062 template <class _OutIt, class _CharT>
0063 _LIBCPP_HIDE_FROM_ABI basic_format_context<_OutIt, _CharT>
0064 __format_context_create(_OutIt __out_it, basic_format_args<basic_format_context<_OutIt, _CharT>> __args) {
0065   return std::basic_format_context(std::move(__out_it), __args);
0066 }
0067 #  endif
0068 
0069 using format_context = basic_format_context<back_insert_iterator<__format::__output_buffer<char>>, char>;
0070 #  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
0071 using wformat_context = basic_format_context< back_insert_iterator<__format::__output_buffer<wchar_t>>, wchar_t>;
0072 #  endif
0073 
0074 template <class _OutIt, class _CharT>
0075   requires output_iterator<_OutIt, const _CharT&>
0076 class
0077     // clang-format off
0078     _LIBCPP_TEMPLATE_VIS
0079     _LIBCPP_PREFERRED_NAME(format_context)
0080     _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wformat_context))
0081     // clang-format on
0082     basic_format_context {
0083 public:
0084   using iterator  = _OutIt;
0085   using char_type = _CharT;
0086   template <class _Tp>
0087   using formatter_type = formatter<_Tp, _CharT>;
0088 
0089   _LIBCPP_HIDE_FROM_ABI basic_format_arg<basic_format_context> arg(size_t __id) const noexcept {
0090     return __args_.get(__id);
0091   }
0092 #  ifndef _LIBCPP_HAS_NO_LOCALIZATION
0093   _LIBCPP_HIDE_FROM_ABI std::locale locale() {
0094     if (!__loc_)
0095       __loc_ = std::locale{};
0096     return *__loc_;
0097   }
0098 #  endif
0099   _LIBCPP_HIDE_FROM_ABI iterator out() { return std::move(__out_it_); }
0100   _LIBCPP_HIDE_FROM_ABI void advance_to(iterator __it) { __out_it_ = std::move(__it); }
0101 
0102 private:
0103   iterator __out_it_;
0104   basic_format_args<basic_format_context> __args_;
0105 #  ifndef _LIBCPP_HAS_NO_LOCALIZATION
0106 
0107   // The Standard doesn't specify how the locale is stored.
0108   // [format.context]/6
0109   // std::locale locale();
0110   //   Returns: The locale passed to the formatting function if the latter
0111   //   takes one, and std::locale() otherwise.
0112   // This is done by storing the locale of the constructor in this optional. If
0113   // locale() is called and the optional has no value the value will be created.
0114   // This allows the implementation to lazily create the locale.
0115   // TODO FMT Validate whether lazy creation is the best solution.
0116   optional<std::locale> __loc_;
0117 
0118   template <class _OtherOutIt, class _OtherCharT>
0119   friend _LIBCPP_HIDE_FROM_ABI basic_format_context<_OtherOutIt, _OtherCharT> __format_context_create(
0120       _OtherOutIt, basic_format_args<basic_format_context<_OtherOutIt, _OtherCharT>>, optional<std::locale>&&);
0121 
0122   // Note: the Standard doesn't specify the required constructors.
0123   _LIBCPP_HIDE_FROM_ABI explicit basic_format_context(
0124       _OutIt __out_it, basic_format_args<basic_format_context> __args, optional<std::locale>&& __loc)
0125       : __out_it_(std::move(__out_it)), __args_(__args), __loc_(std::move(__loc)) {}
0126 #  else
0127   template <class _OtherOutIt, class _OtherCharT>
0128   friend _LIBCPP_HIDE_FROM_ABI basic_format_context<_OtherOutIt, _OtherCharT>
0129       __format_context_create(_OtherOutIt, basic_format_args<basic_format_context<_OtherOutIt, _OtherCharT>>);
0130 
0131   _LIBCPP_HIDE_FROM_ABI explicit basic_format_context(_OutIt __out_it, basic_format_args<basic_format_context> __args)
0132       : __out_it_(std::move(__out_it)), __args_(__args) {}
0133 #  endif
0134 
0135   basic_format_context(const basic_format_context&)            = delete;
0136   basic_format_context& operator=(const basic_format_context&) = delete;
0137 };
0138 
0139 // A specialization for __retarget_buffer
0140 //
0141 // See __retarget_buffer for the motivation for this specialization.
0142 //
0143 // This context holds a reference to the instance of the basic_format_context
0144 // that is retargeted. It converts a formatting argument when it is requested
0145 // during formatting. It is expected that the usage of the arguments is rare so
0146 // the lookups are not expected to be used often. An alternative would be to
0147 // convert all elements during construction.
0148 //
0149 // The elements of the retargets context are only used when an underlying
0150 // formatter uses a locale specific formatting or an formatting argument is
0151 // part for the format spec. For example
0152 //   format("{:256:{}}", input, 8);
0153 // Here the width of an element in input is determined dynamically.
0154 // Note when the top-level element has no width the retargeting is not needed.
0155 template <class _CharT>
0156 class _LIBCPP_TEMPLATE_VIS basic_format_context<typename __format::__retarget_buffer<_CharT>::__iterator, _CharT> {
0157 public:
0158   using iterator  = typename __format::__retarget_buffer<_CharT>::__iterator;
0159   using char_type = _CharT;
0160   template <class _Tp>
0161   using formatter_type = formatter<_Tp, _CharT>;
0162 
0163   template <class _Context>
0164   _LIBCPP_HIDE_FROM_ABI explicit basic_format_context(iterator __out_it, _Context& __ctx)
0165       : __out_it_(std::move(__out_it)),
0166 #  ifndef _LIBCPP_HAS_NO_LOCALIZATION
0167         __loc_([](void* __c) { return static_cast<_Context*>(__c)->locale(); }),
0168 #  endif
0169         __ctx_(std::addressof(__ctx)),
0170         __arg_([](void* __c, size_t __id) {
0171           auto __visitor = [&](auto __arg) -> basic_format_arg<basic_format_context> {
0172             if constexpr (same_as<decltype(__arg), monostate>)
0173               return {};
0174             else if constexpr (same_as<decltype(__arg), typename basic_format_arg<_Context>::handle>)
0175               // At the moment it's not possible for formatting to use a re-targeted handle.
0176               // TODO FMT add this when support is needed.
0177               std::__throw_format_error("Re-targeting handle not supported");
0178             else
0179               return basic_format_arg<basic_format_context>{
0180                   __format::__determine_arg_t<basic_format_context, decltype(__arg)>(),
0181                   __basic_format_arg_value<basic_format_context>(__arg)};
0182           };
0183 #  if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER)
0184           return static_cast<_Context*>(__c)->arg(__id).visit(std::move(__visitor));
0185 #  else
0186           _LIBCPP_SUPPRESS_DEPRECATED_PUSH
0187           return std::visit_format_arg(std::move(__visitor), static_cast<_Context*>(__c)->arg(__id));
0188           _LIBCPP_SUPPRESS_DEPRECATED_POP
0189 #  endif // _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_EXPLICIT_THIS_PARAMETER)
0190         }) {
0191   }
0192 
0193   _LIBCPP_HIDE_FROM_ABI basic_format_arg<basic_format_context> arg(size_t __id) const noexcept {
0194     return __arg_(__ctx_, __id);
0195   }
0196 #  ifndef _LIBCPP_HAS_NO_LOCALIZATION
0197   _LIBCPP_HIDE_FROM_ABI std::locale locale() { return __loc_(__ctx_); }
0198 #  endif
0199   _LIBCPP_HIDE_FROM_ABI iterator out() { return std::move(__out_it_); }
0200   _LIBCPP_HIDE_FROM_ABI void advance_to(iterator __it) { __out_it_ = std::move(__it); }
0201 
0202 private:
0203   iterator __out_it_;
0204 
0205 #  ifndef _LIBCPP_HAS_NO_LOCALIZATION
0206   std::locale (*__loc_)(void* __ctx);
0207 #  endif
0208 
0209   void* __ctx_;
0210   basic_format_arg<basic_format_context> (*__arg_)(void* __ctx, size_t __id);
0211 };
0212 
0213 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_context);
0214 #endif //_LIBCPP_STD_VER >= 20
0215 
0216 _LIBCPP_END_NAMESPACE_STD
0217 
0218 _LIBCPP_POP_MACROS
0219 
0220 #endif // _LIBCPP___CXX03___FORMAT_FORMAT_CONTEXT_H