xref: /llvm-project-15.0.7/libcxx/include/format (revision ef2cdfe3)
1// -*- C++ -*-
2//===--------------------------- format -----------------------------------===//
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
11#define _LIBCPP_FORMAT
12
13/*
14
15namespace std {
16  // [format.context], class template basic_format_context
17  template<class Out, class charT>
18  class basic_format_context {
19    basic_format_args<basic_format_context> args_;      // exposition only
20    Out out_;                                           // exposition only
21
22  public:
23    using iterator = Out;
24    using char_type = charT;
25    template<class T> using formatter_type = formatter<T, charT>;
26
27    basic_format_arg<basic_format_context> arg(size_t id) const;
28    std::locale locale();
29
30    iterator out();
31    void advance_to(iterator it);
32  };
33  using format_context = basic_format_context<unspecified, char>;
34  using wformat_context = basic_format_context<unspecified, wchar_t>;
35
36  // [format.args], class template basic_format_args
37  template<class Context>
38  class basic_format_args {
39    size_t size_;                               // exposition only
40    const basic_format_arg<Context>* data_;     // exposition only
41
42  public:
43    basic_format_args() noexcept;
44
45    template<class... Args>
46      basic_format_args(const format-arg-store<Context, Args...>& store) noexcept;
47
48    basic_format_arg<Context> get(size_t i) const noexcept;
49  };
50  using format_args = basic_format_args<format_context>;
51  using wformat_args = basic_format_args<wformat_context>;
52
53
54  template<class Out, class charT>
55    using format_args_t = basic_format_args<basic_format_context<Out, charT>>;
56
57  // [format.parse.ctx], class template basic_format_parse_context
58  template<class charT>
59  class basic_format_parse_context {
60  public:
61    using char_type = charT;
62    using const_iterator = typename basic_string_view<charT>::const_iterator;
63    using iterator = const_iterator;
64
65  private:
66    iterator begin_;                                    // exposition only
67    iterator end_;                                      // exposition only
68    enum indexing { unknown, manual, automatic };       // exposition only
69    indexing indexing_;                                 // exposition only
70    size_t next_arg_id_;                                // exposition only
71    size_t num_args_;                                   // exposition only
72
73  public:
74    constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt,
75                                                  size_t num_args = 0) noexcept;
76    basic_format_parse_context(const basic_format_parse_context&) = delete;
77    basic_format_parse_context& operator=(const basic_format_parse_context&) = delete;
78
79    constexpr const_iterator begin() const noexcept;
80    constexpr const_iterator end() const noexcept;
81    constexpr void advance_to(const_iterator it);
82
83    constexpr size_t next_arg_id();
84    constexpr void check_arg_id(size_t id);
85  };
86  using format_parse_context = basic_format_parse_context<char>;
87  using wformat_parse_context = basic_format_parse_context<wchar_t>;
88
89  // [format.arguments], arguments
90  // [format.arg], class template basic_format_arg
91  template<class Context>
92  class basic_format_arg {
93  public:
94    class handle;
95
96  private:
97    using char_type = typename Context::char_type;                              // exposition only
98
99    variant<monostate, bool, char_type,
100            int, unsigned int, long long int, unsigned long long int,
101            float, double, long double,
102            const char_type*, basic_string_view<char_type>,
103            const void*, handle> value;                                         // exposition only
104
105    template<class T> explicit basic_format_arg(const T& v) noexcept;           // exposition only
106    explicit basic_format_arg(float n) noexcept;                                // exposition only
107    explicit basic_format_arg(double n) noexcept;                               // exposition only
108    explicit basic_format_arg(long double n) noexcept;                          // exposition only
109    explicit basic_format_arg(const char_type* s);                              // exposition only
110
111    template<class traits>
112      explicit basic_format_arg(
113        basic_string_view<char_type, traits> s) noexcept;                       // exposition only
114
115    template<class traits, class Allocator>
116      explicit basic_format_arg(
117        const basic_string<char_type, traits, Allocator>& s) noexcept;          // exposition only
118
119    explicit basic_format_arg(nullptr_t) noexcept;                              // exposition only
120
121    template<class T>
122      explicit basic_format_arg(const T* p) noexcept;                           // exposition only
123
124  public:
125    basic_format_arg() noexcept;
126
127    explicit operator bool() const noexcept;
128  };
129
130  template<class Visitor, class Context>
131    see below visit_format_arg(Visitor&& vis, basic_format_arg<Context> arg);
132
133  // [format.arg.store], class template format-arg-store
134  template<class Context, class... Args>
135  struct format-arg-store {      // exposition only
136    array<basic_format_arg<Context>, sizeof...(Args)> args;
137  };
138
139  template<class Context = format_context, class... Args>
140    format-arg-store<Context, Args...>
141      make_format_args(const Args&... args);
142  template<class... Args>
143    format-arg-store<wformat_context, Args...>
144      make_wformat_args(const Args&... args);
145
146  // [format.error], class format_error
147  class format_error : public runtime_error {
148  public:
149    explicit format_error(const string& what_arg);
150    explicit format_error(const char* what_arg);
151  };
152
153  // [format.parse.ctx], class template basic_format_parse_context
154  template<class charT>
155  class basic_format_parse_context {
156  public:
157    using char_type = charT;
158    using const_iterator = typename basic_string_view<charT>::const_iterator;
159    using iterator = const_iterator;
160
161  private:
162    iterator begin_;                                    // exposition only
163    iterator end_;                                      // exposition only
164    enum indexing { unknown, manual, automatic };       // exposition only
165    indexing indexing_;                                 // exposition only
166    size_t next_arg_id_;                                // exposition only
167    size_t num_args_;                                   // exposition only
168
169  public:
170    constexpr explicit basic_format_parse_context(basic_string_view<charT> fmt,
171                                                  size_t num_args = 0) noexcept;
172    basic_format_parse_context(const basic_format_parse_context&) = delete;
173    basic_format_parse_context& operator=(const basic_format_parse_context&) = delete;
174
175    constexpr const_iterator begin() const noexcept;
176    constexpr const_iterator end() const noexcept;
177    constexpr void advance_to(const_iterator it);
178
179    constexpr size_t next_arg_id();
180    constexpr void check_arg_id(size_t id);
181  };
182  using format_parse_context = basic_format_parse_context<char>;
183  using wformat_parse_context = basic_format_parse_context<wchar_t>;
184}
185
186*/
187
188// Make sure all feature-test macros are available.
189#include <version>
190// Enable the contents of the header only when libc++ was built with LIBCXX_ENABLE_INCOMPLETE_FEATURES.
191#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
192
193#include <__config>
194#include <__format/format_arg.h>
195#include <__format/format_args.h>
196#include <__format/format_context.h>
197#include <__format/format_error.h>
198#include <__format/format_parse_context.h>
199#include <array>
200
201#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
202#pragma GCC system_header
203#endif
204
205_LIBCPP_BEGIN_NAMESPACE_STD
206
207#if _LIBCPP_STD_VER > 17
208
209// TODO FMT Remove this once we require compilers with proper C++20 support.
210// If the compiler has no concepts support, the format header will be disabled.
211// Without concepts support enable_if needs to be used and that too much effort
212// to support compilers with partial C++20 support.
213#if !defined(_LIBCPP_HAS_NO_CONCEPTS)
214
215// TODO FMT Evaluate which templates should be external templates. This
216// improves the efficiency of the header. However since the header is still
217// under heavy development and not all classes are stable it makes no sense
218// to do this optimization now.
219
220using format_args = basic_format_args<format_context>;
221using wformat_args = basic_format_args<wformat_context>;
222
223template <class _OutIt, class _CharT>
224using format_args_t = basic_format_args<basic_format_context<_OutIt, _CharT>>;
225
226template <class _Context, class... _Args>
227struct _LIBCPP_TEMPLATE_VIS __format_arg_store {
228  // TODO FMT Use a built-in array.
229  array<basic_format_arg<_Context>, sizeof...(_Args)> __args;
230};
231
232template <class _Context = format_context, class... _Args>
233_LIBCPP_HIDE_FROM_ABI __format_arg_store<_Context, _Args...>
234make_format_args(const _Args&... __args) {
235  return {basic_format_arg<_Context>(__args)...};
236}
237
238template <class... _Args>
239_LIBCPP_HIDE_FROM_ABI __format_arg_store<wformat_context, _Args...>
240make_wformat_args(const _Args&... __args) {
241  return _VSTD::make_format_args<wformat_context>(__args...);
242}
243
244#endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)
245#endif //_LIBCPP_STD_VER > 17
246
247_LIBCPP_END_NAMESPACE_STD
248
249#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
250
251#endif // _LIBCPP_FORMAT
252