| 
									
										
										
										
											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
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef FORMAT_H_
 | 
					
						
							|  |  |  | #define FORMAT_H_
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | #include <stdint.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  | #include <cassert>
 | 
					
						
							|  |  |  | #include <climits>
 | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | #include <cstddef>
 | 
					
						
							| 
									
										
										
										
											2012-12-18 15:50:14 -08:00
										 |  |  | #include <cstdio>
 | 
					
						
							| 
									
										
										
										
											2012-12-18 15:39:42 -08:00
										 |  |  | #include <cstring>
 | 
					
						
							| 
									
										
										
										
											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-05-15 10:04:11 -07:00
										 |  |  | // Compatibility with compilers other than clang.
 | 
					
						
							|  |  |  | #ifndef __has_feature
 | 
					
						
							|  |  |  | # define __has_feature(x) 0
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 08:59:44 -07:00
										 |  |  | // Define FMT_USE_NOEXCEPT to make format use noexcept (C++11 feature).
 | 
					
						
							|  |  |  | #if FMT_USE_NOEXCEPT || \
 | 
					
						
							|  |  |  |     (defined(__has_feature) && __has_feature(cxx_noexcept)) | 
					
						
							|  |  |  | # 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-01-21 11:42:25 -08:00
										 |  |  | namespace fmt { | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-12 09:14:00 -08:00
										 |  |  | namespace internal { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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_; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-01-08 09:56:05 -08:00
										 |  |  | // Information about an integer type.
 | 
					
						
							| 
									
										
										
										
											2013-01-13 07:14:54 -08:00
										 |  |  | // IntTraits is not specialized for integer types smaller than int,
 | 
					
						
							|  |  |  | // since these are promoted to int.
 | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | template <typename T> | 
					
						
							| 
									
										
										
										
											2013-01-13 09:41:14 -08:00
										 |  |  | struct IntTraits { | 
					
						
							|  |  |  |   typedef T UnsignedType; | 
					
						
							|  |  |  |   static bool IsNegative(T) { return false; } | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2013-01-13 07:14:54 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | template <typename T, typename UnsignedT> | 
					
						
							|  |  |  | struct SignedIntTraits { | 
					
						
							|  |  |  |   typedef UnsignedT UnsignedType; | 
					
						
							|  |  |  |   static bool IsNegative(T value) { return value < 0; } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | template <> | 
					
						
							| 
									
										
										
										
											2013-01-13 07:14:54 -08:00
										 |  |  | struct IntTraits<int> : SignedIntTraits<int, unsigned> {}; | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-13 07:14:54 -08:00
										 |  |  | template <> | 
					
						
							| 
									
										
										
										
											2013-01-13 09:29:37 -08:00
										 |  |  | struct IntTraits<long> : SignedIntTraits<long, unsigned long> {}; | 
					
						
							| 
									
										
										
										
											2013-01-13 07:14:54 -08: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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							|  |  |  |   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; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											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 }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct Spec {}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <char TYPE> | 
					
						
							|  |  |  | struct TypeSpec : Spec { | 
					
						
							|  |  |  |   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 ' '; } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct AlignSpec : WidthSpec { | 
					
						
							|  |  |  |   Alignment align_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-08 13:07:04 -07:00
										 |  |  |   AlignSpec(unsigned width, wchar_t fill) | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   : WidthSpec(width, fill), align_(ALIGN_DEFAULT) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Alignment align() const { return align_; } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <char TYPE> | 
					
						
							|  |  |  | struct AlignTypeSpec : AlignSpec { | 
					
						
							| 
									
										
										
										
											2013-09-08 13:07:04 -07:00
										 |  |  |   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; } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct FormatSpec : AlignSpec { | 
					
						
							|  |  |  |   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 = ' ') | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   : AlignSpec(width, fill), flags_(0), type_(type) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Alignment align() const { return align_; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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_; } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-12 10:17:56 -08:00
										 |  |  | template <typename T, typename SpecT> | 
					
						
							|  |  |  | class IntFormatter : public SpecT { | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |  private: | 
					
						
							|  |  |  |   T value_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							| 
									
										
										
										
											2013-01-12 10:17:56 -08:00
										 |  |  |   IntFormatter(T value, const SpecT &spec = SpecT()) | 
					
						
							|  |  |  |   : 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
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-22 11:06:56 -08:00
										 |  |  | /**
 | 
					
						
							|  |  |  |   Returns an integer formatter that formats the value in base 8. | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2013-01-22 11:06:56 -08:00
										 |  |  | IntFormatter<int, TypeSpec<'o'> > oct(int value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |   Returns an integer formatter that formats the value in base 16 using | 
					
						
							|  |  |  |   lower-case letters for the digits above 9. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | IntFormatter<int, TypeSpec<'x'> > hex(int value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |   Returns an integer formatter that formats the value in base 16 using | 
					
						
							|  |  |  |   upper-case letters for the digits above 9. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | IntFormatter<int, TypeSpec<'X'> > hexu(int value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |   \rst | 
					
						
							|  |  |  |   Returns an integer formatter that pads the formatted argument with the fill | 
					
						
							|  |  |  |   character to the specified width using the default (right) alignment. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   **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 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | template <char TYPE_CODE> | 
					
						
							|  |  |  | IntFormatter<int, AlignTypeSpec<TYPE_CODE> > pad( | 
					
						
							| 
									
										
										
										
											2013-09-08 13:07:04 -07:00
										 |  |  |     int value, unsigned width, wchar_t fill = ' '); | 
					
						
							| 
									
										
										
										
											2013-01-22 11:06:56 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-13 09:29:37 -08:00
										 |  |  | #define DEFINE_INT_FORMATTERS(TYPE) \
 | 
					
						
							|  |  |  | inline IntFormatter<TYPE, TypeSpec<'o'> > oct(TYPE value) { \ | 
					
						
							|  |  |  |   return IntFormatter<TYPE, TypeSpec<'o'> >(value, TypeSpec<'o'>()); \ | 
					
						
							|  |  |  | } \ | 
					
						
							|  |  |  |  \ | 
					
						
							|  |  |  | inline IntFormatter<TYPE, TypeSpec<'x'> > hex(TYPE value) { \ | 
					
						
							|  |  |  |   return IntFormatter<TYPE, TypeSpec<'x'> >(value, TypeSpec<'x'>()); \ | 
					
						
							|  |  |  | } \ | 
					
						
							|  |  |  |  \ | 
					
						
							|  |  |  | inline IntFormatter<TYPE, TypeSpec<'X'> > hexu(TYPE value) { \ | 
					
						
							|  |  |  |   return IntFormatter<TYPE, TypeSpec<'X'> >(value, TypeSpec<'X'>()); \ | 
					
						
							|  |  |  | } \ | 
					
						
							|  |  |  |  \ | 
					
						
							|  |  |  | template <char TYPE_CODE> \ | 
					
						
							|  |  |  | inline IntFormatter<TYPE, AlignTypeSpec<TYPE_CODE> > pad( \ | 
					
						
							|  |  |  |     IntFormatter<TYPE, TypeSpec<TYPE_CODE> > f, \ | 
					
						
							| 
									
										
										
										
											2013-09-08 13:07:04 -07:00
										 |  |  |     unsigned width, wchar_t fill = ' ') { \ | 
					
						
							| 
									
										
										
										
											2013-01-13 09:29:37 -08:00
										 |  |  |   return IntFormatter<TYPE, AlignTypeSpec<TYPE_CODE> >( \ | 
					
						
							|  |  |  |       f.value(), AlignTypeSpec<TYPE_CODE>(width, fill)); \ | 
					
						
							|  |  |  | } \ | 
					
						
							|  |  |  |  \ | 
					
						
							|  |  |  | inline IntFormatter<TYPE, AlignTypeSpec<0> > pad( \ | 
					
						
							| 
									
										
										
										
											2013-09-08 13:07:04 -07:00
										 |  |  |     TYPE value, unsigned width, wchar_t fill = ' ') { \ | 
					
						
							| 
									
										
										
										
											2013-01-13 09:29:37 -08:00
										 |  |  |   return IntFormatter<TYPE, AlignTypeSpec<0> >( \ | 
					
						
							|  |  |  |       value, AlignTypeSpec<0>(width, fill)); \ | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-13 09:29:37 -08:00
										 |  |  | DEFINE_INT_FORMATTERS(int) | 
					
						
							|  |  |  | DEFINE_INT_FORMATTERS(long) | 
					
						
							|  |  |  | DEFINE_INT_FORMATTERS(unsigned) | 
					
						
							|  |  |  | DEFINE_INT_FORMATTERS(unsigned long) | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  | template <typename Char> | 
					
						
							| 
									
										
										
										
											2013-09-03 18:58:13 -07:00
										 |  |  | class BasicFormatter; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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: | 
					
						
							|  |  |  |   enum { INLINE_BUFFER_SIZE = 500 }; | 
					
						
							|  |  |  |   mutable internal::Array<Char, INLINE_BUFFER_SIZE> buffer_;  // Output buffer.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   friend class BasicFormatter<Char>; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  | #if _SECURE_SCL
 | 
					
						
							|  |  |  |   typedef stdext::checked_array_iterator<Char*> CharPtr; | 
					
						
							|  |  |  |   static Char *GetBase(CharPtr p) { return p.base(); } | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   typedef Char *CharPtr; | 
					
						
							|  |  |  |   static Char *GetBase(Char *p) { return p; } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   static void FormatDecimal( | 
					
						
							|  |  |  |       CharPtr buffer, uint64_t value, unsigned num_digits); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  |   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
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  |   CharPtr PrepareFilledBuffer(unsigned size, const Spec &, char sign) { | 
					
						
							|  |  |  |     CharPtr p = GrowBuffer(size); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     *p = sign; | 
					
						
							|  |  |  |     return p + size - 1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  |   CharPtr PrepareFilledBuffer(unsigned size, const AlignSpec &spec, char sign); | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Formats an integer.
 | 
					
						
							|  |  |  |   template <typename T> | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   void FormatInt(T value, const FormatSpec &spec) { | 
					
						
							|  |  |  |     *this << IntFormatter<T, FormatSpec>(value, 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> | 
					
						
							|  |  |  |   void FormatDouble(T value, const FormatSpec &spec, int precision); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-06 19:32:19 -07:00
										 |  |  |   template <typename StringChar> | 
					
						
							|  |  |  |   CharPtr FormatString(const StringChar *s, | 
					
						
							|  |  |  |       std::size_t size, const FormatSpec &spec); | 
					
						
							| 
									
										
										
										
											2013-01-04 09:14:34 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-25 17:55:41 -08:00
										 |  |  |  public: | 
					
						
							| 
									
										
										
										
											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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-02 20:29:02 -08:00
										 |  |  |   BasicWriter &operator<<(int value) { | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     return *this << IntFormatter<int, TypeSpec<0> >(value, TypeSpec<0>()); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-02-02 20:29:02 -08:00
										 |  |  |   BasicWriter &operator<<(unsigned value) { | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     return *this << IntFormatter<unsigned, TypeSpec<0> >(value, TypeSpec<0>()); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-09-08 14:18:08 -07:00
										 |  |  |   BasicWriter &operator<<(long value) { | 
					
						
							|  |  |  |     return *this << IntFormatter<long, TypeSpec<0> >(value, TypeSpec<0>()); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-09-09 15:12:51 -07:00
										 |  |  |   BasicWriter &operator<<(unsigned long value) { | 
					
						
							|  |  |  |     return *this << | 
					
						
							|  |  |  |         IntFormatter<unsigned long, TypeSpec<0> >(value, TypeSpec<0>()); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   BasicWriter &operator<<(long long value) { | 
					
						
							|  |  |  |     return *this << IntFormatter<long long, TypeSpec<0> >(value, TypeSpec<0>()); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											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
										 |  |  |    */ | 
					
						
							| 
									
										
										
										
											2013-09-09 15:12:51 -07:00
										 |  |  |   BasicWriter &operator<<(unsigned long long value) { | 
					
						
							| 
									
										
										
										
											2013-09-08 14:18:08 -07:00
										 |  |  |     return *this << | 
					
						
							| 
									
										
										
										
											2013-09-09 15:12:51 -07:00
										 |  |  |         IntFormatter<unsigned long long, TypeSpec<0> >(value, TypeSpec<0>()); | 
					
						
							| 
									
										
										
										
											2013-09-08 14:18:08 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-08 16:27:12 -07:00
										 |  |  |   BasicWriter &operator<<(double value) { | 
					
						
							|  |  |  |     FormatDouble(value, FormatSpec(), -1); | 
					
						
							|  |  |  |     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) { | 
					
						
							| 
									
										
										
										
											2013-02-27 13:17:09 -08:00
										 |  |  |     FormatDouble(value, FormatSpec(), -1); | 
					
						
							|  |  |  |     return *this; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-02 20:29:02 -08: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
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-09 15:12:51 -07:00
										 |  |  |   BasicWriter &operator<<(const fmt::StringRef value) { | 
					
						
							|  |  |  |     const char *str = value.c_str(); | 
					
						
							|  |  |  |     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
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   template <typename T, typename Spec> | 
					
						
							| 
									
										
										
										
											2013-02-02 20:29:02 -08:00
										 |  |  |   BasicWriter &operator<<(const IntFormatter<T, Spec> &f); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -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( | 
					
						
							| 
									
										
										
										
											2013-09-06 19:32:19 -07:00
										 |  |  |     const StringChar *s, std::size_t size, const FormatSpec &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> | 
					
						
							| 
									
										
										
										
											2013-02-02 20:29:02 -08:00
										 |  |  | BasicWriter<Char> &BasicWriter<Char>::operator<<( | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  |     const IntFormatter<T, Spec> &f) { | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |   T value = f.value(); | 
					
						
							|  |  |  |   unsigned size = 0; | 
					
						
							|  |  |  |   char sign = 0; | 
					
						
							|  |  |  |   typedef typename internal::IntTraits<T>::UnsignedType UnsignedType; | 
					
						
							|  |  |  |   UnsignedType abs_value = value; | 
					
						
							|  |  |  |   if (internal::IntTraits<T>::IsNegative(value)) { | 
					
						
							|  |  |  |     sign = '-'; | 
					
						
							|  |  |  |     ++size; | 
					
						
							|  |  |  |     abs_value = 0 - abs_value; | 
					
						
							|  |  |  |   } else if (f.sign_flag()) { | 
					
						
							|  |  |  |     sign = f.plus_flag() ? '+' : ' '; | 
					
						
							|  |  |  |     ++size; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   switch (f.type()) { | 
					
						
							|  |  |  |   case 0: case 'd': { | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  |     unsigned num_digits = internal::CountDigits(abs_value); | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  |     CharPtr p = | 
					
						
							|  |  |  |         PrepareFilledBuffer(size + num_digits, f, sign) + 1 - num_digits; | 
					
						
							| 
									
										
										
										
											2013-02-02 20:29:02 -08:00
										 |  |  |     BasicWriter::FormatDecimal(p, abs_value, num_digits); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   case 'x': case 'X': { | 
					
						
							|  |  |  |     UnsignedType n = abs_value; | 
					
						
							|  |  |  |     bool print_prefix = f.hash_flag(); | 
					
						
							|  |  |  |     if (print_prefix) size += 2; | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       ++size; | 
					
						
							|  |  |  |     } while ((n >>= 4) != 0); | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  |     Char *p = GetBase(PrepareFilledBuffer(size, f, sign)); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     n = abs_value; | 
					
						
							|  |  |  |     const char *digits = f.type() == 'x' ? | 
					
						
							|  |  |  |         "0123456789abcdef" : "0123456789ABCDEF"; | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       *p-- = digits[n & 0xf]; | 
					
						
							|  |  |  |     } while ((n >>= 4) != 0); | 
					
						
							|  |  |  |     if (print_prefix) { | 
					
						
							|  |  |  |       *p-- = f.type(); | 
					
						
							|  |  |  |       *p = '0'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   case 'o': { | 
					
						
							|  |  |  |     UnsignedType n = abs_value; | 
					
						
							|  |  |  |     bool print_prefix = f.hash_flag(); | 
					
						
							|  |  |  |     if (print_prefix) ++size; | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |       ++size; | 
					
						
							|  |  |  |     } while ((n >>= 3) != 0); | 
					
						
							| 
									
										
										
										
											2013-09-03 08:16:53 -07:00
										 |  |  |     Char *p = GetBase(PrepareFilledBuffer(size, f, 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: | 
					
						
							| 
									
										
										
										
											2013-01-26 16:07:28 -08:00
										 |  |  |     internal::ReportUnknownType(f.type(), "integer"); | 
					
						
							| 
									
										
										
										
											2013-01-08 09:56:05 -08:00
										 |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return *this; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  | template <typename Char> | 
					
						
							|  |  |  | BasicFormatter<Char> BasicWriter<Char>::Format(StringRef format) { | 
					
						
							|  |  |  |   return BasicFormatter<Char>(*this, format.c_str()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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> | 
					
						
							| 
									
										
										
										
											2013-02-21 17:44:29 -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( | 
					
						
							|  |  |  |     BasicWriter<Char> &w, const void *arg, const FormatSpec &spec) { | 
					
						
							|  |  |  |   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_; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  |   enum Type { | 
					
						
							| 
									
										
										
										
											2012-12-09 11:32:39 -08:00
										 |  |  |     // Numeric types should go first.
 | 
					
						
							| 
									
										
										
										
											2012-12-09 14:13:23 -08:00
										 |  |  |     INT, UINT, LONG, ULONG, DOUBLE, LONG_DOUBLE, | 
					
						
							|  |  |  |     LAST_NUMERIC_TYPE = LONG_DOUBLE, | 
					
						
							|  |  |  |     CHAR, STRING, WSTRING, POINTER, CUSTOM | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-05 08:05:01 -08:00
										 |  |  |   typedef void (*FormatFunc)( | 
					
						
							|  |  |  |       BasicWriter<Char> &w, const void *arg, const FormatSpec &spec); | 
					
						
							| 
									
										
										
										
											2012-12-09 11:32:39 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-10 17:16:08 -08:00
										 |  |  |   // A format argument.
 | 
					
						
							| 
									
										
										
										
											2012-12-11 10:27:13 -08:00
										 |  |  |   class Arg { | 
					
						
							|  |  |  |    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> | 
					
						
							|  |  |  |     Arg(const T *value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // 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> | 
					
						
							|  |  |  |     Arg(T *value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // This method is private to disallow formatting of wide characters.
 | 
					
						
							|  |  |  |     // If you want to output a wide character cast it to integer type.
 | 
					
						
							|  |  |  |     // Do not implement!
 | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  |     // TODO
 | 
					
						
							|  |  |  |     //Arg(wchar_t value);
 | 
					
						
							| 
									
										
										
										
											2012-12-11 10:27:13 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |    public: | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  |     Type type; | 
					
						
							|  |  |  |     union { | 
					
						
							|  |  |  |       int int_value; | 
					
						
							|  |  |  |       unsigned uint_value; | 
					
						
							|  |  |  |       double double_value; | 
					
						
							| 
									
										
										
										
											2013-01-13 09:29:37 -08:00
										 |  |  |       long long_value; | 
					
						
							|  |  |  |       unsigned long ulong_value; | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  |       long double long_double_value; | 
					
						
							| 
									
										
										
										
											2012-12-10 17:16:08 -08:00
										 |  |  |       const void *pointer_value; | 
					
						
							| 
									
										
										
										
											2012-12-08 08:17:12 -08:00
										 |  |  |       struct { | 
					
						
							| 
									
										
										
										
											2013-09-06 19:32:19 -07:00
										 |  |  |         const Char *value; | 
					
						
							| 
									
										
										
										
											2012-12-09 09:03:47 -08:00
										 |  |  |         std::size_t size; | 
					
						
							| 
									
										
										
										
											2012-12-11 21:47:05 -08:00
										 |  |  |       } string; | 
					
						
							| 
									
										
										
										
											2012-12-09 09:03:47 -08:00
										 |  |  |       struct { | 
					
						
							| 
									
										
										
										
											2012-12-11 21:47:05 -08:00
										 |  |  |         const void *value; | 
					
						
							| 
									
										
										
										
											2012-12-09 11:32:39 -08:00
										 |  |  |         FormatFunc format; | 
					
						
							| 
									
										
										
										
											2012-12-11 21:47:05 -08:00
										 |  |  |       } custom; | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  |     mutable BasicFormatter *formatter; | 
					
						
							| 
									
										
										
										
											2012-12-11 10:27:13 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-31 07:01:09 -07:00
										 |  |  |     Arg(short value) : type(INT), int_value(value), formatter(0) {} | 
					
						
							|  |  |  |     Arg(unsigned short value) : type(UINT), int_value(value), formatter(0) {} | 
					
						
							| 
									
										
										
										
											2012-12-11 21:47:05 -08:00
										 |  |  |     Arg(int value) : type(INT), int_value(value), formatter(0) {} | 
					
						
							|  |  |  |     Arg(unsigned value) : type(UINT), uint_value(value), formatter(0) {} | 
					
						
							|  |  |  |     Arg(long value) : type(LONG), long_value(value), formatter(0) {} | 
					
						
							|  |  |  |     Arg(unsigned long value) : type(ULONG), ulong_value(value), formatter(0) {} | 
					
						
							| 
									
										
										
										
											2013-03-31 07:01:09 -07:00
										 |  |  |     Arg(float value) : type(DOUBLE), double_value(value), formatter(0) {} | 
					
						
							| 
									
										
										
										
											2012-12-11 21:47:05 -08:00
										 |  |  |     Arg(double value) : type(DOUBLE), double_value(value), formatter(0) {} | 
					
						
							|  |  |  |     Arg(long double value) | 
					
						
							|  |  |  |     : type(LONG_DOUBLE), long_double_value(value), formatter(0) {} | 
					
						
							| 
									
										
										
										
											2013-09-06 19:34:55 -07:00
										 |  |  |     Arg(Char value) : type(CHAR), int_value(value), formatter(0) {} | 
					
						
							| 
									
										
										
										
											2012-12-11 21:47:05 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-06 19:32:19 -07:00
										 |  |  |     Arg(const Char *value) : type(STRING), formatter(0) { | 
					
						
							| 
									
										
										
										
											2012-12-11 21:47:05 -08:00
										 |  |  |       string.value = value; | 
					
						
							|  |  |  |       string.size = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-06 19:32:19 -07:00
										 |  |  |     Arg(Char *value) : type(STRING), formatter(0) { | 
					
						
							| 
									
										
										
										
											2012-12-11 21:47:05 -08:00
										 |  |  |       string.value = value; | 
					
						
							|  |  |  |       string.size = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Arg(const void *value) | 
					
						
							|  |  |  |     : type(POINTER), pointer_value(value), formatter(0) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Arg(void *value) : type(POINTER), pointer_value(value), formatter(0) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Arg(const std::string &value) : type(STRING), formatter(0) { | 
					
						
							|  |  |  |       string.value = value.c_str(); | 
					
						
							|  |  |  |       string.size = value.size(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-12-11 10:27:13 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     template <typename T> | 
					
						
							| 
									
										
										
										
											2012-12-11 21:47:05 -08:00
										 |  |  |     Arg(const T &value) : type(CUSTOM), formatter(0) { | 
					
						
							|  |  |  |       custom.value = &value; | 
					
						
							| 
									
										
										
										
											2013-02-05 08:05:01 -08:00
										 |  |  |       custom.format = &internal::FormatCustomArg<Char, T>; | 
					
						
							| 
									
										
										
										
											2012-12-11 21:47:05 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-12-11 10:27:13 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-15 08:59:44 -07:00
										 |  |  |     ~Arg() FMT_NOEXCEPT(false) { | 
					
						
							| 
									
										
										
										
											2012-12-11 13:54:53 -08:00
										 |  |  |       // Format is called here to make sure that a referred object is
 | 
					
						
							|  |  |  |       // still alive, for example:
 | 
					
						
							| 
									
										
										
										
											2012-12-11 10:27:13 -08:00
										 |  |  |       //
 | 
					
						
							|  |  |  |       //   Print("{0}") << std::string("test");
 | 
					
						
							|  |  |  |       //
 | 
					
						
							|  |  |  |       // Here an Arg object refers to a temporary std::string which is
 | 
					
						
							|  |  |  |       // destroyed at the end of the statement. Since the string object is
 | 
					
						
							|  |  |  |       // constructed before the Arg object, it will be destroyed after,
 | 
					
						
							| 
									
										
										
										
											2012-12-11 13:54:53 -08:00
										 |  |  |       // so it will be alive in the Arg's destructor where Format is called.
 | 
					
						
							| 
									
										
										
										
											2012-12-11 10:27:13 -08:00
										 |  |  |       // Note that the string object will not necessarily be alive when
 | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |       // the destructor of BasicFormatter is called.
 | 
					
						
							| 
									
										
										
										
											2013-02-27 13:17:09 -08:00
										 |  |  |       if (formatter) | 
					
						
							|  |  |  |         formatter->CompleteFormatting(); | 
					
						
							| 
									
										
										
										
											2012-12-11 10:27:13 -08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-10 20:37:35 -08:00
										 |  |  |   enum { NUM_INLINE_ARGS = 10 }; | 
					
						
							| 
									
										
										
										
											2012-12-12 09:14:00 -08:00
										 |  |  |   internal::Array<const Arg*, 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-12 15:21:11 -08:00
										 |  |  |   int num_open_braces_; | 
					
						
							| 
									
										
										
										
											2012-12-27 06:56:55 -08:00
										 |  |  |   int next_arg_index_; | 
					
						
							| 
									
										
										
										
											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-09-04 19:23:55 -07:00
										 |  |  |   // Forbid copying other than from a temporary. Do not implement.
 | 
					
						
							|  |  |  |   BasicFormatter(BasicFormatter &); | 
					
						
							|  |  |  |   BasicFormatter& operator=(const BasicFormatter &); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  |   void Add(const Arg &arg) { | 
					
						
							| 
									
										
										
										
											2012-12-11 10:27:13 -08:00
										 |  |  |     args_.push_back(&arg); | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  |   void ReportError(const Char *s, StringRef message) const; | 
					
						
							| 
									
										
										
										
											2012-12-12 15:21:11 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  |   unsigned ParseUInt(const Char *&s) const; | 
					
						
							| 
									
										
										
										
											2012-12-12 15:21:11 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Parses argument index and returns an argument with this index.
 | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  |   const Arg &ParseArgIndex(const Char *&s); | 
					
						
							| 
									
										
										
										
											2012-12-12 15:21:11 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  |   void CheckSign(const Char *&s, const Arg &arg); | 
					
						
							| 
									
										
										
										
											2012-12-25 13:45:12 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-11 12:23:52 -08:00
										 |  |  |   void DoFormat(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |   struct Proxy { | 
					
						
							|  |  |  |     BasicWriter<Char> *writer; | 
					
						
							|  |  |  |     const Char *format; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Proxy(BasicWriter<Char> *w, const Char *fmt) : writer(w), format(fmt) {} | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  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; | 
					
						
							|  |  |  |     DoFormat(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											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
 | 
					
						
							|  |  |  |   // format 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-09-04 19:23:55 -07:00
										 |  |  |   ~BasicFormatter() { | 
					
						
							|  |  |  |     CompleteFormatting(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  |   // Constructs a formatter from a proxy object.
 | 
					
						
							| 
									
										
										
										
											2013-09-04 22:10:58 -07:00
										 |  |  |   BasicFormatter(const Proxy &p) : writer_(p.writer), format_(p.format) {} | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   operator Proxy() { | 
					
						
							|  |  |  |     const Char *format = format_; | 
					
						
							|  |  |  |     format_ = 0; | 
					
						
							|  |  |  |     return Proxy(writer_, format); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Feeds an argument to a formatter.
 | 
					
						
							|  |  |  |   BasicFormatter &operator<<(const Arg &arg) { | 
					
						
							|  |  |  |     arg.formatter = this; | 
					
						
							|  |  |  |     Add(arg); | 
					
						
							|  |  |  |     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
										 |  |  |       } | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Formats an error message and prints it to std::cerr.
 | 
					
						
							|  |  |  |     fmt::Formatter<PrintError> ReportError(const char *format) { | 
					
						
							|  |  |  |       return fmt::Formatter<PrintError>(format); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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-09-04 19:23:55 -07:00
										 |  |  |   Formatter(Formatter &); | 
					
						
							|  |  |  |   Formatter& operator=(const Formatter &); | 
					
						
							| 
									
										
										
										
											2012-12-15 20:17:03 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   struct Proxy { | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  |     const Char *format; | 
					
						
							| 
									
										
										
										
											2012-12-15 20:17:03 -08:00
										 |  |  |     Action action; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 22:03:37 -07:00
										 |  |  |     Proxy(const Char *fmt, Action a) : format(fmt), action(a) {} | 
					
						
							| 
									
										
										
										
											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-09-08 15:37:14 -07:00
										 |  |  |   // Constructs a formatter from a proxy object.
 | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |   Formatter(const Proxy &p) | 
					
						
							|  |  |  |   : Action(p.action), BasicFormatter<Char>(writer_, p.format), | 
					
						
							|  |  |  |     inactive_(false) { | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											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
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2012-12-15 20:17:03 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-08 15:37:14 -07:00
										 |  |  |   // Converts the formatter into a proxy object.
 | 
					
						
							| 
									
										
										
										
											2012-12-15 20:17:03 -08:00
										 |  |  |   operator Proxy() { | 
					
						
							| 
									
										
										
										
											2013-09-03 18:58:13 -07:00
										 |  |  |     inactive_ = true; | 
					
						
							| 
									
										
										
										
											2013-09-04 19:23:55 -07:00
										 |  |  |     return Proxy(this->TakeFormatString(), *this); | 
					
						
							| 
									
										
										
										
											2012-12-15 20:17:03 -08: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.
 | 
					
						
							|  |  |  |   enum {BUFFER_SIZE = std::numeric_limits<uint64_t>::digits10 + 3}; | 
					
						
							|  |  |  |   char buffer_[BUFFER_SIZE]; | 
					
						
							|  |  |  |   char *str_; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Formats value in reverse and returns the number of digits.
 | 
					
						
							|  |  |  |   char *FormatDecimal(uint64_t value) { | 
					
						
							|  |  |  |     char *buffer_end = buffer_ + BUFFER_SIZE; | 
					
						
							|  |  |  |     *--buffer_end = '\0'; | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   explicit FormatInt(int value) { | 
					
						
							|  |  |  |     uint64_t abs_value = value; | 
					
						
							|  |  |  |     bool negative = value < 0; | 
					
						
							|  |  |  |     if (negative) | 
					
						
							|  |  |  |       abs_value = 0 - value; | 
					
						
							|  |  |  |     str_ = FormatDecimal(abs_value); | 
					
						
							|  |  |  |     if (negative) | 
					
						
							|  |  |  |       *--str_ = '-'; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   explicit FormatInt(unsigned value) : str_(FormatDecimal(value)) {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const char *c_str() const { return str_; } | 
					
						
							|  |  |  |   std::string str() const { return str_; } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							|  |  |  |   return Formatter<>(format); | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							|  |  |  |   return Formatter<NoAction, wchar_t>(format); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-04 20:44:13 -07:00
										 |  |  | /** A formatting action that writes formatted output to stdout. */ | 
					
						
							|  |  |  | class Write { | 
					
						
							|  |  |  |  public: | 
					
						
							|  |  |  |   /** Write 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) { | 
					
						
							|  |  |  |   return Formatter<Write>(format); | 
					
						
							| 
									
										
										
										
											2013-02-05 07:28:54 -08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-12-07 08:31:09 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif  // FORMAT_H_
 |