1349cc55cSDimitry Andric // -*- C++ -*- 2349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 3349cc55cSDimitry Andric // 4349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7349cc55cSDimitry Andric // 8349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 9349cc55cSDimitry Andric 10349cc55cSDimitry Andric #ifndef _LIBCPP___FORMAT_FORMATTER_CHAR_H 11349cc55cSDimitry Andric #define _LIBCPP___FORMAT_FORMATTER_CHAR_H 12349cc55cSDimitry Andric 1381ad6265SDimitry Andric #include <__concepts/same_as.h> 14349cc55cSDimitry Andric #include <__config> 15bdd1243dSDimitry Andric #include <__format/concepts.h> 1681ad6265SDimitry Andric #include <__format/format_parse_context.h> 17349cc55cSDimitry Andric #include <__format/formatter.h> 18349cc55cSDimitry Andric #include <__format/formatter_integral.h> 1981ad6265SDimitry Andric #include <__format/formatter_output.h> 20349cc55cSDimitry Andric #include <__format/parser_std_format_spec.h> 2106c3fb27SDimitry Andric #include <__format/write_escaped.h> 2281ad6265SDimitry Andric #include <__type_traits/conditional.h> 23*5f757f3fSDimitry Andric #include <__type_traits/make_unsigned.h> 24349cc55cSDimitry Andric 25349cc55cSDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 26349cc55cSDimitry Andric # pragma GCC system_header 27349cc55cSDimitry Andric #endif 28349cc55cSDimitry Andric 29349cc55cSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 30349cc55cSDimitry Andric 3106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20 32349cc55cSDimitry Andric 33bdd1243dSDimitry Andric template <__fmt_char_type _CharT> 3406c3fb27SDimitry Andric struct _LIBCPP_TEMPLATE_VIS __formatter_char { 35349cc55cSDimitry Andric public: 3606c3fb27SDimitry Andric template <class _ParseContext> 3706c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr typename _ParseContext::iterator parse(_ParseContext& __ctx) { 3806c3fb27SDimitry Andric typename _ParseContext::iterator __result = __parser_.__parse(__ctx, __format_spec::__fields_integral); 3906c3fb27SDimitry Andric __format_spec::__process_parsed_char(__parser_, "a character"); 4081ad6265SDimitry Andric return __result; 41349cc55cSDimitry Andric } 42349cc55cSDimitry Andric 4306c3fb27SDimitry Andric template <class _FormatContext> 4406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(_CharT __value, _FormatContext& __ctx) const { 45753f127fSDimitry Andric if (__parser_.__type_ == __format_spec::__type::__default || __parser_.__type_ == __format_spec::__type::__char) 4681ad6265SDimitry Andric return __formatter::__format_char(__value, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx)); 4781ad6265SDimitry Andric 4806c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 49bdd1243dSDimitry Andric if (__parser_.__type_ == __format_spec::__type::__debug) 50bdd1243dSDimitry Andric return __formatter::__format_escaped_char(__value, __ctx.out(), __parser_.__get_parsed_std_specifications(__ctx)); 51bdd1243dSDimitry Andric # endif 52bdd1243dSDimitry Andric 53*5f757f3fSDimitry Andric if constexpr (sizeof(_CharT) <= sizeof(unsigned)) 5481ad6265SDimitry Andric return __formatter::__format_integer( 55*5f757f3fSDimitry Andric static_cast<unsigned>(static_cast<make_unsigned_t<_CharT>>(__value)), 5681ad6265SDimitry Andric __ctx, 5781ad6265SDimitry Andric __parser_.__get_parsed_std_specifications(__ctx)); 5881ad6265SDimitry Andric else 59*5f757f3fSDimitry Andric return __formatter::__format_integer( 60*5f757f3fSDimitry Andric static_cast<make_unsigned_t<_CharT>>(__value), __ctx, __parser_.__get_parsed_std_specifications(__ctx)); 61349cc55cSDimitry Andric } 6281ad6265SDimitry Andric 6306c3fb27SDimitry Andric template <class _FormatContext> 6406c3fb27SDimitry Andric _LIBCPP_HIDE_FROM_ABI typename _FormatContext::iterator format(char __value, _FormatContext& __ctx) const 6581ad6265SDimitry Andric requires(same_as<_CharT, wchar_t>) 6681ad6265SDimitry Andric { 67*5f757f3fSDimitry Andric return format(static_cast<wchar_t>(static_cast<unsigned char>(__value)), __ctx); 6881ad6265SDimitry Andric } 6981ad6265SDimitry Andric 7006c3fb27SDimitry Andric # if _LIBCPP_STD_VER >= 23 71bdd1243dSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr void set_debug_format() { __parser_.__type_ = __format_spec::__type::__debug; } 72bdd1243dSDimitry Andric # endif 73bdd1243dSDimitry Andric 7481ad6265SDimitry Andric __format_spec::__parser<_CharT> __parser_; 75349cc55cSDimitry Andric }; 76349cc55cSDimitry Andric 77349cc55cSDimitry Andric template <> 7806c3fb27SDimitry Andric struct _LIBCPP_TEMPLATE_VIS formatter<char, char> : public __formatter_char<char> {}; 79349cc55cSDimitry Andric 80349cc55cSDimitry Andric # ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 81349cc55cSDimitry Andric template <> 8206c3fb27SDimitry Andric struct _LIBCPP_TEMPLATE_VIS formatter<char, wchar_t> : public __formatter_char<wchar_t> {}; 83349cc55cSDimitry Andric 84349cc55cSDimitry Andric template <> 85*5f757f3fSDimitry Andric struct _LIBCPP_TEMPLATE_VIS formatter<wchar_t, wchar_t> : public __formatter_char<wchar_t> {}; 8681ad6265SDimitry Andric 87349cc55cSDimitry Andric # endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS 88349cc55cSDimitry Andric 8906c3fb27SDimitry Andric #endif //_LIBCPP_STD_VER >= 20 90349cc55cSDimitry Andric 91349cc55cSDimitry Andric _LIBCPP_END_NAMESPACE_STD 92349cc55cSDimitry Andric 93349cc55cSDimitry Andric #endif // _LIBCPP___FORMAT_FORMATTER_CHAR_H 94