| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2012-12-12 07:44:41 -08:00
										 |  |  |  String formatting library for C++ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  Copyright (c) 2012, Victor Zverovich | 
					
						
							|  |  |  |  All rights reserved. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  |  modification, are permitted provided that the following conditions are met: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  1. Redistributions of source code must retain the above copyright notice, this | 
					
						
							|  |  |  |     list of conditions and the following disclaimer. | 
					
						
							|  |  |  |  2. Redistributions in binary form must reproduce the above copyright notice, | 
					
						
							|  |  |  |     this list of conditions and the following disclaimer in the documentation | 
					
						
							|  |  |  |     and/or other materials provided with the distribution. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | 
					
						
							|  |  |  |  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 
					
						
							|  |  |  |  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
					
						
							|  |  |  |  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | 
					
						
							|  |  |  |  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 
					
						
							|  |  |  |  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 
					
						
							|  |  |  |  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 
					
						
							|  |  |  |  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
					
						
							|  |  |  |  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 
					
						
							|  |  |  |  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
					
						
							| 
									
										
										
										
											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-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-02 20:24:09 -07:00
										 |  |  | #include <iterator>
 | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-04-24 14:18:37 -07:00
										 |  |  | #if defined(__GNUC_LIBSTD__) && defined (__GNUC_LIBSTD_MINOR__)
 | 
					
						
							|  |  |  | # define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 10:04:11 -07:00
										 |  |  | // Compatibility with compilers other than clang.
 | 
					
						
							| 
									
										
										
										
											2014-04-23 17:33:50 -07:00
										 |  |  | #ifdef __has_feature
 | 
					
						
							|  |  |  | # define FMT_HAS_FEATURE(x) __has_feature(x)
 | 
					
						
							|  |  |  | # define FMT_HAS_BUILTIN(x) __has_builtin(x)
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | # define FMT_HAS_FEATURE(x) 0
 | 
					
						
							|  |  |  | # 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-03-06 20:06:44 +00:00
										 |  |  |        (FMT_GCC_VERSION >= 404 && __cplusplus >= 201103) || _MSC_VER >= 1800) | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-24 07:30:39 -07:00
										 |  |  | #ifndef FMT_USE_RVALUE_REFERENCES
 | 
					
						
							|  |  |  | # define FMT_USE_RVALUE_REFERENCES \
 | 
					
						
							|  |  |  |    (FMT_HAS_FEATURE(cxx_rvalue_references) || \ | 
					
						
							|  |  |  |        (FMT_GCC_VERSION >= 403 && __cplusplus >= 201103) || _MSC_VER >= 1600) | 
					
						
							| 
									
										
										
										
											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
 | 
					
						
							|  |  |  | # 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
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 08:59:44 -07:00
										 |  |  | // Define FMT_USE_NOEXCEPT to make 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
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-06 07:00:06 -08:00
										 |  |  | #if _MSC_VER
 | 
					
						
							|  |  |  | # pragma warning(push)
 | 
					
						
							| 
									
										
										
										
											2014-03-11 18:56:24 +00:00
										 |  |  | # pragma warning(disable: 4521) // 'class' : multiple copy constructors specified
 | 
					
						
							| 
									
										
										
										
											2013-12-06 07:00:06 -08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2013-12-06 07:12:38 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-04-23 08:27:50 -07:00
										 |  |  | template <typename Char> | 
					
						
							|  |  |  | class BasicWriter; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <typename Char> | 
					
						
							|  |  |  | class BasicFormatter; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct FormatSpec; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-12 09:14:00 -08:00
										 |  |  | namespace internal { | 
					
						
							| 
									
										
										
										
											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
 | 
					
						
							| 
									
										
										
										
											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]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-10 18:08:04 -08:00
										 |  |  |   void Grow(std::size_t size); | 
					
						
							| 
									
										
										
										
											2012-12-10 17:16:08 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Do not implement!
 | 
					
						
							| 
									
										
										
										
											2012-12-11 12:23:52 -08:00
										 |  |  |   Array(const Array &); | 
					
						
							|  |  |  |   void operator=(const Array &); | 
					
						
							| 
									
										
										
										
											2012-12-10 17:16:08 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							| 
									
										
										
										
											2012-12-11 12:23:52 -08:00
										 |  |  |   Array() : size_(0), capacity_(SIZE), ptr_(data_) {} | 
					
						
							|  |  |  |   ~Array() { | 
					
						
							| 
									
										
										
										
											2012-12-10 17:16:08 -08:00
										 |  |  |     if (ptr_ != data_) delete [] ptr_; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-24 07:30:39 -07:00
										 |  |  | #if FMT_USE_RVALUE_REFERENCES
 | 
					
						
							|  |  |  |   Array(Array &&other) | 
					
						
							|  |  |  |   : size_(other.size_), | 
					
						
							|  |  |  |     capacity_(other.capacity_) { | 
					
						
							|  |  |  |     if (other.ptr_ == other.data_) { | 
					
						
							|  |  |  |       ptr_ = data_; | 
					
						
							|  |  |  |       std::copy(other.data_, other.data_ + size_, CheckPtr(data_, capacity_)); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       ptr_ = other.ptr_; | 
					
						
							|  |  |  |       other.ptr_ = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-04-24 14:55:18 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // TODO: move assignment operator
 | 
					
						
							| 
									
										
										
										
											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_) | 
					
						
							|  |  |  |       Grow(new_size); | 
					
						
							|  |  |  |     size_ = new_size; | 
					
						
							| 
									
										
										
										
											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_) | 
					
						
							|  |  |  |       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_) | 
					
						
							|  |  |  |       Grow(size_ + 1); | 
					
						
							|  |  |  |     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> | 
					
						
							| 
									
										
										
										
											2012-12-11 12:23:52 -08: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_) | 
					
						
							|  |  |  |     Grow(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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-09 22:21:40 -07:00
										 |  |  | template <typename Char> | 
					
						
							| 
									
										
										
										
											2013-12-07 08:12:03 -08:00
										 |  |  | class CharTraits; | 
					
						
							| 
									
										
										
										
											2013-09-09 22:21:40 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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: | 
					
						
							|  |  |  |   // Conversion from wchar_t to char is not supported.
 | 
					
						
							| 
									
										
										
										
											2014-02-15 09:39:49 -08:00
										 |  |  |   static char ConvertChar(wchar_t); | 
					
						
							| 
									
										
										
										
											2013-12-07 08:12:03 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   typedef const wchar_t *UnsupportedStrType; | 
					
						
							| 
									
										
										
										
											2013-09-09 22:21:40 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-15 09:39:49 -08:00
										 |  |  |   static char ConvertChar(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-02-15 09:39:49 -08:00
										 |  |  |   static wchar_t ConvertChar(char value) { return value; } | 
					
						
							|  |  |  |   static wchar_t ConvertChar(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-02-20 08:02:32 -08:00
										 |  |  |   static bool IsNegative(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> | 
					
						
							| 
									
										
										
										
											2013-01-13 07:14:54 -08:00
										 |  |  |   static bool IsNegative(T value) { return value < 0; } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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> | 
					
						
							|  |  |  | inline bool IsNegative(T value) { | 
					
						
							|  |  |  |   return SignChecker<std::numeric_limits<T>::is_signed>::IsNegative(value); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-01-13 07:14:54 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
 | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  | // except for n == 0 in which case CountDigits returns 1.
 | 
					
						
							|  |  |  | inline unsigned CountDigits(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-02-19 12:43:55 -08:00
										 |  |  | // Optional version of CountDigits for better performance on 32-bit platforms.
 | 
					
						
							|  |  |  | inline unsigned CountDigits(uint32_t n) { | 
					
						
							|  |  |  |   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-02-19 12:43:55 -08:00
										 |  |  | // Slower version of CountDigits used when __builtin_clz is not available.
 | 
					
						
							|  |  |  | inline unsigned CountDigits(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[]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  | template <typename Char> | 
					
						
							| 
									
										
										
										
											2013-01-13 07:50:28 -08:00
										 |  |  | class FormatterProxy; | 
					
						
							| 
									
										
										
										
											2014-02-14 10:36:17 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							|  |  |  |     buffer[num_digits] = internal::DIGITS[index + 1]; | 
					
						
							|  |  |  |     buffer[num_digits - 1] = internal::DIGITS[index]; | 
					
						
							|  |  |  |     num_digits -= 2; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (value < 10) { | 
					
						
							|  |  |  |     *buffer = static_cast<char>('0' + value); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   unsigned index = static_cast<unsigned>(value * 2); | 
					
						
							|  |  |  |   buffer[1] = internal::DIGITS[index + 1]; | 
					
						
							|  |  |  |   buffer[0] = internal::DIGITS[index]; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | template <typename Char, typename T> | 
					
						
							|  |  |  | void FormatCustomArg( | 
					
						
							|  |  |  |   BasicWriter<Char> &w, const void *arg, const FormatSpec &spec); | 
					
						
							| 
									
										
										
										
											2012-12-12 09:14:00 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-04 07:04:35 -08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |   \rst | 
					
						
							|  |  |  |   A string reference. It can be constructed from a C string, ``std::string`` | 
					
						
							|  |  |  |   or as a result of a formatting operation. It is most useful as a parameter | 
					
						
							|  |  |  |   type to allow passing different types of strings in a function, for example:: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |     Formatter<> Format(StringRef format); | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Format("{}") << 42; | 
					
						
							|  |  |  |     Format(std::string("{}")) << 42; | 
					
						
							|  |  |  |     Format(Format("{{}}")) << 42; | 
					
						
							| 
									
										
										
										
											2013-01-04 07:04:35 -08:00
										 |  |  |   \endrst | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  | template <typename Char> | 
					
						
							|  |  |  | class BasicStringRef { | 
					
						
							| 
									
										
										
										
											2012-12-25 13:25:14 -08:00
										 |  |  |  private: | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  |   const Char *data_; | 
					
						
							| 
									
										
										
										
											2012-12-25 13:25:14 -08:00
										 |  |  |   mutable std::size_t size_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							| 
									
										
										
										
											2013-01-13 07:14:54 -08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |     Constructs a string reference object from a C string and a size. | 
					
						
							| 
									
										
										
										
											2013-09-08 15:37:14 -07:00
										 |  |  |     If *size* is zero, which is the default, the size is computed with | 
					
						
							| 
									
										
										
										
											2013-01-13 07:14:54 -08:00
										 |  |  |     `strlen`. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  |   BasicStringRef(const Char *s, std::size_t size = 0) : data_(s), size_(size) {} | 
					
						
							| 
									
										
										
										
											2013-01-13 07:14:54 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /**
 | 
					
						
							|  |  |  |     Constructs a string reference from an `std::string` object. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  |   BasicStringRef(const std::basic_string<Char> &s) | 
					
						
							|  |  |  |   : data_(s.c_str()), size_(s.size()) {} | 
					
						
							| 
									
										
										
										
											2012-12-25 13:25:14 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-13 07:14:54 -08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |     Converts a string reference to an `std::string` object. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  |   operator std::basic_string<Char>() const { | 
					
						
							|  |  |  |     return std::basic_string<Char>(data_, size()); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-12-25 13:25:14 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-13 07:14:54 -08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |     Returns the pointer to a C string. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  |   const Char *c_str() const { return data_; } | 
					
						
							| 
									
										
										
										
											2012-12-25 13:25:14 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-13 07:14:54 -08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |     Returns the string size. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2012-12-25 13:25:14 -08:00
										 |  |  |   std::size_t size() const { | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  |     if (size_ == 0) size_ = std::char_traits<Char>::length(data_); | 
					
						
							| 
									
										
										
										
											2012-12-25 13:25:14 -08:00
										 |  |  |     return size_; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  | typedef BasicStringRef<char> StringRef; | 
					
						
							|  |  |  | typedef BasicStringRef<wchar_t> WStringRef; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-11 10:27:13 -08:00
										 |  |  | class FormatError : public std::runtime_error { | 
					
						
							|  |  |  |  public: | 
					
						
							| 
									
										
										
										
											2012-12-12 07:44:41 -08:00
										 |  |  |   explicit FormatError(const std::string &message) | 
					
						
							|  |  |  |   : std::runtime_error(message) {} | 
					
						
							| 
									
										
										
										
											2012-12-11 10:27:13 -08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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.
 | 
					
						
							|  |  |  | enum { SIGN_FLAG = 1, PLUS_FLAG = 2, HASH_FLAG = 4 }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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-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_; | 
					
						
							|  |  |  |   char type_; | 
					
						
							| 
									
										
										
										
											2012-12-21 09:12:04 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-08 13:07:04 -07:00
										 |  |  |   FormatSpec(unsigned width = 0, char type = 0, wchar_t fill = ' ') | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  |   : AlignSpec(width, fill), flags_(0), 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; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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**:: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  |     std::string s = str(Writer() << pad(hex(0xcafe), 8, '0')); | 
					
						
							| 
									
										
										
										
											2013-01-22 11:06:56 -08:00
										 |  |  |     // s == "0000cafe"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   \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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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"; | 
					
						
							|  |  |  |      out.Format("({:+f}, {:+f})") << -3.14 << 3.14; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   This will write the following output to the ``out`` object: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   .. code-block:: none | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |      The answer is 42 | 
					
						
							|  |  |  |      (-3.140000, +3.140000) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   The output can be converted to an ``std::string`` with ``out.str()`` or | 
					
						
							|  |  |  |   accessed as a C string with ``out.c_str()``. | 
					
						
							|  |  |  |   \endrst | 
					
						
							| 
									
										
										
										
											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.
 | 
					
						
							|  |  |  |   mutable internal::Array<Char, internal::INLINE_BUFFER_SIZE> buffer_; | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 09:13:03 -07:00
										 |  |  |   // Make BasicFormatter a friend so that it can access ArgInfo and Arg.
 | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |   friend class BasicFormatter<Char>; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-01-01 09:06:25 -08:00
										 |  |  |   CharPtr PrepareFilledBuffer(unsigned size, const EmptySpec &, char sign) { | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  |     CharPtr p = GrowBuffer(size); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     *p = sign; | 
					
						
							|  |  |  |     return p + size - 1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  |   CharPtr PrepareFilledBuffer(unsigned size, const AlignSpec &spec, char sign); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Formats an integer.
 | 
					
						
							|  |  |  |   template <typename T, typename Spec> | 
					
						
							|  |  |  |   void FormatInt(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-01-28 12:47:37 -08:00
										 |  |  |   void FormatDouble(T value, const FormatSpec &spec, int precision); | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |   // Formats a string.
 | 
					
						
							| 
									
										
										
										
											2013-09-06 19:32:19 -07:00
										 |  |  |   template <typename StringChar> | 
					
						
							| 
									
										
										
										
											2013-12-31 09:43:32 -08:00
										 |  |  |   CharPtr FormatString( | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-09 22:21:40 -07:00
										 |  |  |   // This method is private to disallow writing a wide string to a
 | 
					
						
							|  |  |  |   // char stream and vice versa. If you want to print a wide string
 | 
					
						
							|  |  |  |   // as a pointer as std::ostream does, cast it to const void*.
 | 
					
						
							|  |  |  |   // Do not implement!
 | 
					
						
							| 
									
										
										
										
											2013-12-07 08:12:03 -08:00
										 |  |  |   void operator<<(typename internal::CharTraits<Char>::UnsupportedStrType); | 
					
						
							| 
									
										
										
										
											2013-09-09 22:21:40 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  |   enum Type { | 
					
						
							|  |  |  |     // Numeric types should go first.
 | 
					
						
							|  |  |  |     INT, UINT, LONG, ULONG, LONG_LONG, ULONG_LONG, DOUBLE, LONG_DOUBLE, | 
					
						
							|  |  |  |     LAST_NUMERIC_TYPE = LONG_DOUBLE, | 
					
						
							|  |  |  |     CHAR, STRING, WSTRING, POINTER, CUSTOM | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct StringValue { | 
					
						
							|  |  |  |     const Char *value; | 
					
						
							|  |  |  |     std::size_t size; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   typedef void (*FormatFunc)( | 
					
						
							|  |  |  |     BasicWriter<Char> &w, const void *arg, const FormatSpec &spec); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   struct CustomValue { | 
					
						
							|  |  |  |     const void *value; | 
					
						
							|  |  |  |     FormatFunc format; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Information about a format argument. It is a POD type to allow
 | 
					
						
							|  |  |  |   // storage in internal::Array.
 | 
					
						
							|  |  |  |   struct ArgInfo { | 
					
						
							|  |  |  |     Type type; | 
					
						
							|  |  |  |     union { | 
					
						
							|  |  |  |       int int_value; | 
					
						
							|  |  |  |       unsigned uint_value; | 
					
						
							|  |  |  |       double double_value; | 
					
						
							|  |  |  |       long long_value; | 
					
						
							|  |  |  |       unsigned long ulong_value; | 
					
						
							|  |  |  |       LongLong long_long_value; | 
					
						
							|  |  |  |       ULongLong ulong_long_value; | 
					
						
							|  |  |  |       long double long_double_value; | 
					
						
							|  |  |  |       const void *pointer_value; | 
					
						
							|  |  |  |       StringValue string; | 
					
						
							|  |  |  |       CustomValue custom; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 09:13:03 -07:00
										 |  |  |   // Argument action that does nothing.
 | 
					
						
							|  |  |  |   struct EmptyArgAction { | 
					
						
							|  |  |  |     void operator()() const {} | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // A wrapper around a format argument.
 | 
					
						
							|  |  |  |   template <typename Action = EmptyArgAction> | 
					
						
							|  |  |  |   class BasicArg : public Action, public ArgInfo { | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  |    private: | 
					
						
							|  |  |  |     // This method is private to disallow formatting of arbitrary pointers.
 | 
					
						
							|  |  |  |     // If you want to output a pointer cast it to const void*. Do not implement!
 | 
					
						
							|  |  |  |     template <typename T> | 
					
						
							| 
									
										
										
										
											2014-04-23 09:13:03 -07:00
										 |  |  |     BasicArg(const T *value); | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // This method is private to disallow formatting of arbitrary pointers.
 | 
					
						
							|  |  |  |     // If you want to output a pointer cast it to void*. Do not implement!
 | 
					
						
							|  |  |  |     template <typename T> | 
					
						
							| 
									
										
										
										
											2014-04-23 09:13:03 -07:00
										 |  |  |     BasicArg(T *value); | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |    public: | 
					
						
							|  |  |  |     using ArgInfo::type; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 09:13:03 -07:00
										 |  |  |     BasicArg(short value) { type = INT; this->int_value = value; } | 
					
						
							|  |  |  |     BasicArg(unsigned short value) { type = UINT; this->int_value = value; } | 
					
						
							|  |  |  |     BasicArg(int value) { type = INT; this->int_value = value; } | 
					
						
							|  |  |  |     BasicArg(unsigned value) { type = UINT; this->uint_value = value; } | 
					
						
							|  |  |  |     BasicArg(long value) { type = LONG; this->long_value = value; } | 
					
						
							|  |  |  |     BasicArg(unsigned long value) { type = ULONG; this->ulong_value = value; } | 
					
						
							|  |  |  |     BasicArg(LongLong value) { | 
					
						
							|  |  |  |       type = LONG_LONG; | 
					
						
							|  |  |  |       this->long_long_value = value; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     BasicArg(ULongLong value) { | 
					
						
							|  |  |  |       type = ULONG_LONG; | 
					
						
							|  |  |  |       this->ulong_long_value = value; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     BasicArg(float value) { type = DOUBLE; this->double_value = value; } | 
					
						
							|  |  |  |     BasicArg(double value) { type = DOUBLE; this->double_value = value; } | 
					
						
							|  |  |  |     BasicArg(long double value) { | 
					
						
							|  |  |  |       type = LONG_DOUBLE; | 
					
						
							|  |  |  |       this->long_double_value = value; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     BasicArg(char value) { type = CHAR; this->int_value = value; } | 
					
						
							|  |  |  |     BasicArg(wchar_t value) { | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  |       type = CHAR; | 
					
						
							|  |  |  |       this->int_value = internal::CharTraits<Char>::ConvertChar(value); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 09:13:03 -07:00
										 |  |  |     BasicArg(const Char *value) { | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  |       type = STRING; | 
					
						
							|  |  |  |       this->string.value = value; | 
					
						
							|  |  |  |       this->string.size = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 09:13:03 -07:00
										 |  |  |     BasicArg(Char *value) { | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  |       type = STRING; | 
					
						
							|  |  |  |       this->string.value = value; | 
					
						
							|  |  |  |       this->string.size = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 09:13:03 -07:00
										 |  |  |     BasicArg(const void *value) { type = POINTER; this->pointer_value = value; } | 
					
						
							|  |  |  |     BasicArg(void *value) { type = POINTER; this->pointer_value = value; } | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 09:13:03 -07:00
										 |  |  |     BasicArg(const std::basic_string<Char> &value) { | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  |       type = STRING; | 
					
						
							|  |  |  |       this->string.value = value.c_str(); | 
					
						
							|  |  |  |       this->string.size = value.size(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 09:13:03 -07:00
										 |  |  |     BasicArg(BasicStringRef<Char> value) { | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  |       type = STRING; | 
					
						
							|  |  |  |       this->string.value = value.c_str(); | 
					
						
							|  |  |  |       this->string.size = value.size(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template <typename T> | 
					
						
							| 
									
										
										
										
											2014-04-23 09:13:03 -07:00
										 |  |  |     BasicArg(const T &value) { | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  |       type = CUSTOM; | 
					
						
							|  |  |  |       this->custom.value = &value; | 
					
						
							|  |  |  |       this->custom.format = &internal::FormatCustomArg<Char, T>; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 09:13:03 -07:00
										 |  |  |     // The destructor is declared noexcept(false) because the action may throw
 | 
					
						
							|  |  |  |     // an exception.
 | 
					
						
							|  |  |  |     ~BasicArg() FMT_NOEXCEPT(false) { | 
					
						
							|  |  |  |       // Invoke the action.
 | 
					
						
							|  |  |  |       (*this)(); | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 09:13:03 -07:00
										 |  |  |   typedef BasicArg<> Arg; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Format string parser.
 | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  |   class FormatParser { | 
					
						
							|  |  |  |    private: | 
					
						
							|  |  |  |     std::size_t num_args_; | 
					
						
							|  |  |  |     const ArgInfo *args_; | 
					
						
							|  |  |  |     int num_open_braces_; | 
					
						
							|  |  |  |     int next_arg_index_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void ReportError(const Char *s, StringRef message) const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unsigned ParseUInt(const Char *&s) const; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Parses argument index and returns an argument with this index.
 | 
					
						
							|  |  |  |     const ArgInfo &ParseArgIndex(const Char *&s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void CheckSign(const Char *&s, const ArgInfo &arg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    public: | 
					
						
							|  |  |  |     void Format(BasicWriter<Char> &writer, | 
					
						
							|  |  |  |       BasicStringRef<Char> format, std::size_t num_args, const ArgInfo *args); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-25 07:40:37 -07:00
										 |  |  |  public: | 
					
						
							|  |  |  |   BasicWriter() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if FMT_USE_RVALUE_REFERENCES
 | 
					
						
							|  |  |  |   BasicWriter(BasicWriter &&other) : buffer_(std::move(other.buffer_)) {} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |     Returns the number of characters written to the output buffer. | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   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 | 
					
						
							|  |  |  |     Formats a string sending the output to the writer. Arguments are | 
					
						
							|  |  |  |     accepted through the returned ``BasicFormatter`` object using inserter | 
					
						
							|  |  |  |     operator ``<<``. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     **Example**:: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        Writer out; | 
					
						
							|  |  |  |        out.Format("Current point:\n"); | 
					
						
							|  |  |  |        out.Format("({:+f}, {:+f})") << -3.14 << 3.14; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     This will write the following output to the ``out`` object: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     .. code-block:: none | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        Current point: | 
					
						
							|  |  |  |        (-3.140000, +3.140000) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The output can be accessed using :meth:`data` or :meth:`c_str`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     See also `Format String Syntax`_. | 
					
						
							|  |  |  |     \endrst | 
					
						
							|  |  |  |    */ | 
					
						
							|  |  |  |   BasicFormatter<Char> Format(StringRef format); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  |   // TODO: ArgInfo should be made public for this to be usable
 | 
					
						
							|  |  |  |   inline void VFormat(BasicStringRef<Char> format, | 
					
						
							|  |  |  |       std::size_t num_args, const ArgInfo *args) { | 
					
						
							|  |  |  |     FormatParser().Format(*this, format, num_args, args); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if FMT_USE_VARIADIC_TEMPLATES
 | 
					
						
							|  |  |  |   template<typename... Args> | 
					
						
							|  |  |  |   void Format(BasicStringRef<Char> format, const Args & ... args) { | 
					
						
							|  |  |  |     Arg arg_array[] = {args...}; | 
					
						
							|  |  |  |     VFormat(format, sizeof...(Args), arg_array); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-01-28 12:47:37 -08:00
										 |  |  |     FormatDouble(value, FormatSpec(), -1); | 
					
						
							| 
									
										
										
										
											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-01-28 12:47:37 -08:00
										 |  |  |     FormatDouble(value, FormatSpec(), -1); | 
					
						
							| 
									
										
										
										
											2013-02-27 13:17:09 -08:00
										 |  |  |     return *this; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-02 11:30:28 -08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |    * Writes a character to the stream. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2013-09-09 22:21:40 -07:00
										 |  |  |   BasicWriter &operator<<(char value) { | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  |     *GrowBuffer(1) = 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-02-15 09:39:49 -08:00
										 |  |  |     *GrowBuffer(1) = internal::CharTraits<Char>::ConvertChar(value); | 
					
						
							| 
									
										
										
										
											2014-01-02 11:30:28 -08:00
										 |  |  |     return *this; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-10 09:26:11 -07:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |     Writes *value* to the stream. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2013-09-09 22:21:40 -07:00
										 |  |  |   BasicWriter &operator<<(const fmt::BasicStringRef<Char> value) { | 
					
						
							|  |  |  |     const Char *str = value.c_str(); | 
					
						
							| 
									
										
										
										
											2013-09-09 15:12:51 -07:00
										 |  |  |     std::size_t size = value.size(); | 
					
						
							|  |  |  |     std::copy(str, str + size, GrowBuffer(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-02-15 09:39:49 -08:00
										 |  |  |     internal::CharTraits<Char>::ConvertChar(FillChar()); | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  |     FormatInt(spec.value(), spec); | 
					
						
							|  |  |  |     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(); | 
					
						
							|  |  |  |     FormatString(s, std::char_traits<Char>::length(s), spec); | 
					
						
							| 
									
										
										
										
											2013-12-31 09:43:32 -08:00
										 |  |  |     return *this; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-28 12:49:36 -08:00
										 |  |  |   void Write(const std::basic_string<Char> &s, const FormatSpec &spec) { | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     FormatString(s.data(), s.size(), spec); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void Clear() { | 
					
						
							|  |  |  |     buffer_.clear(); | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											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> | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  | typename BasicWriter<Char>::CharPtr BasicWriter<Char>::FormatString( | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <typename Char> | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | template <typename T, typename Spec> | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  | void BasicWriter<Char>::FormatInt(T value, const Spec &spec) { | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   unsigned size = 0; | 
					
						
							|  |  |  |   char sign = 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-02-20 07:53:50 -08:00
										 |  |  |   if (internal::IsNegative(value)) { | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     sign = '-'; | 
					
						
							|  |  |  |     ++size; | 
					
						
							|  |  |  |     abs_value = 0 - abs_value; | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |   } else if (spec.sign_flag()) { | 
					
						
							|  |  |  |     sign = spec.plus_flag() ? '+' : ' '; | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     ++size; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |   switch (spec.type()) { | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   case 0: case 'd': { | 
					
						
							| 
									
										
										
										
											2014-02-20 07:43:37 -08:00
										 |  |  |     unsigned num_digits = internal::CountDigits(abs_value); | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  |     CharPtr p = | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |         PrepareFilledBuffer(size + num_digits, spec, sign) + 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-01-01 09:20:16 -08:00
										 |  |  |     bool print_prefix = spec.hash_flag(); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     if (print_prefix) size += 2; | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       ++size; | 
					
						
							|  |  |  |     } while ((n >>= 4) != 0); | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |     Char *p = GetBase(PrepareFilledBuffer(size, spec, sign)); | 
					
						
							| 
									
										
										
										
											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); | 
					
						
							|  |  |  |     if (print_prefix) { | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |       *p-- = spec.type(); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |       *p = '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-01-01 09:20:16 -08:00
										 |  |  |     bool print_prefix = spec.hash_flag(); | 
					
						
							| 
									
										
										
										
											2013-10-23 20:04:32 -07:00
										 |  |  |     if (print_prefix) size += 2; | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       ++size; | 
					
						
							|  |  |  |     } while ((n >>= 1) != 0); | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |     Char *p = GetBase(PrepareFilledBuffer(size, spec, sign)); | 
					
						
							| 
									
										
										
										
											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); | 
					
						
							|  |  |  |     if (print_prefix) { | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |       *p-- = spec.type(); | 
					
						
							| 
									
										
										
										
											2013-10-23 20:04:32 -07:00
										 |  |  |       *p = '0'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   case 'o': { | 
					
						
							|  |  |  |     UnsignedType n = abs_value; | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |     bool print_prefix = spec.hash_flag(); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     if (print_prefix) ++size; | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       ++size; | 
					
						
							|  |  |  |     } while ((n >>= 3) != 0); | 
					
						
							| 
									
										
										
										
											2014-01-01 09:20:16 -08:00
										 |  |  |     Char *p = GetBase(PrepareFilledBuffer(size, spec, sign)); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     n = abs_value; | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       *p-- = '0' + (n & 7); | 
					
						
							|  |  |  |     } while ((n >>= 3) != 0); | 
					
						
							|  |  |  |     if (print_prefix) | 
					
						
							|  |  |  |       *p = '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; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  | template <typename Char> | 
					
						
							|  |  |  | BasicFormatter<Char> BasicWriter<Char>::Format(StringRef format) { | 
					
						
							| 
									
										
										
										
											2013-12-04 22:22:25 -08:00
										 |  |  |   BasicFormatter<Char> f(*this, format.c_str()); | 
					
						
							|  |  |  |   return f; | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-02 20:29:02 -08:00
										 |  |  | typedef BasicWriter<char> Writer; | 
					
						
							|  |  |  | typedef BasicWriter<wchar_t> WWriter; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-13 07:50:28 -08:00
										 |  |  | // The default formatting function.
 | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  | template <typename Char, typename T> | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  | void Format(BasicWriter<Char> &w, const FormatSpec &spec, 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; | 
					
						
							| 
									
										
										
										
											2013-02-21 17:44:29 -08:00
										 |  |  |   w.Write(os.str(), spec); | 
					
						
							| 
									
										
										
										
											2013-01-13 07:50:28 -08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-05 08:05:01 -08:00
										 |  |  | namespace internal { | 
					
						
							|  |  |  | // Formats an argument of a custom type, such as a user-defined class.
 | 
					
						
							|  |  |  | template <typename Char, typename T> | 
					
						
							|  |  |  | void FormatCustomArg( | 
					
						
							| 
									
										
										
										
											2014-01-28 12:47:37 -08:00
										 |  |  |     BasicWriter<Char> &w, const void *arg, const FormatSpec &spec) { | 
					
						
							| 
									
										
										
										
											2013-02-05 08:05:01 -08:00
										 |  |  |   Format(w, spec, *static_cast<const T*>(arg)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-29 09:27:26 -08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |   \rst | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  |   The :cpp:class:`fmt::BasicFormatter` template provides string formatting | 
					
						
							| 
									
										
										
										
											2012-12-29 09:27:26 -08:00
										 |  |  |   functionality similar to Python's `str.format | 
					
						
							|  |  |  |   <http://docs.python.org/3/library/stdtypes.html#str.format>`__.
 | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  |   The class provides operator<< for feeding formatting arguments and all | 
					
						
							|  |  |  |   the output is sent to a :cpp:class:`fmt::Writer` object. | 
					
						
							| 
									
										
										
										
											2012-12-29 09:27:26 -08:00
										 |  |  |   \endrst | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  | template <typename Char> | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  | class BasicFormatter { | 
					
						
							| 
									
										
										
										
											2012-12-29 09:27:26 -08:00
										 |  |  |  private: | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |   BasicWriter<Char> *writer_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 09:13:03 -07:00
										 |  |  |   // An action used to ensure that formatting is performed before the
 | 
					
						
							|  |  |  |   // argument is destroyed.
 | 
					
						
							|  |  |  |   // Example:
 | 
					
						
							|  |  |  |   //
 | 
					
						
							|  |  |  |   //   Format("{}") << std::string("test");
 | 
					
						
							|  |  |  |   //
 | 
					
						
							|  |  |  |   // Here an Arg object wraps a temporary std::string which is destroyed at
 | 
					
						
							|  |  |  |   // the end of the full expression. Since the string object is constructed
 | 
					
						
							|  |  |  |   // before the Arg object, it will be destroyed after, so it will be alive
 | 
					
						
							|  |  |  |   // in the Arg's destructor where the action is called.
 | 
					
						
							|  |  |  |   // Note that the string object will not necessarily be alive when the
 | 
					
						
							|  |  |  |   // destructor of BasicFormatter is called. Otherwise we wouldn't need
 | 
					
						
							|  |  |  |   // this class.
 | 
					
						
							|  |  |  |   struct ArgAction { | 
					
						
							|  |  |  |     mutable BasicFormatter *formatter; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ArgAction() : formatter(0) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     void operator()() const { | 
					
						
							|  |  |  |       if (formatter) | 
					
						
							|  |  |  |         formatter->CompleteFormatting(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  |   typedef typename BasicWriter<Char>::ArgInfo ArgInfo; | 
					
						
							| 
									
										
										
										
											2014-04-23 09:13:03 -07:00
										 |  |  |   typedef typename BasicWriter<Char>::template BasicArg<ArgAction> Arg; | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-10 20:37:35 -08:00
										 |  |  |   enum { NUM_INLINE_ARGS = 10 }; | 
					
						
							| 
									
										
										
										
											2014-04-22 08:58:54 -07:00
										 |  |  |   internal::Array<ArgInfo, NUM_INLINE_ARGS> args_;  // Format arguments.
 | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  |   const Char *format_;  // Format string.
 | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  |   friend class internal::FormatterProxy<Char>; | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-04 22:22:25 -08:00
										 |  |  |   // Forbid copying from a temporary as in the following example:
 | 
					
						
							| 
									
										
										
										
											2014-04-24 07:30:47 -07:00
										 |  |  |   //
 | 
					
						
							| 
									
										
										
										
											2013-12-04 22:22:25 -08:00
										 |  |  |   //   fmt::Formatter<> f = Format("test"); // not allowed
 | 
					
						
							| 
									
										
										
										
											2014-04-24 07:30:47 -07:00
										 |  |  |   //
 | 
					
						
							| 
									
										
										
										
											2013-12-04 22:22:25 -08:00
										 |  |  |   // This is done because BasicFormatter objects should normally exist
 | 
					
						
							|  |  |  |   // only as temporaries returned by one of the formatting functions.
 | 
					
						
							|  |  |  |   // Do not implement.
 | 
					
						
							|  |  |  |   BasicFormatter(const BasicFormatter &); | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |   BasicFormatter& operator=(const BasicFormatter &); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  protected: | 
					
						
							|  |  |  |   const Char *TakeFormatString() { | 
					
						
							|  |  |  |     const Char *format = this->format_; | 
					
						
							|  |  |  |     this->format_ = 0; | 
					
						
							|  |  |  |     return format; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-17 14:56:44 -08:00
										 |  |  |   void CompleteFormatting() { | 
					
						
							| 
									
										
										
										
											2012-12-11 12:23:52 -08:00
										 |  |  |     if (!format_) return; | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  |     const Char *format = format_; | 
					
						
							|  |  |  |     format_ = 0; | 
					
						
							|  |  |  |     writer_->VFormat(format, args_.size(), &args_[0]); | 
					
						
							| 
									
										
										
										
											2012-12-11 12:23:52 -08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  |   // Constructs a formatter with a writer to be used for output and a format
 | 
					
						
							| 
									
										
										
										
											2013-12-01 06:59:14 -08:00
										 |  |  |   // string.
 | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |   BasicFormatter(BasicWriter<Char> &w, const Char *format = 0) | 
					
						
							|  |  |  |   : writer_(&w), format_(format) {} | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-09 08:12:21 -08:00
										 |  |  |   // Performs formatting if the format string is non-null. The format string
 | 
					
						
							| 
									
										
										
										
											2013-12-01 06:59:14 -08:00
										 |  |  |   // can be null if its ownership has been transferred to another formatter.
 | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |   ~BasicFormatter() { | 
					
						
							|  |  |  |     CompleteFormatting(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-04 22:22:25 -08:00
										 |  |  |   BasicFormatter(BasicFormatter &f) : writer_(f.writer_), format_(f.format_) { | 
					
						
							|  |  |  |     f.format_ = 0; | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Feeds an argument to a formatter.
 | 
					
						
							| 
									
										
										
										
											2014-04-23 09:13:03 -07:00
										 |  |  |   BasicFormatter &operator<<(const Arg &arg) { | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |     arg.formatter = this; | 
					
						
							| 
									
										
										
										
											2014-04-22 08:58:54 -07:00
										 |  |  |     args_.push_back(arg); | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |     return *this; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   operator internal::FormatterProxy<Char>() { | 
					
						
							|  |  |  |     return internal::FormatterProxy<Char>(this); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   operator StringRef() { | 
					
						
							|  |  |  |     CompleteFormatting(); | 
					
						
							|  |  |  |     return StringRef(writer_->c_str(), writer_->size()); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  | template <typename Char> | 
					
						
							| 
									
										
										
										
											2013-02-02 20:29:02 -08:00
										 |  |  | inline std::basic_string<Char> str(const BasicWriter<Char> &f) { | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  |   return f.str(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <typename Char> | 
					
						
							| 
									
										
										
										
											2013-02-02 20:29:02 -08:00
										 |  |  | inline const Char *c_str(const BasicWriter<Char> &f) { return f.c_str(); } | 
					
						
							| 
									
										
										
										
											2013-01-22 11:06:56 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-12 09:14:00 -08:00
										 |  |  | namespace internal { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  | template <typename Char> | 
					
						
							| 
									
										
										
										
											2013-01-13 09:47:01 -08:00
										 |  |  | class FormatterProxy { | 
					
						
							|  |  |  |  private: | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  |   BasicFormatter<Char> *formatter_; | 
					
						
							| 
									
										
										
										
											2013-01-13 09:47:01 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  |   explicit FormatterProxy(BasicFormatter<Char> *f) : formatter_(f) {} | 
					
						
							| 
									
										
										
										
											2013-01-13 07:50:28 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |   BasicWriter<Char> *Format() { | 
					
						
							| 
									
										
										
										
											2013-01-13 09:47:01 -08:00
										 |  |  |     formatter_->CompleteFormatting(); | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |     return formatter_->writer_; | 
					
						
							| 
									
										
										
										
											2013-01-13 07:50:28 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2012-12-12 09:14:00 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-13 07:50:28 -08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |   Returns the content of the output buffer as an `std::string`. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  | inline std::string str(internal::FormatterProxy<char> p) { | 
					
						
							| 
									
										
										
										
											2013-01-13 07:50:28 -08:00
										 |  |  |   return p.Format()->str(); | 
					
						
							| 
									
										
										
										
											2012-12-17 14:56:44 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-13 07:50:28 -08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |   Returns a pointer to the output buffer content with terminating null | 
					
						
							|  |  |  |   character appended. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  | inline const char *c_str(internal::FormatterProxy<char> p) { | 
					
						
							| 
									
										
										
										
											2013-01-13 07:50:28 -08:00
										 |  |  |   return p.Format()->c_str(); | 
					
						
							| 
									
										
										
										
											2012-12-09 09:03:47 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  | inline std::wstring str(internal::FormatterProxy<wchar_t> p) { | 
					
						
							|  |  |  |   return p.Format()->str(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | inline const wchar_t *c_str(internal::FormatterProxy<wchar_t> p) { | 
					
						
							|  |  |  |   return p.Format()->c_str(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  | /**
 | 
					
						
							|  |  |  |   A formatting action that does nothing. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | class NoAction { | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   /** Does nothing. */ | 
					
						
							|  |  |  |   template <typename Char> | 
					
						
							|  |  |  |   void operator()(const BasicWriter<Char> &) const {} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  |   \rst | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  |   A formatter with an action performed when formatting is complete. | 
					
						
							|  |  |  |   Objects of this class normally exist only as temporaries returned | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  |   by one of the formatting functions. You can use this class to create | 
					
						
							|  |  |  |   your own functions similar to :cpp:func:`fmt::Format()`. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   **Example**:: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct PrintError { | 
					
						
							|  |  |  |       void operator()(const fmt::Writer &w) const { | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  |         fmt::Print("Error: {}\n") << w.str(); | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  |       } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-10 09:26:11 -07:00
										 |  |  |     // Formats an error message and prints it to stdout.
 | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  |     fmt::Formatter<PrintError> ReportError(const char *format) { | 
					
						
							| 
									
										
										
										
											2013-12-10 08:08:41 -08:00
										 |  |  |       fmt::Formatter f<PrintError>(format); | 
					
						
							|  |  |  |       return f; | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ReportError("File not found: {}") << path; | 
					
						
							|  |  |  |   \endrst | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2013-02-28 10:47:20 -08:00
										 |  |  | template <typename Action = NoAction, typename Char = char> | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  | class Formatter : private Action, public BasicFormatter<Char> { | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  |  private: | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |   BasicWriter<Char> writer_; | 
					
						
							| 
									
										
										
										
											2013-09-03 18:58:13 -07:00
										 |  |  |   bool inactive_; | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-15 20:17:03 -08:00
										 |  |  |   // Forbid copying other than from a temporary. Do not implement.
 | 
					
						
							| 
									
										
										
										
											2013-12-04 22:22:25 -08:00
										 |  |  |   Formatter(const Formatter &); | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |   Formatter& operator=(const Formatter &); | 
					
						
							| 
									
										
										
										
											2012-12-15 20:17:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  |  public: | 
					
						
							| 
									
										
										
										
											2013-01-12 10:08:39 -08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |     \rst | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |     Constructs a formatter with a format string and an action. | 
					
						
							| 
									
										
										
										
											2013-01-12 10:08:39 -08:00
										 |  |  |     The action should be an unary function object that takes a const | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  |     reference to :cpp:class:`fmt::BasicWriter` as an argument. | 
					
						
							| 
									
										
										
										
											2013-01-21 11:42:25 -08:00
										 |  |  |     See :cpp:class:`fmt::NoAction` and :cpp:class:`fmt::Write` for | 
					
						
							| 
									
										
										
										
											2013-01-12 10:08:39 -08:00
										 |  |  |     examples of action classes. | 
					
						
							|  |  |  |     \endrst | 
					
						
							|  |  |  |   */ | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  |   explicit Formatter(BasicStringRef<Char> format, Action a = Action()) | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |   : Action(a), BasicFormatter<Char>(writer_, format.c_str()), | 
					
						
							|  |  |  |     inactive_(false) { | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-04 22:22:25 -08:00
										 |  |  |   Formatter(Formatter &f) | 
					
						
							|  |  |  |   : Action(f), BasicFormatter<Char>(writer_, f.TakeFormatString()), | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |     inactive_(false) { | 
					
						
							| 
									
										
										
										
											2013-12-04 22:22:25 -08:00
										 |  |  |     f.inactive_ = true; | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-12-08 08:17:12 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-12 10:08:39 -08:00
										 |  |  |   /**
 | 
					
						
							|  |  |  |     Performs the actual formatting, invokes the action and destroys the object. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |   ~Formatter() FMT_NOEXCEPT(false) { | 
					
						
							| 
									
										
										
										
											2013-09-03 18:58:13 -07:00
										 |  |  |     if (!inactive_) { | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |       this->CompleteFormatting(); | 
					
						
							|  |  |  |       (*this)(writer_); | 
					
						
							| 
									
										
										
										
											2013-09-03 18:58:13 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08: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-01-30 08:02:06 -08: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-02-20 07:43:37 -08:00
										 |  |  |   if (internal::IsNegative(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-02-14 10:36:17 -08:00
										 |  |  |   unsigned num_digits = internal::CountDigits(abs_value); | 
					
						
							|  |  |  |   internal::FormatDecimal(buffer, abs_value, num_digits); | 
					
						
							|  |  |  |   buffer += num_digits; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-03 08:57:34 -08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |   \rst | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  |   Formats a string similarly to Python's `str.format | 
					
						
							|  |  |  |   <http://docs.python.org/3/library/stdtypes.html#str.format>`__.
 | 
					
						
							|  |  |  |   Returns a temporary formatter object that accepts arguments via | 
					
						
							|  |  |  |   operator ``<<``. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   *format* is a format string that contains literal text and replacement | 
					
						
							|  |  |  |   fields surrounded by braces ``{}``. The formatter object replaces the | 
					
						
							|  |  |  |   fields with formatted arguments and stores the output in a memory buffer. | 
					
						
							|  |  |  |   The content of the buffer can be converted to ``std::string`` with | 
					
						
							|  |  |  |   :cpp:func:`fmt::str()` or accessed as a C string with | 
					
						
							|  |  |  |   :cpp:func:`fmt::c_str()`. | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-03 08:57:34 -08:00
										 |  |  |   **Example**:: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-12 10:08:39 -08:00
										 |  |  |     std::string message = str(Format("The answer is {}") << 42); | 
					
						
							| 
									
										
										
										
											2013-01-03 08:57:34 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   See also `Format String Syntax`_. | 
					
						
							|  |  |  |   \endrst | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  | inline Formatter<> Format(StringRef format) { | 
					
						
							| 
									
										
										
										
											2013-12-10 08:08:41 -08:00
										 |  |  |   Formatter<> f(format); | 
					
						
							|  |  |  |   return f; | 
					
						
							| 
									
										
										
										
											2012-12-11 13:54:53 -08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  | inline Formatter<NoAction, wchar_t> Format(WStringRef format) { | 
					
						
							| 
									
										
										
										
											2013-12-10 08:08:41 -08:00
										 |  |  |   Formatter<NoAction, wchar_t> f(format); | 
					
						
							|  |  |  |   return f; | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  | /** A formatting action that writes formatted output to stdout. */ | 
					
						
							|  |  |  | class Write { | 
					
						
							|  |  |  |  public: | 
					
						
							| 
									
										
										
										
											2013-09-10 09:26:11 -07:00
										 |  |  |   /** Writes the output to stdout. */ | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |   void operator()(const BasicWriter<char> &w) const { | 
					
						
							|  |  |  |     std::fwrite(w.data(), 1, w.size(), stdout); | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2012-12-11 13:54:53 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-11 16:26:04 -08:00
										 |  |  | // Formats a string and prints it to stdout.
 | 
					
						
							|  |  |  | // Example:
 | 
					
						
							|  |  |  | //   Print("Elapsed time: {0:.2f} seconds") << 1.23;
 | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  | inline Formatter<Write> Print(StringRef format) { | 
					
						
							| 
									
										
										
										
											2013-12-10 08:08:41 -08:00
										 |  |  |   Formatter<Write> f(format); | 
					
						
							|  |  |  |   return f; | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-02-19 13:51:23 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | enum Color {BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** A formatting action that writes colored output to stdout. */ | 
					
						
							|  |  |  | class ColorWriter { | 
					
						
							|  |  |  |  private: | 
					
						
							|  |  |  |   Color color_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   explicit ColorWriter(Color c) : color_(c) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /** Writes the colored output to stdout. */ | 
					
						
							| 
									
										
										
										
											2014-02-19 14:20:26 -08:00
										 |  |  |   void operator()(const BasicWriter<char> &w) const; | 
					
						
							| 
									
										
										
										
											2014-02-19 13:51:23 -08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Formats a string and prints it to stdout with the given color.
 | 
					
						
							|  |  |  | // Example:
 | 
					
						
							|  |  |  | //   PrintColored(fmt::RED, "Elapsed time: {0:.2f} seconds") << 1.23;
 | 
					
						
							|  |  |  | inline Formatter<ColorWriter> PrintColored(Color c, StringRef format) { | 
					
						
							|  |  |  |   Formatter<ColorWriter> f(format, ColorWriter(c)); | 
					
						
							|  |  |  |   return f; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-03-06 20:06:44 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-24 07:32:01 -07:00
										 |  |  | #if FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES
 | 
					
						
							| 
									
										
										
										
											2014-03-06 20:06:44 +00:00
										 |  |  | template<typename... Args> | 
					
						
							| 
									
										
										
										
											2014-04-24 07:32:01 -07:00
										 |  |  | inline Writer Format(const StringRef &format, const Args & ... args) { | 
					
						
							| 
									
										
										
										
											2014-03-06 20:06:44 +00:00
										 |  |  |   Writer w; | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  |   w.Format(format, args...); | 
					
						
							| 
									
										
										
										
											2014-04-24 07:32:01 -07:00
										 |  |  |   return std::move(w); | 
					
						
							| 
									
										
										
										
											2014-03-06 20:06:44 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<typename... Args> | 
					
						
							| 
									
										
										
										
											2014-04-24 07:32:01 -07:00
										 |  |  | inline WWriter Format(const WStringRef &format, const Args & ... args) { | 
					
						
							| 
									
										
										
										
											2014-03-06 20:06:44 +00:00
										 |  |  |   WWriter w; | 
					
						
							| 
									
										
										
										
											2014-04-23 08:27:50 -07:00
										 |  |  |   w.Format(format, args...); | 
					
						
							| 
									
										
										
										
											2014-04-24 07:32:01 -07:00
										 |  |  |   return std::move(w); | 
					
						
							| 
									
										
										
										
											2014-03-06 20:06:44 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-04-24 07:32:01 -07:00
										 |  |  | #endif  // FMT_USE_VARIADIC_TEMPLATES && FMT_USE_RVALUE_REFERENCES
 | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-16 09:19:31 -07:00
										 |  |  | // Restore warnings.
 | 
					
						
							|  |  |  | #if FMT_GCC_VERSION >= 406
 | 
					
						
							|  |  |  | # pragma GCC diagnostic pop
 | 
					
						
							|  |  |  | #elif _MSC_VER
 | 
					
						
							| 
									
										
										
										
											2013-12-06 07:00:06 -08:00
										 |  |  | # pragma warning(pop)
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 17:33:50 -07:00
										 |  |  | #endif  // FMT_FORMAT_H_
 |