Ticket #3190: cppformat.patch
File cppformat.patch, 160.2 KB (added by , 8 years ago) |
---|
-
source/third_party/cppformat/format.cpp
diff --git a/source/third_party/cppformat/format.cpp b/source/third_party/cppformat/format.cpp index b90d629..acd70b2 100644
a b 1 1 /* 2 * Slightly modified version of cppformat, by Wildfire Games, for 0 A.D.3 * Based on cppformat v0.11.0 from https://github.com/cppformat/cppformat4 */5 6 /*7 2 Formatting library for C++ 8 3 9 Copyright (c) 2012 - 201 4, Victor Zverovich4 Copyright (c) 2012 - 2015, Victor Zverovich 10 5 All rights reserved. 11 6 12 7 Redistribution and use in source and binary forms, with or without … … 30 25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 26 */ 32 27 33 #include "precompiled.h"34 35 // Disable useless MSVC warnings.36 #undef _CRT_SECURE_NO_WARNINGS37 #define _CRT_SECURE_NO_WARNINGS38 #undef _SCL_SECURE_NO_WARNINGS39 #define _SCL_SECURE_NO_WARNINGS40 41 28 #include "format.h" 42 29 43 30 #include <string.h> … … 47 34 #include <climits> 48 35 #include <cmath> 49 36 #include <cstdarg> 37 #include <cstddef> // for std::ptrdiff_t 50 38 51 #ifdef _WIN32 52 # define WIN32_LEAN_AND_MEAN 53 # ifdef __MINGW32__ 54 # include <cstring> 39 #if defined(_WIN32) && defined(__MINGW32__) 40 # include <cstring> 41 #endif 42 43 #if FMT_USE_WINDOWS_H 44 # if defined(NOMINMAX) || defined(FMT_WIN_MINMAX) 45 # include <windows.h> 46 # else 47 # define NOMINMAX 48 # include <windows.h> 49 # undef NOMINMAX 55 50 # endif 56 # include <windows.h>57 # undef ERROR58 51 #endif 59 52 60 using fmt::LongLong;61 using fmt::ULongLong;62 53 using fmt::internal::Arg; 63 54 64 #ifdef _MSC_VER 65 # pragma warning(push) 66 # pragma warning(disable: 4127) // conditional expression is constant 55 // Check if exceptions are disabled. 56 #if defined(__GNUC__) && !defined(__EXCEPTIONS) 57 # define FMT_EXCEPTIONS 0 58 #endif 59 #if defined(_MSC_VER) && !_HAS_EXCEPTIONS 60 # define FMT_EXCEPTIONS 0 61 #endif 62 #ifndef FMT_EXCEPTIONS 63 # define FMT_EXCEPTIONS 1 67 64 #endif 68 65 69 namespace { 70 71 #ifndef _MSC_VER 72 73 // Portable version of signbit. 74 // When compiled in C++11 mode signbit is no longer a macro but a function 75 // defined in namespace std and the macro is undefined. 76 inline int getsign(double x) { 77 #ifdef signbit 78 return signbit(x); 66 #if FMT_EXCEPTIONS 67 # define FMT_TRY try 68 # define FMT_CATCH(x) catch (x) 79 69 #else 80 return std::signbit(x); 70 # define FMT_TRY if (true) 71 # define FMT_CATCH(x) if (false) 81 72 #endif 82 }83 73 84 // Portable version of isinf. 85 #ifdef isinf 86 inline int isinfinity(double x) { return isinf(x); } 87 inline int isinfinity(long double x) { return isinf(x); } 88 #else 89 inline int isinfinity(double x) { return std::isinf(x); } 90 inline int isinfinity(long double x) { return std::isinf(x); } 74 #ifndef FMT_THROW 75 # if FMT_EXCEPTIONS 76 # define FMT_THROW(x) throw x 77 # else 78 # define FMT_THROW(x) assert(false) 79 # endif 91 80 #endif 92 81 93 #define FMT_SNPRINTF snprintf 82 #ifdef FMT_HEADER_ONLY 83 # define FMT_FUNC inline 84 #else 85 # define FMT_FUNC 86 #endif 94 87 95 #else // _MSC_VER 88 #ifdef _MSC_VER 89 # pragma warning(push) 90 # pragma warning(disable: 4127) // conditional expression is constant 91 # pragma warning(disable: 4702) // unreachable code 92 // Disable deprecation warning for strerror. The latter is not called but 93 // MSVC fails to detect it. 94 # pragma warning(disable: 4996) 95 #endif 96 96 97 inline int getsign(double value) { 98 if (value < 0) return 1; 99 if (value == value) return 0; 100 int dec = 0, sign = 0;101 char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail. 102 _ecvt_s(buffer, sizeof(buffer), value, 0, &dec, &sign); 103 return sign;97 // Dummy implementations of strerror_r and strerror_s called if corresponding 98 // system functions are not available. 99 static inline fmt::internal::Null<> strerror_r(int, char *, ...) { 100 return fmt::internal::Null<>(); 101 } 102 static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) { 103 return fmt::internal::Null<>(); 104 104 } 105 105 106 inline int isinfinity(double x) { return !_finite(x); } 106 namespace fmt { 107 namespace { 107 108 109 #ifndef _MSC_VER 110 # define FMT_SNPRINTF snprintf 111 #else // _MSC_VER 108 112 inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) { 109 113 va_list args; 110 114 va_start(args, format); … … inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) { 112 116 va_end(args); 113 117 return result; 114 118 } 115 #define FMT_SNPRINTF fmt_snprintf 116 119 # define FMT_SNPRINTF fmt_snprintf 117 120 #endif // _MSC_VER 118 121 119 template <typename T> 120 struct IsLongDouble { enum {VALUE = 0}; }; 121 122 template <> 123 struct IsLongDouble<long double> { enum {VALUE = 1}; }; 122 #if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT) 123 # define FMT_SWPRINTF snwprintf 124 #else 125 # define FMT_SWPRINTF swprintf 126 #endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT) 124 127 125 128 // Checks if a value fits in int - used to avoid warnings about comparing 126 129 // signed and unsigned integers. … … struct IntChecker { 131 134 unsigned max = INT_MAX; 132 135 return value <= max; 133 136 } 137 static bool fits_in_int(bool) { return true; } 134 138 }; 135 139 136 140 template <> … … struct IntChecker<true> { 139 143 static bool fits_in_int(T value) { 140 144 return value >= INT_MIN && value <= INT_MAX; 141 145 } 146 static bool fits_in_int(int) { return true; } 142 147 }; 143 148 144 149 const char RESET_COLOR[] = "\x1b[0m"; 145 150 146 typedef void (*FormatFunc)(fmt::Writer &, int , fmt::StringRef); 151 typedef void (*FormatFunc)(fmt::Writer &, int, fmt::StringRef); 152 153 // Portable thread-safe version of strerror. 154 // Sets buffer to point to a string describing the error code. 155 // This can be either a pointer to a string stored in buffer, 156 // or a pointer to some static immutable string. 157 // Returns one of the following values: 158 // 0 - success 159 // ERANGE - buffer is not large enough to store the error message 160 // other - failure 161 // Buffer should be at least of size 1. 162 int safe_strerror( 163 int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT { 164 FMT_ASSERT(buffer != 0 && buffer_size != 0, "invalid buffer"); 165 166 class StrError { 167 private: 168 int error_code_; 169 char *&buffer_; 170 std::size_t buffer_size_; 147 171 148 void report_error(FormatFunc func, 149 int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) { 150 try { 151 fmt::Writer full_message; 152 func(full_message, error_code, message); // TODO: make sure this doesn't throw 153 std::fwrite(full_message.c_str(), full_message.size(), 1, stderr); 154 std::fputc('\n', stderr); 155 } catch (...) {} 172 // A noop assignment operator to avoid bogus warnings. 173 void operator=(const StrError &) {} 174 175 // Handle the result of XSI-compliant version of strerror_r. 176 int handle(int result) { 177 // glibc versions before 2.13 return result in errno. 178 return result == -1 ? errno : result; 179 } 180 181 // Handle the result of GNU-specific version of strerror_r. 182 int handle(char *message) { 183 // If the buffer is full then the message is probably truncated. 184 if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1) 185 return ERANGE; 186 buffer_ = message; 187 return 0; 188 } 189 190 // Handle the case when strerror_r is not available. 191 int handle(fmt::internal::Null<>) { 192 return fallback(strerror_s(buffer_, buffer_size_, error_code_)); 193 } 194 195 // Fallback to strerror_s when strerror_r is not available. 196 int fallback(int result) { 197 // If the buffer is full then the message is probably truncated. 198 return result == 0 && strlen(buffer_) == buffer_size_ - 1 ? 199 ERANGE : result; 200 } 201 202 // Fallback to strerror if strerror_r and strerror_s are not available. 203 int fallback(fmt::internal::Null<>) { 204 errno = 0; 205 buffer_ = strerror(error_code_); 206 return errno; 207 } 208 209 public: 210 StrError(int err_code, char *&buf, std::size_t buf_size) 211 : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {} 212 213 int run() { 214 strerror_r(0, 0, ""); // Suppress a warning about unused strerror_r. 215 return handle(strerror_r(error_code_, buffer_, buffer_size_)); 216 } 217 }; 218 return StrError(error_code, buffer, buffer_size).run(); 156 219 } 157 220 158 const Arg DUMMY_ARG = {Arg::INT, {0}}; 221 void format_error_code(fmt::Writer &out, int error_code, 222 fmt::StringRef message) FMT_NOEXCEPT { 223 // Report error code making sure that the output fits into 224 // INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential 225 // bad_alloc. 226 out.clear(); 227 static const char SEP[] = ": "; 228 static const char ERROR_STR[] = "error "; 229 fmt::internal::IntTraits<int>::MainType ec_value = error_code; 230 // Subtract 2 to account for terminating null characters in SEP and ERROR_STR. 231 std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2; 232 error_code_size += fmt::internal::count_digits(ec_value); 233 if (message.size() <= fmt::internal::INLINE_BUFFER_SIZE - error_code_size) 234 out << message << SEP; 235 out << ERROR_STR << error_code; 236 assert(out.size() <= fmt::internal::INLINE_BUFFER_SIZE); 237 } 238 239 void report_error(FormatFunc func, 240 int error_code, fmt::StringRef message) FMT_NOEXCEPT { 241 fmt::MemoryWriter full_message; 242 func(full_message, error_code, message); 243 // Use Writer::data instead of Writer::c_str to avoid potential memory 244 // allocation. 245 std::fwrite(full_message.data(), full_message.size(), 1, stderr); 246 std::fputc('\n', stderr); 247 } 159 248 160 249 // IsZeroInt::visit(arg) returns true iff arg is a zero integer. 161 250 class IsZeroInt : public fmt::internal::ArgVisitor<IsZeroInt, bool> { … … class IsZeroInt : public fmt::internal::ArgVisitor<IsZeroInt, bool> { 167 256 // Parses an unsigned integer advancing s to the end of the parsed input. 168 257 // This function assumes that the first character of s is a digit. 169 258 template <typename Char> 170 int parse_nonnegative_int( 171 const Char *&s, const char *&error) FMT_NOEXCEPT(true) { 259 int parse_nonnegative_int(const Char *&s) { 172 260 assert('0' <= *s && *s <= '9'); 173 261 unsigned value = 0; 174 262 do { 175 263 unsigned new_value = value * 10 + (*s++ - '0'); 176 264 // Check if value wrapped around. 177 value = new_value >= value ? new_value : UINT_MAX; 265 if (new_value < value) { 266 value = UINT_MAX; 267 break; 268 } 269 value = new_value; 178 270 } while ('0' <= *s && *s <= '9'); 179 if (value > INT_MAX) { 180 if (!error) 181 error = "number is too big in format"; 182 return 0; 183 } 271 if (value > INT_MAX) 272 FMT_THROW(fmt::FormatError("number is too big")); 184 273 return value; 185 274 } 186 275 187 276 template <typename Char> 188 const Char *find_closing_brace(const Char *s, int num_open_braces = 1) { 189 for (int n = num_open_braces; *s; ++s) { 190 if (*s == '{') { 191 ++n; 192 } else if (*s == '}') { 193 if (--n == 0) 194 return s; 195 } 277 inline bool is_name_start(Char c) { 278 return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c; 279 } 280 281 inline void require_numeric_argument(const Arg &arg, char spec) { 282 if (arg.type > Arg::LAST_NUMERIC_TYPE) { 283 std::string message = 284 fmt::format("format specifier '{}' requires numeric argument", spec); 285 FMT_THROW(fmt::FormatError(message)); 196 286 } 197 throw fmt::FormatError("unmatched '{' in format"); 287 } 288 289 template <typename Char> 290 void check_sign(const Char *&s, const Arg &arg) { 291 char sign = static_cast<char>(*s); 292 require_numeric_argument(arg, sign); 293 if (arg.type == Arg::UINT || arg.type == Arg::ULONG_LONG) { 294 FMT_THROW(fmt::FormatError(fmt::format( 295 "format specifier '{}' requires signed argument", sign))); 296 } 297 ++s; 198 298 } 199 299 200 300 // Checks if an argument is a valid printf width specifier and sets … … class WidthHandler : public fmt::internal::ArgVisitor<WidthHandler, unsigned> { 203 303 private: 204 304 fmt::FormatSpec &spec_; 205 305 306 FMT_DISALLOW_COPY_AND_ASSIGN(WidthHandler); 307 206 308 public: 207 309 explicit WidthHandler(fmt::FormatSpec &spec) : spec_(spec) {} 208 310 209 unsigned visit_unhandled_arg() {210 throw fmt::FormatError("width is not integer");311 void report_unhandled_arg() { 312 FMT_THROW(fmt::FormatError("width is not integer")); 211 313 } 212 314 213 315 template <typename T> … … class WidthHandler : public fmt::internal::ArgVisitor<WidthHandler, unsigned> { 219 321 width = 0 - width; 220 322 } 221 323 if (width > INT_MAX) 222 throw fmt::FormatError("number is too big in format");324 FMT_THROW(fmt::FormatError("number is too big")); 223 325 return static_cast<unsigned>(width); 224 326 } 225 327 }; … … class WidthHandler : public fmt::internal::ArgVisitor<WidthHandler, unsigned> { 227 329 class PrecisionHandler : 228 330 public fmt::internal::ArgVisitor<PrecisionHandler, int> { 229 331 public: 230 unsigned visit_unhandled_arg() {231 throw fmt::FormatError("precision is not integer");332 void report_unhandled_arg() { 333 FMT_THROW(fmt::FormatError("precision is not integer")); 232 334 } 233 335 234 336 template <typename T> 235 337 int visit_any_int(T value) { 236 338 if (!IntChecker<std::numeric_limits<T>::is_signed>::fits_in_int(value)) 237 throw fmt::FormatError("number is too big in format");339 FMT_THROW(fmt::FormatError("number is too big")); 238 340 return static_cast<int>(value); 239 341 } 240 342 }; 241 343 242 // Converts an integer argument to type T.344 // Converts an integer argument to an integral type T for printf. 243 345 template <typename T> 244 346 class ArgConverter : public fmt::internal::ArgVisitor<ArgConverter<T>, void> { 245 347 private: 246 348 fmt::internal::Arg &arg_; 247 349 wchar_t type_; 248 350 351 FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter); 352 249 353 public: 250 354 ArgConverter(fmt::internal::Arg &arg, wchar_t type) 251 355 : arg_(arg), type_(type) {} 252 356 357 void visit_bool(bool value) { 358 if (type_ != 's') 359 visit_any_int(value); 360 } 361 253 362 template <typename U> 254 363 void visit_any_int(U value) { 255 364 bool is_signed = type_ == 'd' || type_ == 'i'; 256 365 using fmt::internal::Arg; 257 366 if (sizeof(T) <= sizeof(int)) { 367 // Extra casts are used to silence warnings. 258 368 if (is_signed) { 259 369 arg_.type = Arg::INT; 260 370 arg_.int_value = static_cast<int>(static_cast<T>(value)); … … class ArgConverter : public fmt::internal::ArgVisitor<ArgConverter<T>, void> { 277 387 } 278 388 }; 279 389 280 // Converts an integer argument to char .390 // Converts an integer argument to char for printf. 281 391 class CharConverter : public fmt::internal::ArgVisitor<CharConverter, void> { 282 392 private: 283 393 fmt::internal::Arg &arg_; 284 394 395 FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter); 396 285 397 public: 286 398 explicit CharConverter(fmt::internal::Arg &arg) : arg_(arg) {} 287 399 … … class CharConverter : public fmt::internal::ArgVisitor<CharConverter, void> { 291 403 arg_.int_value = static_cast<char>(value); 292 404 } 293 405 }; 406 } // namespace 407 408 namespace internal { 409 410 template <typename Impl, typename Char> 411 class BasicArgFormatter : public ArgVisitor<Impl, void> { 412 private: 413 BasicWriter<Char> &writer_; 414 FormatSpec &spec_; 415 416 FMT_DISALLOW_COPY_AND_ASSIGN(BasicArgFormatter); 417 418 void write_pointer(const void *p) { 419 spec_.flags_ = HASH_FLAG; 420 spec_.type_ = 'x'; 421 writer_.write_int(reinterpret_cast<uintptr_t>(p), spec_); 422 } 423 424 protected: 425 BasicWriter<Char> &writer() { return writer_; } 426 FormatSpec &spec() { return spec_; } 427 428 void write(bool value) { 429 const char *str_value = value ? "true" : "false"; 430 Arg::StringValue<char> str = { str_value, strlen(str_value) }; 431 writer_.write_str(str, spec_); 432 } 433 434 void write(const char *value) { 435 Arg::StringValue<char> str = {value, value != 0 ? strlen(value) : 0}; 436 writer_.write_str(str, spec_); 437 } 438 439 public: 440 BasicArgFormatter(BasicWriter<Char> &w, FormatSpec &s) 441 : writer_(w), spec_(s) {} 442 443 template <typename T> 444 void visit_any_int(T value) { writer_.write_int(value, spec_); } 445 446 template <typename T> 447 void visit_any_double(T value) { writer_.write_double(value, spec_); } 448 449 void visit_bool(bool value) { 450 if (spec_.type_) 451 return visit_any_int(value); 452 write(value); 453 } 454 455 void visit_char(int value) { 456 if (spec_.type_ && spec_.type_ != 'c') { 457 spec_.flags_ |= CHAR_FLAG; 458 writer_.write_int(value, spec_); 459 return; 460 } 461 if (spec_.align_ == ALIGN_NUMERIC || spec_.flags_ != 0) 462 FMT_THROW(FormatError("invalid format specifier for char")); 463 typedef typename BasicWriter<Char>::CharPtr CharPtr; 464 Char fill = internal::CharTraits<Char>::cast(spec_.fill()); 465 CharPtr out = CharPtr(); 466 const unsigned CHAR_WIDTH = 1; 467 if (spec_.width_ > CHAR_WIDTH) { 468 out = writer_.grow_buffer(spec_.width_); 469 if (spec_.align_ == ALIGN_RIGHT) { 470 std::fill_n(out, spec_.width_ - CHAR_WIDTH, fill); 471 out += spec_.width_ - CHAR_WIDTH; 472 } else if (spec_.align_ == ALIGN_CENTER) { 473 out = writer_.fill_padding(out, spec_.width_, 474 internal::check(CHAR_WIDTH), fill); 475 } else { 476 std::fill_n(out + CHAR_WIDTH, spec_.width_ - CHAR_WIDTH, fill); 477 } 478 } else { 479 out = writer_.grow_buffer(CHAR_WIDTH); 480 } 481 *out = internal::CharTraits<Char>::cast(value); 482 } 483 484 void visit_cstring(const char *value) { 485 if (spec_.type_ == 'p') 486 return write_pointer(value); 487 write(value); 488 } 489 490 void visit_string(Arg::StringValue<char> value) { 491 writer_.write_str(value, spec_); 492 } 493 494 using ArgVisitor<Impl, void>::visit_wstring; 495 496 void visit_wstring(Arg::StringValue<Char> value) { 497 writer_.write_str(value, spec_); 498 } 499 500 void visit_pointer(const void *value) { 501 if (spec_.type_ && spec_.type_ != 'p') 502 report_unknown_type(spec_.type_, "pointer"); 503 write_pointer(value); 504 } 505 }; 294 506 295 // This function template is used to prevent compile errors when handling 296 // incompatible string arguments, e.g. handling a wide string in a narrow 297 // string formatter. 507 // An argument formatter. 298 508 template <typename Char> 299 Arg::StringValue<Char> ignore_incompatible_str(Arg::StringValue<wchar_t>); 509 class ArgFormatter : public BasicArgFormatter<ArgFormatter<Char>, Char> { 510 private: 511 BasicFormatter<Char> &formatter_; 512 const Char *format_; 300 513 301 template <> 302 inline Arg::StringValue<char> ignore_incompatible_str( 303 Arg::StringValue<wchar_t>) { return Arg::StringValue<char>(); } 514 public: 515 ArgFormatter(BasicFormatter<Char> &f, FormatSpec &s, const Char *fmt) 516 : BasicArgFormatter<ArgFormatter<Char>, Char>(f.writer(), s), 517 formatter_(f), format_(fmt) {} 304 518 305 template <> 306 inline Arg::StringValue<wchar_t> ignore_incompatible_str( 307 Arg::StringValue<wchar_t> s) { return s; } 308 } // namespace 519 void visit_custom(Arg::CustomValue c) { 520 c.format(&formatter_, c.value, &format_); 521 } 522 }; 523 524 template <typename Char> 525 class PrintfArgFormatter : 526 public BasicArgFormatter<PrintfArgFormatter<Char>, Char> { 527 528 void write_null_pointer() { 529 this->spec().type_ = 0; 530 this->write("(nil)"); 531 } 532 533 typedef BasicArgFormatter<PrintfArgFormatter<Char>, Char> Base; 534 535 public: 536 PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s) 537 : BasicArgFormatter<PrintfArgFormatter<Char>, Char>(w, s) {} 538 539 void visit_bool(bool value) { 540 FormatSpec &fmt_spec = this->spec(); 541 if (fmt_spec.type_ != 's') 542 return this->visit_any_int(value); 543 fmt_spec.type_ = 0; 544 this->write(value); 545 } 546 547 void visit_char(int value) { 548 const FormatSpec &fmt_spec = this->spec(); 549 BasicWriter<Char> &w = this->writer(); 550 if (fmt_spec.type_ && fmt_spec.type_ != 'c') 551 w.write_int(value, fmt_spec); 552 typedef typename BasicWriter<Char>::CharPtr CharPtr; 553 CharPtr out = CharPtr(); 554 if (fmt_spec.width_ > 1) { 555 Char fill = ' '; 556 out = w.grow_buffer(fmt_spec.width_); 557 if (fmt_spec.align_ != ALIGN_LEFT) { 558 std::fill_n(out, fmt_spec.width_ - 1, fill); 559 out += fmt_spec.width_ - 1; 560 } else { 561 std::fill_n(out + 1, fmt_spec.width_ - 1, fill); 562 } 563 } else { 564 out = w.grow_buffer(1); 565 } 566 *out = static_cast<Char>(value); 567 } 309 568 310 void fmt::SystemError::init( 311 int error_code, StringRef format_str, const ArgList &args) { 312 error_code_ = error_code; 313 Writer w; 314 internal::format_system_error(w, error_code, format(format_str, args)); 569 void visit_cstring(const char *value) { 570 if (value) 571 Base::visit_cstring(value); 572 else if (this->spec().type_ == 'p') 573 write_null_pointer(); 574 else 575 this->write("(null)"); 576 } 577 578 void visit_pointer(const void *value) { 579 if (value) 580 return Base::visit_pointer(value); 581 this->spec().type_ = 0; 582 write_null_pointer(); 583 } 584 585 void visit_custom(Arg::CustomValue c) { 586 BasicFormatter<Char> formatter(ArgList(), this->writer()); 587 const Char format_str[] = {'}', 0}; 588 const Char *format = format_str; 589 c.format(&formatter, c.value, &format); 590 } 591 }; 592 } // namespace internal 593 } // namespace fmt 594 595 FMT_FUNC void fmt::SystemError::init( 596 int err_code, CStringRef format_str, ArgList args) { 597 error_code_ = err_code; 598 MemoryWriter w; 599 internal::format_system_error(w, err_code, format(format_str, args)); 315 600 std::runtime_error &base = *this; 316 601 base = std::runtime_error(w.str()); 317 602 } … … int fmt::internal::CharTraits<wchar_t>::format_float( 336 621 unsigned width, int precision, T value) { 337 622 if (width == 0) { 338 623 return precision < 0 ? 339 swprintf(buffer, size, format, value) :340 swprintf(buffer, size, format, precision, value);624 FMT_SWPRINTF(buffer, size, format, value) : 625 FMT_SWPRINTF(buffer, size, format, precision, value); 341 626 } 342 627 return precision < 0 ? 343 swprintf(buffer, size, format, width, value) :344 swprintf(buffer, size, format, width, precision, value);628 FMT_SWPRINTF(buffer, size, format, width, value) : 629 FMT_SWPRINTF(buffer, size, format, width, precision, value); 345 630 } 346 631 347 const char fmt::internal::DIGITS[] = 632 template <typename T> 633 const char fmt::internal::BasicData<T>::DIGITS[] = 348 634 "0001020304050607080910111213141516171819" 349 635 "2021222324252627282930313233343536373839" 350 636 "4041424344454647484950515253545556575859" … … const char fmt::internal::DIGITS[] = 362 648 factor * 100000000, \ 363 649 factor * 1000000000 364 650 365 const uint32_t fmt::internal::POWERS_OF_10_32[] = {0, FMT_POWERS_OF_10(1)}; 366 const uint64_t fmt::internal::POWERS_OF_10_64[] = { 651 template <typename T> 652 const uint32_t fmt::internal::BasicData<T>::POWERS_OF_10_32[] = { 653 0, FMT_POWERS_OF_10(1) 654 }; 655 656 template <typename T> 657 const uint64_t fmt::internal::BasicData<T>::POWERS_OF_10_64[] = { 367 658 0, 368 659 FMT_POWERS_OF_10(1), 369 FMT_POWERS_OF_10( ULongLong(1000000000)),660 FMT_POWERS_OF_10(fmt::ULongLong(1000000000)), 370 661 // Multiply several constants instead of using a single long long constant 371 662 // to avoid warnings about C++98 not supporting long long. 372 ULongLong(1000000000) *ULongLong(1000000000) * 10663 fmt::ULongLong(1000000000) * fmt::ULongLong(1000000000) * 10 373 664 }; 374 665 375 void fmt::internal::report_unknown_type(char code, const char *type) { 666 FMT_FUNC void fmt::internal::report_unknown_type(char code, const char *type) { 667 (void)type; 376 668 if (std::isprint(static_cast<unsigned char>(code))) { 377 throwfmt::FormatError(378 fmt::format("unknown format code '{}' for {}", code, type)) ;669 FMT_THROW(fmt::FormatError( 670 fmt::format("unknown format code '{}' for {}", code, type))); 379 671 } 380 throwfmt::FormatError(672 FMT_THROW(fmt::FormatError( 381 673 fmt::format("unknown format code '\\x{:02x}' for {}", 382 static_cast<unsigned>(code), type)) ;674 static_cast<unsigned>(code), type))); 383 675 } 384 676 385 #if def _WIN32677 #if FMT_USE_WINDOWS_H 386 678 387 fmt::internal::UTF8ToUTF16::UTF8ToUTF16(fmt::StringRef s) { 679 FMT_FUNC fmt::internal::UTF8ToUTF16::UTF8ToUTF16(fmt::StringRef s) { 680 static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16"; 681 if (s.size() > INT_MAX) 682 FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG)); 683 int s_size = static_cast<int>(s.size()); 388 684 int length = MultiByteToWideChar( 389 CP_UTF8, MB_ERR_INVALID_CHARS, s.c_str(), -1, 0, 0); 390 static const char ERROR[] = "cannot convert string from UTF-8 to UTF-16"; 685 CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, 0, 0); 391 686 if (length == 0) 392 throw WindowsError(GetLastError(), ERROR);393 buffer_.resize(length );687 FMT_THROW(WindowsError(GetLastError(), ERROR_MSG)); 688 buffer_.resize(length + 1); 394 689 length = MultiByteToWideChar( 395 CP_UTF8, MB_ERR_INVALID_CHARS, s. c_str(), -1, &buffer_[0], length);690 CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length); 396 691 if (length == 0) 397 throw WindowsError(GetLastError(), ERROR); 692 FMT_THROW(WindowsError(GetLastError(), ERROR_MSG)); 693 buffer_[length] = 0; 398 694 } 399 695 400 fmt::internal::UTF16ToUTF8::UTF16ToUTF8(fmt::WStringRef s) {696 FMT_FUNC fmt::internal::UTF16ToUTF8::UTF16ToUTF8(fmt::WStringRef s) { 401 697 if (int error_code = convert(s)) { 402 throwWindowsError(error_code,403 "cannot convert string from UTF-16 to UTF-8") ;698 FMT_THROW(WindowsError(error_code, 699 "cannot convert string from UTF-16 to UTF-8")); 404 700 } 405 701 } 406 702 407 int fmt::internal::UTF16ToUTF8::convert(fmt::WStringRef s) { 408 int length = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, 0, 0, 0, 0); 703 FMT_FUNC int fmt::internal::UTF16ToUTF8::convert(fmt::WStringRef s) { 704 if (s.size() > INT_MAX) 705 return ERROR_INVALID_PARAMETER; 706 int s_size = static_cast<int>(s.size()); 707 int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, 0, 0, 0, 0); 409 708 if (length == 0) 410 709 return GetLastError(); 411 buffer_.resize(length );710 buffer_.resize(length + 1); 412 711 length = WideCharToMultiByte( 413 CP_UTF8, 0, s. c_str(), -1, &buffer_[0], length, 0, 0);712 CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, 0, 0); 414 713 if (length == 0) 415 714 return GetLastError(); 715 buffer_[length] = 0; 416 716 return 0; 417 717 } 418 718 419 void fmt::WindowsError::init(420 int err or_code, StringRef format_str, const ArgList &args) {421 error_code_ = err or_code;422 Writer w;423 internal::format_windows_error(w, err or_code, format(format_str, args));719 FMT_FUNC void fmt::WindowsError::init( 720 int err_code, CStringRef format_str, ArgList args) { 721 error_code_ = err_code; 722 MemoryWriter w; 723 internal::format_windows_error(w, err_code, format(format_str, args)); 424 724 std::runtime_error &base = *this; 425 725 base = std::runtime_error(w.str()); 426 726 } 427 727 428 #endif 429 430 int fmt::internal::safe_strerror( 431 int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT(true) { 432 assert(buffer != 0 && buffer_size != 0); 433 int result = 0; 434 #if defined(_GNU_SOURCE) && !defined(__BIONIC__) 435 char *message = strerror_r(error_code, buffer, buffer_size); 436 // If the buffer is full then the message is probably truncated. 437 if (message == buffer && strlen(buffer) == buffer_size - 1) 438 result = ERANGE; 439 buffer = message; 440 #elif defined(__MINGW32__) 441 errno = 0; 442 (void)buffer_size; 443 buffer = strerror(error_code); 444 result = errno; 445 #elif defined(_WIN32) 446 result = strerror_s(buffer, buffer_size, error_code); 447 // If the buffer is full then the message is probably truncated. 448 if (result == 0 && std::strlen(buffer) == buffer_size - 1) 449 result = ERANGE; 450 #else 451 result = strerror_r(error_code, buffer, buffer_size); 452 if (result == -1) 453 result = errno; // glibc versions before 2.13 return result in errno. 454 #endif 455 return result; 456 } 457 458 void fmt::internal::format_system_error( 459 fmt::Writer &out, int error_code, fmt::StringRef message) { 460 Array<char, INLINE_BUFFER_SIZE> buffer; 461 buffer.resize(INLINE_BUFFER_SIZE); 462 char *system_message = 0; 463 for (;;) { 464 system_message = &buffer[0]; 465 int result = safe_strerror(error_code, system_message, buffer.size()); 466 if (result == 0) 467 break; 468 if (result != ERANGE) { 469 // Can't get error message, report error code instead. 470 out << message << ": error code = " << error_code; 471 return; 472 } 473 buffer.resize(buffer.size() * 2); 474 } 475 out << message << ": " << system_message; 476 } 477 478 #ifdef _WIN32 479 void fmt::internal::format_windows_error( 480 fmt::Writer &out, int error_code, fmt::StringRef message) { 728 FMT_FUNC void fmt::internal::format_windows_error( 729 fmt::Writer &out, int error_code, 730 fmt::StringRef message) FMT_NOEXCEPT { 481 731 class String { 482 732 private: 483 733 LPWSTR str_; … … void fmt::internal::format_windows_error( 488 738 LPWSTR *ptr() { return &str_; } 489 739 LPCWSTR c_str() const { return str_; } 490 740 }; 491 String system_message; 492 if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | 493 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, 494 error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 495 reinterpret_cast<LPWSTR>(system_message.ptr()), 0, 0)) { 496 UTF16ToUTF8 utf8_message; 497 if (!utf8_message.convert(system_message.c_str())) { 498 out << message << ": " << utf8_message; 499 return; 741 FMT_TRY { 742 String system_message; 743 if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | 744 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, 745 error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 746 reinterpret_cast<LPWSTR>(system_message.ptr()), 0, 0)) { 747 UTF16ToUTF8 utf8_message; 748 if (utf8_message.convert(system_message.c_str()) == ERROR_SUCCESS) { 749 out << message << ": " << utf8_message; 750 return; 751 } 500 752 } 501 } 502 // Can't get error message, report error code instead. 503 out << message << ": error code = " << error_code; 753 } FMT_CATCH(...) {} 754 fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32. 504 755 } 505 #endif506 507 // An argument formatter.508 template <typename Char>509 class fmt::internal::ArgFormatter :510 public fmt::internal::ArgVisitor<fmt::internal::ArgFormatter<Char>, void> {511 private:512 fmt::BasicFormatter<Char> &formatter_;513 fmt::BasicWriter<Char> &writer_;514 fmt::FormatSpec &spec_;515 const Char *format_;516 517 public:518 ArgFormatter(519 fmt::BasicFormatter<Char> &f,fmt::FormatSpec &s, const Char *fmt)520 : formatter_(f), writer_(f.writer()), spec_(s), format_(fmt) {}521 522 template <typename T>523 void visit_any_int(T value) { writer_.write_int(value, spec_); }524 756 525 template <typename T> 526 void visit_any_double(T value) { writer_.write_double(value, spec_); } 527 528 void visit_char(int value) { 529 if (spec_.type_ && spec_.type_ != 'c') { 530 spec_.flags_ |= CHAR_FLAG; 531 writer_.write_int(value, spec_); 532 return; 533 } 534 if (spec_.align_ == ALIGN_NUMERIC || spec_.flags_ != 0) 535 throw FormatError("invalid format specifier for char"); 536 typedef typename fmt::BasicWriter<Char>::CharPtr CharPtr; 537 CharPtr out = CharPtr(); 538 if (spec_.width_ > 1) { 539 Char fill = static_cast<Char>(spec_.fill()); 540 out = writer_.grow_buffer(spec_.width_); 541 if (spec_.align_ == fmt::ALIGN_RIGHT) { 542 std::fill_n(out, spec_.width_ - 1, fill); 543 out += spec_.width_ - 1; 544 } else if (spec_.align_ == fmt::ALIGN_CENTER) { 545 out = writer_.fill_padding(out, spec_.width_, 1, fill); 546 } else { 547 std::fill_n(out + 1, spec_.width_ - 1, fill); 757 #endif // FMT_USE_WINDOWS_H 758 759 FMT_FUNC void fmt::internal::format_system_error( 760 fmt::Writer &out, int error_code, 761 fmt::StringRef message) FMT_NOEXCEPT { 762 FMT_TRY { 763 MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer; 764 buffer.resize(INLINE_BUFFER_SIZE); 765 for (;;) { 766 char *system_message = &buffer[0]; 767 int result = safe_strerror(error_code, system_message, buffer.size()); 768 if (result == 0) { 769 out << message << ": " << system_message; 770 return; 548 771 } 549 } else { 550 out = writer_.grow_buffer(1); 772 if (result != ERANGE) 773 break; // Can't get error message, report error code instead. 774 buffer.resize(buffer.size() * 2); 551 775 } 552 *out = static_cast<Char>(value); 553 } 554 555 void visit_string(Arg::StringValue<char> value) { 556 writer_.write_str(value, spec_); 557 } 558 void visit_wstring(Arg::StringValue<wchar_t> value) { 559 writer_.write_str(ignore_incompatible_str<Char>(value), spec_); 560 } 561 562 void visit_pointer(const void *value) { 563 if (spec_.type_ && spec_.type_ != 'p') 564 fmt::internal::report_unknown_type(spec_.type_, "pointer"); 565 spec_.flags_ = fmt::HASH_FLAG; 566 spec_.type_ = 'x'; 567 writer_.write_int(reinterpret_cast<uintptr_t>(value), spec_); 568 } 569 570 void visit_custom(Arg::CustomValue c) { 571 c.format(&formatter_, c.value, format_); 572 } 573 }; 574 575 template <typename Char> 576 void fmt::internal::FormatErrorReporter<Char>::operator()( 577 const Char *s, fmt::StringRef message) const { 578 if (find_closing_brace(s, num_open_braces)) 579 throw fmt::FormatError(message); 776 } FMT_CATCH(...) {} 777 fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32. 580 778 } 581 779 582 // Fills the padding around the content and returns the pointer to the583 // content area.584 780 template <typename Char> 585 typename fmt::BasicWriter<Char>::CharPtr 586 fmt::BasicWriter<Char>::fill_padding(CharPtr buffer, 587 unsigned total_size, std::size_t content_size, wchar_t fill) { 588 std::size_t padding = total_size - content_size; 589 std::size_t left_padding = padding / 2; 590 Char fill_char = static_cast<Char>(fill); 591 std::fill_n(buffer, left_padding, fill_char); 592 buffer += left_padding; 593 CharPtr content = buffer; 594 std::fill_n(buffer + content_size, padding - left_padding, fill_char); 595 return content; 596 } 597 598 template <typename Char> 599 template <typename T> 600 void fmt::BasicWriter<Char>::write_double(T value, const FormatSpec &spec) { 601 // Check type. 602 char type = spec.type(); 603 bool upper = false; 604 switch (type) { 605 case 0: 606 type = 'g'; 607 break; 608 case 'e': case 'f': case 'g': case 'a': 609 break; 610 case 'F': 611 #ifdef _MSC_VER 612 // MSVC's printf doesn't support 'F'. 613 type = 'f'; 614 #endif 615 // Fall through. 616 case 'E': case 'G': case 'A': 617 upper = true; 618 break; 619 default: 620 internal::report_unknown_type(type, "double"); 621 break; 622 } 623 624 char sign = 0; 625 // Use getsign instead of value < 0 because the latter is always 626 // false for NaN. 627 if (getsign(static_cast<double>(value))) { 628 sign = '-'; 629 value = -value; 630 } else if (spec.flag(SIGN_FLAG)) { 631 sign = spec.flag(PLUS_FLAG) ? '+' : ' '; 632 } 633 634 if (value != value) { 635 // Format NaN ourselves because sprintf's output is not consistent 636 // across platforms. 637 std::size_t size = 4; 638 const char *nan = upper ? " NAN" : " nan"; 639 if (!sign) { 640 --size; 641 ++nan; 642 } 643 CharPtr out = write_str(nan, size, spec); 644 if (sign) 645 *out = sign; 781 void fmt::internal::ArgMap<Char>::init(const ArgList &args) { 782 if (!map_.empty()) 646 783 return; 647 } 648 649 if (isinfinity(value)) { 650 // Format infinity ourselves because sprintf's output is not consistent 651 // across platforms. 652 std::size_t size = 4; 653 const char *inf = upper ? " INF" : " inf"; 654 if (!sign) { 655 --size; 656 ++inf; 784 typedef internal::NamedArg<Char> NamedArg; 785 const NamedArg *named_arg = 0; 786 bool use_values = 787 args.type(ArgList::MAX_PACKED_ARGS - 1) == internal::Arg::NONE; 788 if (use_values) { 789 for (unsigned i = 0;/*nothing*/; ++i) { 790 internal::Arg::Type arg_type = args.type(i); 791 switch (arg_type) { 792 case internal::Arg::NONE: 793 return; 794 case internal::Arg::NAMED_ARG: 795 named_arg = static_cast<const NamedArg*>(args.values_[i].pointer); 796 map_.insert(Pair(named_arg->name, *named_arg)); 797 break; 798 default: 799 /*nothing*/; 800 } 657 801 } 658 CharPtr out = write_str(inf, size, spec);659 if (sign)660 *out = sign;661 802 return; 662 803 } 663 664 std::size_t offset = buffer_.size(); 665 unsigned width = spec.width(); 666 if (sign) { 667 buffer_.reserve(buffer_.size() + (std::max)(width, 1u)); 668 if (width > 0) 669 --width; 670 ++offset; 671 } 672 673 // Build format string. 674 enum { MAX_FORMAT_SIZE = 10}; // longest format: %#-*.*Lg 675 Char format[MAX_FORMAT_SIZE]; 676 Char *format_ptr = format; 677 *format_ptr++ = '%'; 678 unsigned width_for_sprintf = width; 679 if (spec.flag(HASH_FLAG)) 680 *format_ptr++ = '#'; 681 if (spec.align() == ALIGN_CENTER) { 682 width_for_sprintf = 0; 683 } else { 684 if (spec.align() == ALIGN_LEFT) 685 *format_ptr++ = '-'; 686 if (width != 0) 687 *format_ptr++ = '*'; 688 } 689 if (spec.precision() >= 0) { 690 *format_ptr++ = '.'; 691 *format_ptr++ = '*'; 692 } 693 if (IsLongDouble<T>::VALUE) 694 *format_ptr++ = 'L'; 695 *format_ptr++ = type; 696 *format_ptr = '\0'; 697 698 // Format using snprintf. 699 Char fill = static_cast<Char>(spec.fill()); 700 for (;;) { 701 std::size_t size = buffer_.capacity() - offset; 702 #ifdef _MSC_VER 703 // MSVC's vsnprintf_s doesn't work with zero size, so reserve 704 // space for at least one extra character to make the size non-zero. 705 // Note that the buffer's capacity will increase by more than 1. 706 if (size == 0) { 707 buffer_.reserve(offset + 1); 708 size = buffer_.capacity() - offset; 804 for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) { 805 internal::Arg::Type arg_type = args.type(i); 806 if (arg_type == internal::Arg::NAMED_ARG) { 807 named_arg = static_cast<const NamedArg*>(args.args_[i].pointer); 808 map_.insert(Pair(named_arg->name, *named_arg)); 709 809 } 710 #endif 711 Char *start = &buffer_[offset]; 712 int n = internal::CharTraits<Char>::format_float( 713 start, size, format, width_for_sprintf, spec.precision(), value); 714 if (n >= 0 && offset + n < buffer_.capacity()) { 715 if (sign) { 716 if ((spec.align() != ALIGN_RIGHT && spec.align() != ALIGN_DEFAULT) || 717 *start != ' ') { 718 *(start - 1) = sign; 719 sign = 0; 720 } else { 721 *(start - 1) = fill; 722 } 723 ++n; 724 } 725 if (spec.align() == ALIGN_CENTER && 726 spec.width() > static_cast<unsigned>(n)) { 727 unsigned width = spec.width(); 728 CharPtr p = grow_buffer(width); 729 std::copy(p, p + n, p + (width - n) / 2); 730 fill_padding(p, spec.width(), n, fill); 731 return; 732 } 733 if (spec.fill() != ' ' || sign) { 734 while (*start == ' ') 735 *start++ = fill; 736 if (sign) 737 *(start - 1) = sign; 738 } 739 grow_buffer(n); 810 } 811 for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) { 812 switch (args.args_[i].type) { 813 case internal::Arg::NONE: 740 814 return; 815 case internal::Arg::NAMED_ARG: 816 named_arg = static_cast<const NamedArg*>(args.args_[i].pointer); 817 map_.insert(Pair(named_arg->name, *named_arg)); 818 break; 819 default: 820 /*nothing*/; 741 821 } 742 // If n is negative we ask to increase the capacity by at least 1,743 // but as std::vector, the buffer grows exponentially.744 buffer_.reserve(n >= 0 ? offset + n + 1 : buffer_.capacity() + 1);745 822 } 746 823 } 747 824 748 825 template <typename Char> 826 void fmt::internal::FixedBuffer<Char>::grow(std::size_t) { 827 FMT_THROW(std::runtime_error("buffer overflow")); 828 } 829 830 template <typename Char> 749 831 template <typename StrChar> 750 832 void fmt::BasicWriter<Char>::write_str( 751 const Arg::StringValue<StrChar> &s tr, const FormatSpec &spec) {833 const Arg::StringValue<StrChar> &s, const FormatSpec &spec) { 752 834 // Check if StrChar is convertible to Char. 753 835 internal::CharTraits<Char>::convert(StrChar()); 754 836 if (spec.type_ && spec.type_ != 's') 755 837 internal::report_unknown_type(spec.type_, "string"); 756 const StrChar *s = str.value; 757 std::size_t size = str.size; 758 if (size == 0) { 759 if (!s) { 760 Char err[] = { '(', 'n', 'u', 'l', 'l', ')' }; 761 write_str(err, sizeof(err)/sizeof(Char), spec); 838 const StrChar *str_value = s.value; 839 std::size_t str_size = s.size; 840 if (str_size == 0) { 841 if (!str_value) { 842 FMT_THROW(FormatError("string pointer is null")); 762 843 return; 763 844 } 764 if (*s)765 size = std::char_traits<StrChar>::length(s);766 845 } 767 write_str(s, size, spec); 846 std::size_t precision = spec.precision_; 847 if (spec.precision_ >= 0 && precision < str_size) 848 str_size = spec.precision_; 849 write_str(str_value, str_size, spec); 768 850 } 769 851 770 852 template <typename Char> 771 inline const Arg 772 &fmt::BasicFormatter<Char>::parse_arg_index(const Char *&s) { 773 unsigned arg_index = 0; 774 if (*s < '0' || *s > '9') { 775 if (*s != '}' && *s != ':') 776 report_error_(s, "invalid argument index in format string"); 777 const Arg &arg = next_arg(); 778 if (error_) 779 report_error_(s, error_); 780 return arg; 781 } 782 if (next_arg_index_ > 0) { 783 report_error_(s, 784 "cannot switch from automatic to manual argument indexing"); 853 inline Arg fmt::BasicFormatter<Char>::get_arg( 854 BasicStringRef<Char> arg_name, const char *&error) { 855 if (check_no_auto_index(error)) { 856 map_.init(args()); 857 const Arg *arg = map_.find(arg_name); 858 if (arg) 859 return *arg; 860 error = "argument not found"; 785 861 } 786 next_arg_index_ = -1; 787 arg_index = parse_nonnegative_int(s, error_); 788 if (error_) 789 report_error_(s, error_); // TODO: don't use report_error_ 790 if (arg_index >= args_.size()) 791 report_error_(s, "argument index is out of range in format"); 792 return args_[arg_index]; 862 return Arg(); 793 863 } 794 864 795 865 template <typename Char> 796 void fmt::BasicFormatter<Char>::check_sign( 797 const Char *&s, const Arg &arg) { 798 char sign = static_cast<char>(*s); 799 if (arg.type > Arg::LAST_NUMERIC_TYPE) { 800 report_error_(s, fmt::format( 801 "format specifier '{}' requires numeric argument", sign).c_str()); 802 } 803 if (arg.type == Arg::UINT || arg.type == Arg::ULONG_LONG) { 804 report_error_(s, fmt::format( 805 "format specifier '{}' requires signed argument", sign).c_str()); 866 inline Arg fmt::BasicFormatter<Char>::parse_arg_index(const Char *&s) { 867 const char *error = 0; 868 Arg arg = *s < '0' || *s > '9' ? 869 next_arg(error) : get_arg(parse_nonnegative_int(s), error); 870 if (error) { 871 FMT_THROW(FormatError( 872 *s != '}' && *s != ':' ? "invalid format string" : error)); 806 873 } 807 ++s;874 return arg; 808 875 } 809 876 810 const Arg &fmt::internal::FormatterBase::next_arg() { 811 if (next_arg_index_ < 0) { 812 if (!error_) 813 error_ = "cannot switch from manual to automatic argument indexing"; 814 return DUMMY_ARG; 877 template <typename Char> 878 inline Arg fmt::BasicFormatter<Char>::parse_arg_name(const Char *&s) { 879 assert(is_name_start(*s)); 880 const Char *start = s; 881 Char c; 882 do { 883 c = *++s; 884 } while (is_name_start(c) || ('0' <= c && c <= '9')); 885 const char *error = 0; 886 Arg arg = get_arg(fmt::BasicStringRef<Char>(start, s - start), error); 887 if (error) 888 FMT_THROW(fmt::FormatError(error)); 889 return arg; 890 } 891 892 FMT_FUNC Arg fmt::internal::FormatterBase::do_get_arg( 893 unsigned arg_index, const char *&error) { 894 Arg arg = args_[arg_index]; 895 switch (arg.type) { 896 case Arg::NONE: 897 error = "argument index out of range"; 898 break; 899 case Arg::NAMED_ARG: 900 arg = *static_cast<const internal::Arg*>(arg.pointer); 901 default: 902 /*nothing*/; 815 903 } 816 unsigned arg_index = next_arg_index_++; 817 if (arg_index < args_.size()) 818 return args_[arg_index]; 819 if (!error_) 820 error_ = "argument index is out of range in format"; 821 return DUMMY_ARG; 904 return arg; 822 905 } 823 906 824 const Arg &fmt::internal::FormatterBase::handle_arg_index(unsigned arg_index) { 825 if (arg_index != UINT_MAX) { 826 if (next_arg_index_ <= 0) { 827 next_arg_index_ = -1; 828 --arg_index; 829 } else if (!error_) { 830 error_ = "cannot switch from automatic to manual argument indexing"; 831 } 832 if (arg_index < args_.size()) 833 return args_[arg_index]; 834 if (!error_) 835 error_ = "argument index is out of range in format"; 836 return DUMMY_ARG; 907 inline Arg fmt::internal::FormatterBase::next_arg(const char *&error) { 908 if (next_arg_index_ >= 0) 909 return do_get_arg(next_arg_index_++, error); 910 error = "cannot switch from manual to automatic argument indexing"; 911 return Arg(); 912 } 913 914 inline bool fmt::internal::FormatterBase::check_no_auto_index( 915 const char *&error) { 916 if (next_arg_index_ > 0) { 917 error = "cannot switch from automatic to manual argument indexing"; 918 return false; 837 919 } 838 return next_arg(); 920 next_arg_index_ = -1; 921 return true; 922 } 923 924 inline Arg fmt::internal::FormatterBase::get_arg( 925 unsigned arg_index, const char *&error) { 926 return check_no_auto_index(error) ? do_get_arg(arg_index, error) : Arg(); 839 927 } 840 928 841 929 template <typename Char> … … void fmt::internal::PrintfFormatter<Char>::parse_flags( 866 954 } 867 955 868 956 template <typename Char> 957 Arg fmt::internal::PrintfFormatter<Char>::get_arg( 958 const Char *s, unsigned arg_index) { 959 (void)s; 960 const char *error = 0; 961 Arg arg = arg_index == UINT_MAX ? 962 next_arg(error) : FormatterBase::get_arg(arg_index - 1, error); 963 if (error) 964 FMT_THROW(FormatError(!*s ? "invalid format string" : error)); 965 return arg; 966 } 967 968 template <typename Char> 869 969 unsigned fmt::internal::PrintfFormatter<Char>::parse_header( 870 970 const Char *&s, FormatSpec &spec) { 871 971 unsigned arg_index = UINT_MAX; … … unsigned fmt::internal::PrintfFormatter<Char>::parse_header( 873 973 if (c >= '0' && c <= '9') { 874 974 // Parse an argument index (if followed by '$') or a width possibly 875 975 // preceded with '0' flag(s). 876 unsigned value = parse_nonnegative_int(s , error_);976 unsigned value = parse_nonnegative_int(s); 877 977 if (*s == '$') { // value is an argument index 878 978 ++s; 879 979 arg_index = value; … … unsigned fmt::internal::PrintfFormatter<Char>::parse_header( 891 991 parse_flags(spec, s); 892 992 // Parse width. 893 993 if (*s >= '0' && *s <= '9') { 894 spec.width_ = parse_nonnegative_int(s , error_);994 spec.width_ = parse_nonnegative_int(s); 895 995 } else if (*s == '*') { 896 996 ++s; 897 spec.width_ = WidthHandler(spec).visit( handle_arg_index(UINT_MAX));997 spec.width_ = WidthHandler(spec).visit(get_arg(s)); 898 998 } 899 999 return arg_index; 900 1000 } 901 1001 902 1002 template <typename Char> 903 1003 void fmt::internal::PrintfFormatter<Char>::format( 904 BasicWriter<Char> &writer, BasicStringRef<Char> format, 905 const ArgList &args) { 906 const Char *start = format.c_str(); 907 args_ = args; 908 next_arg_index_ = 0; 1004 BasicWriter<Char> &writer, BasicCStringRef<Char> format_str) { 1005 const Char *start = format_str.c_str(); 909 1006 const Char *s = start; 910 1007 while (*s) { 911 1008 Char c = *s++; … … void fmt::internal::PrintfFormatter<Char>::format( 920 1017 FormatSpec spec; 921 1018 spec.align_ = ALIGN_RIGHT; 922 1019 923 // Reporting errors is delayed till the format specification is924 // completely parsed. This is done to avoid potentially confusing925 // error messages for incomplete format strings. For example, in926 // sprintf("%2$", 42);927 // the format specification is incomplete. In a naive approach we928 // would parse 2 as an argument index and report an error that the929 // index is out of range which would be rather confusing if the930 // use meant "%2d$" rather than "%2$d". If we delay an error, the931 // user will get an error that the format string is invalid which932 // is OK for both cases.933 934 1020 // Parse argument index, flags and width. 935 1021 unsigned arg_index = parse_header(s, spec); 936 1022 … … void fmt::internal::PrintfFormatter<Char>::format( 938 1024 if (*s == '.') { 939 1025 ++s; 940 1026 if ('0' <= *s && *s <= '9') { 941 spec.precision_ = parse_nonnegative_int(s , error_);1027 spec.precision_ = parse_nonnegative_int(s); 942 1028 } else if (*s == '*') { 943 1029 ++s; 944 spec.precision_ = PrecisionHandler().visit( handle_arg_index(UINT_MAX));1030 spec.precision_ = PrecisionHandler().visit(get_arg(s)); 945 1031 } 946 1032 } 947 1033 948 Arg arg = handle_arg_index(arg_index);1034 Arg arg = get_arg(s, arg_index); 949 1035 if (spec.flag(HASH_FLAG) && IsZeroInt().visit(arg)) 950 1036 spec.flags_ &= ~HASH_FLAG; 951 1037 if (spec.fill_ == '0') { … … void fmt::internal::PrintfFormatter<Char>::format( 973 1059 ArgConverter<intmax_t>(arg, *s).visit(arg); 974 1060 break; 975 1061 case 'z': 976 ArgConverter<s ize_t>(arg, *s).visit(arg);1062 ArgConverter<std::size_t>(arg, *s).visit(arg); 977 1063 break; 978 1064 case 't': 979 ArgConverter< ptrdiff_t>(arg, *s).visit(arg);1065 ArgConverter<std::ptrdiff_t>(arg, *s).visit(arg); 980 1066 break; 981 1067 case 'L': 982 1068 // printf produces garbage when 'L' is omitted for long double, no … … void fmt::internal::PrintfFormatter<Char>::format( 989 1075 990 1076 // Parse type. 991 1077 if (!*s) 992 throw FormatError("invalid format string"); 993 if (error_) 994 throw FormatError(error_); 1078 FMT_THROW(FormatError("invalid format string")); 995 1079 spec.type_ = static_cast<char>(*s++); 996 1080 if (arg.type <= Arg::LAST_INTEGER_TYPE) { 997 1081 // Normalize type. … … void fmt::internal::PrintfFormatter<Char>::format( 1009 1093 start = s; 1010 1094 1011 1095 // Format argument. 1012 switch (arg.type) { 1013 case Arg::INT: 1014 writer.write_int(arg.int_value, spec); 1015 break; 1016 case Arg::UINT: 1017 writer.write_int(arg.uint_value, spec); 1018 break; 1019 case Arg::LONG_LONG: 1020 writer.write_int(arg.long_long_value, spec); 1021 break; 1022 case Arg::ULONG_LONG: 1023 writer.write_int(arg.ulong_long_value, spec); 1024 break; 1025 case Arg::CHAR: { 1026 if (spec.type_ && spec.type_ != 'c') 1027 writer.write_int(arg.int_value, spec); 1028 typedef typename BasicWriter<Char>::CharPtr CharPtr; 1029 CharPtr out = CharPtr(); 1030 if (spec.width_ > 1) { 1031 Char fill = ' '; 1032 out = writer.grow_buffer(spec.width_); 1033 if (spec.align_ != ALIGN_LEFT) { 1034 std::fill_n(out, spec.width_ - 1, fill); 1035 out += spec.width_ - 1; 1036 } else { 1037 std::fill_n(out + 1, spec.width_ - 1, fill); 1038 } 1039 } else { 1040 out = writer.grow_buffer(1); 1041 } 1042 *out = static_cast<Char>(arg.int_value); 1043 break; 1044 } 1045 case Arg::DOUBLE: 1046 writer.write_double(arg.double_value, spec); 1047 break; 1048 case Arg::LONG_DOUBLE: 1049 writer.write_double(arg.long_double_value, spec); 1050 break; 1051 case Arg::STRING: 1052 writer.write_str(arg.string, spec); 1053 break; 1054 case Arg::WSTRING: 1055 writer.write_str(ignore_incompatible_str<Char>(arg.wstring), spec); 1056 break; 1057 case Arg::POINTER: 1058 if (spec.type_ && spec.type_ != 'p') 1059 internal::report_unknown_type(spec.type_, "pointer"); 1060 spec.flags_= HASH_FLAG; 1061 spec.type_ = 'x'; 1062 writer.write_int(reinterpret_cast<uintptr_t>(arg.pointer_value), spec); 1063 break; 1064 case Arg::CUSTOM: 1065 if (spec.type_) 1066 internal::report_unknown_type(spec.type_, "object"); 1067 arg.custom.format(&writer, arg.custom.value, "s"); 1068 break; 1069 default: 1070 assert(false); 1071 break; 1072 } 1096 internal::PrintfArgFormatter<Char>(writer, spec).visit(arg); 1073 1097 } 1074 1098 write(writer, start, s); 1075 1099 } 1076 1100 1077 1101 template <typename Char> 1078 1102 const Char *fmt::BasicFormatter<Char>::format( 1079 const Char * format_str, const Arg &arg) {1103 const Char *&format_str, const Arg &arg) { 1080 1104 const Char *s = format_str; 1081 const char *error = 0;1082 1105 FormatSpec spec; 1083 1106 if (*s == ':') { 1084 1107 if (arg.type == Arg::CUSTOM) { 1085 arg.custom.format(this, arg.custom.value, s);1086 return find_closing_brace(s) + 1;1108 arg.custom.format(this, arg.custom.value, &s); 1109 return s; 1087 1110 } 1088 1111 ++s; 1089 1112 // Parse fill and alignment. … … const Char *fmt::BasicFormatter<Char>::format( 1109 1132 if (p != s) { 1110 1133 if (c == '}') break; 1111 1134 if (c == '{') 1112 report_error_(s, "invalid fill character '{'");1135 FMT_THROW(FormatError("invalid fill character '{'")); 1113 1136 s += 2; 1114 1137 spec.fill_ = c; 1115 1138 } else ++s; 1116 if (spec.align_ == ALIGN_NUMERIC && arg.type > Arg::LAST_NUMERIC_TYPE)1117 re port_error_(s, "format specifier '=' requires numeric argument");1139 if (spec.align_ == ALIGN_NUMERIC) 1140 require_numeric_argument(arg, '='); 1118 1141 break; 1119 1142 } 1120 1143 } while (--p >= s); … … const Char *fmt::BasicFormatter<Char>::format( 1137 1160 } 1138 1161 1139 1162 if (*s == '#') { 1140 if (arg.type > Arg::LAST_NUMERIC_TYPE) 1141 report_error_(s, "format specifier '#' requires numeric argument"); 1163 require_numeric_argument(arg, '#'); 1142 1164 spec.flags_ |= HASH_FLAG; 1143 1165 ++s; 1144 1166 } 1145 1167 1146 // Parse width and zero flag. 1168 // Parse zero flag. 1169 if (*s == '0') { 1170 require_numeric_argument(arg, '0'); 1171 spec.align_ = ALIGN_NUMERIC; 1172 spec.fill_ = '0'; 1173 ++s; 1174 } 1175 1176 // Parse width. 1147 1177 if ('0' <= *s && *s <= '9') { 1148 if (*s == '0') { 1149 if (arg.type > Arg::LAST_NUMERIC_TYPE) 1150 report_error_(s, "format specifier '0' requires numeric argument"); 1151 spec.align_ = ALIGN_NUMERIC; 1152 spec.fill_ = '0'; 1178 spec.width_ = parse_nonnegative_int(s); 1179 } else if (*s == '{') { 1180 ++s; 1181 Arg width_arg = is_name_start(*s) ? 1182 parse_arg_name(s) : parse_arg_index(s); 1183 if (*s++ != '}') 1184 FMT_THROW(FormatError("invalid format string")); 1185 ULongLong value = 0; 1186 switch (width_arg.type) { 1187 case Arg::INT: 1188 if (width_arg.int_value < 0) 1189 FMT_THROW(FormatError("negative width")); 1190 value = width_arg.int_value; 1191 break; 1192 case Arg::UINT: 1193 value = width_arg.uint_value; 1194 break; 1195 case Arg::LONG_LONG: 1196 if (width_arg.long_long_value < 0) 1197 FMT_THROW(FormatError("negative width")); 1198 value = width_arg.long_long_value; 1199 break; 1200 case Arg::ULONG_LONG: 1201 value = width_arg.ulong_long_value; 1202 break; 1203 default: 1204 FMT_THROW(FormatError("width is not integer")); 1153 1205 } 1154 // Zero may be parsed again as a part of the width, but it is simpler 1155 // and more efficient than checking if the next char is a digit. 1156 spec.width_ = parse_nonnegative_int(s, error); 1157 if (error) 1158 report_error_(s, error); 1206 if (value > INT_MAX) 1207 FMT_THROW(FormatError("number is too big")); 1208 spec.width_ = static_cast<int>(value); 1159 1209 } 1160 1210 1161 1211 // Parse precision. … … const Char *fmt::BasicFormatter<Char>::format( 1163 1213 ++s; 1164 1214 spec.precision_ = 0; 1165 1215 if ('0' <= *s && *s <= '9') { 1166 spec.precision_ = parse_nonnegative_int(s, error); 1167 if (error) 1168 report_error_(s, error); 1216 spec.precision_ = parse_nonnegative_int(s); 1169 1217 } else if (*s == '{') { 1170 1218 ++s; 1171 ++report_error_.num_open_braces; 1172 const Arg &precision_arg = parse_arg_index(s); 1219 Arg precision_arg = 1220 is_name_start(*s) ? parse_arg_name(s) : parse_arg_index(s); 1221 if (*s++ != '}') 1222 FMT_THROW(FormatError("invalid format string")); 1173 1223 ULongLong value = 0; 1174 1224 switch (precision_arg.type) { 1175 1225 case Arg::INT: 1176 1226 if (precision_arg.int_value < 0) 1177 report_error_(s, "negative precision in format");1227 FMT_THROW(FormatError("negative precision")); 1178 1228 value = precision_arg.int_value; 1179 1229 break; 1180 1230 case Arg::UINT: … … const Char *fmt::BasicFormatter<Char>::format( 1182 1232 break; 1183 1233 case Arg::LONG_LONG: 1184 1234 if (precision_arg.long_long_value < 0) 1185 report_error_(s, "negative precision in format");1235 FMT_THROW(FormatError("negative precision")); 1186 1236 value = precision_arg.long_long_value; 1187 1237 break; 1188 1238 case Arg::ULONG_LONG: 1189 1239 value = precision_arg.ulong_long_value; 1190 1240 break; 1191 1241 default: 1192 report_error_(s, "precision is not integer");1242 FMT_THROW(FormatError("precision is not integer")); 1193 1243 } 1194 1244 if (value > INT_MAX) 1195 report_error_(s, "number is too big in format");1245 FMT_THROW(FormatError("number is too big")); 1196 1246 spec.precision_ = static_cast<int>(value); 1197 if (*s++ != '}')1198 throw FormatError("unmatched '{' in format");1199 --report_error_.num_open_braces;1200 1247 } else { 1201 report_error_(s, "missing precision in format");1248 FMT_THROW(FormatError("missing precision specifier")); 1202 1249 } 1203 if (arg.type != Arg::DOUBLE && arg.type != Arg::LONG_DOUBLE) { 1204 report_error_(s, 1205 "precision specifier requires floating-point argument"); 1250 if (arg.type <= Arg::LAST_INTEGER_TYPE || arg.type == Arg::POINTER) { 1251 FMT_THROW(FormatError( 1252 fmt::format("precision not allowed in {} format specifier", 1253 arg.type == Arg::POINTER ? "pointer" : "integer"))); 1206 1254 } 1207 1255 } 1208 1256 … … const Char *fmt::BasicFormatter<Char>::format( 1212 1260 } 1213 1261 1214 1262 if (*s++ != '}') 1215 throw FormatError("unmatched '{' in format"); 1216 start_ = s; 1263 FMT_THROW(FormatError("missing '}' in format string")); 1217 1264 1218 1265 // Format argument. 1219 1266 internal::ArgFormatter<Char>(*this, spec, s - 1).visit(arg); … … const Char *fmt::BasicFormatter<Char>::format( 1221 1268 } 1222 1269 1223 1270 template <typename Char> 1224 void fmt::BasicFormatter<Char>::format( 1225 BasicStringRef<Char> format_str, const ArgList &args) { 1226 const Char *s = start_ = format_str.c_str(); 1227 args_ = args; 1228 next_arg_index_ = 0; 1271 void fmt::BasicFormatter<Char>::format(BasicCStringRef<Char> format_str) { 1272 const Char *s = format_str.c_str(); 1273 const Char *start = s; 1229 1274 while (*s) { 1230 1275 Char c = *s++; 1231 1276 if (c != '{' && c != '}') continue; 1232 1277 if (*s == c) { 1233 write(writer_, start _, s);1234 start _= ++s;1278 write(writer_, start, s); 1279 start = ++s; 1235 1280 continue; 1236 1281 } 1237 1282 if (c == '}') 1238 throw FormatError("unmatched '}' in format"); 1239 report_error_.num_open_braces = 1; 1240 write(writer_, start_, s - 1); 1241 Arg arg = parse_arg_index(s); 1242 s = format(s, arg); 1283 FMT_THROW(FormatError("unmatched '}' in format string")); 1284 write(writer_, start, s - 1); 1285 Arg arg = is_name_start(*s) ? parse_arg_name(s) : parse_arg_index(s); 1286 start = s = format(s, arg); 1243 1287 } 1244 write(writer_, start _, s);1288 write(writer_, start, s); 1245 1289 } 1246 1290 1247 void fmt::report_system_error(1248 int error_code, fmt::StringRef message) FMT_NOEXCEPT (true){1249 // FIXME: format_system_error may throw1250 report_error(internal::format_system_error, error_code, message);1291 FMT_FUNC void fmt::report_system_error( 1292 int error_code, fmt::StringRef message) FMT_NOEXCEPT { 1293 // 'fmt::' is for bcc32. 1294 fmt::report_error(internal::format_system_error, error_code, message); 1251 1295 } 1252 1296 1253 #if def _WIN321254 void fmt::report_windows_error(1255 int error_code, fmt::StringRef message) FMT_NOEXCEPT (true){1256 // FIXME: format_windows_error may throw1257 report_error(internal::format_windows_error, error_code, message);1297 #if FMT_USE_WINDOWS_H 1298 FMT_FUNC void fmt::report_windows_error( 1299 int error_code, fmt::StringRef message) FMT_NOEXCEPT { 1300 // 'fmt::' is for bcc32. 1301 fmt::report_error(internal::format_windows_error, error_code, message); 1258 1302 } 1259 1303 #endif 1260 1304 1261 void fmt::print(std::FILE *f, StringRef format_str, const ArgList &args) {1262 Writer w;1305 FMT_FUNC void fmt::print(std::FILE *f, CStringRef format_str, ArgList args) { 1306 MemoryWriter w; 1263 1307 w.write(format_str, args); 1264 1308 std::fwrite(w.data(), 1, w.size(), f); 1265 1309 } 1266 1310 1267 void fmt::print(std::ostream &os, StringRef format_str, const ArgList &args) { 1268 Writer w; 1311 FMT_FUNC void fmt::print(CStringRef format_str, ArgList args) { 1312 print(stdout, format_str, args); 1313 } 1314 1315 FMT_FUNC void fmt::print(std::ostream &os, CStringRef format_str, ArgList args) { 1316 MemoryWriter w; 1269 1317 w.write(format_str, args); 1270 1318 os.write(w.data(), w.size()); 1271 1319 } 1272 1320 1273 void fmt::print_colored(Color c, StringRef format, const ArgList &args) {1321 FMT_FUNC void fmt::print_colored(Color c, CStringRef format, ArgList args) { 1274 1322 char escape[] = "\x1b[30m"; 1275 escape[3] = '0' + static_cast<char>(c);1323 escape[3] = static_cast<char>('0' + c); 1276 1324 std::fputs(escape, stdout); 1277 1325 print(format, args); 1278 1326 std::fputs(RESET_COLOR, stdout); 1279 1327 } 1280 1328 1281 int fmt::fprintf(std::FILE *f, StringRef format, const ArgList &args) {1282 Writer w;1329 FMT_FUNC int fmt::fprintf(std::FILE *f, CStringRef format, ArgList args) { 1330 MemoryWriter w; 1283 1331 printf(w, format, args); 1284 return std::fwrite(w.data(), 1, w.size(), f); 1332 std::size_t size = w.size(); 1333 return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast<int>(size); 1285 1334 } 1286 1335 1336 #ifndef FMT_HEADER_ONLY 1337 1338 template struct fmt::internal::BasicData<void>; 1339 1287 1340 // Explicit instantiations for char. 1288 1341 1289 template fmt::BasicWriter<char>::CharPtr 1290 fmt::BasicWriter<char>::fill_padding(CharPtr buffer, 1291 unsigned total_size, std::size_t content_size, wchar_t fill); 1342 template void fmt::internal::FixedBuffer<char>::grow(std::size_t); 1343 1344 template const char *fmt::BasicFormatter<char>::format( 1345 const char *&format_str, const fmt::internal::Arg &arg); 1292 1346 1293 template void fmt::BasicFormatter<char>::format( 1294 BasicStringRef<char> format, const ArgList &args); 1347 template void fmt::BasicFormatter<char>::format(CStringRef format); 1295 1348 1296 1349 template void fmt::internal::PrintfFormatter<char>::format( 1297 BasicWriter<char> &writer, BasicStringRef<char> format, const ArgList &args); 1350 BasicWriter<char> &writer, CStringRef format); 1351 1352 template int fmt::internal::CharTraits<char>::format_float( 1353 char *buffer, std::size_t size, const char *format, 1354 unsigned width, int precision, double value); 1355 1356 template int fmt::internal::CharTraits<char>::format_float( 1357 char *buffer, std::size_t size, const char *format, 1358 unsigned width, int precision, long double value); 1298 1359 1299 1360 // Explicit instantiations for wchar_t. 1300 1361 1301 template fmt::BasicWriter<wchar_t>::CharPtr 1302 fmt::BasicWriter<wchar_t>::fill_padding(CharPtr buffer, 1303 unsigned total_size, std::size_t content_size, wchar_t fill); 1362 template void fmt::internal::FixedBuffer<wchar_t>::grow(std::size_t); 1363 1364 template const wchar_t *fmt::BasicFormatter<wchar_t>::format( 1365 const wchar_t *&format_str, const fmt::internal::Arg &arg); 1304 1366 1305 1367 template void fmt::BasicFormatter<wchar_t>::format( 1306 Basic StringRef<wchar_t> format, const ArgList &args);1368 BasicCStringRef<wchar_t> format); 1307 1369 1308 1370 template void fmt::internal::PrintfFormatter<wchar_t>::format( 1309 BasicWriter<wchar_t> &writer, BasicStringRef<wchar_t> format, 1310 const ArgList &args); 1371 BasicWriter<wchar_t> &writer, WCStringRef format); 1372 1373 template int fmt::internal::CharTraits<wchar_t>::format_float( 1374 wchar_t *buffer, std::size_t size, const wchar_t *format, 1375 unsigned width, int precision, double value); 1376 1377 template int fmt::internal::CharTraits<wchar_t>::format_float( 1378 wchar_t *buffer, std::size_t size, const wchar_t *format, 1379 unsigned width, int precision, long double value); 1380 1381 #endif // FMT_HEADER_ONLY 1311 1382 1312 1383 #ifdef _MSC_VER 1313 1384 # pragma warning(pop) -
source/third_party/cppformat/format.h
diff --git a/source/third_party/cppformat/format.h b/source/third_party/cppformat/format.h index 5e9fa96..568123d 100644
a b 1 1 /* 2 * Slightly modified version of cppformat, by Wildfire Games, for 0 A.D.3 * Based on cppformat v0.11.0 from https://github.com/cppformat/cppformat4 */5 6 /*7 2 Formatting library for C++ 8 3 9 Copyright (c) 2012 - 201 4, Victor Zverovich4 Copyright (c) 2012 - 2015, Victor Zverovich 10 5 All rights reserved. 11 6 12 7 Redistribution and use in source and binary forms, with or without … … 33 28 #ifndef FMT_FORMAT_H_ 34 29 #define FMT_FORMAT_H_ 35 30 31 #if defined _MSC_VER && _MSC_VER <= 1500 32 typedef unsigned int uint32_t; 33 typedef unsigned long long uint64_t; 34 typedef long long intmax_t; 35 #else 36 36 #include <stdint.h> 37 #endif 37 38 38 39 #include <cassert> 39 #include <c stddef> // for std::ptrdiff_t40 #include <cmath> 40 41 #include <cstdio> 41 42 #include <algorithm> 42 43 #include <limits> 43 44 #include <stdexcept> 44 45 #include <string> 45 #include <sstream> 46 #include <map> 47 48 #ifndef FMT_USE_IOSTREAMS 49 # define FMT_USE_IOSTREAMS 1 50 #endif 51 52 #if FMT_USE_IOSTREAMS 53 # include <ostream> 54 #endif 55 56 #ifdef _SECURE_SCL 57 # define FMT_SECURE_SCL _SECURE_SCL 58 #else 59 # define FMT_SECURE_SCL 0 60 #endif 46 61 47 #if defined(_SECURE_SCL) &&_SECURE_SCL62 #if FMT_SECURE_SCL 48 63 # include <iterator> 49 64 #endif 50 65 66 #ifdef _MSC_VER 67 # include <intrin.h> // _BitScanReverse, _BitScanReverse64 68 69 namespace fmt { 70 namespace internal { 71 # pragma intrinsic(_BitScanReverse) 72 inline uint32_t clz(uint32_t x) { 73 unsigned long r = 0; 74 _BitScanReverse(&r, x); 75 return 31 - r; 76 } 77 # define FMT_BUILTIN_CLZ(n) fmt::internal::clz(n) 78 79 # ifdef _WIN64 80 # pragma intrinsic(_BitScanReverse64) 81 # endif 82 83 inline uint32_t clzll(uint64_t x) { 84 unsigned long r = 0; 85 # ifdef _WIN64 86 _BitScanReverse64(&r, x); 87 # else 88 // Scan the high 32 bits. 89 if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32))) 90 return 63 - (r + 32); 91 92 // Scan the low 32 bits. 93 _BitScanReverse(&r, static_cast<uint32_t>(x)); 94 # endif 95 return 63 - r; 96 } 97 # define FMT_BUILTIN_CLZLL(n) fmt::internal::clzll(n) 98 } 99 } 100 #endif 101 51 102 #ifdef __GNUC__ 52 103 # define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) 53 104 # define FMT_GCC_EXTENSION __extension__ 54 // Disable warning about "long long" which is sometimes reported even55 // when using __extension__.56 105 # if FMT_GCC_VERSION >= 406 57 106 # pragma GCC diagnostic push 107 // Disable the warning about "long long" which is sometimes reported even 108 // when using __extension__. 58 109 # pragma GCC diagnostic ignored "-Wlong-long" 110 // Disable the warning about declaration shadowing because it affects too 111 // many valid cases. 112 # pragma GCC diagnostic ignored "-Wshadow" 113 // Disable the warning about implicit conversions that may change the sign of 114 // an integer; silencing it otherwise would require many explicit casts. 115 # pragma GCC diagnostic ignored "-Wsign-conversion" 116 # endif 117 # if __cplusplus >= 201103L || defined __GXX_EXPERIMENTAL_CXX0X__ 118 # define FMT_HAS_GXX_CXX11 1 59 119 # endif 60 120 #else 61 121 # define FMT_GCC_EXTENSION 62 122 #endif 63 123 124 #if defined(__clang__) && !defined(__INTEL_COMPILER) 125 # pragma clang diagnostic push 126 # pragma clang diagnostic ignored "-Wdocumentation" 127 #endif 128 64 129 #ifdef __GNUC_LIBSTD__ 65 130 # define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__) 66 131 #endif … … 77 142 # define FMT_HAS_BUILTIN(x) 0 78 143 #endif 79 144 145 #ifdef __has_cpp_attribute 146 # define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) 147 #else 148 # define FMT_HAS_CPP_ATTRIBUTE(x) 0 149 #endif 150 80 151 #ifndef FMT_USE_VARIADIC_TEMPLATES 81 152 // Variadic templates are available in GCC since version 4.4 82 153 // (http://gcc.gnu.org/projects/cxx0x.html) and in Visual C++ 83 154 // since version 2013. 84 155 # define FMT_USE_VARIADIC_TEMPLATES \ 85 156 (FMT_HAS_FEATURE(cxx_variadic_templates) || \ 86 (FMT_GCC_VERSION >= 404 && __cplusplus >= 201103) || (defined(_MSC_VER) && _MSC_VER >= 1800))157 (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1800) 87 158 #endif 88 159 89 160 #ifndef FMT_USE_RVALUE_REFERENCES … … 94 165 # else 95 166 # define FMT_USE_RVALUE_REFERENCES \ 96 167 (FMT_HAS_FEATURE(cxx_rvalue_references) || \ 97 (FMT_GCC_VERSION >= 403 && __cplusplus >= 201103) || (defined(_MSC_VER) && _MSC_VER >= 1600))168 (FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600) 98 169 # endif 99 170 #endif 100 171 … … 103 174 #endif 104 175 105 176 // Define FMT_USE_NOEXCEPT to make C++ Format use noexcept (C++11 feature). 106 #if (defined(FMT_USE_NOEXCEPT) && FMT_USE_NOEXCEPT) || FMT_HAS_FEATURE(cxx_noexcept) || \ 107 (FMT_GCC_VERSION >= 408 && __cplusplus >= 201103) 108 # define FMT_NOEXCEPT(expr) noexcept(expr) 109 #else 110 # define FMT_NOEXCEPT(expr) 177 #ifndef FMT_USE_NOEXCEPT 178 # define FMT_USE_NOEXCEPT 0 179 #endif 180 181 #ifndef FMT_NOEXCEPT 182 # if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \ 183 (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || \ 184 _MSC_VER >= 1900 185 # define FMT_NOEXCEPT noexcept 186 # else 187 # define FMT_NOEXCEPT throw() 188 # endif 111 189 #endif 112 190 113 191 // A macro to disallow the copy constructor and operator= functions 114 192 // This should be used in the private: declarations for a class 115 #define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \ 116 TypeName(const TypeName&); \ 117 void operator=(const TypeName&) 193 #ifndef FMT_USE_DELETED_FUNCTIONS 194 # define FMT_USE_DELETED_FUNCTIONS 0 195 #endif 196 197 #if FMT_USE_DELETED_FUNCTIONS || FMT_HAS_FEATURE(cxx_deleted_functions) || \ 198 (FMT_GCC_VERSION >= 404 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1800 199 # define FMT_DELETED_OR_UNDEFINED = delete 200 # define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \ 201 TypeName(const TypeName&) = delete; \ 202 TypeName& operator=(const TypeName&) = delete 203 #else 204 # define FMT_DELETED_OR_UNDEFINED 205 # define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \ 206 TypeName(const TypeName&); \ 207 TypeName& operator=(const TypeName&) 208 #endif 209 210 #ifndef FMT_USE_USER_DEFINED_LITERALS 211 // All compilers which support UDLs also support variadic templates. This 212 // makes the fmt::literals implementation easier. However, an explicit check 213 // for variadic templates is added here just in case. 214 # define FMT_USE_USER_DEFINED_LITERALS \ 215 FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES && \ 216 (FMT_HAS_FEATURE(cxx_user_literals) || \ 217 (FMT_GCC_VERSION >= 407 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1900) 218 #endif 219 220 #ifndef FMT_ASSERT 221 # define FMT_ASSERT(condition, message) assert((condition) && message) 222 #endif 223 224 namespace fmt { 225 namespace internal { 226 struct DummyInt { 227 int data[2]; 228 operator int() const { return 0; } 229 }; 230 typedef std::numeric_limits<fmt::internal::DummyInt> FPUtil; 231 232 // Dummy implementations of system functions such as signbit and ecvt called 233 // if the latter are not available. 234 inline DummyInt signbit(...) { return DummyInt(); } 235 inline DummyInt _ecvt_s(...) { return DummyInt(); } 236 inline DummyInt isinf(...) { return DummyInt(); } 237 inline DummyInt _finite(...) { return DummyInt(); } 238 inline DummyInt isnan(...) { return DummyInt(); } 239 inline DummyInt _isnan(...) { return DummyInt(); } 240 241 // A helper function to suppress bogus "conditional expression is constant" 242 // warnings. 243 template <typename T> 244 inline T check(T value) { return value; } 245 } 246 } // namespace fmt 247 248 namespace std { 249 // Standard permits specialization of std::numeric_limits. This specialization 250 // is used to resolve ambiguity between isinf and std::isinf in glibc: 251 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48891 252 // and the same for isnan and signbit. 253 template <> 254 class numeric_limits<fmt::internal::DummyInt> : 255 public std::numeric_limits<int> { 256 public: 257 // Portable version of isinf. 258 template <typename T> 259 static bool isinfinity(T x) { 260 using namespace fmt::internal; 261 // The resolution "priority" is: 262 // isinf macro > std::isinf > ::isinf > fmt::internal::isinf 263 if (check(sizeof(isinf(x)) == sizeof(bool) || 264 sizeof(isinf(x)) == sizeof(int))) { 265 return !!isinf(x); 266 } 267 return !_finite(static_cast<double>(x)); 268 } 269 270 // Portable version of isnan. 271 template <typename T> 272 static bool isnotanumber(T x) { 273 using namespace fmt::internal; 274 if (check(sizeof(isnan(x)) == sizeof(bool) || 275 sizeof(isnan(x)) == sizeof(int))) { 276 return !!isnan(x); 277 } 278 return _isnan(static_cast<double>(x)) != 0; 279 } 280 281 // Portable version of signbit. 282 static bool isnegative(double x) { 283 using namespace fmt::internal; 284 if (check(sizeof(signbit(x)) == sizeof(int))) 285 return !!signbit(x); 286 if (x < 0) return true; 287 if (!isnotanumber(x)) return false; 288 int dec = 0, sign = 0; 289 char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail. 290 _ecvt_s(buffer, sizeof(buffer), x, 0, &dec, &sign); 291 return sign != 0; 292 } 293 }; 294 } // namespace std 118 295 119 296 namespace fmt { 120 297 … … template <typename Char> 137 314 class BasicFormatter; 138 315 139 316 template <typename Char, typename T> 140 void format(BasicFormatter<Char> &f, const Char * format_str, const T &value);317 void format(BasicFormatter<Char> &f, const Char *&format_str, const T &value); 141 318 142 319 /** 143 320 \rst 144 A string reference. It can be constructed from a C string or 145 ``std::string``. 146 321 A string reference. It can be constructed from a C string or ``std::string``. 322 147 323 You can use one of the following typedefs for common character types: 148 324 149 325 +------------+-------------------------+ … … void format(BasicFormatter<Char> &f, const Char *format_str, const T &value); 157 333 This class is most useful as a parameter type to allow passing 158 334 different types of strings to a function, for example:: 159 335 160 template <typename... Args>161 std::string format(StringRef format , const Args & ... args);336 template <typename... Args> 337 std::string format(StringRef format_str, const Args & ... args); 162 338 163 339 format("{}", 42); 164 340 format(std::string("{}"), 42); … … template <typename Char> 168 344 class BasicStringRef { 169 345 private: 170 346 const Char *data_; 171 mutablestd::size_t size_;347 std::size_t size_; 172 348 173 349 public: 350 /** Constructs a string reference object from a C string and a size. */ 351 BasicStringRef(const Char *s, std::size_t size) : data_(s), size_(size) {} 352 174 353 /** 175 Constructs a string reference object from a C string and a size. 176 If *size* is zero, which is the default, the size is computed 177 automatically. 354 \rst 355 Constructs a string reference object from a C string computing 356 the size with ``std::char_traits<Char>::length``. 357 \endrst 178 358 */ 179 BasicStringRef(const Char *s, std::size_t size = 0) : data_(s), size_(size) {} 359 BasicStringRef(const Char *s) 360 : data_(s), size_(std::char_traits<Char>::length(s)) {} 180 361 181 362 /** 182 Constructs a string reference from an `std::string` object. 363 \rst 364 Constructs a string reference from an ``std::string`` object. 365 \endrst 183 366 */ 184 367 BasicStringRef(const std::basic_string<Char> &s) 185 368 : data_(s.c_str()), size_(s.size()) {} 186 369 187 370 /** 188 Converts a string reference to an `std::string` object. 371 \rst 372 Converts a string reference to an ``std::string`` object. 373 \endrst 189 374 */ 190 operator std::basic_string<Char>() const {191 return std::basic_string<Char>(data_, size ());375 std::basic_string<Char> to_string() const { 376 return std::basic_string<Char>(data_, size_); 192 377 } 193 378 194 /** 195 Returns the pointer to a C string. 196 */ 197 const Char *c_str() const { return data_; } 379 /** Returns the pointer to a C string. */ 380 const Char *data() const { return data_; } 198 381 199 /** 200 Returns the string size. 201 */ 202 std::size_t size() const { 203 if (size_ == 0 && data_) size_ = std::char_traits<Char>::length(data_); 204 return size_; 382 /** Returns the string size. */ 383 std::size_t size() const { return size_; } 384 385 // Lexicographically compare this string reference to other. 386 int compare(BasicStringRef other) const { 387 std::size_t size = std::min(size_, other.size_); 388 int result = std::char_traits<Char>::compare(data_, other.data_, size); 389 if (result == 0) 390 result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1); 391 return result; 205 392 } 206 393 207 394 friend bool operator==(BasicStringRef lhs, BasicStringRef rhs) { 208 return lhs. data_ == rhs.data_;395 return lhs.compare(rhs) == 0; 209 396 } 210 397 friend bool operator!=(BasicStringRef lhs, BasicStringRef rhs) { 211 return lhs.data_ != rhs.data_; 398 return lhs.compare(rhs) != 0; 399 } 400 friend bool operator<(BasicStringRef lhs, BasicStringRef rhs) { 401 return lhs.compare(rhs) < 0; 402 } 403 friend bool operator<=(BasicStringRef lhs, BasicStringRef rhs) { 404 return lhs.compare(rhs) <= 0; 405 } 406 friend bool operator>(BasicStringRef lhs, BasicStringRef rhs) { 407 return lhs.compare(rhs) > 0; 408 } 409 friend bool operator>=(BasicStringRef lhs, BasicStringRef rhs) { 410 return lhs.compare(rhs) >= 0; 212 411 } 213 412 }; 214 413 … … typedef BasicStringRef<char> StringRef; 216 415 typedef BasicStringRef<wchar_t> WStringRef; 217 416 218 417 /** 418 \rst 419 A reference to a null terminated string. It can be constructed from a C 420 string or ``std::string``. 421 422 You can use one of the following typedefs for common character types: 423 424 +-------------+--------------------------+ 425 | Type | Definition | 426 +=============+==========================+ 427 | CStringRef | BasicCStringRef<char> | 428 +-------------+--------------------------+ 429 | WCStringRef | BasicCStringRef<wchar_t> | 430 +-------------+--------------------------+ 431 432 This class is most useful as a parameter type to allow passing 433 different types of strings to a function, for example:: 434 435 template <typename... Args> 436 std::string format(CStringRef format_str, const Args & ... args); 437 438 format("{}", 42); 439 format(std::string("{}"), 42); 440 \endrst 441 */ 442 template <typename Char> 443 class BasicCStringRef { 444 private: 445 const Char *data_; 446 447 public: 448 /** Constructs a string reference object from a C string. */ 449 BasicCStringRef(const Char *s) : data_(s) {} 450 451 /** 452 \rst 453 Constructs a string reference from an ``std::string`` object. 454 \endrst 455 */ 456 BasicCStringRef(const std::basic_string<Char> &s) : data_(s.c_str()) {} 457 458 /** Returns the pointer to a C string. */ 459 const Char *c_str() const { return data_; } 460 }; 461 462 typedef BasicCStringRef<char> CStringRef; 463 typedef BasicCStringRef<wchar_t> WCStringRef; 464 465 /** 219 466 A formatting error such as invalid format string. 220 467 */ 221 468 class FormatError : public std::runtime_error { 222 public:223 explicit FormatError( const std::string &message)224 : std::runtime_error(message ) {}469 public: 470 explicit FormatError(CStringRef message) 471 : std::runtime_error(message.c_str()) {} 225 472 }; 226 473 227 474 namespace internal { 228 229 // The number of characters to store in the Array object, representing the 230 // output buffer, itself to avoid dynamic memory allocation. 475 // The number of characters to store in the MemoryBuffer object itself 476 // to avoid dynamic memory allocation. 231 477 enum { INLINE_BUFFER_SIZE = 500 }; 232 478 233 #if defined(_SECURE_SCL) &&_SECURE_SCL479 #if FMT_SECURE_SCL 234 480 // Use checked iterator to avoid warnings on MSVC. 235 481 template <typename T> 236 482 inline stdext::checked_array_iterator<T*> make_ptr(T *ptr, std::size_t size) { … … inline stdext::checked_array_iterator<T*> make_ptr(T *ptr, std::size_t size) { 240 486 template <typename T> 241 487 inline T *make_ptr(T *ptr, std::size_t) { return ptr; } 242 488 #endif 489 } // namespace internal 243 490 244 // A simple array for POD types with the first SIZE elements stored in 245 // the object itself. It supports a subset of std::vector's operations. 246 template <typename T, std::size_t SIZE> 247 class Array { 491 /** 492 \rst 493 A buffer supporting a subset of ``std::vector``'s operations. 494 \endrst 495 */ 496 template <typename T> 497 class Buffer { 248 498 private: 499 FMT_DISALLOW_COPY_AND_ASSIGN(Buffer); 500 501 protected: 502 T *ptr_; 249 503 std::size_t size_; 250 504 std::size_t capacity_; 251 T *ptr_;252 T data_[SIZE];253 254 void grow(std::size_t size);255 256 // Free memory allocated by the array.257 void free() {258 if (ptr_ != data_) delete [] ptr_;259 }260 505 261 // Move data from other to this array. 262 void move(Array &other) { 263 size_ = other.size_; 264 capacity_ = other.capacity_; 265 if (other.ptr_ == other.data_) { 266 ptr_ = data_; 267 std::copy(other.data_, other.data_ + size_, make_ptr(data_, capacity_)); 268 } else { 269 ptr_ = other.ptr_; 270 // Set pointer to the inline array so that delete is not called 271 // when freeing. 272 other.ptr_ = other.data_; 273 } 274 } 506 Buffer(T *ptr = 0, std::size_t capacity = 0) 507 : ptr_(ptr), size_(0), capacity_(capacity) {} 275 508 276 FMT_DISALLOW_COPY_AND_ASSIGN(Array); 509 /** 510 \rst 511 Increases the buffer capacity to hold at least *size* elements updating 512 ``ptr_`` and ``capacity_``. 513 \endrst 514 */ 515 virtual void grow(std::size_t size) = 0; 277 516 278 517 public: 279 explicit Array(std::size_t size = 0) 280 : size_(size), capacity_(SIZE), ptr_(data_) {} 281 ~Array() { free(); } 518 virtual ~Buffer() {} 282 519 283 #if FMT_USE_RVALUE_REFERENCES 284 Array(Array &&other) { 285 move(other); 286 } 287 288 Array& operator=(Array &&other) { 289 assert(this != &other); 290 free(); 291 move(other); 292 return *this; 293 } 294 #endif 295 296 // Returns the size of this array. 520 /** Returns the size of this buffer. */ 297 521 std::size_t size() const { return size_; } 298 522 299 / / Returns the capacity of this array.523 /** Returns the capacity of this buffer. */ 300 524 std::size_t capacity() const { return capacity_; } 301 525 302 // Resizes the array. If T is a POD type new elements are not initialized. 526 /** 527 Resizes the buffer. If T is a POD type new elements may not be initialized. 528 */ 303 529 void resize(std::size_t new_size) { 304 530 if (new_size > capacity_) 305 531 grow(new_size); 306 532 size_ = new_size; 307 533 } 308 534 309 // Reserves space to store at least capacity elements. 535 /** 536 \rst 537 Reserves space to store at least *capacity* elements. 538 \endrst 539 */ 310 540 void reserve(std::size_t capacity) { 311 541 if (capacity > capacity_) 312 542 grow(capacity); 313 543 } 314 544 315 void clear() { size_ = 0; }545 void clear() FMT_NOEXCEPT { size_ = 0; } 316 546 317 547 void push_back(const T &value) { 318 548 if (size_ == capacity_) … … class Array { 320 550 ptr_[size_++] = value; 321 551 } 322 552 323 // Appends data to the end of the array. 324 void append(const T *begin, const T *end); 553 /** Appends data to the end of the buffer. */ 554 template <typename U> 555 void append(const U *begin, const U *end); 325 556 326 557 T &operator[](std::size_t index) { return ptr_[index]; } 327 558 const T &operator[](std::size_t index) const { return ptr_[index]; } 328 559 }; 329 560 330 template <typename T, std::size_t SIZE> 331 void Array<T, SIZE>::grow(std::size_t size) { 332 capacity_ = (std::max)(size, capacity_ + capacity_ / 2); 333 T *p = new T[capacity_]; 334 std::copy(ptr_, ptr_ + size_, make_ptr(p, capacity_)); 335 if (ptr_ != data_) 336 delete [] ptr_; 337 ptr_ = p; 561 template <typename T> 562 template <typename U> 563 void Buffer<T>::append(const U *begin, const U *end) { 564 assert(begin <= end); 565 std::size_t new_size = size_ + (end - begin); 566 if (new_size > capacity_) 567 grow(new_size); 568 std::copy(begin, end, internal::make_ptr(ptr_, capacity_) + size_); 569 size_ = new_size; 338 570 } 339 571 340 template <typename T, std::size_t SIZE> 341 void Array<T, SIZE>::append(const T *begin, const T *end) { 342 std::ptrdiff_t num_elements = end - begin; 343 if (size_ + num_elements > capacity_) 344 grow(size_ + num_elements); 345 std::copy(begin, end, make_ptr(ptr_, capacity_) + size_); 346 size_ += num_elements; 572 namespace internal { 573 574 // A memory buffer for POD types with the first SIZE elements stored in 575 // the object itself. 576 template <typename T, std::size_t SIZE, typename Allocator = std::allocator<T> > 577 class MemoryBuffer : private Allocator, public Buffer<T> { 578 private: 579 T data_[SIZE]; 580 581 // Deallocate memory allocated by the buffer. 582 void deallocate() { 583 if (this->ptr_ != data_) Allocator::deallocate(this->ptr_, this->capacity_); 584 } 585 586 protected: 587 void grow(std::size_t size); 588 589 public: 590 explicit MemoryBuffer(const Allocator &alloc = Allocator()) 591 : Allocator(alloc), Buffer<T>(data_, SIZE) {} 592 ~MemoryBuffer() { deallocate(); } 593 594 #if FMT_USE_RVALUE_REFERENCES 595 private: 596 // Move data from other to this buffer. 597 void move(MemoryBuffer &other) { 598 Allocator &this_alloc = *this, &other_alloc = other; 599 this_alloc = std::move(other_alloc); 600 this->size_ = other.size_; 601 this->capacity_ = other.capacity_; 602 if (other.ptr_ == other.data_) { 603 this->ptr_ = data_; 604 std::copy(other.data_, 605 other.data_ + this->size_, make_ptr(data_, this->capacity_)); 606 } else { 607 this->ptr_ = other.ptr_; 608 // Set pointer to the inline array so that delete is not called 609 // when deallocating. 610 other.ptr_ = other.data_; 611 } 612 } 613 614 public: 615 MemoryBuffer(MemoryBuffer &&other) { 616 move(other); 617 } 618 619 MemoryBuffer &operator=(MemoryBuffer &&other) { 620 assert(this != &other); 621 deallocate(); 622 move(other); 623 return *this; 624 } 625 #endif 626 627 // Returns a copy of the allocator associated with this buffer. 628 Allocator get_allocator() const { return *this; } 629 }; 630 631 template <typename T, std::size_t SIZE, typename Allocator> 632 void MemoryBuffer<T, SIZE, Allocator>::grow(std::size_t size) { 633 std::size_t new_capacity = 634 (std::max)(size, this->capacity_ + this->capacity_ / 2); 635 T *new_ptr = this->allocate(new_capacity); 636 // The following code doesn't throw, so the raw pointer above doesn't leak. 637 std::copy(this->ptr_, 638 this->ptr_ + this->size_, make_ptr(new_ptr, new_capacity)); 639 std::size_t old_capacity = this->capacity_; 640 T *old_ptr = this->ptr_; 641 this->capacity_ = new_capacity; 642 this->ptr_ = new_ptr; 643 // deallocate may throw (at least in principle), but it doesn't matter since 644 // the buffer already uses the new storage and will deallocate it in case 645 // of exception. 646 if (old_ptr != data_) 647 Allocator::deallocate(old_ptr, old_capacity); 347 648 } 348 649 650 // A fixed-size buffer. 651 template <typename Char> 652 class FixedBuffer : public fmt::Buffer<Char> { 653 public: 654 FixedBuffer(Char *array, std::size_t size) : fmt::Buffer<Char>(array, size) {} 655 656 protected: 657 void grow(std::size_t size); 658 }; 659 349 660 template <typename Char> 350 661 class BasicCharTraits { 351 662 public: 352 #if defined(_SECURE_SCL) &&_SECURE_SCL663 #if FMT_SECURE_SCL 353 664 typedef stdext::checked_array_iterator<Char*> CharPtr; 354 665 #else 355 666 typedef Char *CharPtr; 356 667 #endif 668 static Char cast(wchar_t value) { return static_cast<Char>(value); } 357 669 }; 358 670 359 671 template <typename Char> … … class CharTraits<char> : public BasicCharTraits<char> { 365 677 // Conversion from wchar_t to char is not allowed. 366 678 static char convert(wchar_t); 367 679 368 public: 369 typedef const wchar_t *UnsupportedStrType; 370 680 public: 371 681 static char convert(char value) { return value; } 372 682 373 683 // Formats a floating-point number. … … public: 379 689 template <> 380 690 class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> { 381 691 public: 382 typedef const char *UnsupportedStrType;383 384 692 static wchar_t convert(char value) { return value; } 385 693 static wchar_t convert(wchar_t value) { return value; } 386 694 … … class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> { 389 697 const wchar_t *format, unsigned width, int precision, T value); 390 698 }; 391 699 392 // Selects uint32_t if FitsIn32Bits is true, uint64_t otherwise.393 template <bool FitsIn32Bits>394 struct TypeSelector { typedef uint32_t Type; };395 396 template <>397 struct TypeSelector<false> { typedef uint64_t Type; };398 399 700 // Checks if a number is negative - used to avoid warnings. 400 701 template <bool IsSigned> 401 702 struct SignChecker { 402 703 template <typename T> 403 static bool is_negative(T ) { return false; }704 static bool is_negative(T value) { return value < 0; } 404 705 }; 405 706 406 707 template <> 407 struct SignChecker< true> {708 struct SignChecker<false> { 408 709 template <typename T> 409 static bool is_negative(T value) { return value < 0; }710 static bool is_negative(T) { return false; } 410 711 }; 411 712 412 713 // Returns true if value is negative, false otherwise. … … inline bool is_negative(T value) { 416 717 return SignChecker<std::numeric_limits<T>::is_signed>::is_negative(value); 417 718 } 418 719 720 // Selects uint32_t if FitsIn32Bits is true, uint64_t otherwise. 721 template <bool FitsIn32Bits> 722 struct TypeSelector { typedef uint32_t Type; }; 723 724 template <> 725 struct TypeSelector<false> { typedef uint64_t Type; }; 726 419 727 template <typename T> 420 728 struct IntTraits { 421 729 // Smallest of uint32_t and uint64_t that is large enough to represent … … FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong); 441 749 442 750 void report_unknown_type(char code, const char *type); 443 751 444 extern const uint32_t POWERS_OF_10_32[]; 445 extern const uint64_t POWERS_OF_10_64[]; 752 // Static data is placed in this class template to allow header-only 753 // configuration. 754 template <typename T = void> 755 struct BasicData { 756 static const uint32_t POWERS_OF_10_32[]; 757 static const uint64_t POWERS_OF_10_64[]; 758 static const char DIGITS[]; 759 }; 760 761 typedef BasicData<> Data; 762 763 #if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz) 764 # define FMT_BUILTIN_CLZ(n) __builtin_clz(n) 765 #endif 446 766 447 767 #if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll) 768 # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) 769 #endif 770 771 #ifdef FMT_BUILTIN_CLZLL 448 772 // Returns the number of decimal digits in n. Leading zeros are not counted 449 773 // except for n == 0 in which case count_digits returns 1. 450 774 inline unsigned count_digits(uint64_t n) { 451 775 // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 452 776 // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits. 453 unsigned t = (64 - __builtin_clzll(n | 1)) * 1233 >> 12;454 return t - (n < POWERS_OF_10_64[t]) + 1;777 unsigned t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12; 778 return t - (n < Data::POWERS_OF_10_64[t]) + 1; 455 779 } 456 # if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz)457 // Optional version of count_digits for better performance on 32-bit platforms.458 inline unsigned count_digits(uint32_t n) {459 uint32_t t = (32 - __builtin_clz(n | 1)) * 1233 >> 12;460 return t - (n < POWERS_OF_10_32[t]) + 1;461 }462 # endif463 780 #else 464 // Slowerversion of count_digits used when __builtin_clz is not available.781 // Fallback version of count_digits used when __builtin_clz is not available. 465 782 inline unsigned count_digits(uint64_t n) { 466 783 unsigned count = 1; 467 784 for (;;) { … … inline unsigned count_digits(uint64_t n) { 478 795 } 479 796 #endif 480 797 481 extern const char DIGITS[]; 798 #ifdef FMT_BUILTIN_CLZ 799 // Optional version of count_digits for better performance on 32-bit platforms. 800 inline unsigned count_digits(uint32_t n) { 801 uint32_t t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12; 802 return t - (n < Data::POWERS_OF_10_32[t]) + 1; 803 } 804 #endif 482 805 483 806 // Formats a decimal unsigned integer value writing into buffer. 484 807 template <typename UInt, typename Char> 485 808 inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) { 486 --num_digits;809 buffer += num_digits; 487 810 while (value >= 100) { 488 811 // Integer division is slow so do it for a group of two digits instead 489 812 // of for every digit. The idea comes from the talk by Alexandrescu 490 813 // "Three Optimization Tips for C++". See speed-test for a comparison. 491 unsigned index = (value % 100) * 2;814 unsigned index = static_cast<unsigned>((value % 100) * 2); 492 815 value /= 100; 493 buffer[num_digits] = DIGITS[index + 1]; 494 buffer[num_digits - 1] = DIGITS[index]; 495 num_digits -= 2; 816 *--buffer = Data::DIGITS[index + 1]; 817 *--buffer = Data::DIGITS[index]; 496 818 } 497 819 if (value < 10) { 498 * buffer = static_cast<char>('0' + value);820 *--buffer = static_cast<char>('0' + value); 499 821 return; 500 822 } 501 823 unsigned index = static_cast<unsigned>(value * 2); 502 buffer[1] =DIGITS[index + 1];503 buffer[0] =DIGITS[index];824 *--buffer = Data::DIGITS[index + 1]; 825 *--buffer = Data::DIGITS[index]; 504 826 } 505 827 506 #ifdef _WIN32 828 #ifndef _WIN32 829 # define FMT_USE_WINDOWS_H 0 830 #elif !defined(FMT_USE_WINDOWS_H) 831 # define FMT_USE_WINDOWS_H 1 832 #endif 833 834 // Define FMT_USE_WINDOWS_H to 0 to disable use of windows.h. 835 // All the functionality that relies on it will be disabled too. 836 #if FMT_USE_WINDOWS_H 507 837 // A converter from UTF-8 to UTF-16. 508 // It is only provided for Windows since other systems use UTF-8.838 // It is only provided for Windows since other systems support UTF-8 natively. 509 839 class UTF8ToUTF16 { 510 840 private: 511 Array<wchar_t, INLINE_BUFFER_SIZE> buffer_;841 MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer_; 512 842 513 843 public: 514 844 explicit UTF8ToUTF16(StringRef s); … … class UTF8ToUTF16 { 519 849 }; 520 850 521 851 // A converter from UTF-16 to UTF-8. 522 // It is only provided for Windows since other systems use UTF-8.852 // It is only provided for Windows since other systems support UTF-8 natively. 523 853 class UTF16ToUTF8 { 524 854 private: 525 Array<char, INLINE_BUFFER_SIZE> buffer_;855 MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer_; 526 856 527 857 public: 528 858 UTF16ToUTF8() {} … … class UTF16ToUTF8 { 533 863 std::string str() const { return std::string(&buffer_[0], size()); } 534 864 535 865 // Performs conversion returning a system error code instead of 536 // throwing exception on error. 866 // throwing exception on conversion error. This method may still throw 867 // in case of memory allocation error. 537 868 int convert(WStringRef s); 538 869 }; 539 #endif540 870 541 // Portable thread-safe version of strerror. 542 // Sets buffer to point to a string describing the error code. 543 // This can be either a pointer to a string stored in buffer, 544 // or a pointer to some static immutable string. 545 // Returns one of the following values: 546 // 0 - success 547 // ERANGE - buffer is not large enough to store the error message 548 // other - failure 549 // Buffer should be at least of size 1. 550 int safe_strerror(int error_code, 551 char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT(true); 552 553 void format_system_error( 554 fmt::Writer &out, int error_code, fmt::StringRef message); 555 556 #ifdef _WIN32 557 void format_windows_error( 558 fmt::Writer &out, int error_code, fmt::StringRef message); 871 void format_windows_error(fmt::Writer &out, int error_code, 872 fmt::StringRef message) FMT_NOEXCEPT; 559 873 #endif 560 874 561 // Throws Exception(message) if format contains '}', otherwise throws 562 // FormatError reporting unmatched '{'. The idea is that unmatched '{' 563 // should override other errors. 564 template <typename Char> 565 struct FormatErrorReporter { 566 int num_open_braces; 567 void operator()(const Char *s, fmt::StringRef message) const; 568 }; 569 570 // Computes max(Arg, 1) at compile time. It is used to avoid errors about 571 // allocating an array of 0 size. 572 template <unsigned Arg> 573 struct NonZero { 574 enum { VALUE = Arg }; 575 }; 576 577 template <> 578 struct NonZero<0> { 579 enum { VALUE = 1 }; 580 }; 581 582 // A formatting argument. It is a POD type to allow storage in internal::Array. 583 struct Arg { 584 enum Type { 585 // Integer types should go first, 586 INT, UINT, LONG_LONG, ULONG_LONG, CHAR, LAST_INTEGER_TYPE = CHAR, 587 // followed by floating-point types. 588 DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE, 589 STRING, WSTRING, POINTER, CUSTOM 590 }; 591 Type type; 875 void format_system_error(fmt::Writer &out, int error_code, 876 fmt::StringRef message) FMT_NOEXCEPT; 592 877 878 // A formatting argument value. 879 struct Value { 593 880 template <typename Char> 594 881 struct StringValue { 595 882 const Char *value; … … struct Arg { 597 884 }; 598 885 599 886 typedef void (*FormatFunc)( 600 void *formatter, const void *arg, const void *format_str);887 void *formatter, const void *arg, void *format_str_ptr); 601 888 602 889 struct CustomValue { 603 890 const void *value; … … struct Arg { 611 898 ULongLong ulong_long_value; 612 899 double double_value; 613 900 long double long_double_value; 614 const void *pointer _value;901 const void *pointer; 615 902 StringValue<char> string; 903 StringValue<signed char> sstring; 904 StringValue<unsigned char> ustring; 616 905 StringValue<wchar_t> wstring; 617 906 CustomValue custom; 618 907 }; 908 909 enum Type { 910 NONE, NAMED_ARG, 911 // Integer types should go first, 912 INT, UINT, LONG_LONG, ULONG_LONG, BOOL, CHAR, LAST_INTEGER_TYPE = CHAR, 913 // followed by floating-point types. 914 DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE, 915 CSTRING, STRING, WSTRING, POINTER, CUSTOM 916 }; 917 }; 918 919 // A formatting argument. It is a POD type to allow storage in 920 // internal::MemoryBuffer. 921 struct Arg : Value { 922 Type type; 923 }; 924 925 template <typename Char> 926 struct NamedArg; 927 928 template <typename T = void> 929 struct Null {}; 930 931 // A helper class template to enable or disable overloads taking wide 932 // characters and strings in MakeValue. 933 template <typename T, typename Char> 934 struct WCharHelper { 935 typedef Null<T> Supported; 936 typedef T Unsupported; 937 }; 938 939 template <typename T> 940 struct WCharHelper<T, wchar_t> { 941 typedef T Supported; 942 typedef Null<T> Unsupported; 943 }; 944 945 typedef char Yes[1]; 946 typedef char No[2]; 947 948 // These are non-members to workaround an overload resolution bug in bcc32. 949 Yes &convert(fmt::ULongLong); 950 Yes &convert(std::ostream &); 951 No &convert(...); 952 953 template <typename T> 954 T &get(); 955 956 struct DummyStream : std::ostream { 957 // Hide all operator<< overloads from std::ostream. 958 void operator<<(Null<>); 959 }; 960 961 No &operator<<(std::ostream &, int); 962 963 template<typename T, bool ENABLE_CONVERSION> 964 struct ConvertToIntImpl { 965 enum { value = false }; 966 }; 967 968 template<typename T> 969 struct ConvertToIntImpl<T, true> { 970 // Convert to int only if T doesn't have an overloaded operator<<. 971 enum { 972 value = sizeof(convert(get<DummyStream>() << get<T>())) == sizeof(No) 973 }; 974 }; 975 976 template<typename T, bool ENABLE_CONVERSION> 977 struct ConvertToIntImpl2 { 978 enum { value = false }; 979 }; 980 981 template<typename T> 982 struct ConvertToIntImpl2<T, true> { 983 enum { 984 // Don't convert numeric types. 985 value = ConvertToIntImpl<T, !std::numeric_limits<T>::is_specialized>::value 986 }; 987 }; 988 989 template<typename T> 990 struct ConvertToInt { 991 enum { enable_conversion = sizeof(convert(get<T>())) == sizeof(Yes) }; 992 enum { value = ConvertToIntImpl2<T, enable_conversion>::value }; 619 993 }; 620 994 995 #define FMT_DISABLE_CONVERSION_TO_INT(Type) \ 996 template <> \ 997 struct ConvertToInt<Type> { enum { value = 0 }; } 998 999 // Silence warnings about convering float to int. 1000 FMT_DISABLE_CONVERSION_TO_INT(float); 1001 FMT_DISABLE_CONVERSION_TO_INT(double); 1002 FMT_DISABLE_CONVERSION_TO_INT(long double); 1003 1004 template<bool B, class T = void> 1005 struct EnableIf {}; 1006 1007 template<class T> 1008 struct EnableIf<true, T> { typedef T type; }; 1009 1010 template<bool B, class T, class F> 1011 struct Conditional { typedef T type; }; 1012 1013 template<class T, class F> 1014 struct Conditional<false, T, F> { typedef F type; }; 1015 1016 // For bcc32 which doesn't understand ! in template arguments. 1017 template<bool> 1018 struct Not { enum { value = 0 }; }; 1019 1020 template<> 1021 struct Not<false> { enum { value = 1 }; }; 1022 621 1023 // Makes an Arg object from any type. 622 1024 template <typename Char> 623 class Make Arg: public Arg {1025 class MakeValue : public Arg { 624 1026 private: 625 1027 // The following two methods are private to disallow formatting of 626 1028 // arbitrary pointers. If you want to output a pointer cast it to … … class MakeArg : public Arg { 628 1030 // of "[const] volatile char *" which is printed as bool by iostreams. 629 1031 // Do not implement! 630 1032 template <typename T> 631 Make Arg(const T *value);1033 MakeValue(const T *value); 632 1034 template <typename T> 633 MakeArg(T *value); 1035 MakeValue(T *value); 1036 1037 // The following methods are private to disallow formatting of wide 1038 // characters and strings into narrow strings as in 1039 // fmt::format("{}", L"test"); 1040 // To fix this, use a wide format string: fmt::format(L"{}", L"test"). 1041 #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) 1042 MakeValue(typename WCharHelper<wchar_t, Char>::Unsupported); 1043 #endif 1044 MakeValue(typename WCharHelper<wchar_t *, Char>::Unsupported); 1045 MakeValue(typename WCharHelper<const wchar_t *, Char>::Unsupported); 1046 MakeValue(typename WCharHelper<const std::wstring &, Char>::Unsupported); 1047 MakeValue(typename WCharHelper<WStringRef, Char>::Unsupported); 634 1048 635 1049 void set_string(StringRef str) { 636 type = STRING; 637 string.value = str.c_str(); 1050 string.value = str.data(); 638 1051 string.size = str.size(); 639 1052 } 640 1053 641 1054 void set_string(WStringRef str) { 642 type = WSTRING; 643 CharTraits<Char>::convert(wchar_t()); 644 wstring.value = str.c_str(); 1055 wstring.value = str.data(); 645 1056 wstring.size = str.size(); 646 1057 } 647 1058 648 1059 // Formats an argument of a custom type, such as a user-defined class. 649 1060 template <typename T> 650 1061 static void format_custom_arg( 651 void *formatter, const void *arg, const void *format_str) {1062 void *formatter, const void *arg, void *format_str_ptr) { 652 1063 format(*static_cast<BasicFormatter<Char>*>(formatter), 653 static_cast<const Char*>(format_str), *static_cast<const T*>(arg)); 1064 *static_cast<const Char**>(format_str_ptr), 1065 *static_cast<const T*>(arg)); 654 1066 } 655 1067 656 public: 657 MakeArg() {} 658 MakeArg(bool value) { type = INT; int_value = value; } 659 MakeArg(short value) { type = INT; int_value = value; } 660 MakeArg(unsigned short value) { type = UINT; uint_value = value; } 661 MakeArg(int value) { type = INT; int_value = value; } 662 MakeArg(unsigned value) { type = UINT; uint_value = value; } 663 MakeArg(long value) { 1068 public: 1069 MakeValue() {} 1070 1071 #define FMT_MAKE_VALUE_(Type, field, TYPE, rhs) \ 1072 MakeValue(Type value) { field = rhs; } \ 1073 static uint64_t type(Type) { return Arg::TYPE; } 1074 1075 #define FMT_MAKE_VALUE(Type, field, TYPE) \ 1076 FMT_MAKE_VALUE_(Type, field, TYPE, value) 1077 1078 FMT_MAKE_VALUE(bool, int_value, BOOL) 1079 FMT_MAKE_VALUE(short, int_value, INT) 1080 FMT_MAKE_VALUE(unsigned short, uint_value, UINT) 1081 FMT_MAKE_VALUE(int, int_value, INT) 1082 FMT_MAKE_VALUE(unsigned, uint_value, UINT) 1083 1084 MakeValue(long value) { 664 1085 // To minimize the number of types we need to deal with, long is 665 1086 // translated either to int or to long long depending on its size. 666 if (sizeof(long) == sizeof(int)) { 667 type = INT; 1087 if (check(sizeof(long) == sizeof(int))) 668 1088 int_value = static_cast<int>(value); 669 } else { 670 type = LONG_LONG; 1089 else 671 1090 long_long_value = value; 672 }673 1091 } 674 MakeArg(unsigned long value) { 675 if (sizeof(unsigned long) == sizeof(unsigned)) { 676 type = UINT; 1092 static uint64_t type(long) { 1093 return sizeof(long) == sizeof(int) ? Arg::INT : Arg::LONG_LONG; 1094 } 1095 1096 MakeValue(unsigned long value) { 1097 if (check(sizeof(unsigned long) == sizeof(unsigned))) 677 1098 uint_value = static_cast<unsigned>(value); 678 } else { 679 type = ULONG_LONG; 1099 else 680 1100 ulong_long_value = value; 681 }682 1101 } 683 MakeArg(LongLong value) { type = LONG_LONG; long_long_value = value; } 684 MakeArg(ULongLong value) { type = ULONG_LONG; ulong_long_value = value; } 685 MakeArg(float value) { type = DOUBLE; double_value = value; } 686 MakeArg(double value) { type = DOUBLE; double_value = value; } 687 MakeArg(long double value) { type = LONG_DOUBLE; long_double_value = value; } 688 MakeArg(signed char value) { type = CHAR; int_value = value; } 689 MakeArg(unsigned char value) { type = CHAR; int_value = value; } 690 MakeArg(char value) { type = CHAR; int_value = value; } 691 MakeArg(wchar_t value) { 692 type = CHAR; 693 int_value = internal::CharTraits<Char>::convert(value); 694 } 695 696 MakeArg(char *value) { set_string(value); } 697 MakeArg(const char *value) { set_string(value); } 698 MakeArg(const std::string &value) { set_string(value); } 699 MakeArg(StringRef value) { set_string(value); } 700 701 MakeArg(wchar_t *value) { set_string(value); } 702 MakeArg(const wchar_t *value) { set_string(value); } 703 MakeArg(const std::wstring &value) { set_string(value); } 704 MakeArg(WStringRef value) { set_string(value); } 705 706 MakeArg(void *value) { type = POINTER; pointer_value = value; } 707 MakeArg(const void *value) { type = POINTER; pointer_value = value; } 708 709 #if 0 710 // WFG: Removed this because otherwise you can pass a CStr8 or an enum etc 711 // into fmt::sprintf, and it will be interpreted as a CUSTOM type and then 712 // will throw an exception at runtime, which is terrible behaviour. 1102 static uint64_t type(unsigned long) { 1103 return sizeof(unsigned long) == sizeof(unsigned) ? 1104 Arg::UINT : Arg::ULONG_LONG; 1105 } 1106 1107 FMT_MAKE_VALUE(LongLong, long_long_value, LONG_LONG) 1108 FMT_MAKE_VALUE(ULongLong, ulong_long_value, ULONG_LONG) 1109 FMT_MAKE_VALUE(float, double_value, DOUBLE) 1110 FMT_MAKE_VALUE(double, double_value, DOUBLE) 1111 FMT_MAKE_VALUE(long double, long_double_value, LONG_DOUBLE) 1112 FMT_MAKE_VALUE(signed char, int_value, INT) 1113 FMT_MAKE_VALUE(unsigned char, uint_value, UINT) 1114 FMT_MAKE_VALUE(char, int_value, CHAR) 1115 1116 #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) 1117 MakeValue(typename WCharHelper<wchar_t, Char>::Supported value) { 1118 int_value = value; 1119 } 1120 static uint64_t type(wchar_t) { return Arg::CHAR; } 1121 #endif 1122 1123 #define FMT_MAKE_STR_VALUE(Type, TYPE) \ 1124 MakeValue(Type value) { set_string(value); } \ 1125 static uint64_t type(Type) { return Arg::TYPE; } 1126 1127 FMT_MAKE_VALUE(char *, string.value, CSTRING) 1128 FMT_MAKE_VALUE(const char *, string.value, CSTRING) 1129 FMT_MAKE_VALUE(const signed char *, sstring.value, CSTRING) 1130 FMT_MAKE_VALUE(const unsigned char *, ustring.value, CSTRING) 1131 FMT_MAKE_STR_VALUE(const std::string &, STRING) 1132 FMT_MAKE_STR_VALUE(StringRef, STRING) 1133 FMT_MAKE_VALUE_(CStringRef, string.value, CSTRING, value.c_str()) 1134 1135 #define FMT_MAKE_WSTR_VALUE(Type, TYPE) \ 1136 MakeValue(typename WCharHelper<Type, Char>::Supported value) { \ 1137 set_string(value); \ 1138 } \ 1139 static uint64_t type(Type) { return Arg::TYPE; } 1140 1141 FMT_MAKE_WSTR_VALUE(wchar_t *, WSTRING) 1142 FMT_MAKE_WSTR_VALUE(const wchar_t *, WSTRING) 1143 FMT_MAKE_WSTR_VALUE(const std::wstring &, WSTRING) 1144 FMT_MAKE_WSTR_VALUE(WStringRef, WSTRING) 1145 1146 FMT_MAKE_VALUE(void *, pointer, POINTER) 1147 FMT_MAKE_VALUE(const void *, pointer, POINTER) 1148 713 1149 template <typename T> 714 MakeArg(const T &value) { 715 type = CUSTOM; 1150 MakeValue(const T &value, 1151 typename EnableIf<Not< 1152 ConvertToInt<T>::value>::value, int>::type = 0) { 716 1153 custom.value = &value; 717 1154 custom.format = &format_custom_arg<T>; 718 1155 } 719 #endif 1156 1157 template <typename T> 1158 MakeValue(const T &value, 1159 typename EnableIf<ConvertToInt<T>::value, int>::type = 0) { 1160 int_value = value; 1161 } 1162 1163 template <typename T> 1164 static uint64_t type(const T &) { 1165 return ConvertToInt<T>::value ? Arg::INT : Arg::CUSTOM; 1166 } 1167 1168 // Additional template param `Char_` is needed here because make_type always 1169 // uses MakeValue<char>. 1170 template <typename Char_> 1171 MakeValue(const NamedArg<Char_> &value) { pointer = &value; } 1172 1173 template <typename Char_> 1174 static uint64_t type(const NamedArg<Char_> &) { return Arg::NAMED_ARG; } 1175 }; 1176 1177 template <typename Char> 1178 struct NamedArg : Arg { 1179 BasicStringRef<Char> name; 1180 1181 template <typename T> 1182 NamedArg(BasicStringRef<Char> argname, const T &value) 1183 : Arg(MakeValue<Char>(value)), name(argname) { 1184 type = static_cast<internal::Arg::Type>(MakeValue<Char>::type(value)); 1185 } 720 1186 }; 721 1187 722 1188 #define FMT_DISPATCH(call) static_cast<Impl*>(this)->call … … public: 744 1210 template <typename Impl, typename Result> 745 1211 class ArgVisitor { 746 1212 public: 747 Result visit_unhandled_arg() { return Result(); } 1213 void report_unhandled_arg() {} 1214 1215 Result visit_unhandled_arg() { 1216 FMT_DISPATCH(report_unhandled_arg()); 1217 return Result(); 1218 } 748 1219 749 1220 Result visit_int(int value) { 750 1221 return FMT_DISPATCH(visit_any_int(value)); … … class ArgVisitor { 758 1229 Result visit_ulong_long(ULongLong value) { 759 1230 return FMT_DISPATCH(visit_any_int(value)); 760 1231 } 1232 Result visit_bool(bool value) { 1233 return FMT_DISPATCH(visit_any_int(value)); 1234 } 761 1235 Result visit_char(int value) { 762 1236 return FMT_DISPATCH(visit_any_int(value)); 763 1237 } … … class ArgVisitor { 777 1251 return FMT_DISPATCH(visit_unhandled_arg()); 778 1252 } 779 1253 1254 Result visit_cstring(const char *) { 1255 return FMT_DISPATCH(visit_unhandled_arg()); 1256 } 780 1257 Result visit_string(Arg::StringValue<char>) { 781 1258 return FMT_DISPATCH(visit_unhandled_arg()); 782 1259 } … … class ArgVisitor { 793 1270 Result visit(const Arg &arg) { 794 1271 switch (arg.type) { 795 1272 default: 796 assert(false);797 // Fall through.1273 FMT_ASSERT(false, "invalid argument type"); 1274 return Result(); 798 1275 case Arg::INT: 799 1276 return FMT_DISPATCH(visit_int(arg.int_value)); 800 1277 case Arg::UINT: … … class ArgVisitor { 803 1280 return FMT_DISPATCH(visit_long_long(arg.long_long_value)); 804 1281 case Arg::ULONG_LONG: 805 1282 return FMT_DISPATCH(visit_ulong_long(arg.ulong_long_value)); 1283 case Arg::BOOL: 1284 return FMT_DISPATCH(visit_bool(arg.int_value != 0)); 1285 case Arg::CHAR: 1286 return FMT_DISPATCH(visit_char(arg.int_value)); 806 1287 case Arg::DOUBLE: 807 1288 return FMT_DISPATCH(visit_double(arg.double_value)); 808 1289 case Arg::LONG_DOUBLE: 809 1290 return FMT_DISPATCH(visit_long_double(arg.long_double_value)); 810 case Arg::C HAR:811 return FMT_DISPATCH(visit_c har(arg.int_value));1291 case Arg::CSTRING: 1292 return FMT_DISPATCH(visit_cstring(arg.string.value)); 812 1293 case Arg::STRING: 813 1294 return FMT_DISPATCH(visit_string(arg.string)); 814 1295 case Arg::WSTRING: 815 1296 return FMT_DISPATCH(visit_wstring(arg.wstring)); 816 1297 case Arg::POINTER: 817 return FMT_DISPATCH(visit_pointer(arg.pointer _value));1298 return FMT_DISPATCH(visit_pointer(arg.pointer)); 818 1299 case Arg::CUSTOM: 819 1300 return FMT_DISPATCH(visit_custom(arg.custom)); 820 1301 } … … class RuntimeError : public std::runtime_error { 826 1307 RuntimeError() : std::runtime_error("") {} 827 1308 }; 828 1309 1310 template <typename Impl, typename Char> 1311 class BasicArgFormatter; 1312 829 1313 template <typename Char> 830 class ArgFormatter; 1314 class PrintfArgFormatter; 1315 1316 template <typename Char> 1317 class ArgMap; 831 1318 } // namespace internal 832 1319 833 /** 834 An argument list. 835 */ 1320 /** An argument list. */ 836 1321 class ArgList { 837 1322 private: 838 const internal::Arg *args_; 839 std::size_t size_; 1323 // To reduce compiled code size per formatting function call, types of first 1324 // MAX_PACKED_ARGS arguments are passed in the types_ field. 1325 uint64_t types_; 1326 union { 1327 // If the number of arguments is less than MAX_PACKED_ARGS, the argument 1328 // values are stored in values_, otherwise they are stored in args_. 1329 // This is done to reduce compiled code size as storing larger objects 1330 // may require more code (at least on x86-64) even if the same amount of 1331 // data is actually copied to stack. It saves ~10% on the bloat test. 1332 const internal::Value *values_; 1333 const internal::Arg *args_; 1334 }; 840 1335 841 public: 842 ArgList() : size_(0) {} 843 ArgList(const internal::Arg *args, std::size_t size) 844 : args_(args), size_(size) {} 1336 internal::Arg::Type type(unsigned index) const { 1337 unsigned shift = index * 4; 1338 uint64_t mask = 0xf; 1339 return static_cast<internal::Arg::Type>( 1340 (types_ & (mask << shift)) >> shift); 1341 } 845 1342 846 /** 847 Returns the list size (the number of arguments). 848 */ 849 std::size_t size() const { return size_; } 1343 template <typename Char> 1344 friend class internal::ArgMap; 850 1345 851 /** 852 Returns the argument at specified index. 853 */ 854 const internal::Arg &operator[](std::size_t index) const { 1346 public: 1347 // Maximum number of arguments with packed types. 1348 enum { MAX_PACKED_ARGS = 16 }; 1349 1350 ArgList() : types_(0) {} 1351 1352 ArgList(ULongLong types, const internal::Value *values) 1353 : types_(types), values_(values) {} 1354 ArgList(ULongLong types, const internal::Arg *args) 1355 : types_(types), args_(args) {} 1356 1357 /** Returns the argument at specified index. */ 1358 internal::Arg operator[](unsigned index) const { 1359 using internal::Arg; 1360 Arg arg; 1361 bool use_values = type(MAX_PACKED_ARGS - 1) == Arg::NONE; 1362 if (index < MAX_PACKED_ARGS) { 1363 Arg::Type arg_type = type(index); 1364 internal::Value &val = arg; 1365 if (arg_type != Arg::NONE) 1366 val = use_values ? values_[index] : args_[index]; 1367 arg.type = arg_type; 1368 return arg; 1369 } 1370 if (use_values) { 1371 // The index is greater than the number of arguments that can be stored 1372 // in values, so return a "none" argument. 1373 arg.type = Arg::NONE; 1374 return arg; 1375 } 1376 for (unsigned i = MAX_PACKED_ARGS; i <= index; ++i) { 1377 if (args_[i].type == Arg::NONE) 1378 return args_[i]; 1379 } 855 1380 return args_[index]; 856 1381 } 857 1382 }; … … struct FormatSpec; 860 1385 861 1386 namespace internal { 862 1387 1388 template <typename Char> 1389 class ArgMap { 1390 private: 1391 typedef std::map<fmt::BasicStringRef<Char>, internal::Arg> MapType; 1392 typedef typename MapType::value_type Pair; 1393 1394 MapType map_; 1395 1396 public: 1397 void init(const ArgList &args); 1398 1399 const internal::Arg* find(const fmt::BasicStringRef<Char> &name) const { 1400 typename MapType::const_iterator it = map_.find(name); 1401 return it != map_.end() ? &it->second : 0; 1402 } 1403 }; 1404 863 1405 class FormatterBase { 864 protected:1406 private: 865 1407 ArgList args_; 866 1408 int next_arg_index_; 867 const char *error_;868 1409 869 FormatterBase() : error_(0) {} 1410 // Returns the argument with specified index. 1411 Arg do_get_arg(unsigned arg_index, const char *&error); 870 1412 871 const Arg &next_arg(); 1413 protected: 1414 const ArgList &args() const { return args_; } 1415 1416 explicit FormatterBase(const ArgList &args) { 1417 args_ = args; 1418 next_arg_index_ = 0; 1419 } 872 1420 873 const Arg &handle_arg_index(unsigned arg_index); 1421 // Returns the next argument. 1422 Arg next_arg(const char *&error); 1423 1424 // Checks if manual indexing is used and returns the argument with 1425 // specified index. 1426 Arg get_arg(unsigned arg_index, const char *&error); 1427 1428 bool check_no_auto_index(const char *&error); 874 1429 875 1430 template <typename Char> 876 1431 void write(BasicWriter<Char> &w, const Char *start, const Char *end) { 877 1432 if (start != end) 878 1433 w << BasicStringRef<Char>(start, end - start); 879 1434 } 880 881 // TODO882 1435 }; 883 1436 884 1437 // A printf formatter. … … class PrintfFormatter : private FormatterBase { 887 1440 private: 888 1441 void parse_flags(FormatSpec &spec, const Char *&s); 889 1442 890 // Parses argument index, flags and width and returns the parsed 891 // argument index. 1443 // Returns the argument with specified index or, if arg_index is equal 1444 // to the maximum unsigned value, the next argument. 1445 Arg get_arg(const Char *s, 1446 unsigned arg_index = (std::numeric_limits<unsigned>::max)()); 1447 1448 // Parses argument index, flags and width and returns the argument index. 892 1449 unsigned parse_header(const Char *&s, FormatSpec &spec); 893 1450 894 1451 public: 895 void format(BasicWriter<Char> &writer,896 BasicStringRef<Char> format, const ArgList &args);1452 explicit PrintfFormatter(const ArgList &args) : FormatterBase(args) {} 1453 void format(BasicWriter<Char> &writer, BasicCStringRef<Char> format_str); 897 1454 }; 898 1455 } // namespace internal 899 1456 900 1457 // A formatter. 901 1458 template <typename Char> 902 1459 class BasicFormatter : private internal::FormatterBase { 903 private:1460 private: 904 1461 BasicWriter<Char> &writer_; 905 const Char *start_; 906 internal::FormatErrorReporter<Char> report_error_; 1462 internal::ArgMap<Char> map_; 1463 1464 FMT_DISALLOW_COPY_AND_ASSIGN(BasicFormatter); 1465 1466 using internal::FormatterBase::get_arg; 1467 1468 // Checks if manual indexing is used and returns the argument with 1469 // specified name. 1470 internal::Arg get_arg(BasicStringRef<Char> arg_name, const char *&error); 907 1471 908 // Parses argument index and returns an argument with this index.909 const internal::Arg &parse_arg_index(const Char *&s);1472 // Parses argument index and returns corresponding argument. 1473 internal::Arg parse_arg_index(const Char *&s); 910 1474 911 void check_sign(const Char *&s, const internal::Arg &arg); 1475 // Parses argument name and returns corresponding argument. 1476 internal::Arg parse_arg_name(const Char *&s); 912 1477 913 public: 914 explicit BasicFormatter(BasicWriter<Char> &w) : writer_(w) {} 1478 public: 1479 BasicFormatter(const ArgList &args, BasicWriter<Char> &w) 1480 : internal::FormatterBase(args), writer_(w) {} 915 1481 916 1482 BasicWriter<Char> &writer() { return writer_; } 917 1483 918 void format(Basic StringRef<Char> format_str, const ArgList &args);1484 void format(BasicCStringRef<Char> format_str); 919 1485 920 const Char *format(const Char * format_str, const internal::Arg &arg);1486 const Char *format(const Char *&format_str, const internal::Arg &arg); 921 1487 }; 922 1488 923 1489 enum Alignment { … … class IntFormatSpec : public SpecT { 1000 1566 T value_; 1001 1567 1002 1568 public: 1003 IntFormatSpec(T val ue, const SpecT &spec = SpecT())1004 : SpecT(spec), value_(val ue) {}1569 IntFormatSpec(T val, const SpecT &spec = SpecT()) 1570 : SpecT(spec), value_(val) {} 1005 1571 1006 1572 T value() const { return value_; } 1007 1573 }; 1008 1574 1009 1575 // A string format specifier. 1010 template <typename T>1576 template <typename Char> 1011 1577 class StrFormatSpec : public AlignSpec { 1012 1578 private: 1013 const T*str_;1579 const Char *str_; 1014 1580 1015 1581 public: 1016 StrFormatSpec(const T *str, unsigned width, wchar_t fill) 1017 : AlignSpec(width, fill), str_(str) {} 1582 template <typename FillChar> 1583 StrFormatSpec(const Char *str, unsigned width, FillChar fill) 1584 : AlignSpec(width, fill), str_(str) { 1585 internal::CharTraits<Char>::convert(FillChar()); 1586 } 1018 1587 1019 const T*str() const { return str_; }1588 const Char *str() const { return str_; } 1020 1589 }; 1021 1590 1022 1591 /** … … IntFormatSpec<int, TypeSpec<'X'> > hexu(int value); 1049 1618 1050 1619 **Example**:: 1051 1620 1052 Writer out;1621 MemoryWriter out; 1053 1622 out << pad(hex(0xcafe), 8, '0'); 1054 1623 // out.str() == "0000cafe" 1055 1624 … … FMT_DEFINE_INT_FORMATTERS(ULongLong) 1122 1691 1123 1692 **Example**:: 1124 1693 1125 std::string s = str( Writer() << pad("abc", 8));1694 std::string s = str(MemoryWriter() << pad("abc", 8)); 1126 1695 // s == "abc " 1127 1696 1128 1697 \endrst … … inline StrFormatSpec<wchar_t> pad( 1138 1707 return StrFormatSpec<wchar_t>(str, width, fill); 1139 1708 } 1140 1709 1141 // Generates a comma-separated list with results of applying f to numbers 0..n-1. 1710 // Generates a comma-separated list with results of applying f to 1711 // numbers 0..n-1. 1142 1712 # define FMT_GEN(n, f) FMT_GEN##n(f) 1143 1713 # define FMT_GEN1(f) f(0) 1144 # define FMT_GEN2(f) FMT_GEN1(f), f(1) 1145 # define FMT_GEN3(f) FMT_GEN2(f), f(2) 1146 # define FMT_GEN4(f) FMT_GEN3(f), f(3) 1147 # define FMT_GEN5(f) FMT_GEN4(f), f(4) 1148 # define FMT_GEN6(f) FMT_GEN5(f), f(5) 1149 # define FMT_GEN7(f) FMT_GEN6(f), f(6) 1150 # define FMT_GEN8(f) FMT_GEN7(f), f(7) 1151 # define FMT_GEN9(f) FMT_GEN8(f), f(8) 1152 # define FMT_GEN10(f) FMT_GEN9(f), f(9) 1714 # define FMT_GEN2(f) FMT_GEN1(f), f(1) 1715 # define FMT_GEN3(f) FMT_GEN2(f), f(2) 1716 # define FMT_GEN4(f) FMT_GEN3(f), f(3) 1717 # define FMT_GEN5(f) FMT_GEN4(f), f(4) 1718 # define FMT_GEN6(f) FMT_GEN5(f), f(5) 1719 # define FMT_GEN7(f) FMT_GEN6(f), f(6) 1720 # define FMT_GEN8(f) FMT_GEN7(f), f(7) 1721 # define FMT_GEN9(f) FMT_GEN8(f), f(8) 1722 # define FMT_GEN10(f) FMT_GEN9(f), f(9) 1723 # define FMT_GEN11(f) FMT_GEN10(f), f(10) 1724 # define FMT_GEN12(f) FMT_GEN11(f), f(11) 1725 # define FMT_GEN13(f) FMT_GEN12(f), f(12) 1726 # define FMT_GEN14(f) FMT_GEN13(f), f(13) 1727 # define FMT_GEN15(f) FMT_GEN14(f), f(14) 1728 1729 namespace internal { 1730 inline uint64_t make_type() { return 0; } 1731 1732 template <typename T> 1733 inline uint64_t make_type(const T &arg) { return MakeValue<char>::type(arg); } 1734 1735 template <unsigned N> 1736 struct ArgArray { 1737 // Computes the argument array size by adding 1 to N, which is the number of 1738 // arguments, if N is zero, because array of zero size is invalid, or if N 1739 // is greater than ArgList::MAX_PACKED_ARGS to accommodate for an extra 1740 // argument that marks the end of the list. 1741 enum { SIZE = N + (N == 0 || N >= ArgList::MAX_PACKED_ARGS ? 1 : 0) }; 1742 1743 typedef typename Conditional< 1744 (N < ArgList::MAX_PACKED_ARGS), Value, Arg>::type Type[SIZE]; 1745 }; 1746 1747 #if FMT_USE_VARIADIC_TEMPLATES 1748 template <typename Arg, typename... Args> 1749 inline uint64_t make_type(const Arg &first, const Args & ... tail) { 1750 return make_type(first) | (make_type(tail...) << 4); 1751 } 1752 1753 inline void do_set_types(Arg *) {} 1754 1755 template <typename T, typename... Args> 1756 inline void do_set_types(Arg *args, const T &arg, const Args & ... tail) { 1757 args->type = static_cast<Arg::Type>(MakeValue<T>::type(arg)); 1758 do_set_types(args + 1, tail...); 1759 } 1760 1761 template <typename... Args> 1762 inline void set_types(Arg *array, const Args & ... args) { 1763 if (check(sizeof...(Args) > ArgList::MAX_PACKED_ARGS)) 1764 do_set_types(array, args...); 1765 array[sizeof...(Args)].type = Arg::NONE; 1766 } 1767 1768 template <typename... Args> 1769 inline void set_types(Value *, const Args & ...) { 1770 // Do nothing as types are passed separately from values. 1771 } 1772 1773 template <typename Char, typename Value> 1774 inline void store_args(Value *) {} 1775 1776 template <typename Char, typename Arg, typename T, typename... Args> 1777 inline void store_args(Arg *args, const T &arg, const Args & ... tail) { 1778 // Assign only the Value subobject of Arg and don't overwrite type (if any) 1779 // that is assigned by set_types. 1780 Value &value = *args; 1781 value = MakeValue<Char>(arg); 1782 store_args<Char>(args + 1, tail...); 1783 } 1784 1785 template <typename Char, typename... Args> 1786 ArgList make_arg_list(typename ArgArray<sizeof...(Args)>::Type array, 1787 const Args & ... args) { 1788 if (check(sizeof...(Args) >= ArgList::MAX_PACKED_ARGS)) 1789 set_types(array, args...); 1790 store_args<Char>(array, args...); 1791 return ArgList(make_type(args...), array); 1792 } 1793 #else 1794 1795 struct ArgType { 1796 uint64_t type; 1797 1798 ArgType() : type(0) {} 1799 1800 template <typename T> 1801 ArgType(const T &arg) : type(make_type(arg)) {} 1802 }; 1803 1804 # define FMT_ARG_TYPE_DEFAULT(n) ArgType t##n = ArgType() 1805 1806 inline uint64_t make_type(FMT_GEN15(FMT_ARG_TYPE_DEFAULT)) { 1807 return t0.type | (t1.type << 4) | (t2.type << 8) | (t3.type << 12) | 1808 (t4.type << 16) | (t5.type << 20) | (t6.type << 24) | (t7.type << 28) | 1809 (t8.type << 32) | (t9.type << 36) | (t10.type << 40) | (t11.type << 44) | 1810 (t12.type << 48) | (t13.type << 52) | (t14.type << 56); 1811 } 1812 #endif 1813 1814 template <class Char> 1815 class FormatBuf : public std::basic_streambuf<Char> { 1816 private: 1817 typedef typename std::basic_streambuf<Char>::int_type int_type; 1818 typedef typename std::basic_streambuf<Char>::traits_type traits_type; 1819 1820 Buffer<Char> &buffer_; 1821 Char *start_; 1822 1823 public: 1824 FormatBuf(Buffer<Char> &buffer) : buffer_(buffer), start_(&buffer[0]) { 1825 this->setp(start_, start_ + buffer_.capacity()); 1826 } 1827 1828 int_type overflow(int_type ch = traits_type::eof()) { 1829 if (!traits_type::eq_int_type(ch, traits_type::eof())) { 1830 size_t size = this->pptr() - start_; 1831 buffer_.resize(size); 1832 buffer_.reserve(size * 2); 1833 1834 start_ = &buffer_[0]; 1835 start_[size] = traits_type::to_char_type(ch); 1836 this->setp(start_+ size + 1, start_ + size * 2); 1837 } 1838 return ch; 1839 } 1840 1841 size_t size() const { 1842 return this->pptr() - start_; 1843 } 1844 }; 1845 } // namespace internal 1153 1846 1154 1847 # define FMT_MAKE_TEMPLATE_ARG(n) typename T##n 1848 # define FMT_MAKE_ARG_TYPE(n) T##n 1155 1849 # define FMT_MAKE_ARG(n) const T##n &v##n 1156 # define FMT_ MAKE_REF_char(n) fmt::internal::MakeArg<char>(v##n)1157 # define FMT_ MAKE_REF_wchar_t(n) fmt::internal::MakeArg<wchar_t>(v##n)1850 # define FMT_ASSIGN_char(n) arr[n] = fmt::internal::MakeValue<char>(v##n) 1851 # define FMT_ASSIGN_wchar_t(n) arr[n] = fmt::internal::MakeValue<wchar_t>(v##n) 1158 1852 1159 1853 #if FMT_USE_VARIADIC_TEMPLATES 1160 1854 // Defines a variadic function returning void. 1161 1855 # define FMT_VARIADIC_VOID(func, arg_type) \ 1162 template<typename... Args> \ 1163 void func(arg_type arg1, const Args & ... args) { \ 1164 using fmt::internal::Arg; \ 1165 const Arg arg_array[fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \ 1166 fmt::internal::MakeArg<Char>(args)... \ 1167 }; \ 1168 func(arg1, ArgList(arg_array, sizeof...(Args))); \ 1856 template <typename... Args> \ 1857 void func(arg_type arg0, const Args & ... args) { \ 1858 typename fmt::internal::ArgArray<sizeof...(Args)>::Type array; \ 1859 func(arg0, fmt::internal::make_arg_list<Char>(array, args...)); \ 1169 1860 } 1170 1861 1171 1862 // Defines a variadic constructor. 1172 1863 # define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \ 1173 template <typename... Args> \1864 template <typename... Args> \ 1174 1865 ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) { \ 1175 using fmt::internal::Arg; \ 1176 const Arg arg_array[fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \ 1177 fmt::internal::MakeArg<Char>(args)... \ 1178 }; \ 1179 func(arg0, arg1, ArgList(arg_array, sizeof...(Args))); \ 1866 typename fmt::internal::ArgArray<sizeof...(Args)>::Type array; \ 1867 func(arg0, arg1, fmt::internal::make_arg_list<Char>(array, args...)); \ 1180 1868 } 1181 1869 1182 1870 #else 1183 1871 1184 # define FMT_MAKE_REF(n) fmt::internal::MakeArg<Char>(v##n) 1872 # define FMT_MAKE_REF(n) fmt::internal::MakeValue<Char>(v##n) 1873 # define FMT_MAKE_REF2(n) v##n 1874 1185 1875 // Defines a wrapper for a function taking one argument of type arg_type 1186 1876 // and n additional arguments of arbitrary types. 1187 1877 # define FMT_WRAP1(func, arg_type, n) \ 1188 1878 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \ 1189 1879 inline void func(arg_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \ 1190 const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF)}; \ 1191 func(arg1, fmt::ArgList(args, sizeof(args) / sizeof(*args))); \ 1880 const fmt::internal::ArgArray<n>::Type array = {FMT_GEN(n, FMT_MAKE_REF)}; \ 1881 func(arg1, fmt::ArgList( \ 1882 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), array)); \ 1192 1883 } 1193 1884 1194 1885 // Emulates a variadic function returning void on a pre-C++11 compiler. 1195 1886 # define FMT_VARIADIC_VOID(func, arg_type) \ 1887 inline void func(arg_type arg) { func(arg, fmt::ArgList()); } \ 1196 1888 FMT_WRAP1(func, arg_type, 1) FMT_WRAP1(func, arg_type, 2) \ 1197 1889 FMT_WRAP1(func, arg_type, 3) FMT_WRAP1(func, arg_type, 4) \ 1198 1890 FMT_WRAP1(func, arg_type, 5) FMT_WRAP1(func, arg_type, 6) \ … … inline StrFormatSpec<wchar_t> pad( 1202 1894 # define FMT_CTOR(ctor, func, arg0_type, arg1_type, n) \ 1203 1895 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \ 1204 1896 ctor(arg0_type arg0, arg1_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \ 1205 const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF)}; \ 1206 func(arg0, arg1, fmt::ArgList(args, sizeof(args) / sizeof(*args))); \ 1897 const fmt::internal::ArgArray<n>::Type array = {FMT_GEN(n, FMT_MAKE_REF)}; \ 1898 func(arg0, arg1, fmt::ArgList( \ 1899 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), array)); \ 1207 1900 } 1208 1901 1209 1902 // Emulates a variadic constructor on a pre-C++11 compiler. … … inline StrFormatSpec<wchar_t> pad( 1243 1936 FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8), f(x9, 9) 1244 1937 1245 1938 /** 1246 An error returned by an operating system or a language runtime,1247 for example a file opening error.1939 An error returned by an operating system or a language runtime, 1940 for example a file opening error. 1248 1941 */ 1249 1942 class SystemError : public internal::RuntimeError { 1250 1943 private: 1251 void init(int err or_code, StringRef format_str, const ArgList &args);1944 void init(int err_code, CStringRef format_str, ArgList args); 1252 1945 1253 1946 protected: 1254 1947 int error_code_; … … class SystemError : public internal::RuntimeError { 1260 1953 public: 1261 1954 /** 1262 1955 \rst 1263 Constructs a :cpp:class:`fmt::SystemError` object with the description 1264 of the form "*<message>*: *<system-message>*", where *<message>* is the 1265 formatted message and *<system-message>* is the system message corresponding 1266 to the error code. 1956 Constructs a :class:`fmt::SystemError` object with the description 1957 of the form 1958 1959 .. parsed-literal:: 1960 *<message>*: *<system-message>* 1961 1962 where *<message>* is the formatted message and *<system-message>* is 1963 the system message corresponding to the error code. 1267 1964 *error_code* is a system error code as given by ``errno``. 1965 If *error_code* is not a valid error code such as -1, the system message 1966 may look like "Unknown error -1" and is platform-dependent. 1967 1968 **Example**:: 1969 1970 // This throws a SystemError with the description 1971 // cannot open file 'madeup': No such file or directory 1972 // or similar (system message may vary). 1973 const char *filename = "madeup"; 1974 std::FILE *file = std::fopen(filename, "r"); 1975 if (!file) 1976 throw fmt::SystemError(errno, "cannot open file '{}'", filename); 1268 1977 \endrst 1269 1978 */ 1270 SystemError(int error_code, StringRef message) {1979 SystemError(int error_code, CStringRef message) { 1271 1980 init(error_code, message, ArgList()); 1272 1981 } 1273 FMT_VARIADIC_CTOR(SystemError, init, int, StringRef)1982 FMT_VARIADIC_CTOR(SystemError, init, int, CStringRef) 1274 1983 1275 1984 int error_code() const { return error_code_; } 1276 1985 }; … … class SystemError : public internal::RuntimeError { 1278 1987 /** 1279 1988 \rst 1280 1989 This template provides operations for formatting and writing data into 1281 a character stream. The output is stored in a memory buffer that grows1282 dynamically.1990 a character stream. The output is stored in a buffer provided by a subclass 1991 such as :class:`fmt::BasicMemoryWriter`. 1283 1992 1284 1993 You can use one of the following typedefs for common character types: 1285 1994 … … class SystemError : public internal::RuntimeError { 1291 2000 | WWriter | BasicWriter<wchar_t> | 1292 2001 +---------+----------------------+ 1293 2002 1294 **Example**::1295 1296 Writer out;1297 out << "The answer is " << 42 << "\n";1298 out.write("({:+f}, {:+f})", -3.14, 3.14);1299 1300 This will write the following output to the ``out`` object:1301 1302 .. code-block:: none1303 1304 The answer is 421305 (-3.140000, +3.140000)1306 1307 The output can be converted to an ``std::string`` with ``out.str()`` or1308 accessed as a C string with ``out.c_str()``.1309 2003 \endrst 1310 2004 */ 1311 2005 template <typename Char> 1312 2006 class BasicWriter { 1313 2007 private: 1314 2008 // Output buffer. 1315 mutable internal::Array<Char, internal::INLINE_BUFFER_SIZE> buffer_; 2009 Buffer<Char> &buffer_; 2010 2011 FMT_DISALLOW_COPY_AND_ASSIGN(BasicWriter); 1316 2012 1317 2013 typedef typename internal::CharTraits<Char>::CharPtr CharPtr; 1318 2014 1319 #if defined(_SECURE_SCL) &&_SECURE_SCL2015 #if FMT_SECURE_SCL 1320 2016 // Returns pointer value. 1321 2017 static Char *get(CharPtr p) { return p.base(); } 1322 2018 #else 1323 2019 static Char *get(Char *p) { return p; } 1324 2020 #endif 1325 2021 2022 // Fills the padding around the content and returns the pointer to the 2023 // content area. 1326 2024 static CharPtr fill_padding(CharPtr buffer, 1327 2025 unsigned total_size, std::size_t content_size, wchar_t fill); 1328 2026 … … class BasicWriter { 1334 2032 return internal::make_ptr(&buffer_[size], n); 1335 2033 } 1336 2034 2035 // Writes an unsigned decimal integer. 2036 template <typename UInt> 2037 Char *write_unsigned_decimal(UInt value, unsigned prefix_size = 0) { 2038 unsigned num_digits = internal::count_digits(value); 2039 Char *ptr = get(grow_buffer(prefix_size + num_digits)); 2040 internal::format_decimal(ptr + prefix_size, value, num_digits); 2041 return ptr; 2042 } 2043 2044 // Writes a decimal integer. 2045 template <typename Int> 2046 void write_decimal(Int value) { 2047 typename internal::IntTraits<Int>::MainType abs_value = value; 2048 if (internal::is_negative(value)) { 2049 abs_value = 0 - abs_value; 2050 *write_unsigned_decimal(abs_value, 1) = '-'; 2051 } else { 2052 write_unsigned_decimal(abs_value, 0); 2053 } 2054 } 2055 1337 2056 // Prepare a buffer for integer formatting. 1338 2057 CharPtr prepare_int_buffer(unsigned num_digits, 1339 2058 const EmptySpec &, const char *prefix, unsigned prefix_size) { … … class BasicWriter { 1349 2068 1350 2069 // Formats an integer. 1351 2070 template <typename T, typename Spec> 1352 void write_int(T value, const Spec &spec);2071 void write_int(T value, Spec spec); 1353 2072 1354 2073 // Formats a floating-point number (double or long double). 1355 2074 template <typename T> … … class BasicWriter { 1364 2083 void write_str( 1365 2084 const internal::Arg::StringValue<StrChar> &str, const FormatSpec &spec); 1366 2085 1367 // This method is private to disallow writing a wide string to a1368 // char stream and vice versa. If you want to print a wide string1369 // as apointer as std::ostream does, cast it to const void*.2086 // This following methods are private to disallow writing wide characters 2087 // and strings to a char stream. If you want to print a wide string as a 2088 // pointer as std::ostream does, cast it to const void*. 1370 2089 // Do not implement! 1371 void operator<<(typename internal::CharTraits<Char>::UnsupportedStrType); 2090 void operator<<(typename internal::WCharHelper<wchar_t, Char>::Unsupported); 2091 void operator<<( 2092 typename internal::WCharHelper<const wchar_t *, Char>::Unsupported); 1372 2093 1373 friend class internal::ArgFormatter<Char>; 1374 friend class internal::PrintfFormatter<Char>; 2094 // Appends floating-point length specifier to the format string. 2095 // The second argument is only used for overload resolution. 2096 void append_float_length(Char *&format_ptr, long double) { 2097 *format_ptr++ = 'L'; 2098 } 1375 2099 1376 public: 1377 /** 1378 Constructs a ``BasicWriter`` object. 1379 */ 1380 BasicWriter() {} 2100 template<typename T> 2101 void append_float_length(Char *&, T) {} 1381 2102 1382 #if FMT_USE_RVALUE_REFERENCES 2103 template <typename Impl, typename Char_> 2104 friend class internal::BasicArgFormatter; 2105 2106 friend class internal::PrintfArgFormatter<Char>; 2107 2108 protected: 1383 2109 /** 1384 Constructs a ``BasicWriter`` object moving the content of the other 1385 object to it. 2110 Constructs a ``BasicWriter`` object. 1386 2111 */ 1387 BasicWriter(BasicWriter &&other) : buffer_(std::move(other.buffer_)) {}2112 explicit BasicWriter(Buffer<Char> &b) : buffer_(b) {} 1388 2113 2114 public: 1389 2115 /** 1390 Moves the content of the other ``BasicWriter`` object to this one. 2116 \rst 2117 Destroys a ``BasicWriter`` object. 2118 \endrst 1391 2119 */ 1392 BasicWriter& operator=(BasicWriter &&other) { 1393 assert(this != &other); 1394 buffer_ = std::move(other.buffer_); 1395 return *this; 1396 } 1397 #endif 2120 virtual ~BasicWriter() {} 1398 2121 1399 2122 /** 1400 2123 Returns the total number of characters written. … … class BasicWriter { 1405 2128 Returns a pointer to the output buffer content. No terminating null 1406 2129 character is appended. 1407 2130 */ 1408 const Char *data() const { return &buffer_[0]; }2131 const Char *data() const FMT_NOEXCEPT { return &buffer_[0]; } 1409 2132 1410 2133 /** 1411 2134 Returns a pointer to the output buffer content with terminating null … … class BasicWriter { 1419 2142 } 1420 2143 1421 2144 /** 2145 \rst 1422 2146 Returns the content of the output buffer as an `std::string`. 2147 \endrst 1423 2148 */ 1424 2149 std::basic_string<Char> str() const { 1425 2150 return std::basic_string<Char>(&buffer_[0], buffer_.size()); … … class BasicWriter { 1428 2153 /** 1429 2154 \rst 1430 2155 Writes formatted data. 1431 2156 1432 2157 *args* is an argument list representing arbitrary arguments. 1433 2158 1434 2159 **Example**:: 1435 2160 1436 Writer out;2161 MemoryWriter out; 1437 2162 out.write("Current point:\n"); 1438 2163 out.write("({:+f}, {:+f})", -3.14, 3.14); 1439 2164 … … class BasicWriter { 1444 2169 Current point: 1445 2170 (-3.140000, +3.140000) 1446 2171 1447 The output can be accessed using : meth:`data`, :meth:`c_str` or :meth:`str`1448 methods.2172 The output can be accessed using :func:`data()`, :func:`c_str` or 2173 :func:`str` methods. 1449 2174 1450 See also `Format String Syntax`_.2175 See also :ref:`syntax`. 1451 2176 \endrst 1452 2177 */ 1453 void write(Basic StringRef<Char> format, const ArgList &args) {1454 BasicFormatter<Char>( *this).format(format, args);2178 void write(BasicCStringRef<Char> format, ArgList args) { 2179 BasicFormatter<Char>(args, *this).format(format); 1455 2180 } 1456 FMT_VARIADIC_VOID(write, fmt::BasicStringRef<Char>)2181 FMT_VARIADIC_VOID(write, BasicCStringRef<Char>) 1457 2182 1458 2183 BasicWriter &operator<<(int value) { 1459 return *this << IntFormatSpec<int>(value); 2184 write_decimal(value); 2185 return *this; 1460 2186 } 1461 2187 BasicWriter &operator<<(unsigned value) { 1462 2188 return *this << IntFormatSpec<unsigned>(value); 1463 2189 } 1464 2190 BasicWriter &operator<<(long value) { 1465 return *this << IntFormatSpec<long>(value); 2191 write_decimal(value); 2192 return *this; 1466 2193 } 1467 2194 BasicWriter &operator<<(unsigned long value) { 1468 2195 return *this << IntFormatSpec<unsigned long>(value); 1469 2196 } 1470 2197 BasicWriter &operator<<(LongLong value) { 1471 return *this << IntFormatSpec<LongLong>(value); 2198 write_decimal(value); 2199 return *this; 1472 2200 } 1473 2201 1474 2202 /** 2203 \rst 1475 2204 Formats *value* and writes it to the stream. 2205 \endrst 1476 2206 */ 1477 2207 BasicWriter &operator<<(ULongLong value) { 1478 2208 return *this << IntFormatSpec<ULongLong>(value); … … class BasicWriter { 1484 2214 } 1485 2215 1486 2216 /** 2217 \rst 1487 2218 Formats *value* using the general format for floating-point numbers 1488 2219 (``'g'``) and writes it to the stream. 2220 \endrst 1489 2221 */ 1490 2222 BasicWriter &operator<<(long double value) { 1491 2223 write_double(value, FormatSpec()); … … class BasicWriter { 1500 2232 return *this; 1501 2233 } 1502 2234 1503 BasicWriter &operator<<(wchar_t value) { 1504 buffer_.push_back(internal::CharTraits<Char>::convert(value)); 2235 BasicWriter &operator<<( 2236 typename internal::WCharHelper<wchar_t, Char>::Supported value) { 2237 buffer_.push_back(value); 1505 2238 return *this; 1506 2239 } 1507 2240 1508 2241 /** 2242 \rst 1509 2243 Writes *value* to the stream. 2244 \endrst 1510 2245 */ 1511 2246 BasicWriter &operator<<(fmt::BasicStringRef<Char> value) { 1512 const Char *str = value.c_str(); 2247 const Char *str = value.data(); 2248 buffer_.append(str, str + value.size()); 2249 return *this; 2250 } 2251 2252 BasicWriter &operator<<( 2253 typename internal::WCharHelper<StringRef, Char>::Supported value) { 2254 const char *str = value.data(); 1513 2255 buffer_.append(str, str + value.size()); 1514 2256 return *this; 1515 2257 } 1516 2258 1517 2259 template <typename T, typename Spec, typename FillChar> 1518 BasicWriter &operator<<( const IntFormatSpec<T, Spec, FillChar> &spec) {2260 BasicWriter &operator<<(IntFormatSpec<T, Spec, FillChar> spec) { 1519 2261 internal::CharTraits<Char>::convert(FillChar()); 1520 2262 write_int(spec.value(), spec); 1521 2263 return *this; … … class BasicWriter { 1524 2266 template <typename StrChar> 1525 2267 BasicWriter &operator<<(const StrFormatSpec<StrChar> &spec) { 1526 2268 const StrChar *s = spec.str(); 1527 // TODO: error if fill is not convertible to Char1528 2269 write_str(s, std::char_traits<Char>::length(s), spec); 1529 2270 return *this; 1530 2271 } 1531 2272 1532 void clear() { buffer_.clear(); }2273 void clear() FMT_NOEXCEPT { buffer_.clear(); } 1533 2274 }; 1534 2275 1535 2276 template <typename Char> 1536 2277 template <typename StrChar> 1537 2278 typename BasicWriter<Char>::CharPtr BasicWriter<Char>::write_str( 1538 const StrChar *s, std::size_t size, const AlignSpec &spec) {2279 const StrChar *s, std::size_t size, const AlignSpec &spec) { 1539 2280 CharPtr out = CharPtr(); 1540 2281 if (spec.width() > size) { 1541 2282 out = grow_buffer(spec.width()); 1542 Char fill = static_cast<Char>(spec.fill());2283 Char fill = internal::CharTraits<Char>::cast(spec.fill()); 1543 2284 if (spec.align() == ALIGN_RIGHT) { 1544 2285 std::fill_n(out, spec.width() - size, fill); 1545 2286 out += spec.width() - size; … … typename BasicWriter<Char>::CharPtr BasicWriter<Char>::write_str( 1556 2297 } 1557 2298 1558 2299 template <typename Char> 2300 typename BasicWriter<Char>::CharPtr 2301 BasicWriter<Char>::fill_padding( 2302 CharPtr buffer, unsigned total_size, 2303 std::size_t content_size, wchar_t fill) { 2304 std::size_t padding = total_size - content_size; 2305 std::size_t left_padding = padding / 2; 2306 Char fill_char = internal::CharTraits<Char>::cast(fill); 2307 std::fill_n(buffer, left_padding, fill_char); 2308 buffer += left_padding; 2309 CharPtr content = buffer; 2310 std::fill_n(buffer + content_size, padding - left_padding, fill_char); 2311 return content; 2312 } 2313 2314 template <typename Char> 1559 2315 template <typename Spec> 1560 typename fmt::BasicWriter<Char>::CharPtr1561 fmt::BasicWriter<Char>::prepare_int_buffer(2316 typename BasicWriter<Char>::CharPtr 2317 BasicWriter<Char>::prepare_int_buffer( 1562 2318 unsigned num_digits, const Spec &spec, 1563 2319 const char *prefix, unsigned prefix_size) { 1564 2320 unsigned width = spec.width(); 1565 2321 Alignment align = spec.align(); 1566 Char fill = static_cast<Char>(spec.fill());2322 Char fill = internal::CharTraits<Char>::cast(spec.fill()); 1567 2323 if (spec.precision() > static_cast<int>(num_digits)) { 1568 2324 // Octal prefix '0' is counted as a digit, so ignore it if precision 1569 2325 // is specified. … … typename fmt::BasicWriter<Char>::CharPtr 1620 2376 1621 2377 template <typename Char> 1622 2378 template <typename T, typename Spec> 1623 void BasicWriter<Char>::write_int(T value, const Spec &spec) {2379 void BasicWriter<Char>::write_int(T value, Spec spec) { 1624 2380 unsigned prefix_size = 0; 1625 2381 typedef typename internal::IntTraits<T>::MainType UnsignedType; 1626 2382 UnsignedType abs_value = value; … … void BasicWriter<Char>::write_int(T value, const Spec &spec) { 1674 2430 Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size)); 1675 2431 n = abs_value; 1676 2432 do { 1677 *p-- = '0' + (n & 1);2433 *p-- = static_cast<Char>('0' + (n & 1)); 1678 2434 } while ((n >>= 1) != 0); 1679 2435 break; 1680 2436 } … … void BasicWriter<Char>::write_int(T value, const Spec &spec) { 1689 2445 Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size)); 1690 2446 n = abs_value; 1691 2447 do { 1692 *p-- = '0' + (n & 7);2448 *p-- = static_cast<Char>('0' + (n & 7)); 1693 2449 } while ((n >>= 3) != 0); 1694 2450 break; 1695 2451 } … … void BasicWriter<Char>::write_int(T value, const Spec &spec) { 1700 2456 } 1701 2457 } 1702 2458 2459 template <typename Char> 2460 template <typename T> 2461 void BasicWriter<Char>::write_double( 2462 T value, const FormatSpec &spec) { 2463 // Check type. 2464 char type = spec.type(); 2465 bool upper = false; 2466 switch (type) { 2467 case 0: 2468 type = 'g'; 2469 break; 2470 case 'e': case 'f': case 'g': case 'a': 2471 break; 2472 case 'F': 2473 #ifdef _MSC_VER 2474 // MSVC's printf doesn't support 'F'. 2475 type = 'f'; 2476 #endif 2477 // Fall through. 2478 case 'E': case 'G': case 'A': 2479 upper = true; 2480 break; 2481 default: 2482 internal::report_unknown_type(type, "double"); 2483 break; 2484 } 2485 2486 char sign = 0; 2487 // Use isnegative instead of value < 0 because the latter is always 2488 // false for NaN. 2489 if (internal::FPUtil::isnegative(static_cast<double>(value))) { 2490 sign = '-'; 2491 value = -value; 2492 } else if (spec.flag(SIGN_FLAG)) { 2493 sign = spec.flag(PLUS_FLAG) ? '+' : ' '; 2494 } 2495 2496 if (internal::FPUtil::isnotanumber(value)) { 2497 // Format NaN ourselves because sprintf's output is not consistent 2498 // across platforms. 2499 std::size_t nan_size = 4; 2500 const char *nan = upper ? " NAN" : " nan"; 2501 if (!sign) { 2502 --nan_size; 2503 ++nan; 2504 } 2505 CharPtr out = write_str(nan, nan_size, spec); 2506 if (sign) 2507 *out = sign; 2508 return; 2509 } 2510 2511 if (internal::FPUtil::isinfinity(value)) { 2512 // Format infinity ourselves because sprintf's output is not consistent 2513 // across platforms. 2514 std::size_t inf_size = 4; 2515 const char *inf = upper ? " INF" : " inf"; 2516 if (!sign) { 2517 --inf_size; 2518 ++inf; 2519 } 2520 CharPtr out = write_str(inf, inf_size, spec); 2521 if (sign) 2522 *out = sign; 2523 return; 2524 } 2525 2526 std::size_t offset = buffer_.size(); 2527 unsigned width = spec.width(); 2528 if (sign) { 2529 buffer_.reserve(buffer_.size() + (std::max)(width, 1u)); 2530 if (width > 0) 2531 --width; 2532 ++offset; 2533 } 2534 2535 // Build format string. 2536 enum { MAX_FORMAT_SIZE = 10}; // longest format: %#-*.*Lg 2537 Char format[MAX_FORMAT_SIZE]; 2538 Char *format_ptr = format; 2539 *format_ptr++ = '%'; 2540 unsigned width_for_sprintf = width; 2541 if (spec.flag(HASH_FLAG)) 2542 *format_ptr++ = '#'; 2543 if (spec.align() == ALIGN_CENTER) { 2544 width_for_sprintf = 0; 2545 } else { 2546 if (spec.align() == ALIGN_LEFT) 2547 *format_ptr++ = '-'; 2548 if (width != 0) 2549 *format_ptr++ = '*'; 2550 } 2551 if (spec.precision() >= 0) { 2552 *format_ptr++ = '.'; 2553 *format_ptr++ = '*'; 2554 } 2555 2556 append_float_length(format_ptr, value); 2557 *format_ptr++ = type; 2558 *format_ptr = '\0'; 2559 2560 // Format using snprintf. 2561 Char fill = internal::CharTraits<Char>::cast(spec.fill()); 2562 for (;;) { 2563 std::size_t buffer_size = buffer_.capacity() - offset; 2564 #ifdef _MSC_VER 2565 // MSVC's vsnprintf_s doesn't work with zero size, so reserve 2566 // space for at least one extra character to make the size non-zero. 2567 // Note that the buffer's capacity will increase by more than 1. 2568 if (buffer_size == 0) { 2569 buffer_.reserve(offset + 1); 2570 buffer_size = buffer_.capacity() - offset; 2571 } 2572 #endif 2573 Char *start = &buffer_[offset]; 2574 int n = internal::CharTraits<Char>::format_float( 2575 start, buffer_size, format, width_for_sprintf, spec.precision(), value); 2576 if (n >= 0 && offset + n < buffer_.capacity()) { 2577 if (sign) { 2578 if ((spec.align() != ALIGN_RIGHT && spec.align() != ALIGN_DEFAULT) || 2579 *start != ' ') { 2580 *(start - 1) = sign; 2581 sign = 0; 2582 } else { 2583 *(start - 1) = fill; 2584 } 2585 ++n; 2586 } 2587 if (spec.align() == ALIGN_CENTER && 2588 spec.width() > static_cast<unsigned>(n)) { 2589 width = spec.width(); 2590 CharPtr p = grow_buffer(width); 2591 std::copy(p, p + n, p + (width - n) / 2); 2592 fill_padding(p, spec.width(), n, fill); 2593 return; 2594 } 2595 if (spec.fill() != ' ' || sign) { 2596 while (*start == ' ') 2597 *start++ = fill; 2598 if (sign) 2599 *(start - 1) = sign; 2600 } 2601 grow_buffer(n); 2602 return; 2603 } 2604 // If n is negative we ask to increase the capacity by at least 1, 2605 // but as std::vector, the buffer grows exponentially. 2606 buffer_.reserve(n >= 0 ? offset + n + 1 : buffer_.capacity() + 1); 2607 } 2608 } 2609 2610 /** 2611 \rst 2612 This class template provides operations for formatting and writing data 2613 into a character stream. The output is stored in a memory buffer that grows 2614 dynamically. 2615 2616 You can use one of the following typedefs for common character types 2617 and the standard allocator: 2618 2619 +---------------+-----------------------------------------------------+ 2620 | Type | Definition | 2621 +===============+=====================================================+ 2622 | MemoryWriter | BasicMemoryWriter<char, std::allocator<char>> | 2623 +---------------+-----------------------------------------------------+ 2624 | WMemoryWriter | BasicMemoryWriter<wchar_t, std::allocator<wchar_t>> | 2625 +---------------+-----------------------------------------------------+ 2626 2627 **Example**:: 2628 2629 MemoryWriter out; 2630 out << "The answer is " << 42 << "\n"; 2631 out.write("({:+f}, {:+f})", -3.14, 3.14); 2632 2633 This will write the following output to the ``out`` object: 2634 2635 .. code-block:: none 2636 2637 The answer is 42 2638 (-3.140000, +3.140000) 2639 2640 The output can be converted to an ``std::string`` with ``out.str()`` or 2641 accessed as a C string with ``out.c_str()``. 2642 \endrst 2643 */ 2644 template <typename Char, typename Allocator = std::allocator<Char> > 2645 class BasicMemoryWriter : public BasicWriter<Char> { 2646 private: 2647 internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE, Allocator> buffer_; 2648 2649 public: 2650 explicit BasicMemoryWriter(const Allocator& alloc = Allocator()) 2651 : BasicWriter<Char>(buffer_), buffer_(alloc) {} 2652 2653 #if FMT_USE_RVALUE_REFERENCES 2654 /** 2655 \rst 2656 Constructs a :class:`fmt::BasicMemoryWriter` object moving the content 2657 of the other object to it. 2658 \endrst 2659 */ 2660 BasicMemoryWriter(BasicMemoryWriter &&other) 2661 : BasicWriter<Char>(buffer_), buffer_(std::move(other.buffer_)) { 2662 } 2663 2664 /** 2665 \rst 2666 Moves the content of the other ``BasicMemoryWriter`` object to this one. 2667 \endrst 2668 */ 2669 BasicMemoryWriter &operator=(BasicMemoryWriter &&other) { 2670 buffer_ = std::move(other.buffer_); 2671 return *this; 2672 } 2673 #endif 2674 }; 2675 2676 typedef BasicMemoryWriter<char> MemoryWriter; 2677 typedef BasicMemoryWriter<wchar_t> WMemoryWriter; 2678 2679 /** 2680 \rst 2681 This class template provides operations for formatting and writing data 2682 into a fixed-size array. For writing into a dynamically growing buffer 2683 use :class:`fmt::BasicMemoryWriter`. 2684 2685 Any write method will throw ``std::runtime_error`` if the output doesn't fit 2686 into the array. 2687 2688 You can use one of the following typedefs for common character types: 2689 2690 +--------------+---------------------------+ 2691 | Type | Definition | 2692 +==============+===========================+ 2693 | ArrayWriter | BasicArrayWriter<char> | 2694 +--------------+---------------------------+ 2695 | WArrayWriter | BasicArrayWriter<wchar_t> | 2696 +--------------+---------------------------+ 2697 \endrst 2698 */ 2699 template <typename Char> 2700 class BasicArrayWriter : public BasicWriter<Char> { 2701 private: 2702 internal::FixedBuffer<Char> buffer_; 2703 2704 public: 2705 /** 2706 \rst 2707 Constructs a :class:`fmt::BasicArrayWriter` object for *array* of the 2708 given size. 2709 \endrst 2710 */ 2711 BasicArrayWriter(Char *array, std::size_t size) 2712 : BasicWriter<Char>(buffer_), buffer_(array, size) {} 2713 2714 /** 2715 \rst 2716 Constructs a :class:`fmt::BasicArrayWriter` object for *array* of the 2717 size known at compile time. 2718 \endrst 2719 */ 2720 template <std::size_t SIZE> 2721 explicit BasicArrayWriter(Char (&array)[SIZE]) 2722 : BasicWriter<Char>(buffer_), buffer_(array, SIZE) {} 2723 }; 2724 2725 typedef BasicArrayWriter<char> ArrayWriter; 2726 typedef BasicArrayWriter<wchar_t> WArrayWriter; 2727 1703 2728 // Formats a value. 1704 2729 template <typename Char, typename T> 1705 void format(BasicFormatter<Char> &f, const Char *format_str, const T &value) { 1706 std::basic_ostringstream<Char> os; 1707 os << value; 1708 f.format(format_str, internal::MakeArg<Char>(os.str())); 2730 void format(BasicFormatter<Char> &f, const Char *&format_str, const T &value) { 2731 internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer; 2732 2733 internal::FormatBuf<Char> format_buf(buffer); 2734 std::basic_ostream<Char> output(&format_buf); 2735 output << value; 2736 2737 BasicStringRef<Char> str(&buffer[0], format_buf.size()); 2738 internal::Arg arg = internal::MakeValue<Char>(str); 2739 arg.type = static_cast<internal::Arg::Type>( 2740 internal::MakeValue<Char>::type(str)); 2741 format_str = f.format(format_str, arg); 1709 2742 } 1710 2743 1711 2744 // Reports a system error without throwing an exception. 1712 2745 // Can be used to report errors from destructors. 1713 void report_system_error(int error_code, StringRef message) FMT_NOEXCEPT (true);2746 void report_system_error(int error_code, StringRef message) FMT_NOEXCEPT; 1714 2747 1715 #if def _WIN322748 #if FMT_USE_WINDOWS_H 1716 2749 1717 /** 1718 A Windows error. 1719 */ 2750 /** A Windows error. */ 1720 2751 class WindowsError : public SystemError { 1721 2752 private: 1722 void init(int error_code, StringRef format_str, const ArgList &args);2753 void init(int error_code, CStringRef format_str, ArgList args); 1723 2754 1724 2755 public: 1725 2756 /** 1726 2757 \rst 1727 Constructs a :cpp:class:`fmt::WindowsError` object with the description 1728 of the form "*<message>*: *<system-message>*", where *<message>* is the 1729 formatted message and *<system-message>* is the system message corresponding 1730 to the error code. 2758 Constructs a :class:`fmt::WindowsError` object with the description 2759 of the form 2760 2761 .. parsed-literal:: 2762 *<message>*: *<system-message>* 2763 2764 where *<message>* is the formatted message and *<system-message>* is the 2765 system message corresponding to the error code. 1731 2766 *error_code* is a Windows error code as given by ``GetLastError``. 2767 If *error_code* is not a valid error code such as -1, the system message 2768 will look like "error -1". 2769 2770 **Example**:: 2771 2772 // This throws a WindowsError with the description 2773 // cannot open file 'madeup': The system cannot find the file specified. 2774 // or similar (system message may vary). 2775 const char *filename = "madeup"; 2776 LPOFSTRUCT of = LPOFSTRUCT(); 2777 HFILE file = OpenFile(filename, &of, OF_READ); 2778 if (file == HFILE_ERROR) { 2779 throw fmt::WindowsError(GetLastError(), 2780 "cannot open file '{}'", filename); 2781 } 1732 2782 \endrst 1733 2783 */ 1734 WindowsError(int error_code, StringRef message) {2784 WindowsError(int error_code, CStringRef message) { 1735 2785 init(error_code, message, ArgList()); 1736 2786 } 1737 FMT_VARIADIC_CTOR(WindowsError, init, int, StringRef)2787 FMT_VARIADIC_CTOR(WindowsError, init, int, CStringRef) 1738 2788 }; 1739 2789 1740 2790 // Reports a Windows error without throwing an exception. 1741 2791 // Can be used to report errors from destructors. 1742 void report_windows_error(int error_code, StringRef message) FMT_NOEXCEPT (true);2792 void report_windows_error(int error_code, StringRef message) FMT_NOEXCEPT; 1743 2793 1744 2794 #endif 1745 2795 … … enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE }; 1749 2799 Formats a string and prints it to stdout using ANSI escape sequences 1750 2800 to specify color (experimental). 1751 2801 Example: 1752 PrintColored(fmt::RED, "Elapsed time: {0:.2f} seconds") << 1.23;2802 print_colored(fmt::RED, "Elapsed time: {0:.2f} seconds", 1.23); 1753 2803 */ 1754 void print_colored(Color c, StringRef format, const ArgList &args);2804 void print_colored(Color c, CStringRef format, ArgList args); 1755 2805 1756 2806 /** 1757 2807 \rst … … void print_colored(Color c, StringRef format, const ArgList &args); 1762 2812 std::string message = format("The answer is {}", 42); 1763 2813 \endrst 1764 2814 */ 1765 inline std::string format( StringRef format_str, const ArgList &args) {1766 Writer w;2815 inline std::string format(CStringRef format_str, ArgList args) { 2816 MemoryWriter w; 1767 2817 w.write(format_str, args); 1768 2818 return w.str(); 1769 2819 } 1770 2820 1771 inline std::wstring format(W StringRef format_str, const ArgList &args) {1772 W Writer w;2821 inline std::wstring format(WCStringRef format_str, ArgList args) { 2822 WMemoryWriter w; 1773 2823 w.write(format_str, args); 1774 2824 return w.str(); 1775 2825 } … … inline std::wstring format(WStringRef format_str, const ArgList &args) { 1783 2833 print(stderr, "Don't {}!", "panic"); 1784 2834 \endrst 1785 2835 */ 1786 void print(std::FILE *f, StringRef format_str, const ArgList &args);2836 void print(std::FILE *f, CStringRef format_str, ArgList args); 1787 2837 1788 2838 /** 1789 2839 \rst … … void print(std::FILE *f, StringRef format_str, const ArgList &args); 1794 2844 print("Elapsed time: {0:.2f} seconds", 1.23); 1795 2845 \endrst 1796 2846 */ 1797 inline void print(StringRef format_str, const ArgList &args) { 1798 print(stdout, format_str, args); 1799 } 1800 1801 /** 1802 \rst 1803 Prints formatted data to the stream *os*. 1804 1805 **Example**:: 1806 1807 print(cerr, "Don't {}!", "panic"); 1808 \endrst 1809 */ 1810 void print(std::ostream &os, StringRef format_str, const ArgList &args); 2847 void print(CStringRef format_str, ArgList args); 1811 2848 1812 2849 template <typename Char> 1813 void printf(BasicWriter<Char> &w, 1814 BasicStringRef<Char> format, const ArgList &args) { 1815 internal::PrintfFormatter<Char>().format(w, format, args); 2850 void printf(BasicWriter<Char> &w, BasicCStringRef<Char> format, ArgList args) { 2851 internal::PrintfFormatter<Char>(args).format(w, format); 1816 2852 } 1817 2853 1818 2854 /** … … void printf(BasicWriter<Char> &w, 1824 2860 std::string message = fmt::sprintf("The answer is %d", 42); 1825 2861 \endrst 1826 2862 */ 1827 inline std::string sprintf(StringRef format, const ArgList &args) { 1828 Writer w; 2863 inline std::string sprintf(CStringRef format, ArgList args) { 2864 MemoryWriter w; 2865 printf(w, format, args); 2866 return w.str(); 2867 } 2868 2869 inline std::wstring sprintf(WCStringRef format, ArgList args) { 2870 WMemoryWriter w; 1829 2871 printf(w, format, args); 1830 2872 return w.str(); 1831 2873 } … … inline std::string sprintf(StringRef format, const ArgList &args) { 1839 2881 fmt::fprintf(stderr, "Don't %s!", "panic"); 1840 2882 \endrst 1841 2883 */ 1842 int fprintf(std::FILE *f, StringRef format, const ArgList &args);2884 int fprintf(std::FILE *f, CStringRef format, ArgList args); 1843 2885 1844 2886 /** 1845 2887 \rst … … int fprintf(std::FILE *f, StringRef format, const ArgList &args); 1850 2892 fmt::printf("Elapsed time: %.2f seconds", 1.23); 1851 2893 \endrst 1852 2894 */ 1853 inline int printf( StringRef format, const ArgList &args) {2895 inline int printf(CStringRef format, ArgList args) { 1854 2896 return fprintf(stdout, format, args); 1855 2897 } 1856 2898 … … class FormatInt { 1872 2914 // Integer division is slow so do it for a group of two digits instead 1873 2915 // of for every digit. The idea comes from the talk by Alexandrescu 1874 2916 // "Three Optimization Tips for C++". See speed-test for a comparison. 1875 unsigned index = (value % 100) * 2;2917 unsigned index = static_cast<unsigned>((value % 100) * 2); 1876 2918 value /= 100; 1877 *--buffer_end = internal::D IGITS[index + 1];1878 *--buffer_end = internal::D IGITS[index];2919 *--buffer_end = internal::Data::DIGITS[index + 1]; 2920 *--buffer_end = internal::Data::DIGITS[index]; 1879 2921 } 1880 2922 if (value < 10) { 1881 2923 *--buffer_end = static_cast<char>('0' + value); 1882 2924 return buffer_end; 1883 2925 } 1884 2926 unsigned index = static_cast<unsigned>(value * 2); 1885 *--buffer_end = internal::D IGITS[index + 1];1886 *--buffer_end = internal::D IGITS[index];2927 *--buffer_end = internal::Data::DIGITS[index + 1]; 2928 *--buffer_end = internal::Data::DIGITS[index]; 1887 2929 return buffer_end; 1888 2930 } 1889 2931 … … class FormatInt { 1926 2968 } 1927 2969 1928 2970 /** 1929 Returns the content of the output buffer as an `std::string`. 2971 \rst 2972 Returns the content of the output buffer as an ``std::string``. 2973 \endrst 1930 2974 */ 1931 2975 std::string str() const { return std::string(str_, size()); } 1932 2976 }; … … inline void format_decimal(char *&buffer, T value) { 1947 2991 return; 1948 2992 } 1949 2993 unsigned index = static_cast<unsigned>(abs_value * 2); 1950 *buffer++ = internal::D IGITS[index];1951 *buffer++ = internal::D IGITS[index + 1];2994 *buffer++ = internal::Data::DIGITS[index]; 2995 *buffer++ = internal::Data::DIGITS[index + 1]; 1952 2996 return; 1953 2997 } 1954 2998 unsigned num_digits = internal::count_digits(abs_value); 1955 2999 internal::format_decimal(buffer, abs_value, num_digits); 1956 3000 buffer += num_digits; 1957 3001 } 3002 3003 /** 3004 \rst 3005 Returns a named argument for formatting functions. 3006 3007 **Example**:: 3008 3009 print("Elapsed time: {s:.2f} seconds", arg("s", 1.23)); 3010 3011 \endrst 3012 */ 3013 template <typename T> 3014 inline internal::NamedArg<char> arg(StringRef name, const T &arg) { 3015 return internal::NamedArg<char>(name, arg); 3016 } 3017 3018 template <typename T> 3019 inline internal::NamedArg<wchar_t> arg(WStringRef name, const T &arg) { 3020 return internal::NamedArg<wchar_t>(name, arg); 3021 } 3022 3023 // The following two functions are deleted intentionally to disable 3024 // nested named arguments as in ``format("{}", arg("a", arg("b", 42)))``. 3025 template <typename Char> 3026 void arg(StringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED; 3027 template <typename Char> 3028 void arg(WStringRef, const internal::NamedArg<Char>&) FMT_DELETED_OR_UNDEFINED; 1958 3029 } 1959 3030 1960 3031 #if FMT_GCC_VERSION … … inline void format_decimal(char *&buffer, T value) { 1986 3057 1987 3058 #if FMT_USE_VARIADIC_TEMPLATES 1988 3059 # define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \ 1989 template <typename... Args> \3060 template <typename... Args> \ 1990 3061 ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \ 1991 3062 const Args & ... args) { \ 1992 using fmt::internal::Arg; \ 1993 const Arg array[fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \ 1994 fmt::internal::MakeArg<Char>(args)... \ 1995 }; \ 3063 typename fmt::internal::ArgArray<sizeof...(Args)>::Type array; \ 1996 3064 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \ 1997 fmt:: ArgList(array, sizeof...(Args))); \3065 fmt::internal::make_arg_list<Char>(array, args...)); \ 1998 3066 } 1999 3067 #else 2000 3068 // Defines a wrapper for a function taking __VA_ARGS__ arguments … … inline void format_decimal(char *&buffer, T value) { 2003 3071 template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \ 2004 3072 inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \ 2005 3073 FMT_GEN(n, FMT_MAKE_ARG)) { \ 2006 const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF_##Char)}; \ 2007 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \ 2008 fmt::ArgList(args, sizeof(args) / sizeof(*args))); \ 3074 fmt::internal::ArgArray<n>::Type arr; \ 3075 FMT_GEN(n, FMT_ASSIGN_##Char); \ 3076 call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList( \ 3077 fmt::internal::make_type(FMT_GEN(n, FMT_MAKE_REF2)), arr)); \ 2009 3078 } 2010 3079 2011 3080 # define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \ … … inline void format_decimal(char *&buffer, T value) { 2021 3090 FMT_WRAP(Char, ReturnType, func, call, 7, __VA_ARGS__) \ 2022 3091 FMT_WRAP(Char, ReturnType, func, call, 8, __VA_ARGS__) \ 2023 3092 FMT_WRAP(Char, ReturnType, func, call, 9, __VA_ARGS__) \ 2024 FMT_WRAP(Char, ReturnType, func, call, 10, __VA_ARGS__) 3093 FMT_WRAP(Char, ReturnType, func, call, 10, __VA_ARGS__) \ 3094 FMT_WRAP(Char, ReturnType, func, call, 11, __VA_ARGS__) \ 3095 FMT_WRAP(Char, ReturnType, func, call, 12, __VA_ARGS__) \ 3096 FMT_WRAP(Char, ReturnType, func, call, 13, __VA_ARGS__) \ 3097 FMT_WRAP(Char, ReturnType, func, call, 14, __VA_ARGS__) \ 3098 FMT_WRAP(Char, ReturnType, func, call, 15, __VA_ARGS__) 2025 3099 #endif // FMT_USE_VARIADIC_TEMPLATES 2026 3100 2027 3101 /** … … inline void format_decimal(char *&buffer, T value) { 2032 3106 **Example**:: 2033 3107 2034 3108 void print_error(const char *file, int line, const char *format, 2035 const fmt::ArgList &args) {3109 fmt::ArgList args) { 2036 3110 fmt::print("{}: {}: ", file, line); 2037 3111 fmt::print(format, args); 2038 3112 } … … inline void format_decimal(char *&buffer, T value) { 2043 3117 you don't need legacy compiler support and can use variadic templates 2044 3118 directly:: 2045 3119 2046 template <typename... Args>3120 template <typename... Args> 2047 3121 void print_error(const char *file, int line, const char *format, 2048 3122 const Args & ... args) { 2049 3123 fmt::print("{}: {}: ", file, line); … … inline void format_decimal(char *&buffer, T value) { 2057 3131 #define FMT_VARIADIC_W(ReturnType, func, ...) \ 2058 3132 FMT_VARIADIC_(wchar_t, ReturnType, func, return func, __VA_ARGS__) 2059 3133 3134 #define FMT_CAPTURE_ARG_(id, index) ::fmt::arg(#id, id) 3135 3136 #define FMT_CAPTURE_ARG_W_(id, index) ::fmt::arg(L###id, id) 3137 3138 /** 3139 \rst 3140 Convenient macro to capture the arguments' names and values into several 3141 ``fmt::arg(name, value)``. 3142 3143 **Example**:: 3144 3145 int x = 1, y = 2; 3146 print("point: ({x}, {y})", FMT_CAPTURE(x, y)); 3147 // same as: 3148 // print("point: ({x}, {y})", arg("x", x), arg("y", y)); 3149 3150 \endrst 3151 */ 3152 #define FMT_CAPTURE(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_, __VA_ARGS__) 3153 3154 #define FMT_CAPTURE_W(...) FMT_FOR_EACH(FMT_CAPTURE_ARG_W_, __VA_ARGS__) 3155 2060 3156 namespace fmt { 2061 FMT_VARIADIC(std::string, format, StringRef) 2062 FMT_VARIADIC_W(std::wstring, format, WStringRef) 2063 FMT_VARIADIC(void, print, StringRef) 2064 FMT_VARIADIC(void, print, std::FILE *, StringRef) 2065 FMT_VARIADIC(void, print, std::ostream &, StringRef) 2066 FMT_VARIADIC(void, print_colored, Color, StringRef) 2067 FMT_VARIADIC(std::string, sprintf, StringRef) 2068 FMT_VARIADIC(int, printf, StringRef) 2069 FMT_VARIADIC(int, fprintf, std::FILE *, StringRef) 2070 } 3157 FMT_VARIADIC(std::string, format, CStringRef) 3158 FMT_VARIADIC_W(std::wstring, format, WCStringRef) 3159 FMT_VARIADIC(void, print, CStringRef) 3160 FMT_VARIADIC(void, print, std::FILE *, CStringRef) 3161 3162 FMT_VARIADIC(void, print_colored, Color, CStringRef) 3163 FMT_VARIADIC(std::string, sprintf, CStringRef) 3164 FMT_VARIADIC_W(std::wstring, sprintf, WCStringRef) 3165 FMT_VARIADIC(int, printf, CStringRef) 3166 FMT_VARIADIC(int, fprintf, std::FILE *, CStringRef) 3167 3168 #if FMT_USE_IOSTREAMS 3169 /** 3170 \rst 3171 Prints formatted data to the stream *os*. 3172 3173 **Example**:: 3174 3175 print(cerr, "Don't {}!", "panic"); 3176 \endrst 3177 */ 3178 void print(std::ostream &os, CStringRef format_str, ArgList args); 3179 FMT_VARIADIC(void, print, std::ostream &, CStringRef) 3180 #endif 3181 } // namespace fmt 3182 3183 #if FMT_USE_USER_DEFINED_LITERALS 3184 namespace fmt { 3185 namespace internal { 3186 3187 template <typename Char> 3188 struct UdlFormat { 3189 const Char *str; 3190 3191 template <typename... Args> 3192 auto operator()(Args && ... args) const 3193 -> decltype(format(str, std::forward<Args>(args)...)) { 3194 return format(str, std::forward<Args>(args)...); 3195 } 3196 }; 3197 3198 template <typename Char> 3199 struct UdlArg { 3200 const Char *str; 3201 3202 template <typename T> 3203 NamedArg<Char> operator=(T &&value) const { 3204 return {str, std::forward<T>(value)}; 3205 } 3206 }; 3207 3208 } // namespace internal 3209 3210 inline namespace literals { 3211 3212 /** 3213 \rst 3214 C++11 literal equivalent of :func:`fmt::format`. 3215 3216 **Example**:: 3217 3218 using namespace fmt::literals; 3219 std::string message = "The answer is {}"_format(42); 3220 \endrst 3221 */ 3222 inline internal::UdlFormat<char> 3223 operator"" _format(const char *s, std::size_t) { return {s}; } 3224 inline internal::UdlFormat<wchar_t> 3225 operator"" _format(const wchar_t *s, std::size_t) { return {s}; } 3226 3227 /** 3228 \rst 3229 C++11 literal equivalent of :func:`fmt::arg`. 3230 3231 **Example**:: 3232 3233 using namespace fmt::literals; 3234 print("Elapsed time: {s:.2f} seconds", "s"_a=1.23); 3235 \endrst 3236 */ 3237 inline internal::UdlArg<char> 3238 operator"" _a(const char *s, std::size_t) { return {s}; } 3239 inline internal::UdlArg<wchar_t> 3240 operator"" _a(const wchar_t *s, std::size_t) { return {s}; } 3241 3242 } // inline namespace literals 3243 } // namespace fmt 3244 #endif // FMT_USE_USER_DEFINED_LITERALS 2071 3245 2072 3246 // Restore warnings. 2073 3247 #if FMT_GCC_VERSION >= 406 2074 3248 # pragma GCC diagnostic pop 2075 3249 #endif 2076 3250 3251 #if defined(__clang__) && !defined(__INTEL_COMPILER) 3252 # pragma clang diagnostic pop 3253 #endif 3254 3255 #ifdef FMT_HEADER_ONLY 3256 # include "format.cc" 3257 #endif 3258 2077 3259 #endif // FMT_FORMAT_H_