2 //===----------------------------------------------------------------------===//
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
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP___FORMAT_FORMAT_ARG_H
11 #define _LIBCPP___FORMAT_FORMAT_ARG_H
14 #include <__concepts/arithmetic.h>
16 #include <__cstddef/size_t.h>
17 #include <__format/concepts.h>
18 #include <__format/format_parse_context.h>
19 #include <__functional/invoke.h>
20 #include <__fwd/format.h>
21 #include <__memory/addressof.h>
22 #include <__type_traits/conditional.h>
23 #include <__type_traits/remove_const.h>
24 #include <__utility/forward.h>
25 #include <__utility/move.h>
26 #include <__utility/unreachable.h>
27 #include <__variant/monostate.h>
29 #include <string_view>
31 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
32 # pragma GCC system_header
36 #include <__undef_macros>
38 _LIBCPP_BEGIN_NAMESPACE_STD
40 #if _LIBCPP_STD_VER >= 20
43 /// The type stored in @ref basic_format_arg.
45 /// @note The 128-bit types are unconditionally in the list to avoid the values
46 /// of the enums to depend on the availability of 128-bit integers.
48 /// @note The value is stored as a 5-bit value in the __packed_arg_t_bits. This
49 /// limits the maximum number of elements to 32.
50 /// When modifying update the test
51 /// test/libcxx/utilities/format/format.arguments/format.arg/arg_t.compile.pass.cpp
52 /// It could be packed in 4-bits but that means a new type directly becomes an
53 /// ABI break. The packed type is 64-bit so this reduces the maximum number of
54 /// packed elements from 16 to 12.
56 /// @note Some members of this enum are an extension. These extensions need
57 /// special behaviour in visit_format_arg. There they need to be wrapped in a
58 /// handle to satisfy the user observable behaviour. The internal function
59 /// __visit_format_arg doesn't do this wrapping. So in the format functions
60 /// this function is used to avoid unneeded overhead.
61 enum class __arg_t
: uint8_t {
74 __const_char_type_ptr
,
80 inline constexpr unsigned __packed_arg_t_bits
= 5;
81 inline constexpr uint8_t __packed_arg_t_mask
= 0x1f;
83 inline constexpr unsigned __packed_types_storage_bits
= 64;
84 inline constexpr unsigned __packed_types_max
= __packed_types_storage_bits
/ __packed_arg_t_bits
;
86 _LIBCPP_HIDE_FROM_ABI
constexpr bool __use_packed_format_arg_store(size_t __size
) {
87 return __size
<= __packed_types_max
;
90 _LIBCPP_HIDE_FROM_ABI
constexpr __arg_t
__get_packed_type(uint64_t __types
, size_t __id
) {
91 _LIBCPP_ASSERT_INTERNAL(__id
<= __packed_types_max
, "");
94 __types
>>= __id
* __packed_arg_t_bits
;
96 return static_cast<__format::__arg_t
>(__types
& __packed_arg_t_mask
);
99 } // namespace __format
101 // This function is not user observable, so it can directly use the non-standard
102 // types of the "variant". See __arg_t for more details.
103 template <class _Visitor
, class _Context
>
104 _LIBCPP_HIDE_FROM_ABI
decltype(auto) __visit_format_arg(_Visitor
&& __vis
, basic_format_arg
<_Context
> __arg
) {
105 switch (__arg
.__type_
) {
106 case __format::__arg_t::__none
:
107 return std::invoke(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__monostate_
);
108 case __format::__arg_t::__boolean
:
109 return std::invoke(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__boolean_
);
110 case __format::__arg_t::__char_type
:
111 return std::invoke(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__char_type_
);
112 case __format::__arg_t::__int
:
113 return std::invoke(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__int_
);
114 case __format::__arg_t::__long_long
:
115 return std::invoke(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__long_long_
);
116 case __format::__arg_t::__i128
:
117 # if _LIBCPP_HAS_INT128
118 return std::invoke(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__i128_
);
120 __libcpp_unreachable();
122 case __format::__arg_t::__unsigned
:
123 return std::invoke(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__unsigned_
);
124 case __format::__arg_t::__unsigned_long_long
:
125 return std::invoke(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__unsigned_long_long_
);
126 case __format::__arg_t::__u128
:
127 # if _LIBCPP_HAS_INT128
128 return std::invoke(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__u128_
);
130 __libcpp_unreachable();
132 case __format::__arg_t::__float
:
133 return std::invoke(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__float_
);
134 case __format::__arg_t::__double
:
135 return std::invoke(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__double_
);
136 case __format::__arg_t::__long_double
:
137 return std::invoke(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__long_double_
);
138 case __format::__arg_t::__const_char_type_ptr
:
139 return std::invoke(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__const_char_type_ptr_
);
140 case __format::__arg_t::__string_view
:
141 return std::invoke(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__string_view_
);
142 case __format::__arg_t::__ptr
:
143 return std::invoke(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__ptr_
);
144 case __format::__arg_t::__handle
:
146 std::forward
<_Visitor
>(__vis
), typename basic_format_arg
<_Context
>::handle
{__arg
.__value_
.__handle_
});
149 __libcpp_unreachable();
152 # if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
154 template <class _Rp
, class _Visitor
, class _Context
>
155 _LIBCPP_HIDE_FROM_ABI _Rp
__visit_format_arg(_Visitor
&& __vis
, basic_format_arg
<_Context
> __arg
) {
156 switch (__arg
.__type_
) {
157 case __format::__arg_t::__none
:
158 return std::invoke_r
<_Rp
>(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__monostate_
);
159 case __format::__arg_t::__boolean
:
160 return std::invoke_r
<_Rp
>(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__boolean_
);
161 case __format::__arg_t::__char_type
:
162 return std::invoke_r
<_Rp
>(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__char_type_
);
163 case __format::__arg_t::__int
:
164 return std::invoke_r
<_Rp
>(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__int_
);
165 case __format::__arg_t::__long_long
:
166 return std::invoke_r
<_Rp
>(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__long_long_
);
167 case __format::__arg_t::__i128
:
168 # if _LIBCPP_HAS_INT128
169 return std::invoke_r
<_Rp
>(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__i128_
);
171 __libcpp_unreachable();
173 case __format::__arg_t::__unsigned
:
174 return std::invoke_r
<_Rp
>(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__unsigned_
);
175 case __format::__arg_t::__unsigned_long_long
:
176 return std::invoke_r
<_Rp
>(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__unsigned_long_long_
);
177 case __format::__arg_t::__u128
:
178 # if _LIBCPP_HAS_INT128
179 return std::invoke_r
<_Rp
>(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__u128_
);
181 __libcpp_unreachable();
183 case __format::__arg_t::__float
:
184 return std::invoke_r
<_Rp
>(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__float_
);
185 case __format::__arg_t::__double
:
186 return std::invoke_r
<_Rp
>(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__double_
);
187 case __format::__arg_t::__long_double
:
188 return std::invoke_r
<_Rp
>(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__long_double_
);
189 case __format::__arg_t::__const_char_type_ptr
:
190 return std::invoke_r
<_Rp
>(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__const_char_type_ptr_
);
191 case __format::__arg_t::__string_view
:
192 return std::invoke_r
<_Rp
>(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__string_view_
);
193 case __format::__arg_t::__ptr
:
194 return std::invoke_r
<_Rp
>(std::forward
<_Visitor
>(__vis
), __arg
.__value_
.__ptr_
);
195 case __format::__arg_t::__handle
:
196 return std::invoke_r
<_Rp
>(
197 std::forward
<_Visitor
>(__vis
), typename basic_format_arg
<_Context
>::handle
{__arg
.__value_
.__handle_
});
200 __libcpp_unreachable();
203 # endif // _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
205 /// Contains the values used in basic_format_arg.
207 /// This is a separate type so it's possible to store the values and types in
209 template <class _Context
>
210 class __basic_format_arg_value
{
211 using _CharT
= typename
_Context::char_type
;
214 /// Contains the implementation for basic_format_arg::handle.
217 _LIBCPP_HIDE_FROM_ABI
explicit __handle(_Tp
& __v
) noexcept
218 : __ptr_(std::addressof(__v
)),
219 __format_([](basic_format_parse_context
<_CharT
>& __parse_ctx
, _Context
& __ctx
, const void* __ptr
) {
220 using _Dp
= remove_const_t
<_Tp
>;
221 using _Qp
= conditional_t
<__formattable_with
<const _Dp
, _Context
>, const _Dp
, _Dp
>;
222 static_assert(__formattable_with
<_Qp
, _Context
>, "Mandated by [format.arg]/10");
224 typename
_Context::template formatter_type
<_Dp
> __f
;
225 __parse_ctx
.advance_to(__f
.parse(__parse_ctx
));
226 __ctx
.advance_to(__f
.format(*const_cast<_Qp
*>(static_cast<const _Dp
*>(__ptr
)), __ctx
));
230 void (*__format_
)(basic_format_parse_context
<_CharT
>&, _Context
&, const void*);
234 monostate __monostate_
;
238 unsigned __unsigned_
;
239 long long __long_long_
;
240 unsigned long long __unsigned_long_long_
;
241 # if _LIBCPP_HAS_INT128
247 long double __long_double_
;
248 const _CharT
* __const_char_type_ptr_
;
249 basic_string_view
<_CharT
> __string_view_
;
254 // These constructors contain the exact storage type used. If adjustments are
255 // required, these will be done in __create_format_arg.
257 _LIBCPP_HIDE_FROM_ABI
__basic_format_arg_value() noexcept
: __monostate_() {}
258 _LIBCPP_HIDE_FROM_ABI
__basic_format_arg_value(bool __value
) noexcept
: __boolean_(__value
) {}
259 _LIBCPP_HIDE_FROM_ABI
__basic_format_arg_value(_CharT __value
) noexcept
: __char_type_(__value
) {}
260 _LIBCPP_HIDE_FROM_ABI
__basic_format_arg_value(int __value
) noexcept
: __int_(__value
) {}
261 _LIBCPP_HIDE_FROM_ABI
__basic_format_arg_value(unsigned __value
) noexcept
: __unsigned_(__value
) {}
262 _LIBCPP_HIDE_FROM_ABI
__basic_format_arg_value(long long __value
) noexcept
: __long_long_(__value
) {}
263 _LIBCPP_HIDE_FROM_ABI
__basic_format_arg_value(unsigned long long __value
) noexcept
264 : __unsigned_long_long_(__value
) {}
265 # if _LIBCPP_HAS_INT128
266 _LIBCPP_HIDE_FROM_ABI
__basic_format_arg_value(__int128_t __value
) noexcept
: __i128_(__value
) {}
267 _LIBCPP_HIDE_FROM_ABI
__basic_format_arg_value(__uint128_t __value
) noexcept
: __u128_(__value
) {}
269 _LIBCPP_HIDE_FROM_ABI
__basic_format_arg_value(float __value
) noexcept
: __float_(__value
) {}
270 _LIBCPP_HIDE_FROM_ABI
__basic_format_arg_value(double __value
) noexcept
: __double_(__value
) {}
271 _LIBCPP_HIDE_FROM_ABI
__basic_format_arg_value(long double __value
) noexcept
: __long_double_(__value
) {}
272 _LIBCPP_HIDE_FROM_ABI
__basic_format_arg_value(const _CharT
* __value
) noexcept
: __const_char_type_ptr_(__value
) {}
273 _LIBCPP_HIDE_FROM_ABI
__basic_format_arg_value(basic_string_view
<_CharT
> __value
) noexcept
274 : __string_view_(__value
) {}
275 _LIBCPP_HIDE_FROM_ABI
__basic_format_arg_value(const void* __value
) noexcept
: __ptr_(__value
) {}
276 _LIBCPP_HIDE_FROM_ABI
__basic_format_arg_value(__handle
&& __value
) noexcept
: __handle_(std::move(__value
)) {}
279 template <class _Context
>
280 class _LIBCPP_TEMPLATE_VIS basic_format_arg
{
282 class _LIBCPP_TEMPLATE_VIS handle
;
284 _LIBCPP_HIDE_FROM_ABI
basic_format_arg() noexcept
: __type_
{__format::__arg_t::__none
} {}
286 _LIBCPP_HIDE_FROM_ABI
explicit operator bool() const noexcept
{ return __type_
!= __format::__arg_t::__none
; }
288 # if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
290 // This function is user facing, so it must wrap the non-standard types of
291 // the "variant" in a handle to stay conforming. See __arg_t for more details.
292 template <class _Visitor
>
293 _LIBCPP_HIDE_FROM_ABI
decltype(auto) visit(this basic_format_arg __arg
, _Visitor
&& __vis
) {
294 switch (__arg
.__type_
) {
295 # if _LIBCPP_HAS_INT128
296 case __format::__arg_t::__i128
: {
297 typename __basic_format_arg_value
<_Context
>::__handle __h
{__arg
.__value_
.__i128_
};
298 return std::invoke(std::forward
<_Visitor
>(__vis
), typename basic_format_arg
<_Context
>::handle
{__h
});
301 case __format::__arg_t::__u128
: {
302 typename __basic_format_arg_value
<_Context
>::__handle __h
{__arg
.__value_
.__u128_
};
303 return std::invoke(std::forward
<_Visitor
>(__vis
), typename basic_format_arg
<_Context
>::handle
{__h
});
307 return std::__visit_format_arg(std::forward
<_Visitor
>(__vis
), __arg
);
311 // This function is user facing, so it must wrap the non-standard types of
312 // the "variant" in a handle to stay conforming. See __arg_t for more details.
313 template <class _Rp
, class _Visitor
>
314 _LIBCPP_HIDE_FROM_ABI _Rp
visit(this basic_format_arg __arg
, _Visitor
&& __vis
) {
315 switch (__arg
.__type_
) {
316 # if _LIBCPP_HAS_INT128
317 case __format::__arg_t::__i128
: {
318 typename __basic_format_arg_value
<_Context
>::__handle __h
{__arg
.__value_
.__i128_
};
319 return std::invoke_r
<_Rp
>(std::forward
<_Visitor
>(__vis
), typename basic_format_arg
<_Context
>::handle
{__h
});
322 case __format::__arg_t::__u128
: {
323 typename __basic_format_arg_value
<_Context
>::__handle __h
{__arg
.__value_
.__u128_
};
324 return std::invoke_r
<_Rp
>(std::forward
<_Visitor
>(__vis
), typename basic_format_arg
<_Context
>::handle
{__h
});
328 return std::__visit_format_arg
<_Rp
>(std::forward
<_Visitor
>(__vis
), __arg
);
332 # endif // _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
335 using char_type
= typename
_Context::char_type
;
337 // TODO FMT Implement constrain [format.arg]/4
338 // Constraints: The template specialization
339 // typename Context::template formatter_type<T>
340 // meets the Formatter requirements ([formatter.requirements]). The extent
341 // to which an implementation determines that the specialization meets the
342 // Formatter requirements is unspecified, except that as a minimum the
344 // typename Context::template formatter_type<T>()
345 // .format(declval<const T&>(), declval<Context&>())
346 // shall be well-formed when treated as an unevaluated operand.
349 __basic_format_arg_value
<_Context
> __value_
;
350 __format::__arg_t __type_
;
352 _LIBCPP_HIDE_FROM_ABI
explicit basic_format_arg(__format::__arg_t __type
,
353 __basic_format_arg_value
<_Context
> __value
) noexcept
354 : __value_(__value
), __type_(__type
) {}
357 template <class _Context
>
358 class _LIBCPP_TEMPLATE_VIS basic_format_arg
<_Context
>::handle
{
360 _LIBCPP_HIDE_FROM_ABI
void format(basic_format_parse_context
<char_type
>& __parse_ctx
, _Context
& __ctx
) const {
361 __handle_
.__format_(__parse_ctx
, __ctx
, __handle_
.__ptr_
);
364 _LIBCPP_HIDE_FROM_ABI
explicit handle(typename __basic_format_arg_value
<_Context
>::__handle
& __handle
) noexcept
365 : __handle_(__handle
) {}
368 typename __basic_format_arg_value
<_Context
>::__handle
& __handle_
;
371 // This function is user facing, so it must wrap the non-standard types of
372 // the "variant" in a handle to stay conforming. See __arg_t for more details.
373 template <class _Visitor
, class _Context
>
374 # if _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
375 _LIBCPP_DEPRECATED_IN_CXX26
377 _LIBCPP_HIDE_FROM_ABI
decltype(auto)
378 visit_format_arg(_Visitor
&& __vis
, basic_format_arg
<_Context
> __arg
) {
379 switch (__arg
.__type_
) {
380 # if _LIBCPP_HAS_INT128
381 case __format::__arg_t::__i128
: {
382 typename __basic_format_arg_value
<_Context
>::__handle __h
{__arg
.__value_
.__i128_
};
383 return std::invoke(std::forward
<_Visitor
>(__vis
), typename basic_format_arg
<_Context
>::handle
{__h
});
386 case __format::__arg_t::__u128
: {
387 typename __basic_format_arg_value
<_Context
>::__handle __h
{__arg
.__value_
.__u128_
};
388 return std::invoke(std::forward
<_Visitor
>(__vis
), typename basic_format_arg
<_Context
>::handle
{__h
});
390 # endif // _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
392 return std::__visit_format_arg(std::forward
<_Visitor
>(__vis
), __arg
);
396 #endif // _LIBCPP_STD_VER >= 20
398 _LIBCPP_END_NAMESPACE_STD
402 #endif // _LIBCPP___FORMAT_FORMAT_ARG_H