1*c303c47eSjoerg// -*- C++ -*- 2*c303c47eSjoerg//===--------------------------- format -----------------------------------===// 3*c303c47eSjoerg// 4*c303c47eSjoerg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*c303c47eSjoerg// See https://llvm.org/LICENSE.txt for license information. 6*c303c47eSjoerg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*c303c47eSjoerg// 8*c303c47eSjoerg//===----------------------------------------------------------------------===// 9*c303c47eSjoerg 10*c303c47eSjoerg#ifndef _LIBCPP_FORMAT 11*c303c47eSjoerg#define _LIBCPP_FORMAT 12*c303c47eSjoerg 13*c303c47eSjoerg/* 14*c303c47eSjoerg 15*c303c47eSjoergnamespace std { 16*c303c47eSjoerg // [format.error], class format_error 17*c303c47eSjoerg class format_error : public runtime_error { 18*c303c47eSjoerg public: 19*c303c47eSjoerg explicit format_error(const string& what_arg); 20*c303c47eSjoerg explicit format_error(const char* what_arg); 21*c303c47eSjoerg }; 22*c303c47eSjoerg 23*c303c47eSjoerg // [format.parse.ctx], class template basic_format_parse_context 24*c303c47eSjoerg template<class charT> 25*c303c47eSjoerg class basic_format_parse_context { 26*c303c47eSjoerg public: 27*c303c47eSjoerg using char_type = charT; 28*c303c47eSjoerg using const_iterator = typename basic_string_view<charT>::const_iterator; 29*c303c47eSjoerg using iterator = const_iterator; 30*c303c47eSjoerg 31*c303c47eSjoerg private: 32*c303c47eSjoerg iterator begin_; // exposition only 33*c303c47eSjoerg iterator end_; // exposition only 34*c303c47eSjoerg enum indexing { unknown, manual, automatic }; // exposition only 35*c303c47eSjoerg indexing indexing_; // exposition only 36*c303c47eSjoerg size_t next_arg_id_; // exposition only 37*c303c47eSjoerg size_t num_args_; // exposition only 38*c303c47eSjoerg 39*c303c47eSjoerg public: 40*c303c47eSjoerg constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt, 41*c303c47eSjoerg size_t num_args = 0) noexcept; 42*c303c47eSjoerg basic_format_parse_context(const basic_format_parse_context&) = delete; 43*c303c47eSjoerg basic_format_parse_context& operator=(const basic_format_parse_context&) = delete; 44*c303c47eSjoerg 45*c303c47eSjoerg constexpr const_iterator begin() const noexcept; 46*c303c47eSjoerg constexpr const_iterator end() const noexcept; 47*c303c47eSjoerg constexpr void advance_to(const_iterator it); 48*c303c47eSjoerg 49*c303c47eSjoerg constexpr size_t next_arg_id(); 50*c303c47eSjoerg constexpr void check_arg_id(size_t id); 51*c303c47eSjoerg }; 52*c303c47eSjoerg using format_parse_context = basic_format_parse_context<char>; 53*c303c47eSjoerg using wformat_parse_context = basic_format_parse_context<wchar_t>; 54*c303c47eSjoerg} 55*c303c47eSjoerg 56*c303c47eSjoerg*/ 57*c303c47eSjoerg 58*c303c47eSjoerg#include <__config> 59*c303c47eSjoerg#include <stdexcept> 60*c303c47eSjoerg#include <string_view> 61*c303c47eSjoerg#include <version> 62*c303c47eSjoerg 63*c303c47eSjoerg#ifdef _LIBCPP_NO_EXCEPTIONS 64*c303c47eSjoerg#include <cstdlib> 65*c303c47eSjoerg#endif 66*c303c47eSjoerg 67*c303c47eSjoerg#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 68*c303c47eSjoerg# pragma GCC system_header 69*c303c47eSjoerg#endif 70*c303c47eSjoerg 71*c303c47eSjoerg_LIBCPP_PUSH_MACROS 72*c303c47eSjoerg#include <__undef_macros> 73*c303c47eSjoerg 74*c303c47eSjoerg_LIBCPP_BEGIN_NAMESPACE_STD 75*c303c47eSjoerg 76*c303c47eSjoerg#if _LIBCPP_STD_VER > 17 77*c303c47eSjoerg 78*c303c47eSjoergclass _LIBCPP_EXCEPTION_ABI format_error : public runtime_error { 79*c303c47eSjoergpublic: 80*c303c47eSjoerg _LIBCPP_INLINE_VISIBILITY explicit format_error(const string& __s) 81*c303c47eSjoerg : runtime_error(__s) {} 82*c303c47eSjoerg _LIBCPP_INLINE_VISIBILITY explicit format_error(const char* __s) 83*c303c47eSjoerg : runtime_error(__s) {} 84*c303c47eSjoerg virtual ~format_error() noexcept; 85*c303c47eSjoerg}; 86*c303c47eSjoerg 87*c303c47eSjoerg// TODO FMT Remove this once we require compilers with proper C++20 support. 88*c303c47eSjoerg// If the compiler has no concepts support, the format header will be disabled. 89*c303c47eSjoerg// Without concepts support enable_if needs to be used and that too much effort 90*c303c47eSjoerg// to support compilers with partial C++20 support. 91*c303c47eSjoerg#if !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED) 92*c303c47eSjoerg 93*c303c47eSjoerg_LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY void 94*c303c47eSjoerg__throw_format_error(const char* __s) { 95*c303c47eSjoerg#ifndef _LIBCPP_NO_EXCEPTIONS 96*c303c47eSjoerg throw format_error(__s); 97*c303c47eSjoerg#else 98*c303c47eSjoerg (void)__s; 99*c303c47eSjoerg _VSTD::abort(); 100*c303c47eSjoerg#endif 101*c303c47eSjoerg} 102*c303c47eSjoerg 103*c303c47eSjoergtemplate <class _CharT> 104*c303c47eSjoergclass _LIBCPP_TEMPLATE_VIS basic_format_parse_context { 105*c303c47eSjoergpublic: 106*c303c47eSjoerg using char_type = _CharT; 107*c303c47eSjoerg using const_iterator = 108*c303c47eSjoerg typename basic_string_view<_CharT>::const_iterator; 109*c303c47eSjoerg using iterator = const_iterator; 110*c303c47eSjoerg 111*c303c47eSjoergpublic: 112*c303c47eSjoerg _LIBCPP_INLINE_VISIBILITY 113*c303c47eSjoerg constexpr explicit basic_format_parse_context( 114*c303c47eSjoerg basic_string_view<_CharT> __fmt, size_t __num_args = 0) noexcept 115*c303c47eSjoerg : __begin_(__fmt.begin()), 116*c303c47eSjoerg __end_(__fmt.end()), 117*c303c47eSjoerg __indexing_(__unknown), 118*c303c47eSjoerg __next_arg_id_(0), 119*c303c47eSjoerg __num_args_(__num_args) {} 120*c303c47eSjoerg 121*c303c47eSjoerg basic_format_parse_context(const basic_format_parse_context&) = delete; 122*c303c47eSjoerg basic_format_parse_context& 123*c303c47eSjoerg operator=(const basic_format_parse_context&) = delete; 124*c303c47eSjoerg 125*c303c47eSjoerg _LIBCPP_INLINE_VISIBILITY constexpr const_iterator begin() const noexcept { 126*c303c47eSjoerg return __begin_; 127*c303c47eSjoerg } 128*c303c47eSjoerg _LIBCPP_INLINE_VISIBILITY constexpr const_iterator end() const noexcept { 129*c303c47eSjoerg return __end_; 130*c303c47eSjoerg } 131*c303c47eSjoerg _LIBCPP_INLINE_VISIBILITY constexpr void advance_to(const_iterator __it) { 132*c303c47eSjoerg __begin_ = __it; 133*c303c47eSjoerg } 134*c303c47eSjoerg 135*c303c47eSjoerg _LIBCPP_INLINE_VISIBILITY constexpr size_t next_arg_id() { 136*c303c47eSjoerg if (__indexing_ == __manual) 137*c303c47eSjoerg __throw_format_error("Using automatic argument numbering in manual " 138*c303c47eSjoerg "argument numbering mode"); 139*c303c47eSjoerg 140*c303c47eSjoerg if (__indexing_ == __unknown) 141*c303c47eSjoerg __indexing_ = __automatic; 142*c303c47eSjoerg return __next_arg_id_++; 143*c303c47eSjoerg } 144*c303c47eSjoerg _LIBCPP_INLINE_VISIBILITY constexpr void check_arg_id(size_t __id) { 145*c303c47eSjoerg if (__indexing_ == __automatic) 146*c303c47eSjoerg __throw_format_error("Using manual argument numbering in automatic " 147*c303c47eSjoerg "argument numbering mode"); 148*c303c47eSjoerg 149*c303c47eSjoerg if (__indexing_ == __unknown) 150*c303c47eSjoerg __indexing_ = __manual; 151*c303c47eSjoerg 152*c303c47eSjoerg // Throws an exception to make the expression a non core constant 153*c303c47eSjoerg // expression as required by: 154*c303c47eSjoerg // [format.parse.ctx]/11 155*c303c47eSjoerg // Remarks: Call expressions where id >= num_args_ are not core constant 156*c303c47eSjoerg // expressions ([expr.const]). 157*c303c47eSjoerg // Note: the Throws clause [format.parse.ctx]/10 doesn't specify the 158*c303c47eSjoerg // behavior when id >= num_args_. 159*c303c47eSjoerg if (is_constant_evaluated() && __id >= __num_args_) 160*c303c47eSjoerg __throw_format_error("Argument index outside the valid range"); 161*c303c47eSjoerg } 162*c303c47eSjoerg 163*c303c47eSjoergprivate: 164*c303c47eSjoerg iterator __begin_; 165*c303c47eSjoerg iterator __end_; 166*c303c47eSjoerg enum _Indexing { __unknown, __manual, __automatic }; 167*c303c47eSjoerg _Indexing __indexing_; 168*c303c47eSjoerg size_t __next_arg_id_; 169*c303c47eSjoerg size_t __num_args_; 170*c303c47eSjoerg}; 171*c303c47eSjoerg 172*c303c47eSjoergusing format_parse_context = basic_format_parse_context<char>; 173*c303c47eSjoergusing wformat_parse_context = basic_format_parse_context<wchar_t>; 174*c303c47eSjoerg 175*c303c47eSjoerg#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS) && !defined(_LIBCPP_HAS_NO_BUILTIN_IS_CONSTANT_EVALUATED) 176*c303c47eSjoerg#endif //_LIBCPP_STD_VER > 17 177*c303c47eSjoerg 178*c303c47eSjoerg_LIBCPP_END_NAMESPACE_STD 179*c303c47eSjoerg 180*c303c47eSjoerg_LIBCPP_POP_MACROS 181*c303c47eSjoerg 182*c303c47eSjoerg#endif // _LIBCPP_FORMAT 183