1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H 11 #define _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H 12 13 #include <__config> 14 #include <__format/format_error.h> 15 #include <string_view> 16 17 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 18 # pragma GCC system_header 19 #endif 20 21 _LIBCPP_BEGIN_NAMESPACE_STD 22 23 #if _LIBCPP_STD_VER > 17 24 25 template <class _CharT> 26 class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_parse_context { 27 public: 28 using char_type = _CharT; 29 using const_iterator = typename basic_string_view<_CharT>::const_iterator; 30 using iterator = const_iterator; 31 32 _LIBCPP_HIDE_FROM_ABI 33 constexpr explicit basic_format_parse_context(basic_string_view<_CharT> __fmt, 34 size_t __num_args = 0) noexcept 35 : __begin_(__fmt.begin()), 36 __end_(__fmt.end()), 37 __indexing_(__unknown), 38 __next_arg_id_(0), 39 __num_args_(__num_args) {} 40 41 basic_format_parse_context(const basic_format_parse_context&) = delete; 42 basic_format_parse_context& 43 operator=(const basic_format_parse_context&) = delete; 44 45 _LIBCPP_HIDE_FROM_ABI constexpr const_iterator begin() const noexcept { 46 return __begin_; 47 } 48 _LIBCPP_HIDE_FROM_ABI constexpr const_iterator end() const noexcept { 49 return __end_; 50 } 51 _LIBCPP_HIDE_FROM_ABI constexpr void advance_to(const_iterator __it) { 52 __begin_ = __it; 53 } 54 55 _LIBCPP_HIDE_FROM_ABI constexpr size_t next_arg_id() { 56 if (__indexing_ == __manual) 57 std::__throw_format_error("Using automatic argument numbering in manual argument numbering mode"); 58 59 if (__indexing_ == __unknown) 60 __indexing_ = __automatic; 61 return __next_arg_id_++; 62 } 63 _LIBCPP_HIDE_FROM_ABI constexpr void check_arg_id(size_t __id) { 64 if (__indexing_ == __automatic) 65 std::__throw_format_error("Using manual argument numbering in automatic argument numbering mode"); 66 67 if (__indexing_ == __unknown) 68 __indexing_ = __manual; 69 70 // Throws an exception to make the expression a non core constant 71 // expression as required by: 72 // [format.parse.ctx]/11 73 // Remarks: Call expressions where id >= num_args_ are not core constant 74 // expressions ([expr.const]). 75 // Note: the Throws clause [format.parse.ctx]/10 doesn't specify the 76 // behavior when id >= num_args_. 77 if (is_constant_evaluated() && __id >= __num_args_) 78 std::__throw_format_error("Argument index outside the valid range"); 79 } 80 81 private: 82 iterator __begin_; 83 iterator __end_; 84 enum _Indexing { __unknown, __manual, __automatic }; 85 _Indexing __indexing_; 86 size_t __next_arg_id_; 87 size_t __num_args_; 88 }; 89 _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(basic_format_parse_context); 90 91 using format_parse_context = basic_format_parse_context<char>; 92 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 93 using wformat_parse_context = basic_format_parse_context<wchar_t>; 94 #endif 95 96 #endif //_LIBCPP_STD_VER > 17 97 98 _LIBCPP_END_NAMESPACE_STD 99 100 #endif // _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H 101