blob: b320b75b7d9ecf50a2ed80efede249d3b6ec0439 [file] [log] [blame]
Mark de Weverdf5fd832020-11-26 19:12:18 +01001// -*- 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 {
Mark de Wevercba61372020-12-05 11:45:21 +010016 // [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
Mark de Weverdf5fd832020-11-26 19:12:18 +0100146 // [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 };
Mark de Wever6a67a5f2021-02-02 18:10:33 +0100152
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>;
Mark de Weverdf5fd832020-11-26 19:12:18 +0100184}
185
186*/
187
Mark de Weverbe38c382021-08-11 17:33:54 +0200188// Make sure all feature-test macros are available.
Mark de Wever14151d22021-07-30 14:35:37 -0400189#include <version>
Mark de Weverbe38c382021-08-11 17:33:54 +0200190// Enable the contents of the header only when libc++ was built with LIBCXX_ENABLE_INCOMPLETE_FEATURES.
Mark de Wever14151d22021-07-30 14:35:37 -0400191#if !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
192
Mark de Weverdf5fd832020-11-26 19:12:18 +0100193#include <__config>
Mark de Wevercba61372020-12-05 11:45:21 +0100194#include <__format/format_arg.h>
195#include <__format/format_args.h>
196#include <__format/format_context.h>
Mark de Wever1aef5d02021-04-25 17:58:03 +0200197#include <__format/format_error.h>
Mark de Wevere26bdbb2021-04-25 18:23:42 +0200198#include <__format/format_parse_context.h>
Mark de Wevercba61372020-12-05 11:45:21 +0100199#include <array>
Mark de Wever8a0a1882021-07-25 09:18:53 +0200200
Mark de Weverdf5fd832020-11-26 19:12:18 +0100201#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Mark de Wevercba61372020-12-05 11:45:21 +0100202#pragma GCC system_header
Mark de Weverdf5fd832020-11-26 19:12:18 +0100203#endif
204
Mark de Wevercba61372020-12-05 11:45:21 +0100205_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
Mark de Wever14151d22021-07-30 14:35:37 -0400249#endif // !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
250
Mark de Weverdf5fd832020-11-26 19:12:18 +0100251#endif // _LIBCPP_FORMAT