| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2014-05-03 09:48:54 -07:00
										 |  |  |  Formatting library for C++ | 
					
						
							| 
									
										
										
										
											2012-12-12 07:44:41 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-09 06:56:36 -07:00
										 |  |  |  Copyright (c) 2012 - 2014, Victor Zverovich | 
					
						
							| 
									
										
										
										
											2012-12-12 07:44:41 -08:00
										 |  |  |  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. | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 17:33:50 -07:00
										 |  |  | #ifndef FMT_FORMAT_H_
 | 
					
						
							|  |  |  | #define FMT_FORMAT_H_
 | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | #include <stdint.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-25 08:18:07 -07:00
										 |  |  | #include <cassert>
 | 
					
						
							| 
									
										
										
										
											2014-04-24 12:37:06 -07:00
										 |  |  | #include <cstddef>  // for std::ptrdiff_t
 | 
					
						
							| 
									
										
										
										
											2012-12-18 15:50:14 -08:00
										 |  |  | #include <cstdio>
 | 
					
						
							| 
									
										
										
										
											2013-04-22 08:11:57 -07:00
										 |  |  | #include <algorithm>
 | 
					
						
							| 
									
										
										
										
											2013-09-09 10:42:33 -07:00
										 |  |  | #include <limits>
 | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | #include <stdexcept>
 | 
					
						
							|  |  |  | #include <string>
 | 
					
						
							| 
									
										
										
										
											2012-12-09 09:03:47 -08:00
										 |  |  | #include <sstream>
 | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-23 09:49:59 -07:00
										 |  |  | #if _SECURE_SCL
 | 
					
						
							|  |  |  | # include <iterator>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-09 08:31:08 -08:00
										 |  |  | #ifdef __GNUC__
 | 
					
						
							| 
									
										
										
										
											2013-12-09 17:51:11 -08:00
										 |  |  | # define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
 | 
					
						
							| 
									
										
										
										
											2014-02-15 10:17:10 -08:00
										 |  |  | # define FMT_GCC_EXTENSION __extension__
 | 
					
						
							| 
									
										
										
										
											2014-04-16 09:19:31 -07:00
										 |  |  | // 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
 | 
					
						
							| 
									
										
										
										
											2014-02-15 10:41:00 -08:00
										 |  |  | #else
 | 
					
						
							|  |  |  | # define FMT_GCC_EXTENSION
 | 
					
						
							| 
									
										
										
										
											2013-12-09 08:12:33 -08:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  | #ifdef __GNUC_LIBSTD__
 | 
					
						
							| 
									
										
										
										
											2014-04-24 14:18:37 -07:00
										 |  |  | # define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 17:33:50 -07:00
										 |  |  | #ifdef __has_feature
 | 
					
						
							|  |  |  | # define FMT_HAS_FEATURE(x) __has_feature(x)
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | # define FMT_HAS_FEATURE(x) 0
 | 
					
						
							| 
									
										
										
										
											2014-06-11 15:30:57 +07:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-11 05:52:02 -07:00
										 |  |  | #ifdef __has_builtin
 | 
					
						
							| 
									
										
										
										
											2014-06-11 15:30:57 +07:00
										 |  |  | # define FMT_HAS_BUILTIN(x) __has_builtin(x)
 | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2014-04-23 17:33:50 -07:00
										 |  |  | # define FMT_HAS_BUILTIN(x) 0
 | 
					
						
							| 
									
										
										
										
											2013-05-15 10:04:11 -07:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-06 20:06:44 +00:00
										 |  |  | #ifndef FMT_USE_VARIADIC_TEMPLATES
 | 
					
						
							| 
									
										
										
										
											2014-04-24 07:30:06 -07:00
										 |  |  | // Variadic templates are available in GCC since version 4.4
 | 
					
						
							|  |  |  | // (http://gcc.gnu.org/projects/cxx0x.html) and in Visual C++
 | 
					
						
							|  |  |  | // since version 2013.
 | 
					
						
							| 
									
										
										
										
											2014-03-06 20:06:44 +00:00
										 |  |  | # define FMT_USE_VARIADIC_TEMPLATES \
 | 
					
						
							| 
									
										
										
										
											2014-04-23 17:33:50 -07:00
										 |  |  |    (FMT_HAS_FEATURE(cxx_variadic_templates) || \ | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  |        (FMT_GCC_VERSION >= 404 && __cplusplus >= 201103) || _MSC_VER >= 1800) | 
					
						
							| 
									
										
										
										
											2014-03-06 20:06:44 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-24 07:30:39 -07:00
										 |  |  | #ifndef FMT_USE_RVALUE_REFERENCES
 | 
					
						
							| 
									
										
										
										
											2014-04-24 14:18:37 -07:00
										 |  |  | // Don't use rvalue references when compiling with clang and an old libstdc++
 | 
					
						
							|  |  |  | // as the latter doesn't provide std::move.
 | 
					
						
							| 
									
										
										
										
											2014-04-24 15:39:20 -07:00
										 |  |  | # if defined(FMT_GNUC_LIBSTD_VERSION) && FMT_GNUC_LIBSTD_VERSION <= 402
 | 
					
						
							| 
									
										
										
										
											2014-04-24 14:18:37 -07:00
										 |  |  | #  define FMT_USE_RVALUE_REFERENCES 0
 | 
					
						
							| 
									
										
										
										
											2014-04-26 06:47:25 -07:00
										 |  |  | # else
 | 
					
						
							|  |  |  | #  define FMT_USE_RVALUE_REFERENCES \
 | 
					
						
							|  |  |  |     (FMT_HAS_FEATURE(cxx_rvalue_references) || \ | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  |         (FMT_GCC_VERSION >= 403 && __cplusplus >= 201103) || _MSC_VER >= 1600) | 
					
						
							| 
									
										
										
										
											2014-04-24 14:18:37 -07:00
										 |  |  | # endif
 | 
					
						
							| 
									
										
										
										
											2014-04-24 07:30:39 -07:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-24 12:37:06 -07:00
										 |  |  | #if FMT_USE_RVALUE_REFERENCES
 | 
					
						
							|  |  |  | # include <utility>  // for std::move
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  | // Define FMT_USE_NOEXCEPT to make C++ Format use noexcept (C++11 feature).
 | 
					
						
							| 
									
										
										
										
											2014-04-23 17:33:50 -07:00
										 |  |  | #if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
 | 
					
						
							| 
									
										
										
										
											2013-12-09 17:51:11 -08:00
										 |  |  |   (FMT_GCC_VERSION >= 408 && __cplusplus >= 201103) | 
					
						
							| 
									
										
										
										
											2013-05-15 08:59:44 -07:00
										 |  |  | # define FMT_NOEXCEPT(expr) noexcept(expr)
 | 
					
						
							| 
									
										
										
										
											2013-05-15 10:04:11 -07:00
										 |  |  | #else
 | 
					
						
							|  |  |  | # define FMT_NOEXCEPT(expr)
 | 
					
						
							| 
									
										
										
										
											2013-05-15 08:59:44 -07:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-27 09:46:56 -07:00
										 |  |  | // 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&) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-21 11:42:25 -08:00
										 |  |  | namespace fmt { | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-15 09:58:33 -08:00
										 |  |  | // Fix the warning about long long on older versions of GCC
 | 
					
						
							|  |  |  | // that don't support the diagnostic pragma.
 | 
					
						
							| 
									
										
										
										
											2014-02-15 10:17:10 -08:00
										 |  |  | FMT_GCC_EXTENSION typedef long long LongLong; | 
					
						
							|  |  |  | FMT_GCC_EXTENSION typedef unsigned long long ULongLong; | 
					
						
							| 
									
										
										
										
											2014-02-15 09:58:33 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-28 14:48:42 -07:00
										 |  |  | #if FMT_USE_RVALUE_REFERENCES
 | 
					
						
							|  |  |  | using std::move; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  | template <typename Char> | 
					
						
							|  |  |  | class BasicWriter; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-30 06:55:21 -07:00
										 |  |  | typedef BasicWriter<char> Writer; | 
					
						
							|  |  |  | typedef BasicWriter<wchar_t> WWriter; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 16:20:33 -07:00
										 |  |  | template <typename Char> | 
					
						
							| 
									
										
										
										
											2014-07-08 16:38:50 -07:00
										 |  |  | class BasicFormatter; | 
					
						
							| 
									
										
										
										
											2014-07-08 16:20:33 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-04 07:18:44 -07:00
										 |  |  | template <typename Char, typename T> | 
					
						
							| 
									
										
										
										
											2014-07-08 16:38:50 -07:00
										 |  |  | void format(BasicFormatter<Char> &f, const Char *format_str, const T &value); | 
					
						
							| 
									
										
										
										
											2014-07-04 07:18:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-30 06:55:21 -07:00
										 |  |  | /**
 | 
					
						
							|  |  |  |   \rst | 
					
						
							| 
									
										
										
										
											2014-06-28 15:58:02 -07:00
										 |  |  |   A string reference. It can be constructed from a C string or | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  |   ``std::string``. | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   You can use one of the following typedefs for common character types: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   +------------+-------------------------+ | 
					
						
							|  |  |  |   | Type       | Definition              | | 
					
						
							|  |  |  |   +============+=========================+ | 
					
						
							|  |  |  |   | StringRef  | BasicStringRef<char>    | | 
					
						
							|  |  |  |   +------------+-------------------------+ | 
					
						
							|  |  |  |   | WStringRef | BasicStringRef<wchar_t> | | 
					
						
							|  |  |  |   +------------+-------------------------+ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   This class is most useful as a parameter type to allow passing | 
					
						
							|  |  |  |   different types of strings to a function, for example:: | 
					
						
							| 
									
										
										
										
											2014-04-30 06:55:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-28 14:48:42 -07:00
										 |  |  |     template<typename... Args> | 
					
						
							| 
									
										
										
										
											2014-07-01 09:10:43 -07:00
										 |  |  |     std::string format(StringRef format, const Args & ... args); | 
					
						
							| 
									
										
										
										
											2014-04-30 06:55:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-28 14:48:42 -07:00
										 |  |  |     format("{}", 42); | 
					
						
							|  |  |  |     format(std::string("{}"), 42); | 
					
						
							| 
									
										
										
										
											2014-04-30 06:55:21 -07:00
										 |  |  |   \endrst | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | template <typename Char> | 
					
						
							|  |  |  | class BasicStringRef { | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   const Char *data_; | 
					
						
							|  |  |  |   mutable std::size_t size_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |     Constructs a string reference object from a C string and a size. | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  |     If *size* is zero, which is the default, the size is computed | 
					
						
							|  |  |  |     automatically. | 
					
						
							| 
									
										
										
										
											2014-04-30 06:55:21 -07:00
										 |  |  |    */ | 
					
						
							|  |  |  |   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<Char> &s) | 
					
						
							|  |  |  |   : data_(s.c_str()), size_(s.size()) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |     Converts a string reference to an `std::string` object. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   operator std::basic_string<Char>() const { | 
					
						
							|  |  |  |     return std::basic_string<Char>(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 { | 
					
						
							| 
									
										
										
										
											2014-07-03 08:50:57 -07:00
										 |  |  |     if (size_ == 0 && data_) size_ = std::char_traits<Char>::length(data_); | 
					
						
							| 
									
										
										
										
											2014-04-30 06:55:21 -07:00
										 |  |  |     return size_; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-03 08:50:57 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   friend bool operator==(BasicStringRef lhs, BasicStringRef rhs) { | 
					
						
							|  |  |  |     return lhs.data_ == rhs.data_; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   friend bool operator!=(BasicStringRef lhs, BasicStringRef rhs) { | 
					
						
							|  |  |  |     return lhs.data_ != rhs.data_; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-04-30 06:55:21 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef BasicStringRef<char> StringRef; | 
					
						
							|  |  |  | typedef BasicStringRef<wchar_t> WStringRef; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 06:38:37 -07:00
										 |  |  | /**
 | 
					
						
							|  |  |  |   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) {} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-12 09:14:00 -08:00
										 |  |  | namespace internal { | 
					
						
							| 
									
										
										
										
											2014-04-29 06:54:46 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | // The number of characters to store in the Array object, representing the
 | 
					
						
							|  |  |  | // output buffer, itself to avoid dynamic memory allocation.
 | 
					
						
							| 
									
										
										
										
											2014-04-09 08:05:23 -07:00
										 |  |  | enum { INLINE_BUFFER_SIZE = 500 }; | 
					
						
							| 
									
										
										
										
											2012-12-12 09:14:00 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  | #if _SECURE_SCL
 | 
					
						
							| 
									
										
										
										
											2014-04-29 06:54:46 -07:00
										 |  |  | // Use checked iterator to avoid warnings on MSVC.
 | 
					
						
							| 
									
										
										
										
											2013-09-02 20:24:09 -07:00
										 |  |  | template <typename T> | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  | inline stdext::checked_array_iterator<T*> CheckPtr(T *ptr, std::size_t size) { | 
					
						
							| 
									
										
										
										
											2013-09-02 20:24:09 -07:00
										 |  |  |   return stdext::checked_array_iterator<T*>(ptr, size); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | template <typename T> | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  | inline T *CheckPtr(T *ptr, std::size_t) { return ptr; } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-11 12:23:52 -08:00
										 |  |  | // 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.
 | 
					
						
							| 
									
										
										
										
											2012-12-10 17:16:08 -08:00
										 |  |  | template <typename T, std::size_t SIZE> | 
					
						
							| 
									
										
										
										
											2012-12-11 12:23:52 -08:00
										 |  |  | class Array { | 
					
						
							| 
									
										
										
										
											2012-12-10 17:16:08 -08:00
										 |  |  |  private: | 
					
						
							|  |  |  |   std::size_t size_; | 
					
						
							|  |  |  |   std::size_t capacity_; | 
					
						
							|  |  |  |   T *ptr_; | 
					
						
							|  |  |  |   T data_[SIZE]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  |   void grow(std::size_t size); | 
					
						
							| 
									
										
										
										
											2012-12-10 17:16:08 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-25 08:18:07 -07:00
										 |  |  |   // Free memory allocated by the array.
 | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  |   void free() { | 
					
						
							| 
									
										
										
										
											2012-12-10 17:16:08 -08:00
										 |  |  |     if (ptr_ != data_) delete [] ptr_; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-25 08:18:07 -07:00
										 |  |  |   // Move data from other to this array.
 | 
					
						
							| 
									
										
										
										
											2014-06-28 14:48:42 -07:00
										 |  |  |   void move(Array &other) { | 
					
						
							| 
									
										
										
										
											2014-04-25 08:18:07 -07:00
										 |  |  |     size_ = other.size_; | 
					
						
							|  |  |  |     capacity_ = other.capacity_; | 
					
						
							| 
									
										
										
										
											2014-04-24 07:30:39 -07:00
										 |  |  |     if (other.ptr_ == other.data_) { | 
					
						
							|  |  |  |       ptr_ = data_; | 
					
						
							|  |  |  |       std::copy(other.data_, other.data_ + size_, CheckPtr(data_, capacity_)); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       ptr_ = other.ptr_; | 
					
						
							| 
									
										
										
										
											2014-04-25 08:18:07 -07:00
										 |  |  |       // Set pointer to the inline array so that delete is not called
 | 
					
						
							|  |  |  |       // when freeing.
 | 
					
						
							|  |  |  |       other.ptr_ = other.data_; | 
					
						
							| 
									
										
										
										
											2014-04-24 07:30:39 -07:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-04-24 14:55:18 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |   FMT_DISALLOW_COPY_AND_ASSIGN(Array); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   Array() : size_(0), capacity_(SIZE), ptr_(data_) {} | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  |   ~Array() { free(); } | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-25 08:18:07 -07:00
										 |  |  | #if FMT_USE_RVALUE_REFERENCES
 | 
					
						
							|  |  |  |   Array(Array &&other) { | 
					
						
							| 
									
										
										
										
											2014-06-28 14:48:42 -07:00
										 |  |  |     move(other); | 
					
						
							| 
									
										
										
										
											2014-04-25 08:18:07 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-26 07:10:21 -07:00
										 |  |  |   Array& operator=(Array &&other) { | 
					
						
							| 
									
										
										
										
											2014-04-25 08:18:07 -07:00
										 |  |  |     assert(this != &other); | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  |     free(); | 
					
						
							| 
									
										
										
										
											2014-06-28 14:48:42 -07:00
										 |  |  |     move(other); | 
					
						
							| 
									
										
										
										
											2014-04-25 08:18:07 -07:00
										 |  |  |     return *this; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-04-24 07:30:39 -07:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-11 12:23:52 -08:00
										 |  |  |   // Returns the size of this array.
 | 
					
						
							| 
									
										
										
										
											2012-12-10 17:16:08 -08:00
										 |  |  |   std::size_t size() const { return size_; } | 
					
						
							| 
									
										
										
										
											2012-12-10 20:37:35 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-11 12:23:52 -08:00
										 |  |  |   // Returns the capacity of this array.
 | 
					
						
							| 
									
										
										
										
											2012-12-10 17:16:08 -08:00
										 |  |  |   std::size_t capacity() const { return capacity_; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-11 12:23:52 -08:00
										 |  |  |   // Resizes the array. If T is a POD type new elements are not initialized.
 | 
					
						
							| 
									
										
										
										
											2012-12-10 18:08:04 -08:00
										 |  |  |   void resize(std::size_t new_size) { | 
					
						
							|  |  |  |     if (new_size > capacity_) | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  |       grow(new_size); | 
					
						
							| 
									
										
										
										
											2012-12-10 18:08:04 -08:00
										 |  |  |     size_ = new_size; | 
					
						
							| 
									
										
										
										
											2012-12-10 17:16:08 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-29 06:54:46 -07:00
										 |  |  |   // Reserves space to store at least capacity elements.
 | 
					
						
							| 
									
										
										
										
											2012-12-10 17:16:08 -08:00
										 |  |  |   void reserve(std::size_t capacity) { | 
					
						
							| 
									
										
										
										
											2012-12-10 18:08:04 -08:00
										 |  |  |     if (capacity > capacity_) | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  |       grow(capacity); | 
					
						
							| 
									
										
										
										
											2012-12-10 17:16:08 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-10 20:37:35 -08:00
										 |  |  |   void clear() { size_ = 0; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-10 17:16:08 -08:00
										 |  |  |   void push_back(const T &value) { | 
					
						
							|  |  |  |     if (size_ == capacity_) | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  |       grow(size_ + 1); | 
					
						
							| 
									
										
										
										
											2012-12-10 17:16:08 -08:00
										 |  |  |     ptr_[size_++] = value; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-11 12:23:52 -08:00
										 |  |  |   // Appends data to the end of the array.
 | 
					
						
							| 
									
										
										
										
											2012-12-10 18:08:04 -08:00
										 |  |  |   void append(const T *begin, const T *end); | 
					
						
							| 
									
										
										
										
											2012-12-10 17:16:08 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   T &operator[](std::size_t index) { return ptr_[index]; } | 
					
						
							|  |  |  |   const T &operator[](std::size_t index) const { return ptr_[index]; } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-10 18:08:04 -08:00
										 |  |  | template <typename T, std::size_t SIZE> | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  | void Array<T, SIZE>::grow(std::size_t size) { | 
					
						
							| 
									
										
										
										
											2013-04-22 07:39:36 -07:00
										 |  |  |   capacity_ = (std::max)(size, capacity_ + capacity_ / 2); | 
					
						
							| 
									
										
										
										
											2012-12-10 18:08:04 -08:00
										 |  |  |   T *p = new T[capacity_]; | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  |   std::copy(ptr_, ptr_ + size_, CheckPtr(p, capacity_)); | 
					
						
							| 
									
										
										
										
											2012-12-10 18:08:04 -08:00
										 |  |  |   if (ptr_ != data_) | 
					
						
							|  |  |  |     delete [] ptr_; | 
					
						
							|  |  |  |   ptr_ = p; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <typename T, std::size_t SIZE> | 
					
						
							| 
									
										
										
										
											2012-12-11 12:23:52 -08:00
										 |  |  | void Array<T, SIZE>::append(const T *begin, const T *end) { | 
					
						
							| 
									
										
										
										
											2012-12-10 18:08:04 -08:00
										 |  |  |   std::ptrdiff_t num_elements = end - begin; | 
					
						
							|  |  |  |   if (size_ + num_elements > capacity_) | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  |     grow(size_ + num_elements); | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  |   std::copy(begin, end, CheckPtr(ptr_, capacity_) + size_); | 
					
						
							| 
									
										
										
										
											2012-12-10 18:08:04 -08:00
										 |  |  |   size_ += num_elements; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 10:36:17 -08:00
										 |  |  | template <typename Char> | 
					
						
							|  |  |  | class BasicCharTraits { | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  | #if _SECURE_SCL
 | 
					
						
							|  |  |  |   typedef stdext::checked_array_iterator<Char*> CharPtr; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   typedef Char *CharPtr; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  | template <typename Char> | 
					
						
							|  |  |  | class CharTraits; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-09 22:21:40 -07:00
										 |  |  | template <> | 
					
						
							| 
									
										
										
										
											2014-02-14 10:36:17 -08:00
										 |  |  | class CharTraits<char> : public BasicCharTraits<char> { | 
					
						
							| 
									
										
										
										
											2013-12-07 08:12:03 -08:00
										 |  |  |  private: | 
					
						
							| 
									
										
										
										
											2014-07-02 08:38:31 -07:00
										 |  |  |   // Conversion from wchar_t to char is not allowed.
 | 
					
						
							| 
									
										
										
										
											2014-07-04 07:18:44 -07:00
										 |  |  |   static char convert(wchar_t); | 
					
						
							| 
									
										
										
										
											2013-12-07 08:12:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-04 06:56:19 -07:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2013-12-07 08:12:03 -08:00
										 |  |  |   typedef const wchar_t *UnsupportedStrType; | 
					
						
							| 
									
										
										
										
											2013-09-09 22:21:40 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-04 07:18:44 -07:00
										 |  |  |   static char convert(char value) { return value; } | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-09 22:21:40 -07:00
										 |  |  |   template <typename T> | 
					
						
							|  |  |  |   static int FormatFloat(char *buffer, std::size_t size, | 
					
						
							|  |  |  |       const char *format, unsigned width, int precision, T value); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <> | 
					
						
							| 
									
										
										
										
											2014-02-14 10:36:17 -08:00
										 |  |  | class CharTraits<wchar_t> : public BasicCharTraits<wchar_t> { | 
					
						
							| 
									
										
										
										
											2013-12-07 08:12:03 -08:00
										 |  |  |  public: | 
					
						
							|  |  |  |   typedef const char *UnsupportedStrType; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-04 07:18:44 -07:00
										 |  |  |   static wchar_t convert(char value) { return value; } | 
					
						
							|  |  |  |   static wchar_t convert(wchar_t value) { return value; } | 
					
						
							| 
									
										
										
										
											2013-09-09 22:21:40 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   template <typename T> | 
					
						
							|  |  |  |   static int FormatFloat(wchar_t *buffer, std::size_t size, | 
					
						
							|  |  |  |       const wchar_t *format, unsigned width, int precision, T value); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-19 12:43:55 -08:00
										 |  |  | // Selects uint32_t if FitsIn32Bits is true, uint64_t otherwise.
 | 
					
						
							|  |  |  | template <bool FitsIn32Bits> | 
					
						
							|  |  |  | struct TypeSelector { typedef uint32_t Type; }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <> | 
					
						
							|  |  |  | struct TypeSelector<false> { typedef uint64_t Type; }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 07:43:37 -08:00
										 |  |  | // Checks if a number is negative - used to avoid warnings.
 | 
					
						
							|  |  |  | template <bool IsSigned> | 
					
						
							|  |  |  | struct SignChecker { | 
					
						
							|  |  |  |   template <typename T> | 
					
						
							| 
									
										
										
										
											2014-07-16 07:27:54 -07:00
										 |  |  |   static bool is_negative(T) { return false; } | 
					
						
							| 
									
										
										
										
											2013-01-13 09:41:14 -08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2013-01-13 07:14:54 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 07:43:37 -08:00
										 |  |  | template <> | 
					
						
							|  |  |  | struct SignChecker<true> { | 
					
						
							|  |  |  |   template <typename T> | 
					
						
							| 
									
										
										
										
											2014-07-16 07:27:54 -07:00
										 |  |  |   static bool is_negative(T value) { return value < 0; } | 
					
						
							| 
									
										
										
										
											2013-01-13 07:14:54 -08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 07:43:37 -08:00
										 |  |  | // Returns true if value is negative, false otherwise.
 | 
					
						
							|  |  |  | // Same as (value < 0) but doesn't produce warnings if T is an unsigned type.
 | 
					
						
							|  |  |  | template <typename T> | 
					
						
							| 
									
										
										
										
											2014-07-16 07:27:54 -07:00
										 |  |  | inline bool is_negative(T value) { | 
					
						
							|  |  |  |   return SignChecker<std::numeric_limits<T>::is_signed>::is_negative(value); | 
					
						
							| 
									
										
										
										
											2014-02-20 07:43:37 -08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2013-01-13 07:14:54 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-24 10:46:01 -07:00
										 |  |  | int SignBitNoInline(double value); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-20 07:43:37 -08:00
										 |  |  | template <typename T> | 
					
						
							|  |  |  | struct IntTraits { | 
					
						
							|  |  |  |   // Smallest of uint32_t and uint64_t that is large enough to represent
 | 
					
						
							|  |  |  |   // all values of T.
 | 
					
						
							|  |  |  |   typedef typename | 
					
						
							|  |  |  |     TypeSelector<std::numeric_limits<T>::digits <= 32>::Type MainType; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2013-09-09 15:23:05 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  | template <typename T> | 
					
						
							|  |  |  | struct IsLongDouble { enum {VALUE = 0}; }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <> | 
					
						
							|  |  |  | struct IsLongDouble<long double> { enum {VALUE = 1}; }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ReportUnknownType(char code, const char *type); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-19 12:43:55 -08:00
										 |  |  | extern const uint32_t POWERS_OF_10_32[]; | 
					
						
							|  |  |  | extern const uint64_t POWERS_OF_10_64[]; | 
					
						
							| 
									
										
										
										
											2014-02-14 10:36:17 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 17:33:50 -07:00
										 |  |  | #if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll)
 | 
					
						
							| 
									
										
										
										
											2013-08-31 11:14:43 -07:00
										 |  |  | // Returns the number of decimal digits in n. Leading zeros are not counted
 | 
					
						
							| 
									
										
										
										
											2014-07-24 08:59:52 -07:00
										 |  |  | // except for n == 0 in which case count_digits returns 1.
 | 
					
						
							|  |  |  | inline unsigned count_digits(uint64_t n) { | 
					
						
							| 
									
										
										
										
											2014-02-14 10:36:17 -08:00
										 |  |  |   // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
 | 
					
						
							|  |  |  |   // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits.
 | 
					
						
							|  |  |  |   uint64_t t = (64 - __builtin_clzll(n | 1)) * 1233 >> 12; | 
					
						
							| 
									
										
										
										
											2014-02-19 12:43:55 -08:00
										 |  |  |   return t - (n < POWERS_OF_10_64[t]) + 1; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-04-23 17:33:50 -07:00
										 |  |  | # if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz)
 | 
					
						
							| 
									
										
										
										
											2014-07-24 08:59:52 -07:00
										 |  |  | // Optional version of count_digits for better performance on 32-bit platforms.
 | 
					
						
							|  |  |  | inline unsigned count_digits(uint32_t n) { | 
					
						
							| 
									
										
										
										
											2014-02-19 12:43:55 -08:00
										 |  |  |   uint32_t t = (32 - __builtin_clz(n | 1)) * 1233 >> 12; | 
					
						
							|  |  |  |   return t - (n < POWERS_OF_10_32[t]) + 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | # endif
 | 
					
						
							| 
									
										
										
										
											2014-02-14 10:36:17 -08:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2014-07-24 08:59:52 -07:00
										 |  |  | // Slower version of count_digits used when __builtin_clz is not available.
 | 
					
						
							|  |  |  | inline unsigned count_digits(uint64_t n) { | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  |   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; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-19 12:43:55 -08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-09 06:51:03 -07:00
										 |  |  | extern const char DIGITS[]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-17 09:12:24 -08:00
										 |  |  | // Formats a decimal unsigned integer value writing into buffer.
 | 
					
						
							|  |  |  | template <typename UInt, typename Char> | 
					
						
							|  |  |  | void FormatDecimal(Char *buffer, UInt value, unsigned num_digits) { | 
					
						
							| 
									
										
										
										
											2014-02-20 21:05:46 -08:00
										 |  |  |   --num_digits; | 
					
						
							| 
									
										
										
										
											2014-02-17 09:12:24 -08:00
										 |  |  |   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; | 
					
						
							| 
									
										
										
										
											2014-06-06 08:00:20 -07:00
										 |  |  |     buffer[num_digits] = DIGITS[index + 1]; | 
					
						
							|  |  |  |     buffer[num_digits - 1] = DIGITS[index]; | 
					
						
							| 
									
										
										
										
											2014-02-17 09:12:24 -08:00
										 |  |  |     num_digits -= 2; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (value < 10) { | 
					
						
							|  |  |  |     *buffer = static_cast<char>('0' + value); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   unsigned index = static_cast<unsigned>(value * 2); | 
					
						
							| 
									
										
										
										
											2014-06-06 08:00:20 -07:00
										 |  |  |   buffer[1] = DIGITS[index + 1]; | 
					
						
							|  |  |  |   buffer[0] = DIGITS[index]; | 
					
						
							| 
									
										
										
										
											2014-02-17 09:12:24 -08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-30 07:23:43 -07:00
										 |  |  | #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<wchar_t, INLINE_BUFFER_SIZE> buffer_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   explicit UTF8ToUTF16(StringRef s); | 
					
						
							| 
									
										
										
										
											2014-04-30 07:38:43 -07:00
										 |  |  |   operator WStringRef() const { return WStringRef(&buffer_[0], size()); } | 
					
						
							| 
									
										
										
										
											2014-04-30 07:23:43 -07:00
										 |  |  |   size_t size() const { return buffer_.size() - 1; } | 
					
						
							| 
									
										
										
										
											2014-07-08 16:44:24 -07:00
										 |  |  |   const wchar_t *c_str() const { return &buffer_[0]; } | 
					
						
							| 
									
										
										
										
											2014-06-30 18:26:46 -07:00
										 |  |  |   std::wstring str() const { return std::wstring(&buffer_[0], size()); } | 
					
						
							| 
									
										
										
										
											2014-04-30 07:23:43 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // A converter from UTF-16 to UTF-8.
 | 
					
						
							|  |  |  | // It is only provided for Windows since other systems use UTF-8.
 | 
					
						
							|  |  |  | class UTF16ToUTF8 { | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   Array<char, INLINE_BUFFER_SIZE> buffer_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   UTF16ToUTF8() {} | 
					
						
							|  |  |  |   explicit UTF16ToUTF8(WStringRef s); | 
					
						
							| 
									
										
										
										
											2014-04-30 07:38:43 -07:00
										 |  |  |   operator StringRef() const { return StringRef(&buffer_[0], size()); } | 
					
						
							| 
									
										
										
										
											2014-04-30 07:23:43 -07:00
										 |  |  |   size_t size() const { return buffer_.size() - 1; } | 
					
						
							| 
									
										
										
										
											2014-07-08 16:44:24 -07:00
										 |  |  |   const char *c_str() const { return &buffer_[0]; } | 
					
						
							| 
									
										
										
										
											2014-06-30 18:26:46 -07:00
										 |  |  |   std::string str() const { return std::string(&buffer_[0], size()); } | 
					
						
							| 
									
										
										
										
											2014-04-30 07:23:43 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Performs conversion returning a system error code instead of
 | 
					
						
							|  |  |  |   // throwing exception on error.
 | 
					
						
							|  |  |  |   int Convert(WStringRef s); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-30 09:42:48 -07:00
										 |  |  | // Portable thread-safe version of strerror.
 | 
					
						
							| 
									
										
										
										
											2014-04-30 11:20:41 -07:00
										 |  |  | // 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:
 | 
					
						
							| 
									
										
										
										
											2014-04-30 09:42:48 -07:00
										 |  |  | //   0      - success
 | 
					
						
							|  |  |  | //   ERANGE - buffer is not large enough to store the error message
 | 
					
						
							|  |  |  | //   other  - failure
 | 
					
						
							|  |  |  | // Buffer should be at least of size 1.
 | 
					
						
							| 
									
										
										
										
											2014-05-03 09:48:54 -07:00
										 |  |  | int StrError(int error_code, | 
					
						
							|  |  |  |     char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT(true); | 
					
						
							| 
									
										
										
										
											2013-01-04 07:04:35 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-30 15:00:41 -07:00
										 |  |  | void FormatSystemErrorMessage( | 
					
						
							|  |  |  |     fmt::Writer &out, int error_code, fmt::StringRef message); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef _WIN32
 | 
					
						
							|  |  |  | void FormatWinErrorMessage( | 
					
						
							|  |  |  |     fmt::Writer &out, int error_code, fmt::StringRef message); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 06:38:37 -07:00
										 |  |  | // Throws Exception(message) if format contains '}', otherwise throws
 | 
					
						
							|  |  |  | // FormatError reporting unmatched '{'. The idea is that unmatched '{'
 | 
					
						
							|  |  |  | // should override other errors.
 | 
					
						
							|  |  |  | template <typename Char> | 
					
						
							|  |  |  | struct FormatErrorReporter { | 
					
						
							|  |  |  |   int num_open_braces; | 
					
						
							|  |  |  |   void operator()(const Char *s, fmt::StringRef message) const; | 
					
						
							| 
									
										
										
										
											2012-12-25 13:25:14 -08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-06 08:01:10 -07:00
										 |  |  | // Computes max(Arg, 1) at compile time. It is used to avoid errors about
 | 
					
						
							|  |  |  | // allocating an array of 0 size.
 | 
					
						
							|  |  |  | template <unsigned Arg> | 
					
						
							|  |  |  | struct NonZero { | 
					
						
							|  |  |  |   enum { VALUE = Arg }; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <> | 
					
						
							|  |  |  | struct NonZero<0> { | 
					
						
							|  |  |  |   enum { VALUE = 1 }; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2014-06-24 07:54:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-02 06:33:25 -07:00
										 |  |  | // A formatting argument. It is a POD type to allow storage in internal::Array.
 | 
					
						
							|  |  |  | struct Arg { | 
					
						
							| 
									
										
										
										
											2014-06-24 07:54:26 -07:00
										 |  |  |   enum Type { | 
					
						
							|  |  |  |     // Integer types should go first,
 | 
					
						
							| 
									
										
										
										
											2014-07-22 12:37:10 -07:00
										 |  |  |     INT, UINT, LONG_LONG, ULONG_LONG, CHAR, LAST_INTEGER_TYPE = CHAR, | 
					
						
							| 
									
										
										
										
											2014-06-24 07:54:26 -07:00
										 |  |  |     // followed by floating-point types.
 | 
					
						
							|  |  |  |     DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE, | 
					
						
							| 
									
										
										
										
											2014-07-22 12:37:10 -07:00
										 |  |  |     STRING, WSTRING, POINTER, CUSTOM | 
					
						
							| 
									
										
										
										
											2014-06-24 07:54:26 -07:00
										 |  |  |   }; | 
					
						
							|  |  |  |   Type type; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-14 08:04:17 -07:00
										 |  |  |   template <typename Char> | 
					
						
							|  |  |  |   struct StringValue { | 
					
						
							|  |  |  |     const Char *value; | 
					
						
							|  |  |  |     std::size_t size; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-24 07:54:26 -07:00
										 |  |  |   typedef void (*FormatFunc)( | 
					
						
							| 
									
										
										
										
											2014-07-08 16:20:33 -07:00
										 |  |  |       void *formatter, const void *arg, const void *format_str); | 
					
						
							| 
									
										
										
										
											2014-06-24 07:54:26 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   struct CustomValue { | 
					
						
							|  |  |  |     const void *value; | 
					
						
							|  |  |  |     FormatFunc format; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   union { | 
					
						
							|  |  |  |     int int_value; | 
					
						
							|  |  |  |     unsigned uint_value; | 
					
						
							|  |  |  |     LongLong long_long_value; | 
					
						
							|  |  |  |     ULongLong ulong_long_value; | 
					
						
							| 
									
										
										
										
											2014-07-02 08:38:31 -07:00
										 |  |  |     double double_value; | 
					
						
							| 
									
										
										
										
											2014-06-24 07:54:26 -07:00
										 |  |  |     long double long_double_value; | 
					
						
							|  |  |  |     const void *pointer_value; | 
					
						
							|  |  |  |     StringValue<char> string; | 
					
						
							|  |  |  |     StringValue<wchar_t> wstring; | 
					
						
							|  |  |  |     CustomValue custom; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2014-06-30 06:19:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-02 06:33:25 -07:00
										 |  |  | // Makes an Arg object from any type.
 | 
					
						
							| 
									
										
										
										
											2014-07-01 09:15:20 -07:00
										 |  |  | template <typename Char> | 
					
						
							| 
									
										
										
										
											2014-07-02 06:33:25 -07:00
										 |  |  | class MakeArg : public Arg { | 
					
						
							| 
									
										
										
										
											2014-06-30 06:19:20 -07:00
										 |  |  |  private: | 
					
						
							| 
									
										
										
										
											2014-07-03 08:50:57 -07:00
										 |  |  |   // 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!
 | 
					
						
							| 
									
										
										
										
											2014-06-30 06:19:20 -07:00
										 |  |  |   template <typename T> | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |   MakeArg(const T *value); | 
					
						
							| 
									
										
										
										
											2014-06-30 06:19:20 -07:00
										 |  |  |   template <typename T> | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |   MakeArg(T *value); | 
					
						
							| 
									
										
										
										
											2014-06-30 06:19:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-04 07:18:44 -07:00
										 |  |  |   void set_string(StringRef str) { | 
					
						
							| 
									
										
										
										
											2014-07-03 08:50:57 -07:00
										 |  |  |     type = STRING; | 
					
						
							|  |  |  |     string.value = str.c_str(); | 
					
						
							|  |  |  |     string.size = str.size(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-04 07:18:44 -07:00
										 |  |  |   void set_string(WStringRef str) { | 
					
						
							| 
									
										
										
										
											2014-07-03 08:50:57 -07:00
										 |  |  |     type = WSTRING; | 
					
						
							| 
									
										
										
										
											2014-07-14 08:47:03 -07:00
										 |  |  |     CharTraits<Char>::convert(wchar_t()); | 
					
						
							|  |  |  |     wstring.value = str.c_str(); | 
					
						
							| 
									
										
										
										
											2014-07-03 08:50:57 -07:00
										 |  |  |     wstring.size = str.size(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-04 07:18:44 -07:00
										 |  |  |   // Formats an argument of a custom type, such as a user-defined class.
 | 
					
						
							|  |  |  |   template <typename T> | 
					
						
							|  |  |  |   static void format_custom_arg( | 
					
						
							| 
									
										
										
										
											2014-07-08 16:20:33 -07:00
										 |  |  |       void *formatter, const void *arg, const void *format_str) { | 
					
						
							| 
									
										
										
										
											2014-07-08 16:38:50 -07:00
										 |  |  |     format(*static_cast<BasicFormatter<Char>*>(formatter), | 
					
						
							| 
									
										
										
										
											2014-07-08 16:20:33 -07:00
										 |  |  |         static_cast<const Char*>(format_str), *static_cast<const T*>(arg)); | 
					
						
							| 
									
										
										
										
											2014-07-04 07:18:44 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-03 08:50:57 -07:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |   MakeArg() {} | 
					
						
							| 
									
										
										
										
											2014-07-02 08:38:31 -07:00
										 |  |  |   MakeArg(bool value) { type = INT; int_value = value; } | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |   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) { | 
					
						
							| 
									
										
										
										
											2014-07-03 08:50:57 -07:00
										 |  |  |     // 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.
 | 
					
						
							| 
									
										
										
										
											2014-06-30 06:19:20 -07:00
										 |  |  |     if (sizeof(long) == sizeof(int)) { | 
					
						
							|  |  |  |       type = INT; | 
					
						
							|  |  |  |       int_value = static_cast<int>(value); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       type = LONG_LONG; | 
					
						
							|  |  |  |       long_long_value = value; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |   MakeArg(unsigned long value) { | 
					
						
							| 
									
										
										
										
											2014-06-30 06:19:20 -07:00
										 |  |  |     if (sizeof(unsigned long) == sizeof(unsigned)) { | 
					
						
							|  |  |  |       type = UINT; | 
					
						
							|  |  |  |       uint_value = static_cast<unsigned>(value); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       type = ULONG_LONG; | 
					
						
							|  |  |  |       ulong_long_value = value; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |   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; } | 
					
						
							| 
									
										
										
										
											2014-07-02 08:38:31 -07:00
										 |  |  |   MakeArg(signed char value) { type = CHAR; int_value = value; } | 
					
						
							|  |  |  |   MakeArg(unsigned char value) { type = CHAR; int_value = value; } | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |   MakeArg(char value) { type = CHAR; int_value = value; } | 
					
						
							|  |  |  |   MakeArg(wchar_t value) { | 
					
						
							| 
									
										
										
										
											2014-06-30 06:19:20 -07:00
										 |  |  |     type = CHAR; | 
					
						
							| 
									
										
										
										
											2014-07-04 07:18:44 -07:00
										 |  |  |     int_value = internal::CharTraits<Char>::convert(value); | 
					
						
							| 
									
										
										
										
											2014-06-30 06:19:20 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-04 07:18:44 -07:00
										 |  |  |   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); } | 
					
						
							| 
									
										
										
										
											2014-06-30 06:19:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-04 07:18:44 -07:00
										 |  |  |   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); } | 
					
						
							| 
									
										
										
										
											2014-06-30 06:19:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |   MakeArg(void *value) { type = POINTER; pointer_value = value; } | 
					
						
							| 
									
										
										
										
											2014-07-03 08:50:57 -07:00
										 |  |  |   MakeArg(const void *value) { type = POINTER; pointer_value = value; } | 
					
						
							| 
									
										
										
										
											2014-06-30 06:19:20 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   template <typename T> | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |   MakeArg(const T &value) { | 
					
						
							| 
									
										
										
										
											2014-06-30 06:19:20 -07:00
										 |  |  |     type = CUSTOM; | 
					
						
							|  |  |  |     custom.value = &value; | 
					
						
							| 
									
										
										
										
											2014-07-04 07:18:44 -07:00
										 |  |  |     custom.format = &format_custom_arg<T>; | 
					
						
							| 
									
										
										
										
											2014-06-30 06:19:20 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-14 06:55:29 -07:00
										 |  |  | #define FMT_DISPATCH(call) static_cast<Impl*>(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<MyArgVisitor, void> {
 | 
					
						
							|  |  |  | //   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 <typename Impl, typename Result> | 
					
						
							|  |  |  | class ArgVisitor { | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   Result visit_unhandled_arg() { return Result(); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Result visit_int(int value) { | 
					
						
							| 
									
										
										
										
											2014-07-16 07:55:31 -07:00
										 |  |  |     return FMT_DISPATCH(visit_any_int(value)); | 
					
						
							| 
									
										
										
										
											2014-07-14 06:55:29 -07:00
										 |  |  |   } | 
					
						
							|  |  |  |   Result visit_long_long(LongLong value) { | 
					
						
							| 
									
										
										
										
											2014-07-16 07:27:54 -07:00
										 |  |  |     return FMT_DISPATCH(visit_any_int(value)); | 
					
						
							| 
									
										
										
										
											2014-07-14 06:55:29 -07:00
										 |  |  |   } | 
					
						
							|  |  |  |   Result visit_uint(unsigned value) { | 
					
						
							| 
									
										
										
										
											2014-07-16 07:55:31 -07:00
										 |  |  |     return FMT_DISPATCH(visit_any_int(value)); | 
					
						
							| 
									
										
										
										
											2014-07-14 06:55:29 -07:00
										 |  |  |   } | 
					
						
							|  |  |  |   Result visit_ulong_long(ULongLong value) { | 
					
						
							| 
									
										
										
										
											2014-07-16 07:27:54 -07:00
										 |  |  |     return FMT_DISPATCH(visit_any_int(value)); | 
					
						
							| 
									
										
										
										
											2014-07-14 06:55:29 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-16 07:27:54 -07:00
										 |  |  |   template <typename T> | 
					
						
							|  |  |  |   Result visit_any_int(T) { | 
					
						
							| 
									
										
										
										
											2014-07-14 06:55:29 -07:00
										 |  |  |     return FMT_DISPATCH(visit_unhandled_arg()); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-16 07:27:54 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   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 <typename T> | 
					
						
							|  |  |  |   Result visit_any_double(T) { | 
					
						
							| 
									
										
										
										
											2014-07-14 06:55:29 -07:00
										 |  |  |     return FMT_DISPATCH(visit_unhandled_arg()); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-16 07:27:54 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-14 06:55:29 -07:00
										 |  |  |   Result visit_char(int) { | 
					
						
							|  |  |  |     return FMT_DISPATCH(visit_unhandled_arg()); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-14 08:04:17 -07:00
										 |  |  |   Result visit_string(Arg::StringValue<char>) { | 
					
						
							| 
									
										
										
										
											2014-07-14 06:55:29 -07:00
										 |  |  |     return FMT_DISPATCH(visit_unhandled_arg()); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-14 08:04:17 -07:00
										 |  |  |   Result visit_wstring(Arg::StringValue<wchar_t>) { | 
					
						
							| 
									
										
										
										
											2014-07-14 06:55:29 -07:00
										 |  |  |     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)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  | class RuntimeError : public std::runtime_error { | 
					
						
							|  |  |  |  protected: | 
					
						
							|  |  |  |   RuntimeError() : std::runtime_error("") {} | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2014-07-14 08:47:03 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | template <typename Char> | 
					
						
							|  |  |  | class ArgFormatter; | 
					
						
							| 
									
										
										
										
											2014-06-06 06:38:37 -07:00
										 |  |  | }  // namespace internal
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-30 06:55:21 -07:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  |   An argument list. | 
					
						
							| 
									
										
										
										
											2014-04-30 06:55:21 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  | class ArgList { | 
					
						
							| 
									
										
										
										
											2014-04-30 06:55:21 -07:00
										 |  |  |  private: | 
					
						
							| 
									
										
										
										
											2014-07-02 06:33:25 -07:00
										 |  |  |   const internal::Arg *args_; | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  |   std::size_t size_; | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  |  public: | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  |   ArgList() : size_(0) {} | 
					
						
							| 
									
										
										
										
											2014-07-02 06:33:25 -07:00
										 |  |  |   ArgList(const internal::Arg *args, std::size_t size) | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  |   : args_(args), size_(size) {} | 
					
						
							| 
									
										
										
										
											2014-04-30 06:55:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |     Returns the list size (the number of arguments). | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   std::size_t size() const { return size_; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |     Returns the argument at specified index. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2014-07-02 06:33:25 -07:00
										 |  |  |   const internal::Arg &operator[](std::size_t index) const { | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  |     return args_[index]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-09 06:56:36 -07:00
										 |  |  | struct FormatSpec; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-16 08:38:15 -07:00
										 |  |  | namespace internal { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class FormatterBase { | 
					
						
							|  |  |  | protected: | 
					
						
							| 
									
										
										
										
											2014-07-08 16:20:33 -07:00
										 |  |  |   ArgList args_; | 
					
						
							|  |  |  |   int next_arg_index_; | 
					
						
							| 
									
										
										
										
											2014-07-16 08:38:15 -07:00
										 |  |  |   const char *error_; | 
					
						
							| 
									
										
										
										
											2014-07-08 16:20:33 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-16 08:38:15 -07:00
										 |  |  |   FormatterBase() : error_(0) {} | 
					
						
							| 
									
										
										
										
											2014-07-08 16:20:33 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-16 08:38:15 -07:00
										 |  |  |   const Arg &next_arg(); | 
					
						
							| 
									
										
										
										
											2014-07-08 16:20:33 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-16 08:49:23 -07:00
										 |  |  |   const Arg &handle_arg_index(unsigned arg_index); | 
					
						
							| 
									
										
										
										
											2014-07-08 16:20:33 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-24 08:53:27 -07:00
										 |  |  |   template <typename Char> | 
					
						
							|  |  |  |   void write(BasicWriter<Char> &w, const Char *start, const Char *end) { | 
					
						
							|  |  |  |     if (start != end) | 
					
						
							|  |  |  |       w << BasicStringRef<Char>(start, end - start); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-16 08:38:15 -07:00
										 |  |  |   // TODO
 | 
					
						
							| 
									
										
										
										
											2014-07-08 16:20:33 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-16 07:59:45 -07:00
										 |  |  | // A printf formatter.
 | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  | template <typename Char> | 
					
						
							| 
									
										
										
										
											2014-07-16 08:38:15 -07:00
										 |  |  | class PrintfFormatter : private FormatterBase { | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  |  private: | 
					
						
							|  |  |  |   void ParseFlags(FormatSpec &spec, const Char *&s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Parses argument index, flags and width and returns the parsed
 | 
					
						
							|  |  |  |   // argument index.
 | 
					
						
							| 
									
										
										
										
											2014-07-16 08:49:23 -07:00
										 |  |  |   unsigned ParseHeader(const Char *&s, FormatSpec &spec); | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   void Format(BasicWriter<Char> &writer, | 
					
						
							|  |  |  |     BasicStringRef<Char> format, const ArgList &args); | 
					
						
							| 
									
										
										
										
											2012-12-11 10:27:13 -08:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  | }  // namespace internal
 | 
					
						
							| 
									
										
										
										
											2012-12-11 10:27:13 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-16 08:38:15 -07:00
										 |  |  | // A formatter.
 | 
					
						
							|  |  |  | template <typename Char> | 
					
						
							|  |  |  | class BasicFormatter : private internal::FormatterBase { | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  |   BasicWriter<Char> &writer_; | 
					
						
							|  |  |  |   const Char *start_; | 
					
						
							|  |  |  |   internal::FormatErrorReporter<Char> report_error_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Parses argument index and returns an argument with this index.
 | 
					
						
							|  |  |  |   const internal::Arg &ParseArgIndex(const Char *&s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void CheckSign(const Char *&s, const internal::Arg &arg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							|  |  |  |   explicit BasicFormatter(BasicWriter<Char> &w) : writer_(w) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   BasicWriter<Char> &writer() { return writer_; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void Format(BasicStringRef<Char> format_str, const ArgList &args); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const Char *format(const Char *format_str, const internal::Arg &arg); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-22 14:05:56 -08:00
										 |  |  | enum Alignment { | 
					
						
							|  |  |  |   ALIGN_DEFAULT, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_NUMERIC | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | // Flags.
 | 
					
						
							| 
									
										
										
										
											2014-07-22 12:37:10 -07:00
										 |  |  | enum { SIGN_FLAG = 1, PLUS_FLAG = 2, MINUS_FLAG = 4, HASH_FLAG = 8 }; | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-01 09:06:25 -08:00
										 |  |  | // An empty format specifier.
 | 
					
						
							|  |  |  | struct EmptySpec {}; | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-01 09:06:25 -08:00
										 |  |  | // A type specifier.
 | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | template <char TYPE> | 
					
						
							| 
									
										
										
										
											2014-01-01 09:06:25 -08:00
										 |  |  | struct TypeSpec : EmptySpec { | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   Alignment align() const { return ALIGN_DEFAULT; } | 
					
						
							|  |  |  |   unsigned width() const { return 0; } | 
					
						
							| 
									
										
										
										
											2014-06-20 07:34:02 -07:00
										 |  |  |   int precision() const { return -1; } | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   bool sign_flag() const { return false; } | 
					
						
							|  |  |  |   bool plus_flag() const { return false; } | 
					
						
							|  |  |  |   bool hash_flag() const { return false; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   char type() const { return TYPE; } | 
					
						
							|  |  |  |   char fill() const { return ' '; } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-01 09:06:25 -08:00
										 |  |  | // A width specifier.
 | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | struct WidthSpec { | 
					
						
							|  |  |  |   unsigned width_; | 
					
						
							| 
									
										
										
										
											2013-09-08 13:07:04 -07:00
										 |  |  |   // Fill is always wchar_t and cast to char if necessary to avoid having
 | 
					
						
							|  |  |  |   // two specialization of WidthSpec and its subclasses.
 | 
					
						
							|  |  |  |   wchar_t fill_; | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-08 13:07:04 -07:00
										 |  |  |   WidthSpec(unsigned width, wchar_t fill) : width_(width), fill_(fill) {} | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   unsigned width() const { return width_; } | 
					
						
							| 
									
										
										
										
											2013-09-08 13:07:04 -07:00
										 |  |  |   wchar_t fill() const { return fill_; } | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-01 09:06:25 -08:00
										 |  |  | // An alignment specifier.
 | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | struct AlignSpec : WidthSpec { | 
					
						
							|  |  |  |   Alignment align_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-01 09:06:25 -08:00
										 |  |  |   AlignSpec(unsigned width, wchar_t fill, Alignment align = ALIGN_DEFAULT) | 
					
						
							|  |  |  |   : WidthSpec(width, fill), align_(align) {} | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Alignment align() const { return align_; } | 
					
						
							| 
									
										
										
										
											2014-06-20 07:34:02 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   int precision() const { return -1; } | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-01 09:06:25 -08:00
										 |  |  | // An alignment and type specifier.
 | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  | template <char TYPE> | 
					
						
							|  |  |  | struct AlignTypeSpec : AlignSpec { | 
					
						
							|  |  |  |   AlignTypeSpec(unsigned width, wchar_t fill) : AlignSpec(width, fill) {} | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   bool sign_flag() const { return false; } | 
					
						
							|  |  |  |   bool plus_flag() const { return false; } | 
					
						
							|  |  |  |   bool hash_flag() const { return false; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   char type() const { return TYPE; } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-01 09:06:25 -08:00
										 |  |  | // A full format specifier.
 | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  | struct FormatSpec : AlignSpec { | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   unsigned flags_; | 
					
						
							| 
									
										
										
										
											2014-06-20 07:34:02 -07:00
										 |  |  |   int precision_; | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   char type_; | 
					
						
							| 
									
										
										
										
											2012-12-21 09:12:04 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-20 07:34:02 -07:00
										 |  |  |   FormatSpec( | 
					
						
							|  |  |  |     unsigned width = 0, char type = 0, wchar_t fill = ' ') | 
					
						
							|  |  |  |   : AlignSpec(width, fill), flags_(0), precision_(-1), type_(type) {} | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   bool sign_flag() const { return (flags_ & SIGN_FLAG) != 0; } | 
					
						
							|  |  |  |   bool plus_flag() const { return (flags_ & PLUS_FLAG) != 0; } | 
					
						
							|  |  |  |   bool hash_flag() const { return (flags_ & HASH_FLAG) != 0; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-20 07:34:02 -07:00
										 |  |  |   int precision() const { return precision_; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   char type() const { return type_; } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  | // An integer format specifier.
 | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  | template <typename T, typename SpecT = TypeSpec<0>, typename Char = char> | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  | class IntFormatSpec : public SpecT { | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |  private: | 
					
						
							|  |  |  |   T value_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |   IntFormatSpec(T value, const SpecT &spec = SpecT()) | 
					
						
							| 
									
										
										
										
											2013-01-12 10:17:56 -08:00
										 |  |  |   : SpecT(spec), value_(value) {} | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   T value() const { return value_; } | 
					
						
							| 
									
										
										
										
											2012-12-20 20:10:55 -08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-01 09:22:55 -08:00
										 |  |  | // A string format specifier.
 | 
					
						
							| 
									
										
										
										
											2013-12-31 09:43:32 -08:00
										 |  |  | template <typename T> | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  | class StrFormatSpec : public AlignSpec { | 
					
						
							| 
									
										
										
										
											2013-12-31 09:43:32 -08:00
										 |  |  |  private: | 
					
						
							|  |  |  |   const T *str_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							| 
									
										
										
										
											2014-01-07 08:44:15 -08:00
										 |  |  |   StrFormatSpec(const T *str, unsigned width, wchar_t fill) | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  |   : AlignSpec(width, fill), str_(str) {} | 
					
						
							| 
									
										
										
										
											2013-12-31 09:43:32 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const T *str() const { return str_; } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-23 20:04:32 -07:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |   Returns an integer format specifier to format the value in base 2. | 
					
						
							| 
									
										
										
										
											2013-10-23 20:04:32 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  | IntFormatSpec<int, TypeSpec<'b'> > bin(int value); | 
					
						
							| 
									
										
										
										
											2013-10-23 20:04:32 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-22 11:06:56 -08:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |   Returns an integer format specifier to format the value in base 8. | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  | IntFormatSpec<int, TypeSpec<'o'> > oct(int value); | 
					
						
							| 
									
										
										
										
											2013-01-22 11:06:56 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |   Returns an integer format specifier to format the value in base 16 using | 
					
						
							| 
									
										
										
										
											2013-01-22 11:06:56 -08:00
										 |  |  |   lower-case letters for the digits above 9. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  | IntFormatSpec<int, TypeSpec<'x'> > hex(int value); | 
					
						
							| 
									
										
										
										
											2013-01-22 11:06:56 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |   Returns an integer formatter format specifier to format in base 16 using | 
					
						
							| 
									
										
										
										
											2013-01-22 11:06:56 -08:00
										 |  |  |   upper-case letters for the digits above 9. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  | IntFormatSpec<int, TypeSpec<'X'> > hexu(int value); | 
					
						
							| 
									
										
										
										
											2013-01-22 11:06:56 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |   \rst | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |   Returns an integer format specifier to pad the formatted argument with the | 
					
						
							|  |  |  |   fill character to the specified width using the default (right) numeric | 
					
						
							|  |  |  |   alignment. | 
					
						
							| 
									
										
										
										
											2013-01-22 11:06:56 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   **Example**:: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-13 07:39:18 -07:00
										 |  |  |     Writer out; | 
					
						
							|  |  |  |     out << pad(hex(0xcafe), 8, '0'); | 
					
						
							|  |  |  |     // out.str() == "0000cafe"
 | 
					
						
							| 
									
										
										
										
											2013-01-22 11:06:56 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   \endrst | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  | template <char TYPE_CODE, typename Char> | 
					
						
							|  |  |  | IntFormatSpec<int, AlignTypeSpec<TYPE_CODE>, Char> pad( | 
					
						
							| 
									
										
										
										
											2014-01-08 08:17:38 -08:00
										 |  |  |     int value, unsigned width, Char fill = ' '); | 
					
						
							| 
									
										
										
										
											2013-01-22 11:06:56 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 17:33:50 -07:00
										 |  |  | #define FMT_DEFINE_INT_FORMATTERS(TYPE) \
 | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  | inline IntFormatSpec<TYPE, TypeSpec<'b'> > bin(TYPE value) { \ | 
					
						
							|  |  |  |   return IntFormatSpec<TYPE, TypeSpec<'b'> >(value, TypeSpec<'b'>()); \ | 
					
						
							| 
									
										
										
										
											2013-10-23 20:04:32 -07:00
										 |  |  | } \ | 
					
						
							| 
									
										
										
										
											2013-11-14 08:45:20 -08:00
										 |  |  |  \ | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  | inline IntFormatSpec<TYPE, TypeSpec<'o'> > oct(TYPE value) { \ | 
					
						
							|  |  |  |   return IntFormatSpec<TYPE, TypeSpec<'o'> >(value, TypeSpec<'o'>()); \ | 
					
						
							| 
									
										
										
										
											2013-01-13 09:29:37 -08:00
										 |  |  | } \ | 
					
						
							|  |  |  |  \ | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  | inline IntFormatSpec<TYPE, TypeSpec<'x'> > hex(TYPE value) { \ | 
					
						
							|  |  |  |   return IntFormatSpec<TYPE, TypeSpec<'x'> >(value, TypeSpec<'x'>()); \ | 
					
						
							| 
									
										
										
										
											2013-01-13 09:29:37 -08:00
										 |  |  | } \ | 
					
						
							|  |  |  |  \ | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  | inline IntFormatSpec<TYPE, TypeSpec<'X'> > hexu(TYPE value) { \ | 
					
						
							|  |  |  |   return IntFormatSpec<TYPE, TypeSpec<'X'> >(value, TypeSpec<'X'>()); \ | 
					
						
							| 
									
										
										
										
											2013-01-13 09:29:37 -08:00
										 |  |  | } \ | 
					
						
							|  |  |  |  \ | 
					
						
							|  |  |  | template <char TYPE_CODE> \ | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  | inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> > pad( \ | 
					
						
							| 
									
										
										
										
											2014-01-08 08:17:38 -08:00
										 |  |  |     IntFormatSpec<TYPE, TypeSpec<TYPE_CODE> > f, unsigned width) { \ | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  |   return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE> >( \ | 
					
						
							|  |  |  |       f.value(), AlignTypeSpec<TYPE_CODE>(width, ' ')); \ | 
					
						
							| 
									
										
										
										
											2014-01-08 08:17:38 -08:00
										 |  |  | } \ | 
					
						
							|  |  |  |  \ | 
					
						
							|  |  |  | /* 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 */ \ | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  | /* can be replaced with one overload making the template argument Char      */ \ | 
					
						
							| 
									
										
										
										
											2014-01-08 08:17:38 -08:00
										 |  |  | /* default to char (C++11). */ \ | 
					
						
							|  |  |  | template <char TYPE_CODE, typename Char> \ | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  | inline IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char> pad( \ | 
					
						
							|  |  |  |     IntFormatSpec<TYPE, TypeSpec<TYPE_CODE>, Char> f, \ | 
					
						
							| 
									
										
										
										
											2014-01-08 08:17:38 -08:00
										 |  |  |     unsigned width, Char fill) { \ | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  |   return IntFormatSpec<TYPE, AlignTypeSpec<TYPE_CODE>, Char>( \ | 
					
						
							|  |  |  |       f.value(), AlignTypeSpec<TYPE_CODE>(width, fill)); \ | 
					
						
							| 
									
										
										
										
											2014-01-08 08:17:38 -08:00
										 |  |  | } \ | 
					
						
							|  |  |  |  \ | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  | inline IntFormatSpec<TYPE, AlignTypeSpec<0> > pad( \ | 
					
						
							| 
									
										
										
										
											2014-01-08 08:17:38 -08:00
										 |  |  |     TYPE value, unsigned width) { \ | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  |   return IntFormatSpec<TYPE, AlignTypeSpec<0> >( \ | 
					
						
							|  |  |  |       value, AlignTypeSpec<0>(width, ' ')); \ | 
					
						
							| 
									
										
										
										
											2013-01-13 09:29:37 -08:00
										 |  |  | } \ | 
					
						
							|  |  |  |  \ | 
					
						
							| 
									
										
										
										
											2014-01-08 08:17:38 -08:00
										 |  |  | template <typename Char> \ | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  | inline IntFormatSpec<TYPE, AlignTypeSpec<0>, Char> pad( \ | 
					
						
							| 
									
										
										
										
											2014-01-08 08:17:38 -08:00
										 |  |  |    TYPE value, unsigned width, Char fill) { \ | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  |  return IntFormatSpec<TYPE, AlignTypeSpec<0>, Char>( \ | 
					
						
							|  |  |  |      value, AlignTypeSpec<0>(width, fill)); \ | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 17:33:50 -07:00
										 |  |  | 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) | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-31 09:43:32 -08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |   \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 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-01-01 10:00:55 -08:00
										 |  |  | template <typename Char> | 
					
						
							|  |  |  | inline StrFormatSpec<Char> pad( | 
					
						
							|  |  |  |     const Char *str, unsigned width, Char fill = ' ') { | 
					
						
							| 
									
										
										
										
											2014-01-07 08:44:15 -08:00
										 |  |  |   return StrFormatSpec<Char>(str, width, fill); | 
					
						
							| 
									
										
										
										
											2014-01-01 10:00:55 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline StrFormatSpec<wchar_t> pad( | 
					
						
							|  |  |  |     const wchar_t *str, unsigned width, char fill = ' ') { | 
					
						
							| 
									
										
										
										
											2014-01-07 08:44:15 -08:00
										 |  |  |   return StrFormatSpec<wchar_t>(str, width, fill); | 
					
						
							| 
									
										
										
										
											2013-12-31 09:43:32 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-28 10:32:37 -07:00
										 |  |  | // Generates a comma-separated list with results of applying f to numbers 0..n-1.
 | 
					
						
							| 
									
										
										
										
											2014-06-25 07:50:16 -07:00
										 |  |  | # define FMT_GEN(n, f) FMT_GEN##n(f)
 | 
					
						
							| 
									
										
										
										
											2014-06-28 10:32:37 -07:00
										 |  |  | # 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)
 | 
					
						
							| 
									
										
										
										
											2014-06-25 07:50:16 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | # define FMT_MAKE_TEMPLATE_ARG(n) typename T##n
 | 
					
						
							|  |  |  | # define FMT_MAKE_ARG(n) const T##n &v##n
 | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  | # define FMT_MAKE_REF_char(n) fmt::internal::MakeArg<char>(v##n)
 | 
					
						
							|  |  |  | # define FMT_MAKE_REF_wchar_t(n) fmt::internal::MakeArg<wchar_t>(v##n)
 | 
					
						
							| 
									
										
										
										
											2014-06-25 07:50:16 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-28 11:07:43 -07:00
										 |  |  | #if FMT_USE_VARIADIC_TEMPLATES
 | 
					
						
							|  |  |  | // Defines a variadic function returning void.
 | 
					
						
							|  |  |  | # define FMT_VARIADIC_VOID(func, arg_type) \
 | 
					
						
							|  |  |  |   template<typename... Args> \ | 
					
						
							|  |  |  |   void func(arg_type arg1, const Args & ... args) { \ | 
					
						
							| 
									
										
										
										
											2014-07-02 06:33:25 -07:00
										 |  |  |     using fmt::internal::Arg; \ | 
					
						
							|  |  |  |     const Arg arg_array[fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \ | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |       fmt::internal::MakeArg<Char>(args)... \ | 
					
						
							| 
									
										
										
										
											2014-06-30 06:19:20 -07:00
										 |  |  |     }; \ | 
					
						
							| 
									
										
										
										
											2014-06-28 11:07:43 -07:00
										 |  |  |     func(arg1, ArgList(arg_array, sizeof...(Args))); \ | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Defines a variadic constructor.
 | 
					
						
							|  |  |  | # define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \
 | 
					
						
							|  |  |  |   template<typename... Args> \ | 
					
						
							|  |  |  |   ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) { \ | 
					
						
							| 
									
										
										
										
											2014-07-02 06:33:25 -07:00
										 |  |  |     using fmt::internal::Arg; \ | 
					
						
							|  |  |  |     const Arg arg_array[fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \ | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |       fmt::internal::MakeArg<Char>(args)... \ | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  |     }; \ | 
					
						
							|  |  |  |     func(arg0, arg1, ArgList(arg_array, sizeof...(Args))); \ | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-28 11:07:43 -07:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  | # define FMT_MAKE_REF(n) fmt::internal::MakeArg<Char>(v##n)
 | 
					
						
							| 
									
										
										
										
											2014-06-28 09:15:51 -07:00
										 |  |  | // Defines a wrapper for a function taking one argument of type arg_type
 | 
					
						
							|  |  |  | // and n additional arguments of arbitrary types.
 | 
					
						
							| 
									
										
										
										
											2014-06-28 11:07:43 -07:00
										 |  |  | # define FMT_WRAP1(func, arg_type, n) \
 | 
					
						
							| 
									
										
										
										
											2014-06-24 19:27:26 -07:00
										 |  |  |   template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \ | 
					
						
							| 
									
										
										
										
											2014-06-25 07:50:16 -07:00
										 |  |  |   inline void func(arg_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \ | 
					
						
							| 
									
										
										
										
											2014-07-02 06:33:25 -07:00
										 |  |  |     const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF)}; \ | 
					
						
							| 
									
										
										
										
											2014-06-25 07:50:16 -07:00
										 |  |  |     func(arg1, fmt::ArgList(args, sizeof(args) / sizeof(*args))); \ | 
					
						
							| 
									
										
										
										
											2014-06-24 19:27:26 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-25 07:50:16 -07:00
										 |  |  | // Emulates a variadic function returning void on a pre-C++11 compiler.
 | 
					
						
							|  |  |  | # define FMT_VARIADIC_VOID(func, arg_type) \
 | 
					
						
							| 
									
										
										
										
											2014-06-28 11:07:43 -07:00
										 |  |  |   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) | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | # define FMT_CTOR(ctor, func, arg0_type, arg1_type, n) \
 | 
					
						
							|  |  |  |   template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \ | 
					
						
							|  |  |  |   ctor(arg0_type arg0, arg1_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \ | 
					
						
							| 
									
										
										
										
											2014-07-02 06:33:25 -07:00
										 |  |  |     const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF)}; \ | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  |     func(arg0, arg1, fmt::ArgList(args, sizeof(args) / sizeof(*args))); \ | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  | // Emulates a variadic constructor on a pre-C++11 compiler.
 | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  | # 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) | 
					
						
							| 
									
										
										
										
											2014-06-25 07:50:16 -07:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-06-24 19:27:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-28 10:32:37 -07:00
										 |  |  | // 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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  | /**
 | 
					
						
							|  |  |  | An error returned by an operating system or a language runtime, | 
					
						
							|  |  |  | for example a file opening error. | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2014-07-01 21:01:15 -07:00
										 |  |  | class SystemError : public internal::RuntimeError { | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  |  private: | 
					
						
							|  |  |  |   void init(int error_code, StringRef format_str, const ArgList &args); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  protected: | 
					
						
							|  |  |  |   int error_code_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-30 17:17:48 -07:00
										 |  |  |   typedef char Char;  // For FMT_VARIADIC_CTOR.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-30 16:31:43 -07:00
										 |  |  |   SystemError() {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  |  public: | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    \rst | 
					
						
							|  |  |  |    Constructs a :cpp:class:`fmt::SystemError` object with the description | 
					
						
							|  |  |  |    of the form "*<message>*: *<system-message>*", where *<message>* is the | 
					
						
							|  |  |  |    formatted message and *<system-message>* 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_; } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2013-09-08 15:37:14 -07:00
										 |  |  |   \rst | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  |   This template provides operations for formatting and writing data into | 
					
						
							|  |  |  |   a character stream. The output is stored in a memory buffer that grows | 
					
						
							|  |  |  |   dynamically. | 
					
						
							| 
									
										
										
										
											2013-09-08 15:37:14 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   You can use one of the following typedefs for common character types: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   +---------+----------------------+ | 
					
						
							|  |  |  |   | Type    | Definition           | | 
					
						
							|  |  |  |   +=========+======================+ | 
					
						
							|  |  |  |   | Writer  | BasicWriter<char>    | | 
					
						
							|  |  |  |   +---------+----------------------+ | 
					
						
							|  |  |  |   | WWriter | BasicWriter<wchar_t> | | 
					
						
							|  |  |  |   +---------+----------------------+ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   **Example**:: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |      Writer out; | 
					
						
							|  |  |  |      out << "The answer is " << 42 << "\n"; | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  |      out.write("({:+f}, {:+f})", -3.14, 3.14); | 
					
						
							| 
									
										
										
										
											2013-09-08 15:37:14 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   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 | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  | template <typename Char> | 
					
						
							| 
									
										
										
										
											2013-02-02 20:29:02 -08:00
										 |  |  | class BasicWriter { | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |  private: | 
					
						
							| 
									
										
										
										
											2014-04-25 07:40:37 -07:00
										 |  |  |   // Output buffer.
 | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |   mutable internal::Array<Char, internal::INLINE_BUFFER_SIZE> buffer_; | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 10:36:17 -08:00
										 |  |  |   typedef typename internal::CharTraits<Char>::CharPtr CharPtr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  | #if _SECURE_SCL
 | 
					
						
							|  |  |  |   static Char *GetBase(CharPtr p) { return p.base(); } | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   static Char *GetBase(Char *p) { return p; } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static CharPtr FillPadding(CharPtr buffer, | 
					
						
							| 
									
										
										
										
											2013-09-08 13:07:04 -07:00
										 |  |  |       unsigned total_size, std::size_t content_size, wchar_t fill); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-25 17:55:41 -08:00
										 |  |  |   // Grows the buffer by n characters and returns a pointer to the newly
 | 
					
						
							|  |  |  |   // allocated area.
 | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  |   CharPtr GrowBuffer(std::size_t n) { | 
					
						
							| 
									
										
										
										
											2012-12-25 17:55:41 -08:00
										 |  |  |     std::size_t size = buffer_.size(); | 
					
						
							|  |  |  |     buffer_.resize(size + n); | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  |     return internal::CheckPtr(&buffer_[size], n); | 
					
						
							| 
									
										
										
										
											2012-12-25 17:55:41 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-07 08:57:55 -07:00
										 |  |  |   // Prepare a buffer for integer formatting.
 | 
					
						
							| 
									
										
										
										
											2014-06-20 08:01:58 -07:00
										 |  |  |   CharPtr PrepareBufferForInt(unsigned num_digits, | 
					
						
							| 
									
										
										
										
											2014-06-07 08:57:55 -07:00
										 |  |  |       const EmptySpec &, const char *prefix, unsigned prefix_size) { | 
					
						
							|  |  |  |     unsigned size = prefix_size + num_digits; | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  |     CharPtr p = GrowBuffer(size); | 
					
						
							| 
									
										
										
										
											2014-06-07 08:57:55 -07:00
										 |  |  |     std::copy(prefix, prefix + prefix_size, p); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     return p + size - 1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-20 07:34:02 -07:00
										 |  |  |   template <typename Spec> | 
					
						
							| 
									
										
										
										
											2014-06-20 08:01:58 -07:00
										 |  |  |   CharPtr PrepareBufferForInt(unsigned num_digits, | 
					
						
							| 
									
										
										
										
											2014-06-20 07:34:02 -07:00
										 |  |  |     const Spec &spec, const char *prefix, unsigned prefix_size); | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Formats an integer.
 | 
					
						
							|  |  |  |   template <typename T, typename Spec> | 
					
						
							| 
									
										
										
										
											2014-07-24 08:53:27 -07:00
										 |  |  |   void write_int(T value, const Spec &spec); | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-08 15:37:14 -07:00
										 |  |  |   // Formats a floating-point number (double or long double).
 | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  |   template <typename T> | 
					
						
							| 
									
										
										
										
											2014-07-24 08:53:27 -07:00
										 |  |  |   void write_double(T value, const FormatSpec &spec); | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  |   // Writes a formatted string.
 | 
					
						
							| 
									
										
										
										
											2013-09-06 19:32:19 -07:00
										 |  |  |   template <typename StringChar> | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  |   CharPtr write_str( | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  |       const StringChar *s, std::size_t size, const AlignSpec &spec); | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-24 07:54:26 -07:00
										 |  |  |   template <typename StringChar> | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  |   void write_str( | 
					
						
							| 
									
										
										
										
											2014-07-14 08:04:17 -07:00
										 |  |  |       const internal::Arg::StringValue<StringChar> &str, const FormatSpec &spec); | 
					
						
							| 
									
										
										
										
											2014-06-24 07:54:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-03 08:50:57 -07:00
										 |  |  |   // This method is private to disallow writing a wide string to a
 | 
					
						
							| 
									
										
										
										
											2013-09-09 22:21:40 -07:00
										 |  |  |   // 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!
 | 
					
						
							| 
									
										
										
										
											2013-12-07 08:12:03 -08:00
										 |  |  |   void operator<<(typename internal::CharTraits<Char>::UnsupportedStrType); | 
					
						
							| 
									
										
										
										
											2013-09-09 22:21:40 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-14 08:47:03 -07:00
										 |  |  |   friend class internal::ArgFormatter<Char>; | 
					
						
							| 
									
										
										
										
											2014-07-16 07:59:45 -07:00
										 |  |  |   friend class internal::PrintfFormatter<Char>; | 
					
						
							| 
									
										
										
										
											2014-06-06 06:38:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-25 07:40:37 -07:00
										 |  |  |  public: | 
					
						
							| 
									
										
										
										
											2014-05-13 08:55:13 -07:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |     Constructs a ``BasicWriter`` object. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2014-04-25 07:40:37 -07:00
										 |  |  |   BasicWriter() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if FMT_USE_RVALUE_REFERENCES
 | 
					
						
							| 
									
										
										
										
											2014-05-13 08:55:13 -07:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |     Constructs a ``BasicWriter`` object moving the content of the other | 
					
						
							|  |  |  |     object to it. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2014-04-25 07:40:37 -07:00
										 |  |  |   BasicWriter(BasicWriter &&other) : buffer_(std::move(other.buffer_)) {} | 
					
						
							| 
									
										
										
										
											2014-04-26 07:10:21 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-13 08:55:13 -07:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |     Moves the content of the other ``BasicWriter`` object to this one. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2014-04-26 07:10:21 -07:00
										 |  |  |   BasicWriter& operator=(BasicWriter &&other) { | 
					
						
							|  |  |  |     assert(this != &other); | 
					
						
							|  |  |  |     buffer_ = std::move(other.buffer_); | 
					
						
							|  |  |  |     return *this; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-04-25 07:40:37 -07:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  |   /**
 | 
					
						
							| 
									
										
										
										
											2014-05-13 08:55:13 -07:00
										 |  |  |     Returns the total number of characters written. | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  |    */ | 
					
						
							|  |  |  |   std::size_t size() const { return buffer_.size(); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |     Returns a pointer to the output buffer content. No terminating null | 
					
						
							|  |  |  |     character is appended. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  |   const Char *data() const { return &buffer_[0]; } | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |     Returns a pointer to the output buffer content with terminating null | 
					
						
							|  |  |  |     character appended. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  |   const Char *c_str() const { | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  |     std::size_t size = buffer_.size(); | 
					
						
							|  |  |  |     buffer_.reserve(size + 1); | 
					
						
							|  |  |  |     buffer_[size] = '\0'; | 
					
						
							|  |  |  |     return &buffer_[0]; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							| 
									
										
										
										
											2013-01-13 07:14:54 -08:00
										 |  |  |     Returns the content of the output buffer as an `std::string`. | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  |   std::basic_string<Char> str() const { | 
					
						
							|  |  |  |     return std::basic_string<Char>(&buffer_[0], buffer_.size()); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-08 15:37:14 -07:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |     \rst | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  |     Writes formatted data. | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     *args* is an argument list representing arbitrary arguments. | 
					
						
							| 
									
										
										
										
											2013-09-08 15:37:14 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     **Example**:: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        Writer out; | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  |        out.write("Current point:\n"); | 
					
						
							|  |  |  |        out.write("({:+f}, {:+f})", -3.14, 3.14); | 
					
						
							| 
									
										
										
										
											2013-09-08 15:37:14 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     This will write the following output to the ``out`` object: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     .. code-block:: none | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        Current point: | 
					
						
							|  |  |  |        (-3.140000, +3.140000) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-13 08:55:13 -07:00
										 |  |  |     The output can be accessed using :meth:`data`, :meth:`c_str` or :meth:`str` | 
					
						
							|  |  |  |     methods. | 
					
						
							| 
									
										
										
										
											2013-09-08 15:37:14 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     See also `Format String Syntax`_. | 
					
						
							|  |  |  |     \endrst | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2014-07-08 16:20:33 -07:00
										 |  |  |   void write(BasicStringRef<Char> format, const ArgList &args) { | 
					
						
							| 
									
										
										
										
											2014-07-08 16:38:50 -07:00
										 |  |  |     BasicFormatter<Char>(*this).Format(format, args); | 
					
						
							| 
									
										
										
										
											2014-06-25 07:50:16 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  |   FMT_VARIADIC_VOID(write, fmt::BasicStringRef<Char>) | 
					
						
							| 
									
										
										
										
											2014-06-25 07:50:16 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-02 20:29:02 -08:00
										 |  |  |   BasicWriter &operator<<(int value) { | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  |     return *this << IntFormatSpec<int>(value); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-02-02 20:29:02 -08:00
										 |  |  |   BasicWriter &operator<<(unsigned value) { | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  |     return *this << IntFormatSpec<unsigned>(value); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-09-08 14:18:08 -07:00
										 |  |  |   BasicWriter &operator<<(long value) { | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  |     return *this << IntFormatSpec<long>(value); | 
					
						
							| 
									
										
										
										
											2013-09-08 14:18:08 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-09-09 15:12:51 -07:00
										 |  |  |   BasicWriter &operator<<(unsigned long value) { | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  |     return *this << IntFormatSpec<unsigned long>(value); | 
					
						
							| 
									
										
										
										
											2013-09-09 15:12:51 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-02-15 09:58:33 -08:00
										 |  |  |   BasicWriter &operator<<(LongLong value) { | 
					
						
							|  |  |  |     return *this << IntFormatSpec<LongLong>(value); | 
					
						
							| 
									
										
										
										
											2013-09-09 15:12:51 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-09-08 15:37:14 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							| 
									
										
										
										
											2013-09-08 16:27:12 -07:00
										 |  |  |     Formats *value* and writes it to the stream. | 
					
						
							| 
									
										
										
										
											2013-09-08 15:37:14 -07:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2014-02-15 10:02:02 -08:00
										 |  |  |   BasicWriter &operator<<(ULongLong value) { | 
					
						
							|  |  |  |     return *this << IntFormatSpec<ULongLong>(value); | 
					
						
							| 
									
										
										
										
											2013-09-08 14:18:08 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-08 16:27:12 -07:00
										 |  |  |   BasicWriter &operator<<(double value) { | 
					
						
							| 
									
										
										
										
											2014-07-24 08:53:27 -07:00
										 |  |  |     write_double(value, FormatSpec()); | 
					
						
							| 
									
										
										
										
											2013-09-08 16:27:12 -07:00
										 |  |  |     return *this; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-08 15:37:14 -07:00
										 |  |  |   /**
 | 
					
						
							| 
									
										
										
										
											2013-09-08 16:27:12 -07:00
										 |  |  |     Formats *value* using the general format for floating-point numbers | 
					
						
							|  |  |  |     (``'g'``) and writes it to the stream. | 
					
						
							| 
									
										
										
										
											2013-09-08 15:37:14 -07:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2013-09-08 16:27:12 -07:00
										 |  |  |   BasicWriter &operator<<(long double value) { | 
					
						
							| 
									
										
										
										
											2014-07-24 08:53:27 -07:00
										 |  |  |     write_double(value, FormatSpec()); | 
					
						
							| 
									
										
										
										
											2013-02-27 13:17:09 -08:00
										 |  |  |     return *this; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-02 11:30:28 -08:00
										 |  |  |   /**
 | 
					
						
							| 
									
										
										
										
											2014-04-28 08:59:29 -07:00
										 |  |  |     Writes a character to the stream. | 
					
						
							| 
									
										
										
										
											2014-01-02 11:30:28 -08:00
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2013-09-09 22:21:40 -07:00
										 |  |  |   BasicWriter &operator<<(char value) { | 
					
						
							| 
									
										
										
										
											2014-07-24 08:53:27 -07:00
										 |  |  |     buffer_.push_back(value); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     return *this; | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-02 11:30:28 -08:00
										 |  |  |   BasicWriter &operator<<(wchar_t value) { | 
					
						
							| 
									
										
										
										
											2014-07-24 08:53:27 -07:00
										 |  |  |     buffer_.push_back(internal::CharTraits<Char>::convert(value)); | 
					
						
							| 
									
										
										
										
											2014-01-02 11:30:28 -08:00
										 |  |  |     return *this; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-10 09:26:11 -07:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |     Writes *value* to the stream. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2014-07-24 08:53:27 -07:00
										 |  |  |   BasicWriter &operator<<(fmt::BasicStringRef<Char> value) { | 
					
						
							| 
									
										
										
										
											2013-09-09 22:21:40 -07:00
										 |  |  |     const Char *str = value.c_str(); | 
					
						
							| 
									
										
										
										
											2014-07-24 08:53:27 -07:00
										 |  |  |     buffer_.append(str, str + value.size()); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     return *this; | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  |   template <typename T, typename Spec, typename FillChar> | 
					
						
							|  |  |  |   BasicWriter &operator<<(const IntFormatSpec<T, Spec, FillChar> &spec) { | 
					
						
							| 
									
										
										
										
											2014-07-04 07:18:44 -07:00
										 |  |  |     internal::CharTraits<Char>::convert(FillChar()); | 
					
						
							| 
									
										
										
										
											2014-07-24 08:53:27 -07:00
										 |  |  |     write_int(spec.value(), spec); | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  |     return *this; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-01 10:00:55 -08:00
										 |  |  |   template <typename StringChar> | 
					
						
							|  |  |  |   BasicWriter &operator<<(const StrFormatSpec<StringChar> &spec) { | 
					
						
							|  |  |  |     const StringChar *s = spec.str(); | 
					
						
							| 
									
										
										
										
											2014-07-08 16:20:33 -07:00
										 |  |  |     // TODO: error if fill is not convertible to Char
 | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  |     write_str(s, std::char_traits<Char>::length(s), spec); | 
					
						
							| 
									
										
										
										
											2013-12-31 09:43:32 -08:00
										 |  |  |     return *this; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-28 17:35:57 -07:00
										 |  |  |   void clear() { buffer_.clear(); } | 
					
						
							| 
									
										
										
										
											2012-12-25 17:55:41 -08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  | template <typename Char> | 
					
						
							| 
									
										
										
										
											2013-09-06 19:32:19 -07:00
										 |  |  | template <typename StringChar> | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  | typename BasicWriter<Char>::CharPtr BasicWriter<Char>::write_str( | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  |     const StringChar *s, std::size_t size, const AlignSpec &spec) { | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  |   CharPtr out = CharPtr(); | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  |   if (spec.width() > size) { | 
					
						
							|  |  |  |     out = GrowBuffer(spec.width()); | 
					
						
							| 
									
										
										
										
											2013-09-08 13:47:06 -07:00
										 |  |  |     Char fill = static_cast<Char>(spec.fill()); | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  |     if (spec.align() == ALIGN_RIGHT) { | 
					
						
							| 
									
										
										
										
											2013-09-08 13:47:06 -07:00
										 |  |  |       std::fill_n(out, spec.width() - size, fill); | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  |       out += spec.width() - size; | 
					
						
							|  |  |  |     } else if (spec.align() == ALIGN_CENTER) { | 
					
						
							| 
									
										
										
										
											2013-09-08 13:47:06 -07:00
										 |  |  |       out = FillPadding(out, spec.width(), size, fill); | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2013-09-08 13:47:06 -07:00
										 |  |  |       std::fill_n(out + size, spec.width() - size, fill); | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     out = GrowBuffer(size); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   std::copy(s, s + size, out); | 
					
						
							|  |  |  |   return out; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-20 07:34:02 -07:00
										 |  |  | template <typename Char> | 
					
						
							|  |  |  | template <typename Spec> | 
					
						
							|  |  |  | typename fmt::BasicWriter<Char>::CharPtr | 
					
						
							| 
									
										
										
										
											2014-06-20 08:01:58 -07:00
										 |  |  |   fmt::BasicWriter<Char>::PrepareBufferForInt( | 
					
						
							| 
									
										
										
										
											2014-06-20 07:59:23 -07:00
										 |  |  |     unsigned num_digits, const Spec &spec, | 
					
						
							|  |  |  |     const char *prefix, unsigned prefix_size) { | 
					
						
							|  |  |  |   unsigned width = spec.width(); | 
					
						
							| 
									
										
										
										
											2014-06-21 08:18:05 -07:00
										 |  |  |   Alignment align = spec.align(); | 
					
						
							| 
									
										
										
										
											2014-06-30 17:46:14 -07:00
										 |  |  |   Char fill = static_cast<Char>(spec.fill()); | 
					
						
							| 
									
										
										
										
											2014-06-20 07:59:23 -07:00
										 |  |  |   if (spec.precision() > static_cast<int>(num_digits)) { | 
					
						
							|  |  |  |     // Octal prefix '0' is counted as a digit, so ignore it if precision
 | 
					
						
							|  |  |  |     // is specified.
 | 
					
						
							| 
									
										
										
										
											2014-06-20 08:04:44 -07:00
										 |  |  |     if (prefix_size > 0 && prefix[prefix_size - 1] == '0') | 
					
						
							|  |  |  |       --prefix_size; | 
					
						
							| 
									
										
										
										
											2014-06-20 07:59:23 -07:00
										 |  |  |     unsigned number_size = prefix_size + spec.precision(); | 
					
						
							| 
									
										
										
										
											2014-06-21 08:18:05 -07:00
										 |  |  |     AlignSpec subspec(number_size, '0', ALIGN_NUMERIC); | 
					
						
							|  |  |  |     if (number_size >= width) | 
					
						
							|  |  |  |       return PrepareBufferForInt(num_digits, subspec, prefix, prefix_size); | 
					
						
							|  |  |  |     buffer_.reserve(width); | 
					
						
							|  |  |  |     unsigned fill_size = width - number_size; | 
					
						
							|  |  |  |     if (align != ALIGN_LEFT) { | 
					
						
							|  |  |  |       CharPtr p = GrowBuffer(fill_size); | 
					
						
							| 
									
										
										
										
											2014-06-30 17:46:14 -07:00
										 |  |  |       std::fill(p, p + fill_size, fill); | 
					
						
							| 
									
										
										
										
											2014-06-21 08:18:05 -07:00
										 |  |  |     } | 
					
						
							|  |  |  |     CharPtr result = PrepareBufferForInt(num_digits, subspec, prefix, prefix_size); | 
					
						
							|  |  |  |     if (align == ALIGN_LEFT) { | 
					
						
							|  |  |  |       CharPtr p = GrowBuffer(fill_size); | 
					
						
							| 
									
										
										
										
											2014-06-30 17:46:14 -07:00
										 |  |  |       std::fill(p, p + fill_size, fill); | 
					
						
							| 
									
										
										
										
											2014-06-20 07:59:23 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-06-21 08:18:05 -07:00
										 |  |  |     return result; | 
					
						
							| 
									
										
										
										
											2014-06-20 07:34:02 -07:00
										 |  |  |   } | 
					
						
							|  |  |  |   unsigned size = prefix_size + num_digits; | 
					
						
							|  |  |  |   if (width <= size) { | 
					
						
							|  |  |  |     CharPtr p = GrowBuffer(size); | 
					
						
							|  |  |  |     std::copy(prefix, prefix + prefix_size, p); | 
					
						
							|  |  |  |     return p + size - 1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   CharPtr p = GrowBuffer(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 = FillPadding(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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  | template <typename Char> | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | template <typename T, typename Spec> | 
					
						
							| 
									
										
										
										
											2014-07-24 08:53:27 -07:00
										 |  |  | void BasicWriter<Char>::write_int(T value, const Spec &spec) { | 
					
						
							| 
									
										
										
										
											2014-06-07 08:57:55 -07:00
										 |  |  |   unsigned prefix_size = 0; | 
					
						
							| 
									
										
										
										
											2014-02-19 12:43:55 -08:00
										 |  |  |   typedef typename internal::IntTraits<T>::MainType UnsignedType; | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   UnsignedType abs_value = value; | 
					
						
							| 
									
										
										
										
											2014-06-07 08:57:55 -07:00
										 |  |  |   char prefix[4] = ""; | 
					
						
							| 
									
										
										
										
											2014-07-16 07:27:54 -07:00
										 |  |  |   if (internal::is_negative(value)) { | 
					
						
							| 
									
										
										
										
											2014-06-07 08:57:55 -07:00
										 |  |  |     prefix[0] = '-'; | 
					
						
							|  |  |  |     ++prefix_size; | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     abs_value = 0 - abs_value; | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |   } else if (spec.sign_flag()) { | 
					
						
							| 
									
										
										
										
											2014-06-07 08:57:55 -07:00
										 |  |  |     prefix[0] = spec.plus_flag() ? '+' : ' '; | 
					
						
							|  |  |  |     ++prefix_size; | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |   switch (spec.type()) { | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   case 0: case 'd': { | 
					
						
							| 
									
										
										
										
											2014-07-24 08:59:52 -07:00
										 |  |  |     unsigned num_digits = internal::count_digits(abs_value); | 
					
						
							| 
									
										
										
										
											2014-06-20 08:01:58 -07:00
										 |  |  |     CharPtr p = PrepareBufferForInt( | 
					
						
							| 
									
										
										
										
											2014-06-07 08:57:55 -07:00
										 |  |  |       num_digits, spec, prefix, prefix_size) + 1 - num_digits; | 
					
						
							| 
									
										
										
										
											2014-02-14 10:36:17 -08:00
										 |  |  |     internal::FormatDecimal(GetBase(p), abs_value, num_digits); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   case 'x': case 'X': { | 
					
						
							|  |  |  |     UnsignedType n = abs_value; | 
					
						
							| 
									
										
										
										
											2014-06-07 08:57:55 -07:00
										 |  |  |     if (spec.hash_flag()) { | 
					
						
							|  |  |  |       prefix[prefix_size++] = '0'; | 
					
						
							|  |  |  |       prefix[prefix_size++] = spec.type(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     unsigned num_digits = 0; | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     do { | 
					
						
							| 
									
										
										
										
											2014-06-07 08:57:55 -07:00
										 |  |  |       ++num_digits; | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     } while ((n >>= 4) != 0); | 
					
						
							| 
									
										
										
										
											2014-06-20 08:01:58 -07:00
										 |  |  |     Char *p = GetBase(PrepareBufferForInt( | 
					
						
							| 
									
										
										
										
											2014-06-07 08:57:55 -07:00
										 |  |  |       num_digits, spec, prefix, prefix_size)); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     n = abs_value; | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |     const char *digits = spec.type() == 'x' ? | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |         "0123456789abcdef" : "0123456789ABCDEF"; | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       *p-- = digits[n & 0xf]; | 
					
						
							|  |  |  |     } while ((n >>= 4) != 0); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-11-16 21:25:48 -08:00
										 |  |  |   case 'b': case 'B': { | 
					
						
							| 
									
										
										
										
											2013-10-23 20:04:32 -07:00
										 |  |  |     UnsignedType n = abs_value; | 
					
						
							| 
									
										
										
										
											2014-06-07 08:57:55 -07:00
										 |  |  |     if (spec.hash_flag()) { | 
					
						
							|  |  |  |       prefix[prefix_size++] = '0'; | 
					
						
							|  |  |  |       prefix[prefix_size++] = spec.type(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     unsigned num_digits = 0; | 
					
						
							| 
									
										
										
										
											2013-10-23 20:04:32 -07:00
										 |  |  |     do { | 
					
						
							| 
									
										
										
										
											2014-06-07 08:57:55 -07:00
										 |  |  |       ++num_digits; | 
					
						
							| 
									
										
										
										
											2013-10-23 20:04:32 -07:00
										 |  |  |     } while ((n >>= 1) != 0); | 
					
						
							| 
									
										
										
										
											2014-06-20 08:01:58 -07:00
										 |  |  |     Char *p = GetBase(PrepareBufferForInt(num_digits, spec, prefix, prefix_size)); | 
					
						
							| 
									
										
										
										
											2013-10-23 20:04:32 -07:00
										 |  |  |     n = abs_value; | 
					
						
							|  |  |  |     do { | 
					
						
							| 
									
										
										
										
											2013-11-14 08:45:20 -08:00
										 |  |  |       *p-- = '0' + (n & 1); | 
					
						
							| 
									
										
										
										
											2013-10-23 20:04:32 -07:00
										 |  |  |     } while ((n >>= 1) != 0); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   case 'o': { | 
					
						
							|  |  |  |     UnsignedType n = abs_value; | 
					
						
							| 
									
										
										
										
											2014-06-07 08:57:55 -07:00
										 |  |  |     if (spec.hash_flag()) | 
					
						
							|  |  |  |       prefix[prefix_size++] = '0'; | 
					
						
							|  |  |  |     unsigned num_digits = 0; | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     do { | 
					
						
							| 
									
										
										
										
											2014-06-07 08:57:55 -07:00
										 |  |  |       ++num_digits; | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     } while ((n >>= 3) != 0); | 
					
						
							| 
									
										
										
										
											2014-06-20 08:01:58 -07:00
										 |  |  |     Char *p = GetBase(PrepareBufferForInt( | 
					
						
							| 
									
										
										
										
											2014-06-07 08:57:55 -07:00
										 |  |  |       num_digits, spec, prefix, prefix_size)); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     n = abs_value; | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       *p-- = '0' + (n & 7); | 
					
						
							|  |  |  |     } while ((n >>= 3) != 0); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   default: | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |     internal::ReportUnknownType(spec.type(), "integer"); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-08 16:20:33 -07:00
										 |  |  | // Formats a value.
 | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  | template <typename Char, typename T> | 
					
						
							| 
									
										
										
										
											2014-07-08 16:38:50 -07:00
										 |  |  | void format(BasicFormatter<Char> &f, const Char *format_str, const T &value) { | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  |   std::basic_ostringstream<Char> os; | 
					
						
							| 
									
										
										
										
											2013-01-13 07:50:28 -08:00
										 |  |  |   os << value; | 
					
						
							| 
									
										
										
										
											2014-07-08 16:20:33 -07:00
										 |  |  |   f.format(format_str, internal::MakeArg<Char>(os.str())); | 
					
						
							| 
									
										
										
										
											2013-01-13 07:50:28 -08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-03 09:48:54 -07:00
										 |  |  | // Reports a system error without throwing an exception.
 | 
					
						
							|  |  |  | // Can be used to report errors from destructors.
 | 
					
						
							|  |  |  | void ReportSystemError(int error_code, StringRef message) FMT_NOEXCEPT(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef _WIN32
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-30 10:18:11 -07:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  |  A Windows error. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | class WindowsError : public SystemError { | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   void init(int error_code, StringRef format_str, const ArgList &args); | 
					
						
							| 
									
										
										
										
											2014-05-14 07:05:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-30 14:26:29 -07:00
										 |  |  |  public: | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |    \rst | 
					
						
							|  |  |  |    Constructs a :cpp:class:`fmt::WindowsError` object with the description | 
					
						
							|  |  |  |    of the form "*<message>*: *<system-message>*", where *<message>* is the | 
					
						
							|  |  |  |    formatted message and *<system-message>* 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) | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-03 09:48:54 -07:00
										 |  |  | // Reports a Windows error without throwing an exception.
 | 
					
						
							|  |  |  | // Can be used to report errors from destructors.
 | 
					
						
							|  |  |  | void ReportWinError(int error_code, StringRef message) FMT_NOEXCEPT(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-28 08:59:29 -07:00
										 |  |  | 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; | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-07-01 09:10:43 -07:00
										 |  |  | void print_colored(Color c, StringRef format, const ArgList &args); | 
					
						
							| 
									
										
										
										
											2014-04-28 08:59:29 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-13 08:55:13 -07:00
										 |  |  | /**
 | 
					
						
							|  |  |  |   \rst | 
					
						
							|  |  |  |   Formats a string similarly to Python's `str.format | 
					
						
							|  |  |  |   <http://docs.python.org/3/library/stdtypes.html#str.format>`__ function
 | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  |   and returns the result as a string. | 
					
						
							| 
									
										
										
										
											2014-06-06 06:38:37 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  |   *format_str* is a format string that contains literal text and replacement | 
					
						
							|  |  |  |   fields surrounded by braces ``{}``. The fields are replaced with formatted | 
					
						
							|  |  |  |   arguments in the resulting string. | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   *args* is an argument list representing arbitrary arguments. | 
					
						
							| 
									
										
										
										
											2014-05-13 08:55:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   **Example**:: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  |     std::string message = format("The answer is {}", 42); | 
					
						
							| 
									
										
										
										
											2014-05-13 08:55:13 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   See also `Format String Syntax`_. | 
					
						
							|  |  |  |   \endrst | 
					
						
							| 
									
										
										
										
											2014-06-28 14:48:42 -07:00
										 |  |  | */ | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  | inline std::string format(StringRef format_str, const ArgList &args) { | 
					
						
							| 
									
										
										
										
											2014-06-28 14:48:42 -07:00
										 |  |  |   Writer w; | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  |   w.write(format_str, args); | 
					
						
							|  |  |  |   return w.str(); | 
					
						
							| 
									
										
										
										
											2014-06-28 14:48:42 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  | inline std::wstring format(WStringRef format, const ArgList &args) { | 
					
						
							| 
									
										
										
										
											2014-06-28 15:58:02 -07:00
										 |  |  |   WWriter w; | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  |   w.write(format, args); | 
					
						
							|  |  |  |   return w.str(); | 
					
						
							| 
									
										
										
										
											2014-06-28 15:58:02 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  | /**
 | 
					
						
							|  |  |  |   \rst | 
					
						
							|  |  |  |   Prints formatted data to ``stdout``. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   **Example**:: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     print("Elapsed time: {0:.2f} seconds", 1.23); | 
					
						
							|  |  |  |   \endrst | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-06-28 19:44:39 -07:00
										 |  |  | void print(StringRef format, const ArgList &args); | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |   \rst | 
					
						
							|  |  |  |   Prints formatted data to a file. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   **Example**:: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     print(stderr, "Don't {}!", "panic"); | 
					
						
							|  |  |  |   \endrst | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-06-28 21:56:40 -07:00
										 |  |  | void print(std::FILE *f, StringRef format, const ArgList &args); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-09 06:56:36 -07:00
										 |  |  | /**
 | 
					
						
							|  |  |  |   \rst | 
					
						
							|  |  |  |   Prints formatted data to a stream. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   **Example**:: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     print(cerr, "Don't {}!", "panic"); | 
					
						
							|  |  |  |   \endrst | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void print(std::ostream &os, StringRef format, const ArgList &args); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  | template <typename Char> | 
					
						
							|  |  |  | void printf(BasicWriter<Char> &w, | 
					
						
							|  |  |  |     BasicStringRef<Char> format, const ArgList &args) { | 
					
						
							| 
									
										
										
										
											2014-07-16 07:59:45 -07:00
										 |  |  |   internal::PrintfFormatter<Char>().Format(w, format, args); | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  | inline std::string sprintf(StringRef format, const ArgList &args) { | 
					
						
							| 
									
										
										
										
											2014-06-28 21:56:40 -07:00
										 |  |  |   Writer w; | 
					
						
							| 
									
										
										
										
											2014-06-29 19:52:26 -07:00
										 |  |  |   printf(w, format, args); | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  |   return w.str(); | 
					
						
							| 
									
										
										
										
											2014-06-28 21:56:40 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void printf(StringRef format, const ArgList &args); | 
					
						
							| 
									
										
										
										
											2014-06-28 19:44:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-09 06:51:03 -07:00
										 |  |  | /**
 | 
					
						
							|  |  |  |   Fast integer formatter. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class FormatInt { | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   // Buffer should be large enough to hold all digits (digits10 + 1),
 | 
					
						
							|  |  |  |   // a sign and a null character.
 | 
					
						
							| 
									
										
										
										
											2014-02-15 10:02:02 -08:00
										 |  |  |   enum {BUFFER_SIZE = std::numeric_limits<ULongLong>::digits10 + 3}; | 
					
						
							| 
									
										
										
										
											2014-02-15 09:24:31 -08:00
										 |  |  |   mutable char buffer_[BUFFER_SIZE]; | 
					
						
							| 
									
										
										
										
											2013-09-09 06:51:03 -07:00
										 |  |  |   char *str_; | 
					
						
							| 
									
										
										
										
											2013-11-21 09:11:58 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-09 06:51:03 -07:00
										 |  |  |   // Formats value in reverse and returns the number of digits.
 | 
					
						
							| 
									
										
										
										
											2014-02-15 10:02:02 -08:00
										 |  |  |   char *FormatDecimal(ULongLong value) { | 
					
						
							| 
									
										
										
										
											2014-02-15 09:24:31 -08:00
										 |  |  |     char *buffer_end = buffer_ + BUFFER_SIZE - 1; | 
					
						
							| 
									
										
										
										
											2013-09-09 06:51:03 -07:00
										 |  |  |     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<char>('0' + value); | 
					
						
							|  |  |  |       return buffer_end; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     unsigned index = static_cast<unsigned>(value * 2); | 
					
						
							|  |  |  |     *--buffer_end = internal::DIGITS[index + 1]; | 
					
						
							|  |  |  |     *--buffer_end = internal::DIGITS[index]; | 
					
						
							|  |  |  |     return buffer_end; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-04-28 08:59:29 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-15 09:58:33 -08:00
										 |  |  |   void FormatSigned(LongLong value) { | 
					
						
							| 
									
										
										
										
											2014-02-15 10:02:02 -08:00
										 |  |  |     ULongLong abs_value = value; | 
					
						
							| 
									
										
										
										
											2013-09-09 06:51:03 -07:00
										 |  |  |     bool negative = value < 0; | 
					
						
							|  |  |  |     if (negative) | 
					
						
							|  |  |  |       abs_value = 0 - value; | 
					
						
							|  |  |  |     str_ = FormatDecimal(abs_value); | 
					
						
							|  |  |  |     if (negative) | 
					
						
							|  |  |  |       *--str_ = '-'; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-01-30 08:02:06 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   explicit FormatInt(int value) { FormatSigned(value); } | 
					
						
							| 
									
										
										
										
											2014-02-13 09:59:49 -08:00
										 |  |  |   explicit FormatInt(long value) { FormatSigned(value); } | 
					
						
							| 
									
										
										
										
											2014-02-15 09:58:33 -08:00
										 |  |  |   explicit FormatInt(LongLong value) { FormatSigned(value); } | 
					
						
							| 
									
										
										
										
											2013-09-09 06:51:03 -07:00
										 |  |  |   explicit FormatInt(unsigned value) : str_(FormatDecimal(value)) {} | 
					
						
							| 
									
										
										
										
											2014-02-13 09:59:49 -08:00
										 |  |  |   explicit FormatInt(unsigned long value) : str_(FormatDecimal(value)) {} | 
					
						
							| 
									
										
										
										
											2014-02-15 10:02:02 -08:00
										 |  |  |   explicit FormatInt(ULongLong value) : str_(FormatDecimal(value)) {} | 
					
						
							| 
									
										
										
										
											2013-09-09 06:51:03 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-15 09:39:06 -08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |     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. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2014-02-15 09:24:31 -08:00
										 |  |  |   const char *c_str() const { | 
					
						
							|  |  |  |     buffer_[BUFFER_SIZE - 1] = '\0'; | 
					
						
							|  |  |  |     return str_; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-02-15 09:39:06 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |     Returns the content of the output buffer as an `std::string`. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2014-02-15 09:24:31 -08:00
										 |  |  |   std::string str() const { return std::string(str_, size()); } | 
					
						
							| 
									
										
										
										
											2013-09-09 06:51:03 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-14 10:36:17 -08:00
										 |  |  | // 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 <typename T> | 
					
						
							|  |  |  | inline void FormatDec(char *&buffer, T value) { | 
					
						
							| 
									
										
										
										
											2014-02-20 07:04:54 -08:00
										 |  |  |   typename internal::IntTraits<T>::MainType abs_value = value; | 
					
						
							| 
									
										
										
										
											2014-07-16 07:27:54 -07:00
										 |  |  |   if (internal::is_negative(value)) { | 
					
						
							| 
									
										
										
										
											2014-02-14 10:36:17 -08:00
										 |  |  |     *buffer++ = '-'; | 
					
						
							|  |  |  |     abs_value = 0 - abs_value; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-02-20 21:05:46 -08:00
										 |  |  |   if (abs_value < 100) { | 
					
						
							|  |  |  |     if (abs_value < 10) { | 
					
						
							|  |  |  |       *buffer++ = static_cast<char>('0' + abs_value); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     unsigned index = static_cast<unsigned>(abs_value * 2); | 
					
						
							|  |  |  |     *buffer++ = internal::DIGITS[index]; | 
					
						
							|  |  |  |     *buffer++ = internal::DIGITS[index + 1]; | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-24 08:59:52 -07:00
										 |  |  |   unsigned num_digits = internal::count_digits(abs_value); | 
					
						
							| 
									
										
										
										
											2014-02-14 10:36:17 -08:00
										 |  |  |   internal::FormatDecimal(buffer, abs_value, num_digits); | 
					
						
							|  |  |  |   buffer += num_digits; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-24 13:01:44 -07:00
										 |  |  | #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.
 | 
					
						
							| 
									
										
										
										
											2014-06-28 13:31:44 -07:00
										 |  |  | // It is used at the end because we want to suppress as little warnings as
 | 
					
						
							|  |  |  | // possible.
 | 
					
						
							| 
									
										
										
										
											2014-06-24 13:01:44 -07:00
										 |  |  | # pragma GCC system_header
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-28 11:36:49 -07:00
										 |  |  | // This is used to work around VC++ bugs in handling variadic macros.
 | 
					
						
							| 
									
										
										
										
											2014-06-24 11:09:07 -07:00
										 |  |  | #define FMT_EXPAND(args) args
 | 
					
						
							| 
									
										
										
										
											2014-06-28 11:30:15 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | // 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())
 | 
					
						
							| 
									
										
										
										
											2014-06-28 11:36:49 -07:00
										 |  |  | #define FMT_NARG_(...) FMT_EXPAND(FMT_ARG_N(__VA_ARGS__))
 | 
					
						
							| 
									
										
										
										
											2014-06-28 11:30:15 -07:00
										 |  |  | #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
 | 
					
						
							| 
									
										
										
										
											2014-06-24 10:14:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-28 11:43:07 -07:00
										 |  |  | #define FMT_CONCAT(a, b) a##b
 | 
					
						
							| 
									
										
										
										
											2014-06-28 12:49:51 -07:00
										 |  |  | #define FMT_FOR_EACH_(N, f, ...) \
 | 
					
						
							|  |  |  |   FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__)) | 
					
						
							| 
									
										
										
										
											2014-06-28 11:07:43 -07:00
										 |  |  | #define FMT_FOR_EACH(f, ...) \
 | 
					
						
							| 
									
										
										
										
											2014-06-28 11:30:15 -07:00
										 |  |  |   FMT_EXPAND(FMT_FOR_EACH_(FMT_NARG(__VA_ARGS__), f, __VA_ARGS__)) | 
					
						
							| 
									
										
										
										
											2014-06-24 10:14:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define FMT_ADD_ARG_NAME(type, index) type arg##index
 | 
					
						
							|  |  |  | #define FMT_GET_ARG_NAME(type, index) arg##index
 | 
					
						
							| 
									
										
										
										
											2014-06-28 13:31:44 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if FMT_USE_VARIADIC_TEMPLATES
 | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  | # define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \
 | 
					
						
							| 
									
										
										
										
											2014-06-28 13:31:44 -07:00
										 |  |  |   template<typename... Args> \ | 
					
						
							| 
									
										
										
										
											2014-06-28 15:58:02 -07:00
										 |  |  |   ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \ | 
					
						
							| 
									
										
										
										
											2014-06-28 13:31:44 -07:00
										 |  |  |       const Args & ... args) { \ | 
					
						
							| 
									
										
										
										
											2014-07-02 06:33:25 -07:00
										 |  |  |     using fmt::internal::Arg; \ | 
					
						
							|  |  |  |     const Arg array[fmt::internal::NonZero<sizeof...(Args)>::VALUE] = { \ | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |       fmt::internal::MakeArg<Char>(args)... \ | 
					
						
							| 
									
										
										
										
											2014-06-28 15:58:02 -07:00
										 |  |  |     }; \ | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |     call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \ | 
					
						
							| 
									
										
										
										
											2014-06-28 13:31:44 -07:00
										 |  |  |       fmt::ArgList(array, sizeof...(Args))); \ | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2014-06-28 11:07:43 -07:00
										 |  |  | // Defines a wrapper for a function taking __VA_ARGS__ arguments
 | 
					
						
							|  |  |  | // and n additional arguments of arbitrary types.
 | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  | # define FMT_WRAP(Char, ReturnType, func, call, n, ...) \
 | 
					
						
							| 
									
										
										
										
											2014-06-28 11:07:43 -07:00
										 |  |  |   template <FMT_GEN(n, FMT_MAKE_TEMPLATE_ARG)> \ | 
					
						
							| 
									
										
										
										
											2014-06-28 15:58:02 -07:00
										 |  |  |   inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \ | 
					
						
							| 
									
										
										
										
											2014-06-28 12:14:43 -07:00
										 |  |  |       FMT_GEN(n, FMT_MAKE_ARG)) { \ | 
					
						
							| 
									
										
										
										
											2014-07-02 06:33:25 -07:00
										 |  |  |     const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF_##Char)}; \ | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |     call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \ | 
					
						
							| 
									
										
										
										
											2014-06-28 13:31:44 -07:00
										 |  |  |       fmt::ArgList(args, sizeof(args) / sizeof(*args))); \ | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  | # define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \
 | 
					
						
							| 
									
										
										
										
											2014-06-28 15:58:02 -07:00
										 |  |  |   inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__)) { \ | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |     call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList()); \ | 
					
						
							| 
									
										
										
										
											2014-06-24 10:14:50 -07:00
										 |  |  |   } \ | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |   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__) | 
					
						
							| 
									
										
										
										
											2014-06-28 13:31:44 -07:00
										 |  |  | #endif  // FMT_USE_VARIADIC_TEMPLATES
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-28 19:44:39 -07:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  |   \rst | 
					
						
							|  |  |  |   Defines a variadic function with the specified return type, function name | 
					
						
							|  |  |  |   and argument types passed as variable arguments to this macro. | 
					
						
							| 
									
										
										
										
											2014-06-28 19:44:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  |   **Example**:: | 
					
						
							| 
									
										
										
										
											2014-06-28 19:44:39 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 12:04:28 -07:00
										 |  |  |     void print_error(const char *file, int line, const char *format, | 
					
						
							|  |  |  |                      const fmt::ArgList &args) { | 
					
						
							|  |  |  |       fmt::print("{}: {}: ", file, line); | 
					
						
							|  |  |  |       fmt::print(format, args); | 
					
						
							| 
									
										
										
										
											2014-06-28 19:44:39 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2014-06-29 12:04:28 -07:00
										 |  |  |     FMT_VARIADIC(void, print_error, const char *, int, const char *) | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  |   \endrst | 
					
						
							| 
									
										
										
										
											2014-06-28 19:44:39 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-06-28 15:58:02 -07:00
										 |  |  | #define FMT_VARIADIC(ReturnType, func, ...) \
 | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |   FMT_VARIADIC_(char, ReturnType, func, return func, __VA_ARGS__) | 
					
						
							| 
									
										
										
										
											2014-06-28 15:58:02 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define FMT_VARIADIC_W(ReturnType, func, ...) \
 | 
					
						
							| 
									
										
										
										
											2014-07-01 16:23:50 -07:00
										 |  |  |   FMT_VARIADIC_(wchar_t, ReturnType, func, return func, __VA_ARGS__) | 
					
						
							| 
									
										
										
										
											2014-06-28 15:58:02 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace fmt { | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  | FMT_VARIADIC(std::string, format, StringRef) | 
					
						
							|  |  |  | FMT_VARIADIC_W(std::wstring, format, WStringRef) | 
					
						
							| 
									
										
										
										
											2014-06-28 21:56:40 -07:00
										 |  |  | FMT_VARIADIC(void, print, StringRef) | 
					
						
							|  |  |  | FMT_VARIADIC(void, print, std::FILE *, StringRef) | 
					
						
							| 
									
										
										
										
											2014-07-09 06:56:36 -07:00
										 |  |  | FMT_VARIADIC(void, print, std::ostream &, StringRef) | 
					
						
							| 
									
										
										
										
											2014-07-01 09:10:43 -07:00
										 |  |  | FMT_VARIADIC(void, print_colored, Color, StringRef) | 
					
						
							| 
									
										
										
										
											2014-06-29 11:51:10 -07:00
										 |  |  | FMT_VARIADIC(std::string, sprintf, StringRef) | 
					
						
							| 
									
										
										
										
											2014-06-28 21:56:40 -07:00
										 |  |  | FMT_VARIADIC(void, printf, StringRef) | 
					
						
							| 
									
										
										
										
											2014-06-28 15:58:02 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-06-28 14:48:42 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-16 09:19:31 -07:00
										 |  |  | // Restore warnings.
 | 
					
						
							|  |  |  | #if FMT_GCC_VERSION >= 406
 | 
					
						
							|  |  |  | # pragma GCC diagnostic pop
 | 
					
						
							| 
									
										
										
										
											2013-12-06 07:00:06 -08:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 17:33:50 -07:00
										 |  |  | #endif  // FMT_FORMAT_H_
 |