Index: ps/trunk/source/ps/tests/test_cppformat.h
===================================================================
--- ps/trunk/source/ps/tests/test_cppformat.h (revision 23561)
+++ ps/trunk/source/ps/tests/test_cppformat.h (nonexistent)
@@ -1,63 +0,0 @@
-/* Copyright (C) 2015 Wildfire Games.
- * This file is part of 0 A.D.
- *
- * 0 A.D. is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * 0 A.D. is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with 0 A.D. If not, see .
- */
-
-#include "lib/self_test.h"
-
-#include "third_party/cppformat/format.h"
-
-class TestCppformat : public CxxTest::TestSuite
-{
-public:
- void test_basic()
- {
- // Make test behave independent of current host locale
- char* old = setlocale(LC_ALL, "en_US.UTF-8");
-
- TS_ASSERT_EQUALS(fmt::sprintf("abc"), "abc");
-
- TS_ASSERT_EQUALS(fmt::sprintf("%d", 123), "123");
- TS_ASSERT_EQUALS(fmt::sprintf("%d", (int64_t)123), "123");
- TS_ASSERT_EQUALS(fmt::sprintf("%i", 123), "123");
-
- TS_ASSERT_EQUALS(fmt::sprintf("%04x", 123), "007b");
- TS_ASSERT_EQUALS(fmt::sprintf("%04X", 123), "007B");
-
- TS_ASSERT_EQUALS(fmt::sprintf("%f", 0.5f), "0.500000");
- TS_ASSERT_EQUALS(fmt::sprintf("%.1f", 0.1111f), "0.1");
-
- TS_ASSERT_EQUALS(fmt::sprintf("%d", 0x100000001ULL), "1");
- if (sizeof(long) == sizeof(int32_t))
- {
- TS_ASSERT_EQUALS(fmt::sprintf("%ld", 0x100000001ULL), "1");
- }
- else
- {
- TS_ASSERT_EQUALS(fmt::sprintf("%ld", 0x100000001ULL), "4294967297");
- }
- TS_ASSERT_EQUALS(fmt::sprintf("%lld", 0x100000001ULL), "4294967297");
-
- TS_ASSERT_EQUALS(fmt::sprintf("T%sT", "abc"), "TabcT");
- TS_ASSERT_EQUALS(fmt::sprintf("T%sT", std::string("abc")), "TabcT");
- TS_ASSERT_EQUALS(fmt::sprintf("T%sT", CStr("abc")), "TabcT");
-
- TS_ASSERT_EQUALS(fmt::sprintf("T%sT", (const char*)NULL), "T(null)T");
-
- TS_ASSERT_EQUALS(fmt::sprintf("T%pT", (void*)0x1234), "T0x1234T");
-
- setlocale(LC_ALL, old);
- }
-};
Property changes on: ps/trunk/source/ps/tests/test_cppformat.h
___________________________________________________________________
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Index: ps/trunk/source/third_party/cppformat/format.h
===================================================================
--- ps/trunk/source/third_party/cppformat/format.h (revision 23561)
+++ ps/trunk/source/third_party/cppformat/format.h (nonexistent)
@@ -1,2083 +0,0 @@
-/*
- * Slightly modified version of cppformat, by Wildfire Games, for 0 A.D.
- * Based on cppformat v0.11.0 from https://github.com/cppformat/cppformat
- */
-
-/*
- Formatting library for C++
-
- Copyright (c) 2012 - 2014, Victor Zverovich
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef FMT_FORMAT_H_
-#define FMT_FORMAT_H_
-
-#include
-
-#include
-#include // for std::ptrdiff_t
-#include
-#include
-#include
-#include
-#include
-#include
-
-#if defined(_SECURE_SCL) && _SECURE_SCL
-# include
-#endif
-
-#ifdef __GNUC__
-# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
-# define FMT_GCC_EXTENSION __extension__
-// Disable warning about "long long" which is sometimes reported even
-// when using __extension__.
-# if FMT_GCC_VERSION >= 406
-# pragma GCC diagnostic push
-# pragma GCC diagnostic ignored "-Wlong-long"
-# endif
-#else
-# define FMT_GCC_EXTENSION
-#endif
-
-#ifdef __GNUC_LIBSTD__
-# define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__)
-#endif
-
-#ifdef __has_feature
-# define FMT_HAS_FEATURE(x) __has_feature(x)
-#else
-# define FMT_HAS_FEATURE(x) 0
-#endif
-
-#ifdef __has_builtin
-# define FMT_HAS_BUILTIN(x) __has_builtin(x)
-#else
-# define FMT_HAS_BUILTIN(x) 0
-#endif
-
-#ifndef FMT_USE_VARIADIC_TEMPLATES
-// Variadic templates are available in GCC since version 4.4
-// (http://gcc.gnu.org/projects/cxx0x.html) and in Visual C++
-// since version 2013.
-# if defined(_MSC_VER)
-# define FMT_USE_VARIADIC_TEMPLATES 1
-# else
-# define FMT_USE_VARIADIC_TEMPLATES \
- (FMT_HAS_FEATURE(cxx_variadic_templates) || \
- (FMT_GCC_VERSION >= 404 && __cplusplus >= 201103))
-# endif
-#endif
-
-#ifndef FMT_USE_RVALUE_REFERENCES
-// Don't use rvalue references when compiling with clang and an old libstdc++
-// as the latter doesn't provide std::move.
-# if defined(FMT_GNUC_LIBSTD_VERSION) && FMT_GNUC_LIBSTD_VERSION <= 402
-# define FMT_USE_RVALUE_REFERENCES 0
-# elif defined(_MSC_VER)
-# define FMT_USE_RVALUE_REFERENCES 1
-# else
-# define FMT_USE_RVALUE_REFERENCES \
- (FMT_HAS_FEATURE(cxx_rvalue_references) || \
- (FMT_GCC_VERSION >= 403 && __cplusplus >= 201103))
-# endif
-#endif
-
-#if FMT_USE_RVALUE_REFERENCES
-# include // for std::move
-#endif
-
-// Define FMT_USE_NOEXCEPT to make C++ Format use noexcept (C++11 feature).
-#if (defined(FMT_USE_NOEXCEPT) && FMT_USE_NOEXCEPT) || FMT_HAS_FEATURE(cxx_noexcept) || \
- (FMT_GCC_VERSION >= 408 && __cplusplus >= 201103)
-# define FMT_NOEXCEPT(expr) noexcept(expr)
-#else
-# define FMT_NOEXCEPT(expr)
-#endif
-
-// A macro to disallow the copy constructor and operator= functions
-// This should be used in the private: declarations for a class
-#define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \
- TypeName(const TypeName&); \
- void operator=(const TypeName&)
-
-namespace fmt {
-
-// Fix the warning about long long on older versions of GCC
-// that don't support the diagnostic pragma.
-FMT_GCC_EXTENSION typedef long long LongLong;
-FMT_GCC_EXTENSION typedef unsigned long long ULongLong;
-
-#if FMT_USE_RVALUE_REFERENCES
-using std::move;
-#endif
-
-template
-class BasicWriter;
-
-typedef BasicWriter Writer;
-typedef BasicWriter WWriter;
-
-template
-class BasicFormatter;
-
-template
-void format(BasicFormatter &f, const Char *format_str, const T &value);
-
-/**
- \rst
- A string reference. It can be constructed from a C string or
- ``std::string``.
-
- You can use one of the following typedefs for common character types:
-
- +------------+-------------------------+
- | Type | Definition |
- +============+=========================+
- | StringRef | BasicStringRef |
- +------------+-------------------------+
- | WStringRef | BasicStringRef |
- +------------+-------------------------+
-
- This class is most useful as a parameter type to allow passing
- different types of strings to a function, for example::
-
- template
- std::string format(StringRef format, const Args & ... args);
-
- format("{}", 42);
- format(std::string("{}"), 42);
- \endrst
- */
-template
-class BasicStringRef {
- private:
- const Char *data_;
- mutable std::size_t size_;
-
- public:
- /**
- Constructs a string reference object from a C string and a size.
- If *size* is zero, which is the default, the size is computed
- automatically.
- */
- BasicStringRef(const Char *s, std::size_t size = 0) : data_(s), size_(size) {}
-
- /**
- Constructs a string reference from an `std::string` object.
- */
- BasicStringRef(const std::basic_string &s)
- : data_(s.c_str()), size_(s.size()) {}
-
- /**
- Converts a string reference to an `std::string` object.
- */
- operator std::basic_string() const {
- return std::basic_string(data_, size());
- }
-
- /**
- Returns the pointer to a C string.
- */
- const Char *c_str() const { return data_; }
-
- /**
- Returns the string size.
- */
- std::size_t size() const {
- if (size_ == 0 && data_) size_ = std::char_traits::length(data_);
- return size_;
- }
-
- friend bool operator==(BasicStringRef lhs, BasicStringRef rhs) {
- return lhs.data_ == rhs.data_;
- }
- friend bool operator!=(BasicStringRef lhs, BasicStringRef rhs) {
- return lhs.data_ != rhs.data_;
- }
-};
-
-typedef BasicStringRef StringRef;
-typedef BasicStringRef WStringRef;
-
-/**
- A formatting error such as invalid format string.
-*/
-class FormatError : public std::runtime_error {
-public:
- explicit FormatError(const std::string &message)
- : std::runtime_error(message) {}
-};
-
-namespace internal {
-
-// The number of characters to store in the Array object, representing the
-// output buffer, itself to avoid dynamic memory allocation.
-enum { INLINE_BUFFER_SIZE = 500 };
-
-#if defined(_SECURE_SCL) && _SECURE_SCL
-// Use checked iterator to avoid warnings on MSVC.
-template
-inline stdext::checked_array_iterator make_ptr(T *ptr, std::size_t size) {
- return stdext::checked_array_iterator(ptr, size);
-}
-#else
-template
-inline T *make_ptr(T *ptr, std::size_t) { return ptr; }
-#endif
-
-// A simple array for POD types with the first SIZE elements stored in
-// the object itself. It supports a subset of std::vector's operations.
-template
-class Array {
- private:
- std::size_t size_;
- std::size_t capacity_;
- T *ptr_;
- T data_[SIZE];
-
- void grow(std::size_t size);
-
- // Free memory allocated by the array.
- void free() {
- if (ptr_ != data_) delete [] ptr_;
- }
-
- // Move data from other to this array.
- void move(Array &other) {
- size_ = other.size_;
- capacity_ = other.capacity_;
- if (other.ptr_ == other.data_) {
- ptr_ = data_;
- std::copy(other.data_, other.data_ + size_, make_ptr(data_, capacity_));
- } else {
- ptr_ = other.ptr_;
- // Set pointer to the inline array so that delete is not called
- // when freeing.
- other.ptr_ = other.data_;
- }
- }
-
- FMT_DISALLOW_COPY_AND_ASSIGN(Array);
-
- public:
- explicit Array(std::size_t size = 0)
- : size_(size), capacity_(SIZE), ptr_(data_) {}
- ~Array() { free(); }
-
-#if FMT_USE_RVALUE_REFERENCES
- Array(Array &&other) {
- move(other);
- }
-
- Array& operator=(Array &&other) {
- assert(this != &other);
- free();
- move(other);
- return *this;
- }
-#endif
-
- // Returns the size of this array.
- std::size_t size() const { return size_; }
-
- // Returns the capacity of this array.
- std::size_t capacity() const { return capacity_; }
-
- // Resizes the array. If T is a POD type new elements are not initialized.
- void resize(std::size_t new_size) {
- if (new_size > capacity_)
- grow(new_size);
- size_ = new_size;
- }
-
- // Reserves space to store at least capacity elements.
- void reserve(std::size_t capacity) {
- if (capacity > capacity_)
- grow(capacity);
- }
-
- void clear() { size_ = 0; }
-
- void push_back(const T &value) {
- if (size_ == capacity_)
- grow(size_ + 1);
- ptr_[size_++] = value;
- }
-
- // Appends data to the end of the array.
- void append(const T *begin, const T *end);
-
- T &operator[](std::size_t index) { return ptr_[index]; }
- const T &operator[](std::size_t index) const { return ptr_[index]; }
-};
-
-template
-void Array::grow(std::size_t size) {
- capacity_ = (std::max)(size, capacity_ + capacity_ / 2);
- T *p = new T[capacity_];
- std::copy(ptr_, ptr_ + size_, make_ptr(p, capacity_));
- if (ptr_ != data_)
- delete [] ptr_;
- ptr_ = p;
-}
-
-template
-void Array::append(const T *begin, const T *end) {
- std::ptrdiff_t num_elements = end - begin;
- if (size_ + num_elements > capacity_)
- grow(size_ + num_elements);
- std::copy(begin, end, make_ptr(ptr_, capacity_) + size_);
- size_ += num_elements;
-}
-
-template
-class BasicCharTraits {
- public:
-#if defined(_SECURE_SCL) && _SECURE_SCL
- typedef stdext::checked_array_iterator CharPtr;
-#else
- typedef Char *CharPtr;
-#endif
-};
-
-template
-class CharTraits;
-
-template <>
-class CharTraits : public BasicCharTraits {
- private:
- // Conversion from wchar_t to char is not allowed.
- static char convert(wchar_t);
-
-public:
- typedef const wchar_t *UnsupportedStrType;
-
- static char convert(char value) { return value; }
-
- // Formats a floating-point number.
- template
- static int format_float(char *buffer, std::size_t size,
- const char *format, unsigned width, int precision, T value);
-};
-
-template <>
-class CharTraits : public BasicCharTraits {
- public:
- typedef const char *UnsupportedStrType;
-
- static wchar_t convert(char value) { return value; }
- static wchar_t convert(wchar_t value) { return value; }
-
- template
- static int format_float(wchar_t *buffer, std::size_t size,
- const wchar_t *format, unsigned width, int precision, T value);
-};
-
-// Selects uint32_t if FitsIn32Bits is true, uint64_t otherwise.
-template
-struct TypeSelector { typedef uint32_t Type; };
-
-template <>
-struct TypeSelector { typedef uint64_t Type; };
-
-// Checks if a number is negative - used to avoid warnings.
-template
-struct SignChecker {
- template
- static bool is_negative(T) { return false; }
-};
-
-template <>
-struct SignChecker {
- template
- static bool is_negative(T value) { return value < 0; }
-};
-
-// Returns true if value is negative, false otherwise.
-// Same as (value < 0) but doesn't produce warnings if T is an unsigned type.
-template
-inline bool is_negative(T value) {
- return SignChecker::is_signed>::is_negative(value);
-}
-
-template
-struct IntTraits {
- // Smallest of uint32_t and uint64_t that is large enough to represent
- // all values of T.
- typedef typename
- TypeSelector::digits <= 32>::Type MainType;
-};
-
-// MakeUnsigned::Type gives an unsigned type corresponding to integer type T.
-template
-struct MakeUnsigned { typedef T Type; };
-
-#define FMT_SPECIALIZE_MAKE_UNSIGNED(T, U) \
- template <> \
- struct MakeUnsigned { typedef U Type; }
-
-FMT_SPECIALIZE_MAKE_UNSIGNED(char, unsigned char);
-FMT_SPECIALIZE_MAKE_UNSIGNED(signed char, unsigned char);
-FMT_SPECIALIZE_MAKE_UNSIGNED(short, unsigned short);
-FMT_SPECIALIZE_MAKE_UNSIGNED(int, unsigned);
-FMT_SPECIALIZE_MAKE_UNSIGNED(long, unsigned long);
-FMT_SPECIALIZE_MAKE_UNSIGNED(LongLong, ULongLong);
-
-void report_unknown_type(char code, const char *type);
-
-extern const uint32_t POWERS_OF_10_32[];
-extern const uint64_t POWERS_OF_10_64[];
-
-#if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll)
-// Returns the number of decimal digits in n. Leading zeros are not counted
-// except for n == 0 in which case count_digits returns 1.
-inline unsigned count_digits(uint64_t n) {
- // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
- // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits.
- unsigned t = (64 - __builtin_clzll(n | 1)) * 1233 >> 12;
- return t - (n < POWERS_OF_10_64[t]) + 1;
-}
-# if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz)
-// Optional version of count_digits for better performance on 32-bit platforms.
-inline unsigned count_digits(uint32_t n) {
- uint32_t t = (32 - __builtin_clz(n | 1)) * 1233 >> 12;
- return t - (n < POWERS_OF_10_32[t]) + 1;
-}
-# endif
-#else
-// Slower version of count_digits used when __builtin_clz is not available.
-inline unsigned count_digits(uint64_t n) {
- unsigned count = 1;
- for (;;) {
- // Integer division is slow so do it for a group of four digits instead
- // of for every digit. The idea comes from the talk by Alexandrescu
- // "Three Optimization Tips for C++". See speed-test for a comparison.
- if (n < 10) return count;
- if (n < 100) return count + 1;
- if (n < 1000) return count + 2;
- if (n < 10000) return count + 3;
- n /= 10000u;
- count += 4;
- }
-}
-#endif
-
-extern const char DIGITS[];
-
-// Formats a decimal unsigned integer value writing into buffer.
-template
-inline void format_decimal(Char *buffer, UInt value, unsigned num_digits) {
- --num_digits;
- while (value >= 100) {
- // Integer division is slow so do it for a group of two digits instead
- // of for every digit. The idea comes from the talk by Alexandrescu
- // "Three Optimization Tips for C++". See speed-test for a comparison.
- unsigned index = (value % 100) * 2;
- value /= 100;
- buffer[num_digits] = DIGITS[index + 1];
- buffer[num_digits - 1] = DIGITS[index];
- num_digits -= 2;
- }
- if (value < 10) {
- *buffer = static_cast('0' + value);
- return;
- }
- unsigned index = static_cast(value * 2);
- buffer[1] = DIGITS[index + 1];
- buffer[0] = DIGITS[index];
-}
-
-#ifdef _WIN32
-// A converter from UTF-8 to UTF-16.
-// It is only provided for Windows since other systems use UTF-8.
-class UTF8ToUTF16 {
- private:
- Array buffer_;
-
- public:
- explicit UTF8ToUTF16(StringRef s);
- operator WStringRef() const { return WStringRef(&buffer_[0], size()); }
- size_t size() const { return buffer_.size() - 1; }
- const wchar_t *c_str() const { return &buffer_[0]; }
- std::wstring str() const { return std::wstring(&buffer_[0], size()); }
-};
-
-// A converter from UTF-16 to UTF-8.
-// It is only provided for Windows since other systems use UTF-8.
-class UTF16ToUTF8 {
- private:
- Array buffer_;
-
- public:
- UTF16ToUTF8() {}
- explicit UTF16ToUTF8(WStringRef s);
- operator StringRef() const { return StringRef(&buffer_[0], size()); }
- size_t size() const { return buffer_.size() - 1; }
- const char *c_str() const { return &buffer_[0]; }
- std::string str() const { return std::string(&buffer_[0], size()); }
-
- // Performs conversion returning a system error code instead of
- // throwing exception on error.
- int convert(WStringRef s);
-};
-#endif
-
-// Portable thread-safe version of strerror.
-// Sets buffer to point to a string describing the error code.
-// This can be either a pointer to a string stored in buffer,
-// or a pointer to some static immutable string.
-// Returns one of the following values:
-// 0 - success
-// ERANGE - buffer is not large enough to store the error message
-// other - failure
-// Buffer should be at least of size 1.
-int safe_strerror(int error_code,
- char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT(true);
-
-void format_system_error(
- fmt::Writer &out, int error_code, fmt::StringRef message);
-
-#ifdef _WIN32
-void format_windows_error(
- fmt::Writer &out, int error_code, fmt::StringRef message);
-#endif
-
-// Throws Exception(message) if format contains '}', otherwise throws
-// FormatError reporting unmatched '{'. The idea is that unmatched '{'
-// should override other errors.
-template
-struct FormatErrorReporter {
- int num_open_braces;
- void operator()(const Char *s, fmt::StringRef message) const;
-};
-
-// Computes max(Arg, 1) at compile time. It is used to avoid errors about
-// allocating an array of 0 size.
-template
-struct NonZero {
- enum { VALUE = Arg };
-};
-
-template <>
-struct NonZero<0> {
- enum { VALUE = 1 };
-};
-
-// A formatting argument. It is a POD type to allow storage in internal::Array.
-struct Arg {
- enum Type {
- // Integer types should go first,
- INT, UINT, LONG_LONG, ULONG_LONG, CHAR, LAST_INTEGER_TYPE = CHAR,
- // followed by floating-point types.
- DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE,
- STRING, WSTRING, POINTER, CUSTOM
- };
- Type type;
-
- template
- struct StringValue {
- const Char *value;
- std::size_t size;
- };
-
- typedef void (*FormatFunc)(
- void *formatter, const void *arg, const void *format_str);
-
- struct CustomValue {
- const void *value;
- FormatFunc format;
- };
-
- union {
- int int_value;
- unsigned uint_value;
- LongLong long_long_value;
- ULongLong ulong_long_value;
- double double_value;
- long double long_double_value;
- const void *pointer_value;
- StringValue string;
- StringValue wstring;
- CustomValue custom;
- };
-};
-
-// Makes an Arg object from any type.
-template
-class MakeArg : public Arg {
- private:
- // The following two methods are private to disallow formatting of
- // arbitrary pointers. If you want to output a pointer cast it to
- // "void *" or "const void *". In particular, this forbids formatting
- // of "[const] volatile char *" which is printed as bool by iostreams.
- // Do not implement!
- template
- MakeArg(const T *value);
- template
- MakeArg(T *value);
-
- void set_string(StringRef str) {
- type = STRING;
- string.value = str.c_str();
- string.size = str.size();
- }
-
- void set_string(WStringRef str) {
- type = WSTRING;
- CharTraits::convert(wchar_t());
- wstring.value = str.c_str();
- wstring.size = str.size();
- }
-
- // Formats an argument of a custom type, such as a user-defined class.
- template
- static void format_custom_arg(
- void *formatter, const void *arg, const void *format_str) {
- format(*static_cast*>(formatter),
- static_cast(format_str), *static_cast(arg));
- }
-
-public:
- MakeArg() {}
- MakeArg(bool value) { type = INT; int_value = value; }
- MakeArg(short value) { type = INT; int_value = value; }
- MakeArg(unsigned short value) { type = UINT; uint_value = value; }
- MakeArg(int value) { type = INT; int_value = value; }
- MakeArg(unsigned value) { type = UINT; uint_value = value; }
- MakeArg(long value) {
- // To minimize the number of types we need to deal with, long is
- // translated either to int or to long long depending on its size.
- if (sizeof(long) == sizeof(int)) {
- type = INT;
- int_value = static_cast(value);
- } else {
- type = LONG_LONG;
- long_long_value = value;
- }
- }
- MakeArg(unsigned long value) {
- if (sizeof(unsigned long) == sizeof(unsigned)) {
- type = UINT;
- uint_value = static_cast(value);
- } else {
- type = ULONG_LONG;
- ulong_long_value = value;
- }
- }
- MakeArg(LongLong value) { type = LONG_LONG; long_long_value = value; }
- MakeArg(ULongLong value) { type = ULONG_LONG; ulong_long_value = value; }
- MakeArg(float value) { type = DOUBLE; double_value = value; }
- MakeArg(double value) { type = DOUBLE; double_value = value; }
- MakeArg(long double value) { type = LONG_DOUBLE; long_double_value = value; }
- MakeArg(signed char value) { type = CHAR; int_value = value; }
- MakeArg(unsigned char value) { type = CHAR; int_value = value; }
- MakeArg(char value) { type = CHAR; int_value = value; }
- MakeArg(wchar_t value) {
- type = CHAR;
- int_value = internal::CharTraits::convert(value);
- }
-
- MakeArg(char *value) { set_string(value); }
- MakeArg(const char *value) { set_string(value); }
- MakeArg(const std::string &value) { set_string(value); }
- MakeArg(StringRef value) { set_string(value); }
-
- MakeArg(wchar_t *value) { set_string(value); }
- MakeArg(const wchar_t *value) { set_string(value); }
- MakeArg(const std::wstring &value) { set_string(value); }
- MakeArg(WStringRef value) { set_string(value); }
-
- MakeArg(void *value) { type = POINTER; pointer_value = value; }
- MakeArg(const void *value) { type = POINTER; pointer_value = value; }
-
-#if 0
- // WFG: Removed this because otherwise you can pass a CStr8 or an enum etc
- // into fmt::sprintf, and it will be interpreted as a CUSTOM type and then
- // will throw an exception at runtime, which is terrible behaviour.
- template
- MakeArg(const T &value) {
- type = CUSTOM;
- custom.value = &value;
- custom.format = &format_custom_arg;
- }
-#endif
-};
-
-#define FMT_DISPATCH(call) static_cast(this)->call
-
-// An argument visitor.
-// To use ArgVisitor define a subclass that implements some or all of the
-// visit methods with the same signatures as the methods in ArgVisitor,
-// for example, visit_int(int).
-// Specify the subclass name as the Impl template parameter. Then calling
-// ArgVisitor::visit for some argument will dispatch to a visit method
-// specific to the argument type. For example, if the argument type is
-// double then visit_double(double) method of a subclass will be called.
-// If the subclass doesn't contain a method with this signature, then
-// a corresponding method of ArgVisitor will be called.
-//
-// Example:
-// class MyArgVisitor : public ArgVisitor {
-// public:
-// void visit_int(int value) { print("{}", value); }
-// void visit_double(double value) { print("{}", value ); }
-// };
-//
-// ArgVisitor uses the curiously recurring template pattern:
-// http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
-template
-class ArgVisitor {
- public:
- Result visit_unhandled_arg() { return Result(); }
-
- Result visit_int(int value) {
- return FMT_DISPATCH(visit_any_int(value));
- }
- Result visit_long_long(LongLong value) {
- return FMT_DISPATCH(visit_any_int(value));
- }
- Result visit_uint(unsigned value) {
- return FMT_DISPATCH(visit_any_int(value));
- }
- Result visit_ulong_long(ULongLong value) {
- return FMT_DISPATCH(visit_any_int(value));
- }
- Result visit_char(int value) {
- return FMT_DISPATCH(visit_any_int(value));
- }
- template
- Result visit_any_int(T) {
- return FMT_DISPATCH(visit_unhandled_arg());
- }
-
- Result visit_double(double value) {
- return FMT_DISPATCH(visit_any_double(value));
- }
- Result visit_long_double(long double value) {
- return FMT_DISPATCH(visit_any_double(value));
- }
- template
- Result visit_any_double(T) {
- return FMT_DISPATCH(visit_unhandled_arg());
- }
-
- Result visit_string(Arg::StringValue) {
- return FMT_DISPATCH(visit_unhandled_arg());
- }
- Result visit_wstring(Arg::StringValue) {
- return FMT_DISPATCH(visit_unhandled_arg());
- }
- Result visit_pointer(const void *) {
- return FMT_DISPATCH(visit_unhandled_arg());
- }
- Result visit_custom(Arg::CustomValue) {
- return FMT_DISPATCH(visit_unhandled_arg());
- }
-
- Result visit(const Arg &arg) {
- switch (arg.type) {
- default:
- assert(false);
- // Fall through.
- case Arg::INT:
- return FMT_DISPATCH(visit_int(arg.int_value));
- case Arg::UINT:
- return FMT_DISPATCH(visit_uint(arg.uint_value));
- case Arg::LONG_LONG:
- return FMT_DISPATCH(visit_long_long(arg.long_long_value));
- case Arg::ULONG_LONG:
- return FMT_DISPATCH(visit_ulong_long(arg.ulong_long_value));
- case Arg::DOUBLE:
- return FMT_DISPATCH(visit_double(arg.double_value));
- case Arg::LONG_DOUBLE:
- return FMT_DISPATCH(visit_long_double(arg.long_double_value));
- case Arg::CHAR:
- return FMT_DISPATCH(visit_char(arg.int_value));
- case Arg::STRING:
- return FMT_DISPATCH(visit_string(arg.string));
- case Arg::WSTRING:
- return FMT_DISPATCH(visit_wstring(arg.wstring));
- case Arg::POINTER:
- return FMT_DISPATCH(visit_pointer(arg.pointer_value));
- case Arg::CUSTOM:
- return FMT_DISPATCH(visit_custom(arg.custom));
- }
- }
-};
-
-class RuntimeError : public std::runtime_error {
- protected:
- RuntimeError() : std::runtime_error("") {}
-};
-
-template
-class ArgFormatter;
-} // namespace internal
-
-/**
- An argument list.
- */
-class ArgList {
- private:
- const internal::Arg *args_;
- std::size_t size_;
-
- public:
- ArgList() : size_(0) {}
- ArgList(const internal::Arg *args, std::size_t size)
- : args_(args), size_(size) {}
-
- /**
- Returns the list size (the number of arguments).
- */
- std::size_t size() const { return size_; }
-
- /**
- Returns the argument at specified index.
- */
- const internal::Arg &operator[](std::size_t index) const {
- return args_[index];
- }
-};
-
-struct FormatSpec;
-
-namespace internal {
-
-class FormatterBase {
-protected:
- ArgList args_;
- int next_arg_index_;
- const char *error_;
-
- FormatterBase() : error_(0) {}
-
- const Arg &next_arg();
-
- const Arg &handle_arg_index(unsigned arg_index);
-
- template
- void write(BasicWriter &w, const Char *start, const Char *end) {
- if (start != end)
- w << BasicStringRef(start, end - start);
- }
-
- // TODO
-};
-
-// A printf formatter.
-template
-class PrintfFormatter : private FormatterBase {
- private:
- void parse_flags(FormatSpec &spec, const Char *&s);
-
- // Parses argument index, flags and width and returns the parsed
- // argument index.
- unsigned parse_header(const Char *&s, FormatSpec &spec);
-
- public:
- void format(BasicWriter &writer,
- BasicStringRef format, const ArgList &args);
-};
-} // namespace internal
-
-// A formatter.
-template
-class BasicFormatter : private internal::FormatterBase {
-private:
- BasicWriter &writer_;
- const Char *start_;
- internal::FormatErrorReporter report_error_;
-
- // Parses argument index and returns an argument with this index.
- const internal::Arg &parse_arg_index(const Char *&s);
-
- void check_sign(const Char *&s, const internal::Arg &arg);
-
-public:
- explicit BasicFormatter(BasicWriter &w) : writer_(w) {}
-
- BasicWriter &writer() { return writer_; }
-
- void format(BasicStringRef format_str, const ArgList &args);
-
- const Char *format(const Char *format_str, const internal::Arg &arg);
-};
-
-enum Alignment {
- ALIGN_DEFAULT, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_NUMERIC
-};
-
-// Flags.
-enum {
- SIGN_FLAG = 1, PLUS_FLAG = 2, MINUS_FLAG = 4, HASH_FLAG = 8,
- CHAR_FLAG = 0x10 // Argument has char type - used in error reporting.
-};
-
-// An empty format specifier.
-struct EmptySpec {};
-
-// A type specifier.
-template
-struct TypeSpec : EmptySpec {
- Alignment align() const { return ALIGN_DEFAULT; }
- unsigned width() const { return 0; }
- int precision() const { return -1; }
- bool flag(unsigned) const { return false; }
- char type() const { return TYPE; }
- char fill() const { return ' '; }
-};
-
-// A width specifier.
-struct WidthSpec {
- unsigned width_;
- // Fill is always wchar_t and cast to char if necessary to avoid having
- // two specialization of WidthSpec and its subclasses.
- wchar_t fill_;
-
- WidthSpec(unsigned width, wchar_t fill) : width_(width), fill_(fill) {}
-
- unsigned width() const { return width_; }
- wchar_t fill() const { return fill_; }
-};
-
-// An alignment specifier.
-struct AlignSpec : WidthSpec {
- Alignment align_;
-
- AlignSpec(unsigned width, wchar_t fill, Alignment align = ALIGN_DEFAULT)
- : WidthSpec(width, fill), align_(align) {}
-
- Alignment align() const { return align_; }
-
- int precision() const { return -1; }
-};
-
-// An alignment and type specifier.
-template
-struct AlignTypeSpec : AlignSpec {
- AlignTypeSpec(unsigned width, wchar_t fill) : AlignSpec(width, fill) {}
-
- bool flag(unsigned) const { return false; }
- char type() const { return TYPE; }
-};
-
-// A full format specifier.
-struct FormatSpec : AlignSpec {
- unsigned flags_;
- int precision_;
- char type_;
-
- FormatSpec(
- unsigned width = 0, char type = 0, wchar_t fill = ' ')
- : AlignSpec(width, fill), flags_(0), precision_(-1), type_(type) {}
-
- bool flag(unsigned f) const { return (flags_ & f) != 0; }
- int precision() const { return precision_; }
- char type() const { return type_; }
-};
-
-// An integer format specifier.
-template , typename Char = char>
-class IntFormatSpec : public SpecT {
- private:
- T value_;
-
- public:
- IntFormatSpec(T value, const SpecT &spec = SpecT())
- : SpecT(spec), value_(value) {}
-
- T value() const { return value_; }
-};
-
-// A string format specifier.
-template
-class StrFormatSpec : public AlignSpec {
- private:
- const T *str_;
-
- public:
- StrFormatSpec(const T *str, unsigned width, wchar_t fill)
- : AlignSpec(width, fill), str_(str) {}
-
- const T *str() const { return str_; }
-};
-
-/**
- Returns an integer format specifier to format the value in base 2.
- */
-IntFormatSpec > bin(int value);
-
-/**
- Returns an integer format specifier to format the value in base 8.
- */
-IntFormatSpec > oct(int value);
-
-/**
- Returns an integer format specifier to format the value in base 16 using
- lower-case letters for the digits above 9.
- */
-IntFormatSpec > hex(int value);
-
-/**
- Returns an integer formatter format specifier to format in base 16 using
- upper-case letters for the digits above 9.
- */
-IntFormatSpec > hexu(int value);
-
-/**
- \rst
- Returns an integer format specifier to pad the formatted argument with the
- fill character to the specified width using the default (right) numeric
- alignment.
-
- **Example**::
-
- Writer out;
- out << pad(hex(0xcafe), 8, '0');
- // out.str() == "0000cafe"
-
- \endrst
- */
-template
-IntFormatSpec, Char> pad(
- int value, unsigned width, Char fill = ' ');
-
-#define FMT_DEFINE_INT_FORMATTERS(TYPE) \
-inline IntFormatSpec > bin(TYPE value) { \
- return IntFormatSpec >(value, TypeSpec<'b'>()); \
-} \
- \
-inline IntFormatSpec > oct(TYPE value) { \
- return IntFormatSpec >(value, TypeSpec<'o'>()); \
-} \
- \
-inline IntFormatSpec > hex(TYPE value) { \
- return IntFormatSpec >(value, TypeSpec<'x'>()); \
-} \
- \
-inline IntFormatSpec > hexu(TYPE value) { \
- return IntFormatSpec >(value, TypeSpec<'X'>()); \
-} \
- \
-template \
-inline IntFormatSpec > pad( \
- IntFormatSpec > f, unsigned width) { \
- return IntFormatSpec >( \
- f.value(), AlignTypeSpec(width, ' ')); \
-} \
- \
-/* For compatibility with older compilers we provide two overloads for pad, */ \
-/* one that takes a fill character and one that doesn't. In the future this */ \
-/* can be replaced with one overload making the template argument Char */ \
-/* default to char (C++11). */ \
-template \
-inline IntFormatSpec, Char> pad( \
- IntFormatSpec, Char> f, \
- unsigned width, Char fill) { \
- return IntFormatSpec, Char>( \
- f.value(), AlignTypeSpec(width, fill)); \
-} \
- \
-inline IntFormatSpec > pad( \
- TYPE value, unsigned width) { \
- return IntFormatSpec >( \
- value, AlignTypeSpec<0>(width, ' ')); \
-} \
- \
-template \
-inline IntFormatSpec, Char> pad( \
- TYPE value, unsigned width, Char fill) { \
- return IntFormatSpec, Char>( \
- value, AlignTypeSpec<0>(width, fill)); \
-}
-
-FMT_DEFINE_INT_FORMATTERS(int)
-FMT_DEFINE_INT_FORMATTERS(long)
-FMT_DEFINE_INT_FORMATTERS(unsigned)
-FMT_DEFINE_INT_FORMATTERS(unsigned long)
-FMT_DEFINE_INT_FORMATTERS(LongLong)
-FMT_DEFINE_INT_FORMATTERS(ULongLong)
-
-/**
- \rst
- Returns a string formatter that pads the formatted argument with the fill
- character to the specified width using the default (left) string alignment.
-
- **Example**::
-
- std::string s = str(Writer() << pad("abc", 8));
- // s == "abc "
-
- \endrst
- */
-template
-inline StrFormatSpec pad(
- const Char *str, unsigned width, Char fill = ' ') {
- return StrFormatSpec(str, width, fill);
-}
-
-inline StrFormatSpec pad(
- const wchar_t *str, unsigned width, char fill = ' ') {
- return StrFormatSpec(str, width, fill);
-}
-
-// Generates a comma-separated list with results of applying f to numbers 0..n-1.
-# define FMT_GEN(n, f) FMT_GEN##n(f)
-# define FMT_GEN1(f) f(0)
-# define FMT_GEN2(f) FMT_GEN1(f), f(1)
-# define FMT_GEN3(f) FMT_GEN2(f), f(2)
-# define FMT_GEN4(f) FMT_GEN3(f), f(3)
-# define FMT_GEN5(f) FMT_GEN4(f), f(4)
-# define FMT_GEN6(f) FMT_GEN5(f), f(5)
-# define FMT_GEN7(f) FMT_GEN6(f), f(6)
-# define FMT_GEN8(f) FMT_GEN7(f), f(7)
-# define FMT_GEN9(f) FMT_GEN8(f), f(8)
-# define FMT_GEN10(f) FMT_GEN9(f), f(9)
-
-# define FMT_MAKE_TEMPLATE_ARG(n) typename T##n
-# define FMT_MAKE_ARG(n) const T##n &v##n
-# define FMT_MAKE_REF_char(n) fmt::internal::MakeArg(v##n)
-# define FMT_MAKE_REF_wchar_t(n) fmt::internal::MakeArg(v##n)
-
-#if FMT_USE_VARIADIC_TEMPLATES
-// Defines a variadic function returning void.
-# define FMT_VARIADIC_VOID(func, arg_type) \
- template \
- void func(arg_type arg1, const Args & ... args) { \
- using fmt::internal::Arg; \
- const Arg arg_array[fmt::internal::NonZero::VALUE] = { \
- fmt::internal::MakeArg(args)... \
- }; \
- func(arg1, ArgList(arg_array, sizeof...(Args))); \
- }
-
-// Defines a variadic constructor.
-# define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \
- template \
- ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) { \
- using fmt::internal::Arg; \
- const Arg arg_array[fmt::internal::NonZero::VALUE] = { \
- fmt::internal::MakeArg(args)... \
- }; \
- func(arg0, arg1, ArgList(arg_array, sizeof...(Args))); \
- }
-
-#else
-
-# define FMT_MAKE_REF(n) fmt::internal::MakeArg(v##n)
-// Defines a wrapper for a function taking one argument of type arg_type
-// and n additional arguments of arbitrary types.
-# define FMT_WRAP1(func, arg_type, n) \
- template \
- inline void func(arg_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \
- const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF)}; \
- func(arg1, fmt::ArgList(args, sizeof(args) / sizeof(*args))); \
- }
-
-// Emulates a variadic function returning void on a pre-C++11 compiler.
-# define FMT_VARIADIC_VOID(func, arg_type) \
- FMT_WRAP1(func, arg_type, 1) FMT_WRAP1(func, arg_type, 2) \
- FMT_WRAP1(func, arg_type, 3) FMT_WRAP1(func, arg_type, 4) \
- FMT_WRAP1(func, arg_type, 5) FMT_WRAP1(func, arg_type, 6) \
- FMT_WRAP1(func, arg_type, 7) FMT_WRAP1(func, arg_type, 8) \
- FMT_WRAP1(func, arg_type, 9) FMT_WRAP1(func, arg_type, 10)
-
-# define FMT_CTOR(ctor, func, arg0_type, arg1_type, n) \
- template \
- ctor(arg0_type arg0, arg1_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \
- const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF)}; \
- func(arg0, arg1, fmt::ArgList(args, sizeof(args) / sizeof(*args))); \
- }
-
-// Emulates a variadic constructor on a pre-C++11 compiler.
-# define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \
- FMT_CTOR(ctor, func, arg0_type, arg1_type, 1) \
- FMT_CTOR(ctor, func, arg0_type, arg1_type, 2) \
- FMT_CTOR(ctor, func, arg0_type, arg1_type, 3) \
- FMT_CTOR(ctor, func, arg0_type, arg1_type, 4) \
- FMT_CTOR(ctor, func, arg0_type, arg1_type, 5) \
- FMT_CTOR(ctor, func, arg0_type, arg1_type, 6) \
- FMT_CTOR(ctor, func, arg0_type, arg1_type, 7) \
- FMT_CTOR(ctor, func, arg0_type, arg1_type, 8) \
- FMT_CTOR(ctor, func, arg0_type, arg1_type, 9) \
- FMT_CTOR(ctor, func, arg0_type, arg1_type, 10)
-#endif
-
-// Generates a comma-separated list with results of applying f to pairs
-// (argument, index).
-#define FMT_FOR_EACH1(f, x0) f(x0, 0)
-#define FMT_FOR_EACH2(f, x0, x1) \
- FMT_FOR_EACH1(f, x0), f(x1, 1)
-#define FMT_FOR_EACH3(f, x0, x1, x2) \
- FMT_FOR_EACH2(f, x0 ,x1), f(x2, 2)
-#define FMT_FOR_EACH4(f, x0, x1, x2, x3) \
- FMT_FOR_EACH3(f, x0, x1, x2), f(x3, 3)
-#define FMT_FOR_EACH5(f, x0, x1, x2, x3, x4) \
- FMT_FOR_EACH4(f, x0, x1, x2, x3), f(x4, 4)
-#define FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5) \
- FMT_FOR_EACH5(f, x0, x1, x2, x3, x4), f(x5, 5)
-#define FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6) \
- FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5), f(x6, 6)
-#define FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7) \
- FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6), f(x7, 7)
-#define FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8) \
- FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7), f(x8, 8)
-#define FMT_FOR_EACH10(f, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) \
- FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8), f(x9, 9)
-
-/**
-An error returned by an operating system or a language runtime,
-for example a file opening error.
-*/
-class SystemError : public internal::RuntimeError {
- private:
- void init(int error_code, StringRef format_str, const ArgList &args);
-
- protected:
- int error_code_;
-
- typedef char Char; // For FMT_VARIADIC_CTOR.
-
- SystemError() {}
-
- public:
- /**
- \rst
- Constructs a :cpp:class:`fmt::SystemError` object with the description
- of the form "**: **", where ** is the
- formatted message and ** is the system message corresponding
- to the error code.
- *error_code* is a system error code as given by ``errno``.
- \endrst
- */
- SystemError(int error_code, StringRef message) {
- init(error_code, message, ArgList());
- }
- FMT_VARIADIC_CTOR(SystemError, init, int, StringRef)
-
- int error_code() const { return error_code_; }
-};
-
-/**
- \rst
- This template provides operations for formatting and writing data into
- a character stream. The output is stored in a memory buffer that grows
- dynamically.
-
- You can use one of the following typedefs for common character types:
-
- +---------+----------------------+
- | Type | Definition |
- +=========+======================+
- | Writer | BasicWriter |
- +---------+----------------------+
- | WWriter | BasicWriter |
- +---------+----------------------+
-
- **Example**::
-
- Writer out;
- out << "The answer is " << 42 << "\n";
- out.write("({:+f}, {:+f})", -3.14, 3.14);
-
- This will write the following output to the ``out`` object:
-
- .. code-block:: none
-
- The answer is 42
- (-3.140000, +3.140000)
-
- The output can be converted to an ``std::string`` with ``out.str()`` or
- accessed as a C string with ``out.c_str()``.
- \endrst
- */
-template
-class BasicWriter {
- private:
- // Output buffer.
- mutable internal::Array buffer_;
-
- typedef typename internal::CharTraits::CharPtr CharPtr;
-
-#if defined(_SECURE_SCL) && _SECURE_SCL
- // Returns pointer value.
- static Char *get(CharPtr p) { return p.base(); }
-#else
- static Char *get(Char *p) { return p; }
-#endif
-
- static CharPtr fill_padding(CharPtr buffer,
- unsigned total_size, std::size_t content_size, wchar_t fill);
-
- // Grows the buffer by n characters and returns a pointer to the newly
- // allocated area.
- CharPtr grow_buffer(std::size_t n) {
- std::size_t size = buffer_.size();
- buffer_.resize(size + n);
- return internal::make_ptr(&buffer_[size], n);
- }
-
- // Prepare a buffer for integer formatting.
- CharPtr prepare_int_buffer(unsigned num_digits,
- const EmptySpec &, const char *prefix, unsigned prefix_size) {
- unsigned size = prefix_size + num_digits;
- CharPtr p = grow_buffer(size);
- std::copy(prefix, prefix + prefix_size, p);
- return p + size - 1;
- }
-
- template
- CharPtr prepare_int_buffer(unsigned num_digits,
- const Spec &spec, const char *prefix, unsigned prefix_size);
-
- // Formats an integer.
- template
- void write_int(T value, const Spec &spec);
-
- // Formats a floating-point number (double or long double).
- template
- void write_double(T value, const FormatSpec &spec);
-
- // Writes a formatted string.
- template
- CharPtr write_str(
- const StrChar *s, std::size_t size, const AlignSpec &spec);
-
- template
- void write_str(
- const internal::Arg::StringValue &str, const FormatSpec &spec);
-
- // This method is private to disallow writing a wide string to a
- // char stream and vice versa. If you want to print a wide string
- // as a pointer as std::ostream does, cast it to const void*.
- // Do not implement!
- void operator<<(typename internal::CharTraits::UnsupportedStrType);
-
- friend class internal::ArgFormatter;
- friend class internal::PrintfFormatter;
-
- public:
- /**
- Constructs a ``BasicWriter`` object.
- */
- BasicWriter() {}
-
-#if FMT_USE_RVALUE_REFERENCES
- /**
- Constructs a ``BasicWriter`` object moving the content of the other
- object to it.
- */
- BasicWriter(BasicWriter &&other) : buffer_(std::move(other.buffer_)) {}
-
- /**
- Moves the content of the other ``BasicWriter`` object to this one.
- */
- BasicWriter& operator=(BasicWriter &&other) {
- assert(this != &other);
- buffer_ = std::move(other.buffer_);
- return *this;
- }
-#endif
-
- /**
- Returns the total number of characters written.
- */
- std::size_t size() const { return buffer_.size(); }
-
- /**
- Returns a pointer to the output buffer content. No terminating null
- character is appended.
- */
- const Char *data() const { return &buffer_[0]; }
-
- /**
- Returns a pointer to the output buffer content with terminating null
- character appended.
- */
- const Char *c_str() const {
- std::size_t size = buffer_.size();
- buffer_.reserve(size + 1);
- buffer_[size] = '\0';
- return &buffer_[0];
- }
-
- /**
- Returns the content of the output buffer as an `std::string`.
- */
- std::basic_string str() const {
- return std::basic_string(&buffer_[0], buffer_.size());
- }
-
- /**
- \rst
- Writes formatted data.
-
- *args* is an argument list representing arbitrary arguments.
-
- **Example**::
-
- Writer out;
- out.write("Current point:\n");
- out.write("({:+f}, {:+f})", -3.14, 3.14);
-
- This will write the following output to the ``out`` object:
-
- .. code-block:: none
-
- Current point:
- (-3.140000, +3.140000)
-
- The output can be accessed using :meth:`data`, :meth:`c_str` or :meth:`str`
- methods.
-
- See also `Format String Syntax`_.
- \endrst
- */
- void write(BasicStringRef format, const ArgList &args) {
- BasicFormatter(*this).format(format, args);
- }
- FMT_VARIADIC_VOID(write, fmt::BasicStringRef)
-
- BasicWriter &operator<<(int value) {
- return *this << IntFormatSpec(value);
- }
- BasicWriter &operator<<(unsigned value) {
- return *this << IntFormatSpec(value);
- }
- BasicWriter &operator<<(long value) {
- return *this << IntFormatSpec(value);
- }
- BasicWriter &operator<<(unsigned long value) {
- return *this << IntFormatSpec(value);
- }
- BasicWriter &operator<<(LongLong value) {
- return *this << IntFormatSpec(value);
- }
-
- /**
- Formats *value* and writes it to the stream.
- */
- BasicWriter &operator<<(ULongLong value) {
- return *this << IntFormatSpec(value);
- }
-
- BasicWriter &operator<<(double value) {
- write_double(value, FormatSpec());
- return *this;
- }
-
- /**
- Formats *value* using the general format for floating-point numbers
- (``'g'``) and writes it to the stream.
- */
- BasicWriter &operator<<(long double value) {
- write_double(value, FormatSpec());
- return *this;
- }
-
- /**
- Writes a character to the stream.
- */
- BasicWriter &operator<<(char value) {
- buffer_.push_back(value);
- return *this;
- }
-
- BasicWriter &operator<<(wchar_t value) {
- buffer_.push_back(internal::CharTraits::convert(value));
- return *this;
- }
-
- /**
- Writes *value* to the stream.
- */
- BasicWriter &operator<<(fmt::BasicStringRef value) {
- const Char *str = value.c_str();
- buffer_.append(str, str + value.size());
- return *this;
- }
-
- template
- BasicWriter &operator<<(const IntFormatSpec &spec) {
- internal::CharTraits::convert(FillChar());
- write_int(spec.value(), spec);
- return *this;
- }
-
- template
- BasicWriter &operator<<(const StrFormatSpec &spec) {
- const StrChar *s = spec.str();
- // TODO: error if fill is not convertible to Char
- write_str(s, std::char_traits::length(s), spec);
- return *this;
- }
-
- void clear() { buffer_.clear(); }
-};
-
-template
-template
-typename BasicWriter::CharPtr BasicWriter::write_str(
- const StrChar *s, std::size_t size, const AlignSpec &spec) {
- CharPtr out = CharPtr();
- if (spec.width() > size) {
- out = grow_buffer(spec.width());
- Char fill = static_cast(spec.fill());
- if (spec.align() == ALIGN_RIGHT) {
- std::fill_n(out, spec.width() - size, fill);
- out += spec.width() - size;
- } else if (spec.align() == ALIGN_CENTER) {
- out = fill_padding(out, spec.width(), size, fill);
- } else {
- std::fill_n(out + size, spec.width() - size, fill);
- }
- } else {
- out = grow_buffer(size);
- }
- std::copy(s, s + size, out);
- return out;
-}
-
-template
-template
-typename fmt::BasicWriter::CharPtr
- fmt::BasicWriter::prepare_int_buffer(
- unsigned num_digits, const Spec &spec,
- const char *prefix, unsigned prefix_size) {
- unsigned width = spec.width();
- Alignment align = spec.align();
- Char fill = static_cast(spec.fill());
- if (spec.precision() > static_cast(num_digits)) {
- // Octal prefix '0' is counted as a digit, so ignore it if precision
- // is specified.
- if (prefix_size > 0 && prefix[prefix_size - 1] == '0')
- --prefix_size;
- unsigned number_size = prefix_size + spec.precision();
- AlignSpec subspec(number_size, '0', ALIGN_NUMERIC);
- if (number_size >= width)
- return prepare_int_buffer(num_digits, subspec, prefix, prefix_size);
- buffer_.reserve(width);
- unsigned fill_size = width - number_size;
- if (align != ALIGN_LEFT) {
- CharPtr p = grow_buffer(fill_size);
- std::fill(p, p + fill_size, fill);
- }
- CharPtr result = prepare_int_buffer(
- num_digits, subspec, prefix, prefix_size);
- if (align == ALIGN_LEFT) {
- CharPtr p = grow_buffer(fill_size);
- std::fill(p, p + fill_size, fill);
- }
- return result;
- }
- unsigned size = prefix_size + num_digits;
- if (width <= size) {
- CharPtr p = grow_buffer(size);
- std::copy(prefix, prefix + prefix_size, p);
- return p + size - 1;
- }
- CharPtr p = grow_buffer(width);
- CharPtr end = p + width;
- if (align == ALIGN_LEFT) {
- std::copy(prefix, prefix + prefix_size, p);
- p += size;
- std::fill(p, end, fill);
- } else if (align == ALIGN_CENTER) {
- p = fill_padding(p, width, size, fill);
- std::copy(prefix, prefix + prefix_size, p);
- p += size;
- } else {
- if (align == ALIGN_NUMERIC) {
- if (prefix_size != 0) {
- p = std::copy(prefix, prefix + prefix_size, p);
- size -= prefix_size;
- }
- } else {
- std::copy(prefix, prefix + prefix_size, end - size);
- }
- std::fill(p, end - size, fill);
- p = end;
- }
- return p - 1;
-}
-
-template
-template
-void BasicWriter::write_int(T value, const Spec &spec) {
- unsigned prefix_size = 0;
- typedef typename internal::IntTraits::MainType UnsignedType;
- UnsignedType abs_value = value;
- char prefix[4] = "";
- if (internal::is_negative(value)) {
- prefix[0] = '-';
- ++prefix_size;
- abs_value = 0 - abs_value;
- } else if (spec.flag(SIGN_FLAG)) {
- prefix[0] = spec.flag(PLUS_FLAG) ? '+' : ' ';
- ++prefix_size;
- }
- switch (spec.type()) {
- case 0: case 'd': {
- unsigned num_digits = internal::count_digits(abs_value);
- CharPtr p = prepare_int_buffer(
- num_digits, spec, prefix, prefix_size) + 1 - num_digits;
- internal::format_decimal(get(p), abs_value, num_digits);
- break;
- }
- case 'x': case 'X': {
- UnsignedType n = abs_value;
- if (spec.flag(HASH_FLAG)) {
- prefix[prefix_size++] = '0';
- prefix[prefix_size++] = spec.type();
- }
- unsigned num_digits = 0;
- do {
- ++num_digits;
- } while ((n >>= 4) != 0);
- Char *p = get(prepare_int_buffer(
- num_digits, spec, prefix, prefix_size));
- n = abs_value;
- const char *digits = spec.type() == 'x' ?
- "0123456789abcdef" : "0123456789ABCDEF";
- do {
- *p-- = digits[n & 0xf];
- } while ((n >>= 4) != 0);
- break;
- }
- case 'b': case 'B': {
- UnsignedType n = abs_value;
- if (spec.flag(HASH_FLAG)) {
- prefix[prefix_size++] = '0';
- prefix[prefix_size++] = spec.type();
- }
- unsigned num_digits = 0;
- do {
- ++num_digits;
- } while ((n >>= 1) != 0);
- Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size));
- n = abs_value;
- do {
- *p-- = '0' + (n & 1);
- } while ((n >>= 1) != 0);
- break;
- }
- case 'o': {
- UnsignedType n = abs_value;
- if (spec.flag(HASH_FLAG))
- prefix[prefix_size++] = '0';
- unsigned num_digits = 0;
- do {
- ++num_digits;
- } while ((n >>= 3) != 0);
- Char *p = get(prepare_int_buffer(num_digits, spec, prefix, prefix_size));
- n = abs_value;
- do {
- *p-- = '0' + (n & 7);
- } while ((n >>= 3) != 0);
- break;
- }
- default:
- internal::report_unknown_type(
- spec.type(), spec.flag(CHAR_FLAG) ? "char" : "integer");
- break;
- }
-}
-
-// Formats a value.
-template
-void format(BasicFormatter &f, const Char *format_str, const T &value) {
- std::basic_ostringstream os;
- os << value;
- f.format(format_str, internal::MakeArg(os.str()));
-}
-
-// Reports a system error without throwing an exception.
-// Can be used to report errors from destructors.
-void report_system_error(int error_code, StringRef message) FMT_NOEXCEPT(true);
-
-#ifdef _WIN32
-
-/**
- A Windows error.
-*/
-class WindowsError : public SystemError {
- private:
- void init(int error_code, StringRef format_str, const ArgList &args);
-
- public:
- /**
- \rst
- Constructs a :cpp:class:`fmt::WindowsError` object with the description
- of the form "**: **", where ** is the
- formatted message and ** is the system message corresponding
- to the error code.
- *error_code* is a Windows error code as given by ``GetLastError``.
- \endrst
- */
- WindowsError(int error_code, StringRef message) {
- init(error_code, message, ArgList());
- }
- FMT_VARIADIC_CTOR(WindowsError, init, int, StringRef)
-};
-
-// Reports a Windows error without throwing an exception.
-// Can be used to report errors from destructors.
-void report_windows_error(int error_code, StringRef message) FMT_NOEXCEPT(true);
-
-#endif
-
-enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE };
-
-/**
- Formats a string and prints it to stdout using ANSI escape sequences
- to specify color (experimental).
- Example:
- PrintColored(fmt::RED, "Elapsed time: {0:.2f} seconds") << 1.23;
- */
-void print_colored(Color c, StringRef format, const ArgList &args);
-
-/**
- \rst
- Formats arguments and returns the result as a string.
-
- **Example**::
-
- std::string message = format("The answer is {}", 42);
- \endrst
-*/
-inline std::string format(StringRef format_str, const ArgList &args) {
- Writer w;
- w.write(format_str, args);
- return w.str();
-}
-
-inline std::wstring format(WStringRef format_str, const ArgList &args) {
- WWriter w;
- w.write(format_str, args);
- return w.str();
-}
-
-/**
- \rst
- Prints formatted data to the file *f*.
-
- **Example**::
-
- print(stderr, "Don't {}!", "panic");
- \endrst
- */
-void print(std::FILE *f, StringRef format_str, const ArgList &args);
-
-/**
- \rst
- Prints formatted data to ``stdout``.
-
- **Example**::
-
- print("Elapsed time: {0:.2f} seconds", 1.23);
- \endrst
- */
-inline void print(StringRef format_str, const ArgList &args) {
- print(stdout, format_str, args);
-}
-
-/**
- \rst
- Prints formatted data to the stream *os*.
-
- **Example**::
-
- print(cerr, "Don't {}!", "panic");
- \endrst
- */
-void print(std::ostream &os, StringRef format_str, const ArgList &args);
-
-template
-void printf(BasicWriter &w,
- BasicStringRef format, const ArgList &args) {
- internal::PrintfFormatter().format(w, format, args);
-}
-
-/**
- \rst
- Formats arguments and returns the result as a string.
-
- **Example**::
-
- std::string message = fmt::sprintf("The answer is %d", 42);
- \endrst
-*/
-inline std::string sprintf(StringRef format, const ArgList &args) {
- Writer w;
- printf(w, format, args);
- return w.str();
-}
-
-/**
- \rst
- Prints formatted data to the file *f*.
-
- **Example**::
-
- fmt::fprintf(stderr, "Don't %s!", "panic");
- \endrst
- */
-int fprintf(std::FILE *f, StringRef format, const ArgList &args);
-
-/**
- \rst
- Prints formatted data to ``stdout``.
-
- **Example**::
-
- fmt::printf("Elapsed time: %.2f seconds", 1.23);
- \endrst
- */
-inline int printf(StringRef format, const ArgList &args) {
- return fprintf(stdout, format, args);
-}
-
-/**
- Fast integer formatter.
- */
-class FormatInt {
- private:
- // Buffer should be large enough to hold all digits (digits10 + 1),
- // a sign and a null character.
- enum {BUFFER_SIZE = std::numeric_limits::digits10 + 3};
- mutable char buffer_[BUFFER_SIZE];
- char *str_;
-
- // Formats value in reverse and returns the number of digits.
- char *format_decimal(ULongLong value) {
- char *buffer_end = buffer_ + BUFFER_SIZE - 1;
- while (value >= 100) {
- // Integer division is slow so do it for a group of two digits instead
- // of for every digit. The idea comes from the talk by Alexandrescu
- // "Three Optimization Tips for C++". See speed-test for a comparison.
- unsigned index = (value % 100) * 2;
- value /= 100;
- *--buffer_end = internal::DIGITS[index + 1];
- *--buffer_end = internal::DIGITS[index];
- }
- if (value < 10) {
- *--buffer_end = static_cast('0' + value);
- return buffer_end;
- }
- unsigned index = static_cast(value * 2);
- *--buffer_end = internal::DIGITS[index + 1];
- *--buffer_end = internal::DIGITS[index];
- return buffer_end;
- }
-
- void FormatSigned(LongLong value) {
- ULongLong abs_value = static_cast(value);
- bool negative = value < 0;
- if (negative)
- abs_value = 0 - abs_value;
- str_ = format_decimal(abs_value);
- if (negative)
- *--str_ = '-';
- }
-
- public:
- explicit FormatInt(int value) { FormatSigned(value); }
- explicit FormatInt(long value) { FormatSigned(value); }
- explicit FormatInt(LongLong value) { FormatSigned(value); }
- explicit FormatInt(unsigned value) : str_(format_decimal(value)) {}
- explicit FormatInt(unsigned long value) : str_(format_decimal(value)) {}
- explicit FormatInt(ULongLong value) : str_(format_decimal(value)) {}
-
- /**
- Returns the number of characters written to the output buffer.
- */
- std::size_t size() const { return buffer_ - str_ + BUFFER_SIZE - 1; }
-
- /**
- Returns a pointer to the output buffer content. No terminating null
- character is appended.
- */
- const char *data() const { return str_; }
-
- /**
- Returns a pointer to the output buffer content with terminating null
- character appended.
- */
- const char *c_str() const {
- buffer_[BUFFER_SIZE - 1] = '\0';
- return str_;
- }
-
- /**
- Returns the content of the output buffer as an `std::string`.
- */
- std::string str() const { return std::string(str_, size()); }
-};
-
-// Formats a decimal integer value writing into buffer and returns
-// a pointer to the end of the formatted string. This function doesn't
-// write a terminating null character.
-template
-inline void format_decimal(char *&buffer, T value) {
- typename internal::IntTraits::MainType abs_value = value;
- if (internal::is_negative(value)) {
- *buffer++ = '-';
- abs_value = 0 - abs_value;
- }
- if (abs_value < 100) {
- if (abs_value < 10) {
- *buffer++ = static_cast('0' + abs_value);
- return;
- }
- unsigned index = static_cast(abs_value * 2);
- *buffer++ = internal::DIGITS[index];
- *buffer++ = internal::DIGITS[index + 1];
- return;
- }
- unsigned num_digits = internal::count_digits(abs_value);
- internal::format_decimal(buffer, abs_value, num_digits);
- buffer += num_digits;
-}
-}
-
-#if FMT_GCC_VERSION
-// Use the system_header pragma to suppress warnings about variadic macros
-// because suppressing -Wvariadic-macros with the diagnostic pragma doesn't
-// work. It is used at the end because we want to suppress as little warnings
-// as possible.
-# pragma GCC system_header
-#endif
-
-// This is used to work around VC++ bugs in handling variadic macros.
-#define FMT_EXPAND(args) args
-
-// Returns the number of arguments.
-// Based on https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s.
-#define FMT_NARG(...) FMT_NARG_(__VA_ARGS__, FMT_RSEQ_N())
-#define FMT_NARG_(...) FMT_EXPAND(FMT_ARG_N(__VA_ARGS__))
-#define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
-#define FMT_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
-
-#define FMT_CONCAT(a, b) a##b
-#define FMT_FOR_EACH_(N, f, ...) \
- FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__))
-#define FMT_FOR_EACH(f, ...) \
- FMT_EXPAND(FMT_FOR_EACH_(FMT_NARG(__VA_ARGS__), f, __VA_ARGS__))
-
-#define FMT_ADD_ARG_NAME(type, index) type arg##index
-#define FMT_GET_ARG_NAME(type, index) arg##index
-
-#if FMT_USE_VARIADIC_TEMPLATES
-# define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \
- template \
- ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
- const Args & ... args) { \
- using fmt::internal::Arg; \
- const Arg array[fmt::internal::NonZero::VALUE] = { \
- fmt::internal::MakeArg(args)... \
- }; \
- call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \
- fmt::ArgList(array, sizeof...(Args))); \
- }
-#else
-// Defines a wrapper for a function taking __VA_ARGS__ arguments
-// and n additional arguments of arbitrary types.
-# define FMT_WRAP(Char, ReturnType, func, call, n, ...) \
- template \
- inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \
- FMT_GEN(n, FMT_MAKE_ARG)) { \
- const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF_##Char)}; \
- call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \
- fmt::ArgList(args, sizeof(args) / sizeof(*args))); \
- }
-
-# define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \
- inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__)) { \
- call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList()); \
- } \
- FMT_WRAP(Char, ReturnType, func, call, 1, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 2, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 3, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 4, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 5, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 6, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 7, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 8, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 9, __VA_ARGS__) \
- FMT_WRAP(Char, ReturnType, func, call, 10, __VA_ARGS__)
-#endif // FMT_USE_VARIADIC_TEMPLATES
-
-/**
- \rst
- Defines a variadic function with the specified return type, function name
- and argument types passed as variable arguments to this macro.
-
- **Example**::
-
- void print_error(const char *file, int line, const char *format,
- const fmt::ArgList &args) {
- fmt::print("{}: {}: ", file, line);
- fmt::print(format, args);
- }
- FMT_VARIADIC(void, print_error, const char *, int, const char *)
-
- ``FMT_VARIADIC`` is used for compatibility with legacy C++ compilers that
- don't implement variadic templates. You don't have to use this macro if
- you don't need legacy compiler support and can use variadic templates
- directly::
-
- template
- void print_error(const char *file, int line, const char *format,
- const Args & ... args) {
- fmt::print("{}: {}: ", file, line);
- fmt::print(format, args...);
- }
- \endrst
- */
-#define FMT_VARIADIC(ReturnType, func, ...) \
- FMT_VARIADIC_(char, ReturnType, func, return func, __VA_ARGS__)
-
-#define FMT_VARIADIC_W(ReturnType, func, ...) \
- FMT_VARIADIC_(wchar_t, ReturnType, func, return func, __VA_ARGS__)
-
-namespace fmt {
-FMT_VARIADIC(std::string, format, StringRef)
-FMT_VARIADIC_W(std::wstring, format, WStringRef)
-FMT_VARIADIC(void, print, StringRef)
-FMT_VARIADIC(void, print, std::FILE *, StringRef)
-FMT_VARIADIC(void, print, std::ostream &, StringRef)
-FMT_VARIADIC(void, print_colored, Color, StringRef)
-FMT_VARIADIC(std::string, sprintf, StringRef)
-FMT_VARIADIC(int, printf, StringRef)
-FMT_VARIADIC(int, fprintf, std::FILE *, StringRef)
-}
-
-// Restore warnings.
-#if FMT_GCC_VERSION >= 406
-# pragma GCC diagnostic pop
-#endif
-
-#endif // FMT_FORMAT_H_
Property changes on: ps/trunk/source/third_party/cppformat/format.h
___________________________________________________________________
Deleted: svn:eol-style
## -1 +0,0 ##
-native
\ No newline at end of property
Index: ps/trunk/source/third_party/cppformat/format.cpp
===================================================================
--- ps/trunk/source/third_party/cppformat/format.cpp (revision 23561)
+++ ps/trunk/source/third_party/cppformat/format.cpp (nonexistent)
@@ -1,1313 +0,0 @@
-/*
- * Slightly modified version of cppformat, by Wildfire Games, for 0 A.D.
- * Based on cppformat v0.11.0 from https://github.com/cppformat/cppformat
- */
-
-/*
- Formatting library for C++
-
- Copyright (c) 2012 - 2014, Victor Zverovich
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "precompiled.h"
-
-// Disable useless MSVC warnings.
-#undef _CRT_SECURE_NO_WARNINGS
-#define _CRT_SECURE_NO_WARNINGS
-#undef _SCL_SECURE_NO_WARNINGS
-#define _SCL_SECURE_NO_WARNINGS
-
-#include "format.h"
-
-#include
-
-#include
-#include
-#include
-#include
-#include
-
-#ifdef _WIN32
-# define WIN32_LEAN_AND_MEAN
-# ifdef __MINGW32__
-# include
-# endif
-# include
-# undef ERROR
-#endif
-
-using fmt::LongLong;
-using fmt::ULongLong;
-using fmt::internal::Arg;
-
-namespace {
-
-#ifndef _MSC_VER
-
-// Portable version of signbit.
-// When compiled in C++11 mode signbit is no longer a macro but a function
-// defined in namespace std and the macro is undefined.
-inline int getsign(double x) {
-#ifdef signbit
- return signbit(x);
-#else
- return std::signbit(x);
-#endif
-}
-
-// Portable version of isinf.
-#ifdef isinf
-inline int isinfinity(double x) { return isinf(x); }
-inline int isinfinity(long double x) { return isinf(x); }
-#else
-inline int isinfinity(double x) { return std::isinf(x); }
-inline int isinfinity(long double x) { return std::isinf(x); }
-#endif
-
-#define FMT_SNPRINTF snprintf
-
-#else // _MSC_VER
-
-# pragma warning(push)
-# pragma warning(disable: 4127) // conditional expression is constant
-# pragma warning(disable:4456) // hides previous local declaration
-
-inline int getsign(double value) {
- if (value < 0) return 1;
- if (value == value) return 0;
- int dec = 0, sign = 0;
- char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail.
- _ecvt_s(buffer, sizeof(buffer), value, 0, &dec, &sign);
- return sign;
-}
-
-inline int isinfinity(double x) { return !_finite(x); }
-
-inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
- va_list args;
- va_start(args, format);
- int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
- va_end(args);
- return result;
-}
-#define FMT_SNPRINTF fmt_snprintf
-
-#endif // _MSC_VER
-
-template
-struct IsLongDouble { enum {VALUE = 0}; };
-
-template <>
-struct IsLongDouble { enum {VALUE = 1}; };
-
-// Checks if a value fits in int - used to avoid warnings about comparing
-// signed and unsigned integers.
-template
-struct IntChecker {
- template
- static bool fits_in_int(T value) {
- unsigned max = INT_MAX;
- return value <= max;
- }
-};
-
-template <>
-struct IntChecker {
- template
- static bool fits_in_int(T value) {
- return value >= INT_MIN && value <= INT_MAX;
- }
-};
-
-const char RESET_COLOR[] = "\x1b[0m";
-
-typedef void (*FormatFunc)(fmt::Writer &, int , fmt::StringRef);
-
-void report_error(FormatFunc func,
- int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) {
- try {
- fmt::Writer full_message;
- func(full_message, error_code, message); // TODO: make sure this doesn't throw
- std::fwrite(full_message.c_str(), full_message.size(), 1, stderr);
- std::fputc('\n', stderr);
- } catch (...) {}
-}
-
-const Arg DUMMY_ARG = {Arg::INT, {0}};
-
-// IsZeroInt::visit(arg) returns true iff arg is a zero integer.
-class IsZeroInt : public fmt::internal::ArgVisitor {
- public:
- template
- bool visit_any_int(T value) { return value == 0; }
-};
-
-// Parses an unsigned integer advancing s to the end of the parsed input.
-// This function assumes that the first character of s is a digit.
-template
-int parse_nonnegative_int(
- const Char *&s, const char *&error) FMT_NOEXCEPT(true) {
- assert('0' <= *s && *s <= '9');
- unsigned value = 0;
- do {
- unsigned new_value = value * 10 + (*s++ - '0');
- // Check if value wrapped around.
- value = new_value >= value ? new_value : UINT_MAX;
- } while ('0' <= *s && *s <= '9');
- if (value > INT_MAX) {
- if (!error)
- error = "number is too big in format";
- return 0;
- }
- return value;
-}
-
-template
-const Char *find_closing_brace(const Char *s, int num_open_braces = 1) {
- for (int n = num_open_braces; *s; ++s) {
- if (*s == '{') {
- ++n;
- } else if (*s == '}') {
- if (--n == 0)
- return s;
- }
- }
- throw fmt::FormatError("unmatched '{' in format");
-}
-
-// Checks if an argument is a valid printf width specifier and sets
-// left alignment if it is negative.
-class WidthHandler : public fmt::internal::ArgVisitor {
- private:
- fmt::FormatSpec &spec_;
-
- public:
- explicit WidthHandler(fmt::FormatSpec &spec) : spec_(spec) {}
-
- unsigned visit_unhandled_arg() {
- throw fmt::FormatError("width is not integer");
- }
-
- template
- unsigned visit_any_int(T value) {
- typedef typename fmt::internal::IntTraits::MainType UnsignedType;
- UnsignedType width = value;
- if (fmt::internal::is_negative(value)) {
- spec_.align_ = fmt::ALIGN_LEFT;
- width = 0 - width;
- }
- if (width > INT_MAX)
- throw fmt::FormatError("number is too big in format");
- return static_cast(width);
- }
-};
-
-class PrecisionHandler :
- public fmt::internal::ArgVisitor {
- public:
- unsigned visit_unhandled_arg() {
- throw fmt::FormatError("precision is not integer");
- }
-
- template
- int visit_any_int(T value) {
- if (!IntChecker::is_signed>::fits_in_int(value))
- throw fmt::FormatError("number is too big in format");
- return static_cast(value);
- }
-};
-
-// Converts an integer argument to type T.
-template
-class ArgConverter : public fmt::internal::ArgVisitor