xref: /netbsd-src/external/apache2/llvm/dist/libcxx/include/format (revision 4d6fc14bc9b0c5bf3e30be318c143ee82cadd108)
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