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