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