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