Home | History | Annotate | Download | only in test
      1 /*
      2  Utility tests.
      3 
      4  Copyright (c) 2012-2014, Victor Zverovich
      5  All rights reserved.
      6 
      7  Redistribution and use in source and binary forms, with or without
      8  modification, are permitted provided that the following conditions are met:
      9 
     10  1. Redistributions of source code must retain the above copyright notice, this
     11     list of conditions and the following disclaimer.
     12  2. Redistributions in binary form must reproduce the above copyright notice,
     13     this list of conditions and the following disclaimer in the documentation
     14     and/or other materials provided with the distribution.
     15 
     16  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     17  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     18  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     19  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
     20  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     21  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     22  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     23  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     25  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #include "test-assert.h"
     29 
     30 #include <cfloat>
     31 #include <climits>
     32 #include <cstring>
     33 #include <functional>
     34 #include <limits>
     35 
     36 #if FMT_USE_TYPE_TRAITS
     37 # include <type_traits>
     38 #endif
     39 
     40 #include "gmock/gmock.h"
     41 #include "gtest-extra.h"
     42 #include "mock-allocator.h"
     43 #include "util.h"
     44 
     45 // Check if format.h compiles with windows.h included.
     46 #ifdef _WIN32
     47 # include <windows.h>
     48 #endif
     49 
     50 #include "fmt/format.h"
     51 
     52 #undef max
     53 
     54 using fmt::StringRef;
     55 using fmt::internal::Arg;
     56 using fmt::Buffer;
     57 using fmt::internal::MemoryBuffer;
     58 
     59 using testing::Return;
     60 using testing::StrictMock;
     61 
     62 namespace {
     63 
     64 struct Test {};
     65 
     66 template <typename Char>
     67 void format_arg(fmt::BasicFormatter<Char> &f, const Char *, Test) {
     68   f.writer() << "test";
     69 }
     70 
     71 template <typename Char, typename T>
     72 Arg make_arg(const T &value) {
     73   typedef fmt::internal::MakeValue< fmt::BasicFormatter<Char> > MakeValue;
     74   Arg arg = MakeValue(value);
     75   arg.type = static_cast<Arg::Type>(MakeValue::type(value));
     76   return arg;
     77 }
     78 }  // namespace
     79 
     80 void CheckForwarding(
     81     MockAllocator<int> &alloc, AllocatorRef< MockAllocator<int> > &ref) {
     82   int mem;
     83   // Check if value_type is properly defined.
     84   AllocatorRef< MockAllocator<int> >::value_type *ptr = &mem;
     85   // Check forwarding.
     86   EXPECT_CALL(alloc, allocate(42, 0)).WillOnce(Return(ptr));
     87   ref.allocate(42, 0);
     88   EXPECT_CALL(alloc, deallocate(ptr, 42));
     89   ref.deallocate(ptr, 42);
     90 }
     91 
     92 TEST(AllocatorTest, AllocatorRef) {
     93   StrictMock< MockAllocator<int> > alloc;
     94   typedef AllocatorRef< MockAllocator<int> > TestAllocatorRef;
     95   TestAllocatorRef ref(&alloc);
     96   // Check if AllocatorRef forwards to the underlying allocator.
     97   CheckForwarding(alloc, ref);
     98   TestAllocatorRef ref2(ref);
     99   CheckForwarding(alloc, ref2);
    100   TestAllocatorRef ref3;
    101   EXPECT_EQ(0, ref3.get());
    102   ref3 = ref;
    103   CheckForwarding(alloc, ref3);
    104 }
    105 
    106 #if FMT_USE_TYPE_TRAITS
    107 TEST(BufferTest, Noncopyable) {
    108   EXPECT_FALSE(std::is_copy_constructible<Buffer<char> >::value);
    109   EXPECT_FALSE(std::is_copy_assignable<Buffer<char> >::value);
    110 }
    111 
    112 TEST(BufferTest, Nonmoveable) {
    113   EXPECT_FALSE(std::is_move_constructible<Buffer<char> >::value);
    114   EXPECT_FALSE(std::is_move_assignable<Buffer<char> >::value);
    115 }
    116 #endif
    117 
    118 // A test buffer with a dummy grow method.
    119 template <typename T>
    120 struct TestBuffer : Buffer<T> {
    121   void grow(std::size_t size) { this->capacity_ = size; }
    122 };
    123 
    124 template <typename T>
    125 struct MockBuffer : Buffer<T> {
    126   MOCK_METHOD1(do_grow, void (std::size_t size));
    127 
    128   void grow(std::size_t size) {
    129     this->capacity_ = size;
    130     do_grow(size);
    131   }
    132 
    133   MockBuffer() {}
    134   MockBuffer(T *ptr) : Buffer<T>(ptr) {}
    135   MockBuffer(T *ptr, std::size_t capacity) : Buffer<T>(ptr, capacity) {}
    136 };
    137 
    138 TEST(BufferTest, Ctor) {
    139   {
    140     MockBuffer<int> buffer;
    141     EXPECT_EQ(0, &buffer[0]);
    142     EXPECT_EQ(0u, buffer.size());
    143     EXPECT_EQ(0u, buffer.capacity());
    144   }
    145   {
    146     int dummy;
    147     MockBuffer<int> buffer(&dummy);
    148     EXPECT_EQ(&dummy, &buffer[0]);
    149     EXPECT_EQ(0u, buffer.size());
    150     EXPECT_EQ(0u, buffer.capacity());
    151   }
    152   {
    153     int dummy;
    154     std::size_t capacity = std::numeric_limits<std::size_t>::max();
    155     MockBuffer<int> buffer(&dummy, capacity);
    156     EXPECT_EQ(&dummy, &buffer[0]);
    157     EXPECT_EQ(0u, buffer.size());
    158     EXPECT_EQ(capacity, buffer.capacity());
    159   }
    160 }
    161 
    162 struct DyingBuffer : TestBuffer<int> {
    163   MOCK_METHOD0(die, void());
    164   ~DyingBuffer() { die(); }
    165 };
    166 
    167 TEST(BufferTest, VirtualDtor) {
    168   typedef StrictMock<DyingBuffer> StictMockBuffer;
    169   StictMockBuffer *mock_buffer = new StictMockBuffer();
    170   EXPECT_CALL(*mock_buffer, die());
    171   Buffer<int> *buffer = mock_buffer;
    172   delete buffer;
    173 }
    174 
    175 TEST(BufferTest, Access) {
    176   char data[10];
    177   MockBuffer<char> buffer(data, sizeof(data));
    178   buffer[0] = 11;
    179   EXPECT_EQ(11, buffer[0]);
    180   buffer[3] = 42;
    181   EXPECT_EQ(42, *(&buffer[0] + 3));
    182   const Buffer<char> &const_buffer = buffer;
    183   EXPECT_EQ(42, const_buffer[3]);
    184 }
    185 
    186 TEST(BufferTest, Resize) {
    187   char data[123];
    188   MockBuffer<char> buffer(data, sizeof(data));
    189   buffer[10] = 42;
    190   EXPECT_EQ(42, buffer[10]);
    191   buffer.resize(20);
    192   EXPECT_EQ(20u, buffer.size());
    193   EXPECT_EQ(123u, buffer.capacity());
    194   EXPECT_EQ(42, buffer[10]);
    195   buffer.resize(5);
    196   EXPECT_EQ(5u, buffer.size());
    197   EXPECT_EQ(123u, buffer.capacity());
    198   EXPECT_EQ(42, buffer[10]);
    199   // Check if resize calls grow.
    200   EXPECT_CALL(buffer, do_grow(124));
    201   buffer.resize(124);
    202   EXPECT_CALL(buffer, do_grow(200));
    203   buffer.resize(200);
    204 }
    205 
    206 TEST(BufferTest, Clear) {
    207   TestBuffer<char> buffer;
    208   buffer.resize(20);
    209   buffer.clear();
    210   EXPECT_EQ(0u, buffer.size());
    211   EXPECT_EQ(20u, buffer.capacity());
    212 }
    213 
    214 TEST(BufferTest, PushBack) {
    215   int data[15];
    216   MockBuffer<int> buffer(data, 10);
    217   buffer.push_back(11);
    218   EXPECT_EQ(11, buffer[0]);
    219   EXPECT_EQ(1u, buffer.size());
    220   buffer.resize(10);
    221   EXPECT_CALL(buffer, do_grow(11));
    222   buffer.push_back(22);
    223   EXPECT_EQ(22, buffer[10]);
    224   EXPECT_EQ(11u, buffer.size());
    225 }
    226 
    227 TEST(BufferTest, Append) {
    228   char data[15];
    229   MockBuffer<char> buffer(data, 10);
    230   const char *test = "test";
    231   buffer.append(test, test + 5);
    232   EXPECT_STREQ(test, &buffer[0]);
    233   EXPECT_EQ(5u, buffer.size());
    234   buffer.resize(10);
    235   EXPECT_CALL(buffer, do_grow(12));
    236   buffer.append(test, test + 2);
    237   EXPECT_EQ('t', buffer[10]);
    238   EXPECT_EQ('e', buffer[11]);
    239   EXPECT_EQ(12u, buffer.size());
    240 }
    241 
    242 TEST(BufferTest, AppendAllocatesEnoughStorage) {
    243   char data[19];
    244   MockBuffer<char> buffer(data, 10);
    245   const char *test = "abcdefgh";
    246   buffer.resize(10);
    247   EXPECT_CALL(buffer, do_grow(19));
    248   buffer.append(test, test + 9);
    249 }
    250 
    251 TEST(MemoryBufferTest, Ctor) {
    252   MemoryBuffer<char, 123> buffer;
    253   EXPECT_EQ(0u, buffer.size());
    254   EXPECT_EQ(123u, buffer.capacity());
    255 }
    256 
    257 #if FMT_USE_RVALUE_REFERENCES
    258 
    259 typedef AllocatorRef< std::allocator<char> > TestAllocator;
    260 
    261 void check_move_buffer(const char *str,
    262                        MemoryBuffer<char, 5, TestAllocator> &buffer) {
    263   std::allocator<char> *alloc = buffer.get_allocator().get();
    264   MemoryBuffer<char, 5, TestAllocator> buffer2(std::move(buffer));
    265   // Move shouldn't destroy the inline content of the first buffer.
    266   EXPECT_EQ(str, std::string(&buffer[0], buffer.size()));
    267   EXPECT_EQ(str, std::string(&buffer2[0], buffer2.size()));
    268   EXPECT_EQ(5u, buffer2.capacity());
    269   // Move should transfer allocator.
    270   EXPECT_EQ(0, buffer.get_allocator().get());
    271   EXPECT_EQ(alloc, buffer2.get_allocator().get());
    272 }
    273 
    274 TEST(MemoryBufferTest, MoveCtor) {
    275   std::allocator<char> alloc;
    276   MemoryBuffer<char, 5, TestAllocator> buffer((TestAllocator(&alloc)));
    277   const char test[] = "test";
    278   buffer.append(test, test + 4);
    279   check_move_buffer("test", buffer);
    280   // Adding one more character fills the inline buffer, but doesn't cause
    281   // dynamic allocation.
    282   buffer.push_back('a');
    283   check_move_buffer("testa", buffer);
    284   const char *inline_buffer_ptr = &buffer[0];
    285   // Adding one more character causes the content to move from the inline to
    286   // a dynamically allocated buffer.
    287   buffer.push_back('b');
    288   MemoryBuffer<char, 5, TestAllocator> buffer2(std::move(buffer));
    289   // Move should rip the guts of the first buffer.
    290   EXPECT_EQ(inline_buffer_ptr, &buffer[0]);
    291   EXPECT_EQ("testab", std::string(&buffer2[0], buffer2.size()));
    292   EXPECT_GT(buffer2.capacity(), 5u);
    293 }
    294 
    295 void check_move_assign_buffer(const char *str, MemoryBuffer<char, 5> &buffer) {
    296   MemoryBuffer<char, 5> buffer2;
    297   buffer2 = std::move(buffer);
    298   // Move shouldn't destroy the inline content of the first buffer.
    299   EXPECT_EQ(str, std::string(&buffer[0], buffer.size()));
    300   EXPECT_EQ(str, std::string(&buffer2[0], buffer2.size()));
    301   EXPECT_EQ(5u, buffer2.capacity());
    302 }
    303 
    304 TEST(MemoryBufferTest, MoveAssignment) {
    305   MemoryBuffer<char, 5> buffer;
    306   const char test[] = "test";
    307   buffer.append(test, test + 4);
    308   check_move_assign_buffer("test", buffer);
    309   // Adding one more character fills the inline buffer, but doesn't cause
    310   // dynamic allocation.
    311   buffer.push_back('a');
    312   check_move_assign_buffer("testa", buffer);
    313   const char *inline_buffer_ptr = &buffer[0];
    314   // Adding one more character causes the content to move from the inline to
    315   // a dynamically allocated buffer.
    316   buffer.push_back('b');
    317   MemoryBuffer<char, 5> buffer2;
    318   buffer2 = std::move(buffer);
    319   // Move should rip the guts of the first buffer.
    320   EXPECT_EQ(inline_buffer_ptr, &buffer[0]);
    321   EXPECT_EQ("testab", std::string(&buffer2[0], buffer2.size()));
    322   EXPECT_GT(buffer2.capacity(), 5u);
    323 }
    324 
    325 #endif  // FMT_USE_RVALUE_REFERENCES
    326 
    327 TEST(MemoryBufferTest, Grow) {
    328   typedef AllocatorRef< MockAllocator<int> > Allocator;
    329   typedef MemoryBuffer<int, 10, Allocator> Base;
    330   MockAllocator<int> alloc;
    331   struct TestMemoryBuffer : Base {
    332     TestMemoryBuffer(Allocator alloc) : Base(alloc) {}
    333     void grow(std::size_t size) { Base::grow(size); }
    334   } buffer((Allocator(&alloc)));
    335   buffer.resize(7);
    336   using fmt::internal::to_unsigned;
    337   for (int i = 0; i < 7; ++i)
    338     buffer[to_unsigned(i)] = i * i;
    339   EXPECT_EQ(10u, buffer.capacity());
    340   int mem[20];
    341   mem[7] = 0xdead;
    342   EXPECT_CALL(alloc, allocate(20, 0)).WillOnce(Return(mem));
    343   buffer.grow(20);
    344   EXPECT_EQ(20u, buffer.capacity());
    345   // Check if size elements have been copied
    346   for (int i = 0; i < 7; ++i)
    347     EXPECT_EQ(i * i, buffer[to_unsigned(i)]);
    348   // and no more than that.
    349   EXPECT_EQ(0xdead, buffer[7]);
    350   EXPECT_CALL(alloc, deallocate(mem, 20));
    351 }
    352 
    353 TEST(MemoryBufferTest, Allocator) {
    354   typedef AllocatorRef< MockAllocator<char> > TestAllocator;
    355   MemoryBuffer<char, 10, TestAllocator> buffer;
    356   EXPECT_EQ(0, buffer.get_allocator().get());
    357   StrictMock< MockAllocator<char> > alloc;
    358   char mem;
    359   {
    360     MemoryBuffer<char, 10, TestAllocator> buffer2((TestAllocator(&alloc)));
    361     EXPECT_EQ(&alloc, buffer2.get_allocator().get());
    362     std::size_t size = 2 * fmt::internal::INLINE_BUFFER_SIZE;
    363     EXPECT_CALL(alloc, allocate(size, 0)).WillOnce(Return(&mem));
    364     buffer2.reserve(size);
    365     EXPECT_CALL(alloc, deallocate(&mem, size));
    366   }
    367 }
    368 
    369 TEST(MemoryBufferTest, ExceptionInDeallocate) {
    370   typedef AllocatorRef< MockAllocator<char> > TestAllocator;
    371   StrictMock< MockAllocator<char> > alloc;
    372   MemoryBuffer<char, 10, TestAllocator> buffer((TestAllocator(&alloc)));
    373   std::size_t size = 2 * fmt::internal::INLINE_BUFFER_SIZE;
    374   std::vector<char> mem(size);
    375   {
    376     EXPECT_CALL(alloc, allocate(size, 0)).WillOnce(Return(&mem[0]));
    377     buffer.resize(size);
    378     std::fill(&buffer[0], &buffer[0] + size, 'x');
    379   }
    380   std::vector<char> mem2(2 * size);
    381   {
    382     EXPECT_CALL(alloc, allocate(2 * size, 0)).WillOnce(Return(&mem2[0]));
    383     std::exception e;
    384     EXPECT_CALL(alloc, deallocate(&mem[0], size)).WillOnce(testing::Throw(e));
    385     EXPECT_THROW(buffer.reserve(2 * size), std::exception);
    386     EXPECT_EQ(&mem2[0], &buffer[0]);
    387     // Check that the data has been copied.
    388     for (std::size_t i = 0; i < size; ++i)
    389       EXPECT_EQ('x', buffer[i]);
    390   }
    391   EXPECT_CALL(alloc, deallocate(&mem2[0], 2 * size));
    392 }
    393 
    394 TEST(UtilTest, Increment) {
    395   char s[10] = "123";
    396   increment(s);
    397   EXPECT_STREQ("124", s);
    398   s[2] = '8';
    399   increment(s);
    400   EXPECT_STREQ("129", s);
    401   increment(s);
    402   EXPECT_STREQ("130", s);
    403   s[1] = s[2] = '9';
    404   increment(s);
    405   EXPECT_STREQ("200", s);
    406 }
    407 
    408 template <Arg::Type>
    409 struct ArgInfo;
    410 
    411 #define ARG_INFO(type_code, Type, field) \
    412   template <> \
    413   struct ArgInfo<Arg::type_code> { \
    414     static Type get(const Arg &arg) { return arg.field; } \
    415   }
    416 
    417 ARG_INFO(INT, int, int_value);
    418 ARG_INFO(UINT, unsigned, uint_value);
    419 ARG_INFO(LONG_LONG, fmt::LongLong, long_long_value);
    420 ARG_INFO(ULONG_LONG, fmt::ULongLong, ulong_long_value);
    421 ARG_INFO(BOOL, int, int_value);
    422 ARG_INFO(CHAR, int, int_value);
    423 ARG_INFO(DOUBLE, double, double_value);
    424 ARG_INFO(LONG_DOUBLE, long double, long_double_value);
    425 ARG_INFO(CSTRING, const char *, string.value);
    426 ARG_INFO(STRING, const char *, string.value);
    427 ARG_INFO(WSTRING, const wchar_t *, wstring.value);
    428 ARG_INFO(POINTER, const void *, pointer);
    429 ARG_INFO(CUSTOM, Arg::CustomValue, custom);
    430 
    431 #define CHECK_ARG_INFO(Type, field, value) { \
    432   Arg arg = Arg(); \
    433   arg.field = value; \
    434   EXPECT_EQ(value, ArgInfo<Arg::Type>::get(arg)); \
    435 }
    436 
    437 TEST(ArgTest, ArgInfo) {
    438   CHECK_ARG_INFO(INT, int_value, 42);
    439   CHECK_ARG_INFO(UINT, uint_value, 42u);
    440   CHECK_ARG_INFO(LONG_LONG, long_long_value, 42);
    441   CHECK_ARG_INFO(ULONG_LONG, ulong_long_value, 42u);
    442   CHECK_ARG_INFO(DOUBLE, double_value, 4.2);
    443   CHECK_ARG_INFO(LONG_DOUBLE, long_double_value, 4.2);
    444   CHECK_ARG_INFO(CHAR, int_value, 'x');
    445   const char STR[] = "abc";
    446   CHECK_ARG_INFO(CSTRING, string.value, STR);
    447   const wchar_t WSTR[] = L"abc";
    448   CHECK_ARG_INFO(WSTRING, wstring.value, WSTR);
    449   int p = 0;
    450   CHECK_ARG_INFO(POINTER, pointer, &p);
    451   Arg arg = Arg();
    452   arg.custom.value = &p;
    453   EXPECT_EQ(&p, ArgInfo<Arg::CUSTOM>::get(arg).value);
    454 }
    455 
    456 #define EXPECT_ARG_(Char, type_code, MakeArgType, ExpectedType, value) { \
    457   MakeArgType input = static_cast<MakeArgType>(value); \
    458   Arg arg = make_arg<Char>(input); \
    459   EXPECT_EQ(Arg::type_code, arg.type); \
    460   ExpectedType expected_value = static_cast<ExpectedType>(value); \
    461   EXPECT_EQ(expected_value, ArgInfo<Arg::type_code>::get(arg)); \
    462 }
    463 
    464 #define EXPECT_ARG(type_code, Type, value) \
    465   EXPECT_ARG_(char, type_code, Type, Type, value)
    466 
    467 #define EXPECT_ARGW(type_code, Type, value) \
    468   EXPECT_ARG_(wchar_t, type_code, Type, Type, value)
    469 
    470 TEST(ArgTest, MakeArg) {
    471   // Test bool.
    472   EXPECT_ARG_(char, BOOL, bool, int, true);
    473   EXPECT_ARG_(wchar_t, BOOL, bool, int, true);
    474 
    475   // Test char.
    476   EXPECT_ARG(CHAR, char, 'a');
    477   EXPECT_ARG(CHAR, char, CHAR_MIN);
    478   EXPECT_ARG(CHAR, char, CHAR_MAX);
    479 
    480   // Test wchar_t.
    481   EXPECT_ARGW(CHAR, wchar_t, L'a');
    482   EXPECT_ARGW(CHAR, wchar_t, WCHAR_MIN);
    483   EXPECT_ARGW(CHAR, wchar_t, WCHAR_MAX);
    484 
    485   // Test signed/unsigned char.
    486   EXPECT_ARG(INT, signed char, 42);
    487   EXPECT_ARG(INT, signed char, SCHAR_MIN);
    488   EXPECT_ARG(INT, signed char, SCHAR_MAX);
    489   EXPECT_ARG(UINT, unsigned char, 42);
    490   EXPECT_ARG(UINT, unsigned char, UCHAR_MAX );
    491 
    492   // Test short.
    493   EXPECT_ARG(INT, short, 42);
    494   EXPECT_ARG(INT, short, SHRT_MIN);
    495   EXPECT_ARG(INT, short, SHRT_MAX);
    496   EXPECT_ARG(UINT, unsigned short, 42);
    497   EXPECT_ARG(UINT, unsigned short, USHRT_MAX);
    498 
    499   // Test int.
    500   EXPECT_ARG(INT, int, 42);
    501   EXPECT_ARG(INT, int, INT_MIN);
    502   EXPECT_ARG(INT, int, INT_MAX);
    503   EXPECT_ARG(UINT, unsigned, 42);
    504   EXPECT_ARG(UINT, unsigned, UINT_MAX);
    505 
    506   // Test long.
    507 #if LONG_MAX == INT_MAX
    508 # define LONG INT
    509 # define ULONG UINT
    510 # define long_value int_value
    511 # define ulong_value uint_value
    512 #else
    513 # define LONG LONG_LONG
    514 # define ULONG ULONG_LONG
    515 # define long_value long_long_value
    516 # define ulong_value ulong_long_value
    517 #endif
    518   EXPECT_ARG(LONG, long, 42);
    519   EXPECT_ARG(LONG, long, LONG_MIN);
    520   EXPECT_ARG(LONG, long, LONG_MAX);
    521   EXPECT_ARG(ULONG, unsigned long, 42);
    522   EXPECT_ARG(ULONG, unsigned long, ULONG_MAX);
    523 
    524   // Test long long.
    525   EXPECT_ARG(LONG_LONG, fmt::LongLong, 42);
    526   EXPECT_ARG(LONG_LONG, fmt::LongLong, LLONG_MIN);
    527   EXPECT_ARG(LONG_LONG, fmt::LongLong, LLONG_MAX);
    528   EXPECT_ARG(ULONG_LONG, fmt::ULongLong, 42);
    529   EXPECT_ARG(ULONG_LONG, fmt::ULongLong, ULLONG_MAX);
    530 
    531   // Test float.
    532   EXPECT_ARG(DOUBLE, float, 4.2);
    533   EXPECT_ARG(DOUBLE, float, FLT_MIN);
    534   EXPECT_ARG(DOUBLE, float, FLT_MAX);
    535 
    536   // Test double.
    537   EXPECT_ARG(DOUBLE, double, 4.2);
    538   EXPECT_ARG(DOUBLE, double, DBL_MIN);
    539   EXPECT_ARG(DOUBLE, double, DBL_MAX);
    540 
    541   // Test long double.
    542   EXPECT_ARG(LONG_DOUBLE, long double, 4.2);
    543   EXPECT_ARG(LONG_DOUBLE, long double, LDBL_MIN);
    544   EXPECT_ARG(LONG_DOUBLE, long double, LDBL_MAX);
    545 
    546   // Test string.
    547   char STR[] = "test";
    548   EXPECT_ARG(CSTRING, char*, STR);
    549   EXPECT_ARG(CSTRING, const char*, STR);
    550   EXPECT_ARG(STRING, std::string, STR);
    551   EXPECT_ARG(STRING, fmt::StringRef, STR);
    552 
    553   // Test wide string.
    554   wchar_t WSTR[] = L"test";
    555   EXPECT_ARGW(WSTRING, wchar_t*, WSTR);
    556   EXPECT_ARGW(WSTRING, const wchar_t*, WSTR);
    557   EXPECT_ARGW(WSTRING, std::wstring, WSTR);
    558   EXPECT_ARGW(WSTRING, fmt::WStringRef, WSTR);
    559 
    560   int n = 42;
    561   EXPECT_ARG(POINTER, void*, &n);
    562   EXPECT_ARG(POINTER, const void*, &n);
    563 
    564   ::Test t;
    565   Arg arg = make_arg<char>(t);
    566   EXPECT_EQ(fmt::internal::Arg::CUSTOM, arg.type);
    567   EXPECT_EQ(&t, arg.custom.value);
    568   fmt::MemoryWriter w;
    569   fmt::BasicFormatter<char> formatter(fmt::ArgList(), w);
    570   const char *s = "}";
    571   arg.custom.format(&formatter, &t, &s);
    572   EXPECT_EQ("test", w.str());
    573 }
    574 
    575 TEST(UtilTest, ArgList) {
    576   fmt::ArgList args;
    577   EXPECT_EQ(Arg::NONE, args[1].type);
    578 }
    579 
    580 struct CustomFormatter {
    581   typedef char Char;
    582 };
    583 
    584 void format_arg(CustomFormatter &, const char *&s, const Test &) {
    585   s = "custom_format";
    586 }
    587 
    588 TEST(UtilTest, MakeValueWithCustomFormatter) {
    589   ::Test t;
    590   Arg arg = fmt::internal::MakeValue<CustomFormatter>(t);
    591   CustomFormatter formatter;
    592   const char *s = "";
    593   arg.custom.format(&formatter, &t, &s);
    594   EXPECT_STREQ("custom_format", s);
    595 }
    596 
    597 struct Result {
    598   Arg arg;
    599 
    600   Result() : arg(make_arg<char>(0xdeadbeef)) {}
    601 
    602   template <typename T>
    603   Result(const T& value) : arg(make_arg<char>(value)) {}
    604   Result(const wchar_t *s) : arg(make_arg<wchar_t>(s)) {}
    605 };
    606 
    607 struct TestVisitor : fmt::ArgVisitor<TestVisitor, Result> {
    608   Result visit_int(int value) { return value; }
    609   Result visit_uint(unsigned value) { return value; }
    610   Result visit_long_long(fmt::LongLong value) { return value; }
    611   Result visit_ulong_long(fmt::ULongLong value) { return value; }
    612   Result visit_double(double value) { return value; }
    613   Result visit_long_double(long double value) { return value; }
    614   Result visit_char(int value) { return static_cast<char>(value); }
    615   Result visit_cstring(const char *s) { return s; }
    616   Result visit_string(fmt::internal::Arg::StringValue<char> s) {
    617     return s.value;
    618   }
    619   Result visit_wstring(fmt::internal::Arg::StringValue<wchar_t> s) {
    620     return s.value;
    621   }
    622   Result visit_pointer(const void *p) { return p; }
    623   Result visit_custom(fmt::internal::Arg::CustomValue c) {
    624     return *static_cast<const ::Test*>(c.value);
    625   }
    626 };
    627 
    628 #define EXPECT_RESULT_(Char, type_code, value) { \
    629   Arg arg = make_arg<Char>(value); \
    630   Result result = TestVisitor().visit(arg); \
    631   EXPECT_EQ(Arg::type_code, result.arg.type); \
    632   EXPECT_EQ(value, ArgInfo<Arg::type_code>::get(result.arg)); \
    633 }
    634 
    635 #define EXPECT_RESULT(type_code, value) \
    636   EXPECT_RESULT_(char, type_code, value)
    637 #define EXPECT_RESULTW(type_code, value) \
    638   EXPECT_RESULT_(wchar_t, type_code, value)
    639 
    640 TEST(ArgVisitorTest, VisitAll) {
    641   EXPECT_RESULT(INT, 42);
    642   EXPECT_RESULT(UINT, 42u);
    643   EXPECT_RESULT(LONG_LONG, 42ll);
    644   EXPECT_RESULT(ULONG_LONG, 42ull);
    645   EXPECT_RESULT(DOUBLE, 4.2);
    646   EXPECT_RESULT(LONG_DOUBLE, 4.2l);
    647   EXPECT_RESULT(CHAR, 'x');
    648   const char STR[] = "abc";
    649   EXPECT_RESULT(CSTRING, STR);
    650   const wchar_t WSTR[] = L"abc";
    651   EXPECT_RESULTW(WSTRING, WSTR);
    652   const void *p = STR;
    653   EXPECT_RESULT(POINTER, p);
    654   ::Test t;
    655   Result result = TestVisitor().visit(make_arg<char>(t));
    656   EXPECT_EQ(Arg::CUSTOM, result.arg.type);
    657   EXPECT_EQ(&t, result.arg.custom.value);
    658 }
    659 
    660 struct TestAnyVisitor : fmt::ArgVisitor<TestAnyVisitor, Result> {
    661   template <typename T>
    662   Result visit_any_int(T value) { return value; }
    663 
    664   template <typename T>
    665   Result visit_any_double(T value) { return value; }
    666 };
    667 
    668 #undef EXPECT_RESULT
    669 #define EXPECT_RESULT(type_code, value) { \
    670   Result result = TestAnyVisitor().visit(make_arg<char>(value)); \
    671   EXPECT_EQ(Arg::type_code, result.arg.type); \
    672   EXPECT_EQ(value, ArgInfo<Arg::type_code>::get(result.arg)); \
    673 }
    674 
    675 TEST(ArgVisitorTest, VisitAny) {
    676   EXPECT_RESULT(INT, 42);
    677   EXPECT_RESULT(UINT, 42u);
    678   EXPECT_RESULT(LONG_LONG, 42ll);
    679   EXPECT_RESULT(ULONG_LONG, 42ull);
    680   EXPECT_RESULT(DOUBLE, 4.2);
    681   EXPECT_RESULT(LONG_DOUBLE, 4.2l);
    682 }
    683 
    684 struct TestUnhandledVisitor :
    685     fmt::ArgVisitor<TestUnhandledVisitor, const char *> {
    686   const char *visit_unhandled_arg() { return "test"; }
    687 };
    688 
    689 #define EXPECT_UNHANDLED(value) \
    690   EXPECT_STREQ("test", TestUnhandledVisitor().visit(make_arg<wchar_t>(value)));
    691 
    692 TEST(ArgVisitorTest, VisitUnhandledArg) {
    693   EXPECT_UNHANDLED(42);
    694   EXPECT_UNHANDLED(42u);
    695   EXPECT_UNHANDLED(42ll);
    696   EXPECT_UNHANDLED(42ull);
    697   EXPECT_UNHANDLED(4.2);
    698   EXPECT_UNHANDLED(4.2l);
    699   EXPECT_UNHANDLED('x');
    700   const char STR[] = "abc";
    701   EXPECT_UNHANDLED(STR);
    702   const wchar_t WSTR[] = L"abc";
    703   EXPECT_UNHANDLED(WSTR);
    704   const void *p = STR;
    705   EXPECT_UNHANDLED(p);
    706   EXPECT_UNHANDLED(::Test());
    707 }
    708 
    709 TEST(ArgVisitorTest, VisitInvalidArg) {
    710   Arg arg = Arg();
    711   arg.type = static_cast<Arg::Type>(Arg::NONE);
    712   EXPECT_ASSERT(TestVisitor().visit(arg), "invalid argument type");
    713 }
    714 
    715 // Tests fmt::internal::count_digits for integer type Int.
    716 template <typename Int>
    717 void test_count_digits() {
    718   for (Int i = 0; i < 10; ++i)
    719     EXPECT_EQ(1u, fmt::internal::count_digits(i));
    720   for (Int i = 1, n = 1,
    721       end = std::numeric_limits<Int>::max() / 10; n <= end; ++i) {
    722     n *= 10;
    723     EXPECT_EQ(i, fmt::internal::count_digits(n - 1));
    724     EXPECT_EQ(i + 1, fmt::internal::count_digits(n));
    725   }
    726 }
    727 
    728 TEST(UtilTest, StringRef) {
    729   // Test that StringRef::size() returns string length, not buffer size.
    730   char str[100] = "some string";
    731   EXPECT_EQ(std::strlen(str), StringRef(str).size());
    732   EXPECT_LT(std::strlen(str), sizeof(str));
    733 }
    734 
    735 // Check StringRef's comparison operator.
    736 template <template <typename> class Op>
    737 void CheckOp() {
    738   const char *inputs[] = {"foo", "fop", "fo"};
    739   std::size_t num_inputs = sizeof(inputs) / sizeof(*inputs);
    740   for (std::size_t i = 0; i < num_inputs; ++i) {
    741     for (std::size_t j = 0; j < num_inputs; ++j) {
    742       StringRef lhs(inputs[i]), rhs(inputs[j]);
    743       EXPECT_EQ(Op<int>()(lhs.compare(rhs), 0), Op<StringRef>()(lhs, rhs));
    744     }
    745   }
    746 }
    747 
    748 TEST(UtilTest, StringRefCompare) {
    749   EXPECT_EQ(0, StringRef("foo").compare(StringRef("foo")));
    750   EXPECT_GT(StringRef("fop").compare(StringRef("foo")), 0);
    751   EXPECT_LT(StringRef("foo").compare(StringRef("fop")), 0);
    752   EXPECT_GT(StringRef("foo").compare(StringRef("fo")), 0);
    753   EXPECT_LT(StringRef("fo").compare(StringRef("foo")), 0);
    754   CheckOp<std::equal_to>();
    755   CheckOp<std::not_equal_to>();
    756   CheckOp<std::less>();
    757   CheckOp<std::less_equal>();
    758   CheckOp<std::greater>();
    759   CheckOp<std::greater_equal>();
    760 }
    761 
    762 TEST(UtilTest, CountDigits) {
    763   test_count_digits<uint32_t>();
    764   test_count_digits<uint64_t>();
    765 }
    766 
    767 #ifdef _WIN32
    768 TEST(UtilTest, UTF16ToUTF8) {
    769   std::string s = "";
    770   fmt::internal::UTF16ToUTF8 u(L"\x0451\x0436\x0438\x043A");
    771   EXPECT_EQ(s, u.str());
    772   EXPECT_EQ(s.size(), u.size());
    773 }
    774 
    775 TEST(UtilTest, UTF8ToUTF16) {
    776   std::string s = "";
    777   fmt::internal::UTF8ToUTF16 u(s.c_str());
    778   EXPECT_EQ(L"\x043B\x043E\x0448\x0430\x0434\x043A\x0430", u.str());
    779   EXPECT_EQ(7, u.size());
    780 }
    781 
    782 template <typename Converter, typename Char>
    783 void check_utf_conversion_error(
    784         const char *message,
    785         fmt::BasicStringRef<Char> str = fmt::BasicStringRef<Char>(0, 0)) {
    786   fmt::MemoryWriter out;
    787   fmt::internal::format_windows_error(out, ERROR_INVALID_PARAMETER, message);
    788   fmt::SystemError error(0, "");
    789   try {
    790     (Converter)(str);
    791   } catch (const fmt::SystemError &e) {
    792     error = e;
    793   }
    794   EXPECT_EQ(ERROR_INVALID_PARAMETER, error.error_code());
    795   EXPECT_EQ(out.str(), error.what());
    796 }
    797 
    798 TEST(UtilTest, UTF16ToUTF8Error) {
    799   check_utf_conversion_error<fmt::internal::UTF16ToUTF8, wchar_t>(
    800       "cannot convert string from UTF-16 to UTF-8");
    801 }
    802 
    803 TEST(UtilTest, UTF8ToUTF16Error) {
    804   const char *message = "cannot convert string from UTF-8 to UTF-16";
    805   check_utf_conversion_error<fmt::internal::UTF8ToUTF16, char>(message);
    806   check_utf_conversion_error<fmt::internal::UTF8ToUTF16, char>(
    807     message, fmt::StringRef("foo", INT_MAX + 1u));
    808 }
    809 
    810 TEST(UtilTest, UTF16ToUTF8Convert) {
    811   fmt::internal::UTF16ToUTF8 u;
    812   EXPECT_EQ(ERROR_INVALID_PARAMETER, u.convert(fmt::WStringRef(0, 0)));
    813   EXPECT_EQ(ERROR_INVALID_PARAMETER,
    814             u.convert(fmt::WStringRef(L"foo", INT_MAX + 1u)));
    815 }
    816 #endif  // _WIN32
    817 
    818 typedef void (*FormatErrorMessage)(
    819         fmt::Writer &out, int error_code, StringRef message);
    820 
    821 template <typename Error>
    822 void check_throw_error(int error_code, FormatErrorMessage format) {
    823   fmt::SystemError error(0, "");
    824   try {
    825     throw Error(error_code, "test {}", "error");
    826   } catch (const fmt::SystemError &e) {
    827     error = e;
    828   }
    829   fmt::MemoryWriter message;
    830   format(message, error_code, "test error");
    831   EXPECT_EQ(message.str(), error.what());
    832   EXPECT_EQ(error_code, error.error_code());
    833 }
    834 
    835 TEST(UtilTest, FormatSystemError) {
    836   fmt::MemoryWriter message;
    837   fmt::format_system_error(message, EDOM, "test");
    838   EXPECT_EQ(fmt::format("test: {}", get_system_error(EDOM)), message.str());
    839   message.clear();
    840   fmt::format_system_error(
    841         message, EDOM, fmt::StringRef(0, std::numeric_limits<size_t>::max()));
    842   EXPECT_EQ(fmt::format("error {}", EDOM), message.str());
    843 }
    844 
    845 TEST(UtilTest, SystemError) {
    846   fmt::SystemError e(EDOM, "test");
    847   EXPECT_EQ(fmt::format("test: {}", get_system_error(EDOM)), e.what());
    848   EXPECT_EQ(EDOM, e.error_code());
    849   check_throw_error<fmt::SystemError>(EDOM, fmt::format_system_error);
    850 }
    851 
    852 TEST(UtilTest, ReportSystemError) {
    853   fmt::MemoryWriter out;
    854   fmt::format_system_error(out, EDOM, "test error");
    855   out << '\n';
    856   EXPECT_WRITE(stderr, fmt::report_system_error(EDOM, "test error"), out.str());
    857 }
    858 
    859 #ifdef _WIN32
    860 
    861 TEST(UtilTest, FormatWindowsError) {
    862   LPWSTR message = 0;
    863   FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
    864       FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0,
    865       ERROR_FILE_EXISTS, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    866       reinterpret_cast<LPWSTR>(&message), 0, 0);
    867   fmt::internal::UTF16ToUTF8 utf8_message(message);
    868   LocalFree(message);
    869   fmt::MemoryWriter actual_message;
    870   fmt::internal::format_windows_error(
    871       actual_message, ERROR_FILE_EXISTS, "test");
    872   EXPECT_EQ(fmt::format("test: {}", utf8_message.str()),
    873       actual_message.str());
    874   actual_message.clear();
    875   fmt::internal::format_windows_error(
    876         actual_message, ERROR_FILE_EXISTS,
    877         fmt::StringRef(0, std::numeric_limits<size_t>::max()));
    878   EXPECT_EQ(fmt::format("error {}", ERROR_FILE_EXISTS), actual_message.str());
    879 }
    880 
    881 TEST(UtilTest, FormatLongWindowsError) {
    882   LPWSTR message = 0;
    883   // this error code is not available on all Windows platforms and
    884   // Windows SDKs, so do not fail the test if the error string cannot
    885   // be retrieved.
    886   const int provisioning_not_allowed = 0x80284013L /*TBS_E_PROVISIONING_NOT_ALLOWED*/;
    887   if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
    888       FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0,
    889       provisioning_not_allowed, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    890       reinterpret_cast<LPWSTR>(&message), 0, 0) == 0) {
    891     return;
    892   }
    893   fmt::internal::UTF16ToUTF8 utf8_message(message);
    894   LocalFree(message);
    895   fmt::MemoryWriter actual_message;
    896   fmt::internal::format_windows_error(
    897       actual_message, provisioning_not_allowed, "test");
    898   EXPECT_EQ(fmt::format("test: {}", utf8_message.str()),
    899       actual_message.str());
    900 }
    901 
    902 TEST(UtilTest, WindowsError) {
    903   check_throw_error<fmt::WindowsError>(
    904       ERROR_FILE_EXISTS, fmt::internal::format_windows_error);
    905 }
    906 
    907 TEST(UtilTest, ReportWindowsError) {
    908   fmt::MemoryWriter out;
    909   fmt::internal::format_windows_error(out, ERROR_FILE_EXISTS, "test error");
    910   out << '\n';
    911   EXPECT_WRITE(stderr,
    912       fmt::report_windows_error(ERROR_FILE_EXISTS, "test error"), out.str());
    913 }
    914 
    915 #endif  // _WIN32
    916 
    917 enum TestEnum2 {};
    918 
    919 TEST(UtilTest, ConvertToInt) {
    920   EXPECT_TRUE(fmt::internal::ConvertToInt<char>::enable_conversion);
    921   EXPECT_FALSE(fmt::internal::ConvertToInt<const char *>::enable_conversion);
    922   EXPECT_TRUE(fmt::internal::ConvertToInt<TestEnum2>::value);
    923 }
    924 
    925 #if FMT_USE_ENUM_BASE
    926 enum TestEnum : char {TestValue};
    927 TEST(UtilTest, IsEnumConvertibleToInt) {
    928   EXPECT_TRUE(fmt::internal::ConvertToInt<TestEnum>::enable_conversion);
    929 }
    930 #endif
    931 
    932 template <typename T>
    933 bool check_enable_if(
    934     typename fmt::internal::EnableIf<sizeof(T) == sizeof(int), T>::type *) {
    935   return true;
    936 }
    937 
    938 template <typename T>
    939 bool check_enable_if(
    940     typename fmt::internal::EnableIf<sizeof(T) != sizeof(int), T>::type *) {
    941   return false;
    942 }
    943 
    944 TEST(UtilTest, EnableIf) {
    945   int i = 0;
    946   EXPECT_TRUE(check_enable_if<int>(&i));
    947   char c = 0;
    948   EXPECT_FALSE(check_enable_if<char>(&c));
    949 }
    950 
    951 TEST(UtilTest, Conditional) {
    952   int i = 0;
    953   fmt::internal::Conditional<true, int, char>::type *pi = &i;
    954   (void)pi;
    955   char c = 0;
    956   fmt::internal::Conditional<false, int, char>::type *pc = &c;
    957   (void)pc;
    958 }
    959 
    960 struct TestLConv {
    961   char *thousands_sep;
    962 };
    963 
    964 struct EmptyLConv {};
    965 
    966 TEST(UtilTest, ThousandsSep) {
    967   char foo[] = "foo";
    968   TestLConv lc = {foo};
    969   EXPECT_EQ("foo", fmt::internal::thousands_sep(&lc).to_string());
    970   EmptyLConv empty_lc;
    971   EXPECT_EQ("", fmt::internal::thousands_sep(&empty_lc));
    972 }
    973