1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef _LIBCPP___FORMAT_FORMAT_CONTEXT_H 11 #define _LIBCPP___FORMAT_FORMAT_CONTEXT_H 12 13 #include <__availability> 14 #include <__config> 15 #include <__format/buffer.h> 16 #include <__format/format_args.h> 17 #include <__format/format_fwd.h> 18 #include <__iterator/back_insert_iterator.h> 19 #include <__iterator/concepts.h> 20 #include <concepts> 21 22 #ifndef _LIBCPP_HAS_NO_LOCALIZATION 23 #include <locale> 24 #include <optional> 25 #endif 26 27 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 28 # pragma GCC system_header 29 #endif 30 31 _LIBCPP_BEGIN_NAMESPACE_STD 32 33 #if _LIBCPP_STD_VER > 17 34 35 template <class _OutIt, class _CharT> 36 requires output_iterator<_OutIt, const _CharT&> 37 class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_context; 38 39 #ifndef _LIBCPP_HAS_NO_LOCALIZATION 40 /** 41 * Helper to create a basic_format_context. 42 * 43 * This is needed since the constructor is private. 44 */ 45 template <class _OutIt, class _CharT> 46 _LIBCPP_HIDE_FROM_ABI basic_format_context<_OutIt, _CharT> 47 __format_context_create( 48 _OutIt __out_it, 49 basic_format_args<basic_format_context<_OutIt, _CharT>> __args, 50 optional<_VSTD::locale>&& __loc = nullopt) { 51 return _VSTD::basic_format_context(_VSTD::move(__out_it), __args, 52 _VSTD::move(__loc)); 53 } 54 #else 55 template <class _OutIt, class _CharT> 56 _LIBCPP_HIDE_FROM_ABI basic_format_context<_OutIt, _CharT> 57 __format_context_create( 58 _OutIt __out_it, 59 basic_format_args<basic_format_context<_OutIt, _CharT>> __args) { 60 return _VSTD::basic_format_context(_VSTD::move(__out_it), __args); 61 } 62 #endif 63 64 using format_context = 65 basic_format_context<back_insert_iterator<__format::__output_buffer<char>>, 66 char>; 67 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 68 using wformat_context = basic_format_context< 69 back_insert_iterator<__format::__output_buffer<wchar_t>>, wchar_t>; 70 #endif 71 72 template <class _OutIt, class _CharT> 73 requires output_iterator<_OutIt, const _CharT&> 74 class 75 // clang-format off 76 _LIBCPP_TEMPLATE_VIS 77 _LIBCPP_AVAILABILITY_FORMAT 78 _LIBCPP_PREFERRED_NAME(format_context) 79 _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERRED_NAME(wformat_context)) 80 // clang-format on 81 basic_format_context { 82 public: 83 using iterator = _OutIt; 84 using char_type = _CharT; 85 template <class _Tp> 86 using formatter_type = formatter<_Tp, _CharT>; 87 88 basic_format_context(const basic_format_context&) = delete; 89 basic_format_context& operator=(const basic_format_context&) = delete; 90 91 _LIBCPP_HIDE_FROM_ABI basic_format_arg<basic_format_context> 92 arg(size_t __id) const noexcept { 93 return __args_.get(__id); 94 } 95 #ifndef _LIBCPP_HAS_NO_LOCALIZATION 96 _LIBCPP_HIDE_FROM_ABI _VSTD::locale locale() { 97 if (!__loc_) 98 __loc_ = _VSTD::locale{}; 99 return *__loc_; 100 } 101 #endif 102 _LIBCPP_HIDE_FROM_ABI iterator out() { return __out_it_; } 103 _LIBCPP_HIDE_FROM_ABI void advance_to(iterator __it) { __out_it_ = __it; } 104 105 private: 106 iterator __out_it_; 107 basic_format_args<basic_format_context> __args_; 108 #ifndef _LIBCPP_HAS_NO_LOCALIZATION 109 110 // The Standard doesn't specify how the locale is stored. 111 // [format.context]/6 112 // std::locale locale(); 113 // Returns: The locale passed to the formatting function if the latter 114 // takes one, and std::locale() otherwise. 115 // This is done by storing the locale of the constructor in this optional. If 116 // locale() is called and the optional has no value the value will be created. 117 // This allows the implementation to lazily create the locale. 118 // TODO FMT Validate whether lazy creation is the best solution. 119 optional<_VSTD::locale> __loc_; 120 121 template <class __OutIt, class __CharT> 122 friend _LIBCPP_HIDE_FROM_ABI basic_format_context<__OutIt, __CharT> 123 __format_context_create(__OutIt, basic_format_args<basic_format_context<__OutIt, __CharT>>, 124 optional<_VSTD::locale>&&); 125 126 // Note: the Standard doesn't specify the required constructors. 127 _LIBCPP_HIDE_FROM_ABI 128 explicit basic_format_context(_OutIt __out_it, 129 basic_format_args<basic_format_context> __args, 130 optional<_VSTD::locale>&& __loc) 131 : __out_it_(_VSTD::move(__out_it)), __args_(__args), 132 __loc_(_VSTD::move(__loc)) {} 133 #else 134 template <class __OutIt, class __CharT> 135 friend _LIBCPP_HIDE_FROM_ABI basic_format_context<__OutIt, __CharT> 136 __format_context_create(__OutIt, basic_format_args<basic_format_context<__OutIt, __CharT>>); 137 138 _LIBCPP_HIDE_FROM_ABI 139 explicit basic_format_context(_OutIt __out_it, 140 basic_format_args<basic_format_context> __args) 141 : __out_it_(_VSTD::move(__out_it)), __args_(__args) {} 142 #endif 143 }; 144 145 #endif //_LIBCPP_STD_VER > 17 146 147 _LIBCPP_END_NAMESPACE_STD 148 149 #endif // _LIBCPP___FORMAT_FORMAT_CONTEXT_H 150