115c809e8SMark de Wever // -*- C++ -*- 215c809e8SMark de Wever //===----------------------------------------------------------------------===// 315c809e8SMark de Wever // 415c809e8SMark de Wever // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 515c809e8SMark de Wever // See https://llvm.org/LICENSE.txt for license information. 615c809e8SMark de Wever // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 715c809e8SMark de Wever // 815c809e8SMark de Wever //===----------------------------------------------------------------------===// 915c809e8SMark de Wever 1015c809e8SMark de Wever #ifndef _LIBCPP___FORMAT_CONCEPTS_H 1115c809e8SMark de Wever #define _LIBCPP___FORMAT_CONCEPTS_H 1215c809e8SMark de Wever 1315c809e8SMark de Wever #include <__concepts/same_as.h> 1415c809e8SMark de Wever #include <__concepts/semiregular.h> 1515c809e8SMark de Wever #include <__config> 1615c809e8SMark de Wever #include <__format/format_parse_context.h> 1708766681SNikolas Klauser #include <__fwd/format.h> 184528c44dSNikolas Klauser #include <__fwd/tuple.h> 194528c44dSNikolas Klauser #include <__tuple/tuple_size.h> 20d184958bSMark de Wever #include <__type_traits/is_specialization.h> 2148abcf11SMark de Wever #include <__type_traits/remove_const.h> 224528c44dSNikolas Klauser #include <__type_traits/remove_reference.h> 23d184958bSMark de Wever #include <__utility/pair.h> 2415c809e8SMark de Wever 2515c809e8SMark de Wever #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 2615c809e8SMark de Wever # pragma GCC system_header 2715c809e8SMark de Wever #endif 2815c809e8SMark de Wever 2915c809e8SMark de Wever _LIBCPP_BEGIN_NAMESPACE_STD 3015c809e8SMark de Wever 314f15267dSNikolas Klauser #if _LIBCPP_STD_VER >= 20 3215c809e8SMark de Wever 33a595fcf9SMark de Wever /// The character type specializations of \ref formatter. 34a595fcf9SMark de Wever template <class _CharT> 35a595fcf9SMark de Wever concept __fmt_char_type = 36a595fcf9SMark de Wever same_as<_CharT, char> 37c6f3b7bcSNikolas Klauser # if _LIBCPP_HAS_WIDE_CHARACTERS 38a595fcf9SMark de Wever || same_as<_CharT, wchar_t> 39a595fcf9SMark de Wever # endif 40a595fcf9SMark de Wever ; 41a595fcf9SMark de Wever 4215c809e8SMark de Wever // The output iterator isn't specified. A formatter should accept any 4315c809e8SMark de Wever // output_iterator. This iterator is a minimal iterator to test the concept. 4415c809e8SMark de Wever // (Note testing for (w)format_context would be a valid choice, but requires 4515c809e8SMark de Wever // selecting the proper one depending on the type of _CharT.) 4615c809e8SMark de Wever template <class _CharT> 47*f6958523SNikolas Klauser using __fmt_iter_for _LIBCPP_NODEBUG = _CharT*; 4815c809e8SMark de Wever 4948abcf11SMark de Wever template <class _Tp, class _Context, class _Formatter = typename _Context::template formatter_type<remove_const_t<_Tp>>> 5048abcf11SMark de Wever concept __formattable_with = 5148abcf11SMark de Wever semiregular<_Formatter> && 5248abcf11SMark de Wever requires(_Formatter& __f, 5348abcf11SMark de Wever const _Formatter& __cf, 5448abcf11SMark de Wever _Tp&& __t, 5548abcf11SMark de Wever _Context __fc, 5648abcf11SMark de Wever basic_format_parse_context<typename _Context::char_type> __pc) { 5748abcf11SMark de Wever { __f.parse(__pc) } -> same_as<typename decltype(__pc)::iterator>; 5848abcf11SMark de Wever { __cf.format(__t, __fc) } -> same_as<typename _Context::iterator>; 5948abcf11SMark de Wever }; 6048abcf11SMark de Wever 6115c809e8SMark de Wever template <class _Tp, class _CharT> 62a1beb0a3SMark de Wever concept __formattable = 6348abcf11SMark de Wever __formattable_with<remove_reference_t<_Tp>, basic_format_context<__fmt_iter_for<_CharT>, _CharT>>; 6415c809e8SMark de Wever 654f15267dSNikolas Klauser # if _LIBCPP_STD_VER >= 23 66a1beb0a3SMark de Wever template <class _Tp, class _CharT> 67a1beb0a3SMark de Wever concept formattable = __formattable<_Tp, _CharT>; 68d184958bSMark de Wever 69d184958bSMark de Wever // [tuple.like] defines a tuple-like exposition only concept. This concept is 70d184958bSMark de Wever // not related to that. Therefore it uses a different name for the concept. 71d184958bSMark de Wever // 72d184958bSMark de Wever // TODO FMT Add a test to validate we fail when using that concept after P2165 73d184958bSMark de Wever // has been implemented. 74d184958bSMark de Wever template <class _Tp> 75347a65a1SMark de Wever concept __fmt_pair_like = 76347a65a1SMark de Wever __is_specialization_v<_Tp, pair> || (__is_specialization_v<_Tp, tuple> && tuple_size_v<_Tp> == 2); 77d184958bSMark de Wever 784f15267dSNikolas Klauser # endif // _LIBCPP_STD_VER >= 23 794f15267dSNikolas Klauser #endif // _LIBCPP_STD_VER >= 20 8015c809e8SMark de Wever 8115c809e8SMark de Wever _LIBCPP_END_NAMESPACE_STD 8215c809e8SMark de Wever 8315c809e8SMark de Wever #endif // _LIBCPP___FORMAT_CONCEPTS_H 84