1*4bdff4beSrobert // -*- C++ -*-
2*4bdff4beSrobert //===----------------------------------------------------------------------===//
3*4bdff4beSrobert //
4*4bdff4beSrobert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*4bdff4beSrobert // See https://llvm.org/LICENSE.txt for license information.
6*4bdff4beSrobert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*4bdff4beSrobert //
8*4bdff4beSrobert //===----------------------------------------------------------------------===//
9*4bdff4beSrobert 
10*4bdff4beSrobert #ifndef _LIBCPP___FORMAT_CONCEPTS_H
11*4bdff4beSrobert #define _LIBCPP___FORMAT_CONCEPTS_H
12*4bdff4beSrobert 
13*4bdff4beSrobert #include <__concepts/same_as.h>
14*4bdff4beSrobert #include <__concepts/semiregular.h>
15*4bdff4beSrobert #include <__config>
16*4bdff4beSrobert #include <__format/format_fwd.h>
17*4bdff4beSrobert #include <__format/format_parse_context.h>
18*4bdff4beSrobert #include <__type_traits/is_specialization.h>
19*4bdff4beSrobert #include <__utility/pair.h>
20*4bdff4beSrobert #include <tuple>
21*4bdff4beSrobert #include <type_traits>
22*4bdff4beSrobert 
23*4bdff4beSrobert #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
24*4bdff4beSrobert #  pragma GCC system_header
25*4bdff4beSrobert #endif
26*4bdff4beSrobert 
27*4bdff4beSrobert _LIBCPP_BEGIN_NAMESPACE_STD
28*4bdff4beSrobert 
29*4bdff4beSrobert #if _LIBCPP_STD_VER > 17
30*4bdff4beSrobert 
31*4bdff4beSrobert /// The character type specializations of \ref formatter.
32*4bdff4beSrobert template <class _CharT>
33*4bdff4beSrobert concept __fmt_char_type =
34*4bdff4beSrobert     same_as<_CharT, char>
35*4bdff4beSrobert #  ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
36*4bdff4beSrobert     || same_as<_CharT, wchar_t>
37*4bdff4beSrobert #  endif
38*4bdff4beSrobert     ;
39*4bdff4beSrobert 
40*4bdff4beSrobert // The output iterator isn't specified. A formatter should accept any
41*4bdff4beSrobert // output_iterator. This iterator is a minimal iterator to test the concept.
42*4bdff4beSrobert // (Note testing for (w)format_context would be a valid choice, but requires
43*4bdff4beSrobert // selecting the proper one depending on the type of _CharT.)
44*4bdff4beSrobert template <class _CharT>
45*4bdff4beSrobert using __fmt_iter_for = _CharT*;
46*4bdff4beSrobert 
47*4bdff4beSrobert template <class _Tp, class _CharT>
48*4bdff4beSrobert concept __formattable =
49*4bdff4beSrobert     (semiregular<formatter<remove_cvref_t<_Tp>, _CharT>>) &&
requires(formatter<remove_cvref_t<_Tp>,_CharT> __f,const formatter<remove_cvref_t<_Tp>,_CharT> __cf,_Tp __t,basic_format_context<__fmt_iter_for<_CharT>,_CharT> __fc,basic_format_parse_context<_CharT> __pc)50*4bdff4beSrobert     requires(formatter<remove_cvref_t<_Tp>, _CharT> __f,
51*4bdff4beSrobert              const formatter<remove_cvref_t<_Tp>, _CharT> __cf,
52*4bdff4beSrobert              _Tp __t,
53*4bdff4beSrobert              basic_format_context<__fmt_iter_for<_CharT>, _CharT> __fc,
54*4bdff4beSrobert              basic_format_parse_context<_CharT> __pc) {
55*4bdff4beSrobert       { __f.parse(__pc) } -> same_as<typename basic_format_parse_context<_CharT>::iterator>;
56*4bdff4beSrobert       { __cf.format(__t, __fc) } -> same_as<__fmt_iter_for<_CharT>>;
57*4bdff4beSrobert     };
58*4bdff4beSrobert 
59*4bdff4beSrobert #  if _LIBCPP_STD_VER > 20
60*4bdff4beSrobert template <class _Tp, class _CharT>
61*4bdff4beSrobert concept formattable = __formattable<_Tp, _CharT>;
62*4bdff4beSrobert 
63*4bdff4beSrobert // [tuple.like] defines a tuple-like exposition only concept. This concept is
64*4bdff4beSrobert // not related to that. Therefore it uses a different name for the concept.
65*4bdff4beSrobert //
66*4bdff4beSrobert // TODO FMT Add a test to validate we fail when using that concept after P2165
67*4bdff4beSrobert // has been implemented.
68*4bdff4beSrobert template <class _Tp>
69*4bdff4beSrobert concept __fmt_pair_like =
70*4bdff4beSrobert     __is_specialization_v<_Tp, pair> || (__is_specialization_v<_Tp, tuple> && tuple_size_v<_Tp> == 2);
71*4bdff4beSrobert 
72*4bdff4beSrobert #  endif //_LIBCPP_STD_VER > 20
73*4bdff4beSrobert #endif //_LIBCPP_STD_VER > 17
74*4bdff4beSrobert 
75*4bdff4beSrobert _LIBCPP_END_NAMESPACE_STD
76*4bdff4beSrobert 
77*4bdff4beSrobert #endif // _LIBCPP___FORMAT_CONCEPTS_H
78