tunit - Reference Guide  1.0.0
Modern c++17 unit testing framework on Windows, macOS, Linux, iOS and android.
default_insert_basic_ostream_operator.h
Go to the documentation of this file.
1 #pragma once
4 #include <array>
5 #include <deque>
6 #include <exception>
7 #include <forward_list>
8 #include <initializer_list>
9 #include <iomanip>
10 #include <iostream>
11 #include <list>
12 #include <map>
13 #if !__APPLE__ || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101401
14 #include <optional>
15 #endif
16 #include <set>
17 #include <stdexcept>
18 #include <string>
19 #include <sstream>
20 #include <type_traits>
21 #include <tuple>
22 #include <unordered_map>
23 #include <unordered_set>
24 #include <utility>
25 #include <vector>
26 
28 template<class T> struct __tunit_is_printable : std::false_type {};
29 template<> struct __tunit_is_printable<bool> : std::true_type {};
30 template<> struct __tunit_is_printable<char> : std::true_type {};
31 template<> struct __tunit_is_printable<signed char> : std::true_type {};
32 template<> struct __tunit_is_printable<unsigned char> : std::true_type {};
33 template<> struct __tunit_is_printable<wchar_t> : std::true_type {};
34 template<> struct __tunit_is_printable<char16_t> : std::true_type {};
35 template<> struct __tunit_is_printable<char32_t> : std::true_type {};
36 template<> struct __tunit_is_printable<short> : std::true_type {};
37 template<> struct __tunit_is_printable<unsigned short> : std::true_type {};
38 template<> struct __tunit_is_printable<int> : std::true_type {};
39 template<> struct __tunit_is_printable<unsigned int> : std::true_type {};
40 template<> struct __tunit_is_printable<long> : std::true_type {};
41 template<> struct __tunit_is_printable<unsigned long> : std::true_type {};
42 template<> struct __tunit_is_printable<long long> : std::true_type {};
43 template<> struct __tunit_is_printable<unsigned long long> : std::true_type {};
44 template<> struct __tunit_is_printable<const char*> : std::true_type {};
45 template<> struct __tunit_is_printable<const wchar_t*> : std::true_type {};
46 template<> struct __tunit_is_printable<float> : std::true_type {};
47 template<> struct __tunit_is_printable<double> : std::true_type {};
48 template<> struct __tunit_is_printable<long double> : std::true_type {};
49 template<> struct __tunit_is_printable<std::string> : std::true_type {};
50 template<> struct __tunit_is_printable<std::wstring> : std::true_type {};
51 
52 template<typename Char, typename CharTraits, typename Value>
53 static void __tunit_print_value(std::basic_ostream<Char, CharTraits>& os, const Value& value, std::true_type) {
54  os.operator<<(value);
55 }
56 
57 template<typename Char, typename CharTraits, typename Value>
58 static void __tunit_print_value(std::basic_ostream<Char, CharTraits>& os, Value* value, std::true_type) {
59  os.operator<<(value);
60 }
61 
62 template<typename Char, typename CharTraits, typename Value>
63 static void __tunit_print_value(std::basic_ostream<Char, CharTraits>& os, const Value* value, std::true_type) {
64  os.operator<<(value);
65 }
66 
67 template<typename Char, typename CharTraits, typename Value>
68 static void __tunit_print_value(std::basic_ostream<Char, CharTraits>& os, const Value& value, std::false_type) {
69  size_t size = sizeof(value) > 32 ? 32 : sizeof(value);
70  os << size << "-byte object <";
71  for (size_t index = 0; index != size; index++)
72  os << (index != 0 ? (index % 2 == 0 ? " " : "-") : "") << std::hex << std::setiosflags(std::ios_base::uppercase) << std::setw(2) << std::setfill('0') << static_cast<int>(reinterpret_cast<const unsigned char*>(&value)[index]) << std::resetiosflags(std::ios_base::dec) << std::dec;
73  os << (size < sizeof(value) ? "-..." : "") << ">";
74 }
75 
76 template<typename Char, typename CharTraits, typename Value>
77 static void __print(std::basic_ostream<Char, CharTraits>& os, const Value& value) {
78  __tunit_print_value(os, value, __tunit_is_printable<Value>());
79 }
80 
81 template<typename Char, typename CharTraits, typename Value>
82 static void __print(std::basic_ostream<Char, CharTraits>& os, Value* value) {
83  __tunit_print_value(os, value, __tunit_is_printable<Value>());
84 }
85 
86 template<typename Char, typename CharTraits, typename Value>
87 static void __print(std::basic_ostream<Char, CharTraits>& os, const Value* value) {
88  __tunit_print_value(os, value, __tunit_is_printable<Value>());
89 }
90 
91 template <typename Char, typename CharTraits, typename Value>
92 struct __tunit_value_printer {
93  static void print(std::basic_ostream<Char, CharTraits>& os, const Value* & value) {
94  __print(os, value);
95  }
96  static void print(std::basic_ostream<Char, CharTraits>& os, const Value* const & value) {
97  __print(os, value);
98  }
99  static void print(std::basic_ostream<Char, CharTraits>& os, const Value& value) {
100  __print(os, value);
101  }
102 };
103 
104 template <typename Char, typename CharTraits>
105 struct __tunit_value_printer<Char, CharTraits, std::exception> {
106  static void print(std::basic_ostream<Char, CharTraits>& os, const std::exception& value) {
107  os << "exception: " << value.what();
108  }
109 };
110 
111 #if !__APPLE__ || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101401
112 template <typename Char, typename CharTraits, typename Value>
113 struct __tunit_value_printer<Char, CharTraits, std::optional<Value>> {
114  static void print(std::basic_ostream<Char, CharTraits>& os, const std::optional<Value>& value) {
115  if (!value.has_value())
116  os << "(null)";
117  else {
118  os << "(";
119  __tunit_value_printer<Char, CharTraits, Value>::print(os, value.value());
120  os << ")";
121  }
122  }
123 };
124 #endif
125 
126 template <typename Char, typename CharTraits>
127 struct __tunit_value_printer<Char, CharTraits, std::string> {
128  static void print(std::basic_ostream<Char, CharTraits>& os, const std::string& value) {
129  os << "\"" << value << "\"";
130  }
131 };
132 
133 template <typename Char, typename CharTraits>
134 struct __tunit_value_printer<Char, CharTraits, std::u16string> {
135  static void print(std::basic_ostream<Char, CharTraits>& os, const std::u16string& value) {
136  __tunit_value_printer<Char, CharTraits, char16_t>::print(os, value.c_str());
137  }
138 };
139 
140 template <typename Char, typename CharTraits>
141 struct __tunit_value_printer<Char, CharTraits, std::u32string> {
142  static void print(std::basic_ostream<Char, CharTraits>& os, const std::u32string& value) {
143  __tunit_value_printer<Char, CharTraits, char32_t>::print(os, value.c_str());
144  }
145 };
146 
147 template <typename Char, typename CharTraits>
148 struct __tunit_value_printer<Char, CharTraits, std::wstring> {
149  static void print(std::basic_ostream<Char, CharTraits>& os, const std::wstring& value) {
150  __tunit_value_printer<Char, CharTraits, wchar_t>::print(os, value.c_str());
151  }
152 };
153 
154 template <typename Char, typename CharTraits>
155 struct __tunit_value_printer<Char, CharTraits, const char*> {
156  static void print(std::basic_ostream<Char, CharTraits>& os, const char* const & value) {
157  os << "\"" << value << "\"";
158  }
159 
160  static void print(std::basic_ostream<Char, CharTraits>& os, const char* & value) {
161  os << "\"" << value << "\"";
162  }
163 
164  static void print(std::basic_ostream<Char, CharTraits>& os, char value) {
165  os << value;
166  }
167 };
168 
169 template <typename Char, typename CharTraits>
170 struct __tunit_value_printer<Char, CharTraits, char> {
171  static void print(std::basic_ostream<Char, CharTraits>& os, const char* const & value) {
172  os << "\"" << value << "\"";
173  }
174 
175  static void print(std::basic_ostream<Char, CharTraits>& os, const char* & value) {
176  os << "\"" << value << "\"";
177  }
178 
179  static void print(std::basic_ostream<Char, CharTraits>& os, char value) {
180  os << value;
181  }
182 };
183 
184 template <typename Char, typename CharTraits>
185 struct __tunit_value_printer<Char, CharTraits, const char16_t*> {
186  static void print(std::basic_ostream<Char, CharTraits>& os, const char16_t* const & value) {
187  os << "\"";
188  for (size_t index = 0; value[index] != L'\0'; index++)
189  __tunit_value_printer<Char, CharTraits, char16_t>::print(os, value[index]);
190  os << "\"";
191  }
192 
193  static void print(std::basic_ostream<Char, CharTraits>& os, const char16_t* & value) {
194  os << "\"";
195  for (size_t index = 0; value[index] != L'\0'; index++)
196  __tunit_value_printer<Char, CharTraits, char16_t>::print(os, value[index]);
197  os << "\"";
198  }
199 
200  static void print(std::basic_ostream<Char, CharTraits>& os, char16_t value) {
201  if (value <= 0xFF)
202  os << static_cast<char>(value);
203  else {
204  os << "\\x" << std::hex << static_cast<int>(value);
205  }
206  }
207 };
208 
209 template <typename Char, typename CharTraits>
210 struct __tunit_value_printer<Char, CharTraits, char16_t> {
211  static void print(std::basic_ostream<Char, CharTraits>& os, const char16_t* const & value) {
212  os << "\"";
213  for (size_t index = 0; value[index] != L'\0'; index++)
214  __tunit_value_printer<Char, CharTraits, char16_t>::print(os, value[index]);
215  os << "\"";
216  }
217 
218  static void print(std::basic_ostream<Char, CharTraits>& os, const char16_t* & value) {
219  os << "\"";
220  for (size_t index = 0; value[index] != L'\0'; index++)
221  __tunit_value_printer<Char, CharTraits, char16_t>::print(os, value[index]);
222  os << "\"";
223  }
224 
225  static void print(std::basic_ostream<Char, CharTraits>& os, char16_t value) {
226  if (value <= 0xFF)
227  os << static_cast<char>(value);
228  else {
229  os << "\\x" << std::hex << static_cast<int>(value);
230  }
231  }
232 };
233 
234 template <typename Char, typename CharTraits>
235 struct __tunit_value_printer<Char, CharTraits, const char32_t*> {
236  static void print(std::basic_ostream<Char, CharTraits>& os, const char32_t* const & value) {
237  os << "\"";
238  for (size_t index = 0; value[index] != L'\0'; index++)
239  __tunit_value_printer<Char, CharTraits, char32_t>::print(os, value[index]);
240  os << "\"";
241  }
242 
243  static void print(std::basic_ostream<Char, CharTraits>& os, const char32_t* & value) {
244  os << "\"";
245  for (size_t index = 0; value[index] != L'\0'; index++)
246  __tunit_value_printer<Char, CharTraits, char32_t>::print(os, value[index]);
247  os << "\"";
248  }
249 
250  static void print(std::basic_ostream<Char, CharTraits>& os, char32_t value) {
251  if (value <= 0xFF)
252  os << static_cast<char>(value);
253  else {
254  os << "\\x" << std::hex << static_cast<int>(value);
255  }
256  }
257 };
258 
259 template <typename Char, typename CharTraits>
260 struct __tunit_value_printer<Char, CharTraits, char32_t> {
261  static void print(std::basic_ostream<Char, CharTraits>& os, const char32_t* const & value) {
262  os << "\"";
263  for (size_t index = 0; value[index] != L'\0'; index++)
264  __tunit_value_printer<Char, CharTraits, char32_t>::print(os, value[index]);
265  os << "\"";
266  }
267 
268  static void print(std::basic_ostream<Char, CharTraits>& os, const char32_t* & value) {
269  os << "\"";
270  for (size_t index = 0; value[index] != L'\0'; index++)
271  __tunit_value_printer<Char, CharTraits, char32_t>::print(os, value[index]);
272  os << "\"";
273  }
274 
275  static void print(std::basic_ostream<Char, CharTraits>& os, char32_t value) {
276  if (value <= 0xFF)
277  os << static_cast<char>(value);
278  else {
279  os << "\\x" << std::hex << static_cast<int>(value);
280  }
281  }
282 };
283 
284 template <typename Char, typename CharTraits>
285 struct __tunit_value_printer<Char, CharTraits, const wchar_t*> {
286  static void print(std::basic_ostream<Char, CharTraits>& os, const wchar_t* const & value) {
287  os << "\"";
288  for (size_t index = 0; value[index] != L'\0'; index++)
289  __tunit_value_printer<Char, CharTraits, wchar_t>::print(os, value[index]);
290  os << "\"";
291  }
292 
293  static void print(std::basic_ostream<Char, CharTraits>& os, const wchar_t* & value) {
294  os << "\"";
295  for (size_t index = 0; value[index] != L'\0'; index++)
296  __tunit_value_printer<Char, CharTraits, wchar_t>::print(os, value[index]);
297  os << "\"";
298  }
299 
300  static void print(std::basic_ostream<Char, CharTraits>& os, wchar_t value) {
301  if (value <= 0xFF)
302  os << static_cast<char>(value);
303  else {
304  os << "\\x" << std::hex << static_cast<int>(value);
305  }
306  }
307 };
308 
309 template <typename Char, typename CharTraits>
310 struct __tunit_value_printer<Char, CharTraits, wchar_t> {
311  static void print(std::basic_ostream<Char, CharTraits>& os, const wchar_t* const & value) {
312  os << "\"";
313  for (size_t index = 0; value[index] != L'\0'; index++)
314  __tunit_value_printer<Char, CharTraits, wchar_t>::print(os, value[index]);
315  os << "\"";
316  }
317 
318  static void print(std::basic_ostream<Char, CharTraits>& os, const wchar_t* & value) {
319  os << "\"";
320  for (size_t index = 0; value[index] != L'\0'; index++)
321  __tunit_value_printer<Char, CharTraits, wchar_t>::print(os, value[index]);
322  os << "\"";
323  }
324 
325  static void print(std::basic_ostream<Char, CharTraits>& os, wchar_t value) {
326  if (value <= 0xFF)
327  os << static_cast<char>(value);
328  else {
329  os << "\\x" << std::hex << static_cast<int>(value);
330  }
331  }
332 };
333 
334 template <typename Char, typename CharTraits, typename Type1, typename Type2>
335 struct __tunit_value_printer<Char, CharTraits, std::pair<Type1, Type2>> {
336  static void print(std::basic_ostream<Char, CharTraits>& os, const std::pair<Type1, Type2>& value) {
337  os << "(";
338  __tunit_value_printer<Char, CharTraits, Type1>::print(os, value.first);
339  os << ", ";
340  __tunit_value_printer<Char, CharTraits, Type2>::print(os, value.second);
341  os << ")";
342  }
343 };
344 
345 template<typename Char, typename CharTraits, typename Type, unsigned N, unsigned Last>
346 struct __tuple_printer {
347  static void print(std::basic_ostream<Char, CharTraits>& os, const Type& value) {
348  __tunit_value_printer<Char, CharTraits, typename std::tuple_element<N, Type>::type>::print(os, std::get<N>(value));
349  os << ", ";
350  __tuple_printer<Char, CharTraits, Type, N + 1, Last>::print(os, value);
351  }
352 };
353 
354 template<typename Char, typename CharTraits, typename Type, unsigned N>
355 struct __tuple_printer<Char, CharTraits, Type, N, N> {
356  static void print(std::basic_ostream<Char, CharTraits>& os, const Type& value) {
357  __tunit_value_printer<Char, CharTraits, typename std::tuple_element<N, Type>::type>::print(os, std::get<N>(value));
358  }
359 };
360 
361 template <typename Char, typename CharTraits, typename ... Types>
362 struct __tunit_value_printer<Char, CharTraits, std::tuple<Types ...>> {
363  static void print(std::basic_ostream<Char, CharTraits>& os, const std::tuple<Types ...>& value) {
364  os << "(";
365  __tuple_printer<Char, CharTraits, std::tuple<Types ...>, 0, sizeof...(Types) - 1>::print(os, value);
366  os << ")";
367  }
368 };
369 
370 template <typename Char, typename CharTraits>
371 struct __tunit_value_printer<Char, CharTraits, std::tuple<>> {
372  static void print(std::basic_ostream<Char, CharTraits>& os, const std::tuple<>&) {
373  os << "()";
374  }
375 };
376 
377 template <typename Char, typename CharTraits, typename Iterator>
378 std::basic_ostream<Char, CharTraits>& __print_sequence_container(std::basic_ostream<Char, CharTraits>& os, const Iterator& begin, const Iterator& end) {
379  os << "[";
380  bool first = true;
381  for (Iterator it = begin; it != end; ++it) {
382  if (!first) os << ", ";
383  __tunit_value_printer<Char, CharTraits, typename std::iterator_traits<Iterator>::value_type>::print(os, *it);
384  first = false;
385  }
386  return os << "]";
387 }
388 
389 template <typename Char, typename CharTraits, typename Value, size_t Size>
390 struct __tunit_value_printer<Char, CharTraits, std::array<Value, Size>> {
391  static void print(std::basic_ostream<Char, CharTraits>& os, const std::array<Value, Size>& values) {
392  __print_sequence_container(os, values.begin(), values.end());
393  }
394 };
395 
396 template <typename Char, typename CharTraits, typename Value>
397 struct __tunit_value_printer<Char, CharTraits, std::deque<Value>> {
398  static void print(std::basic_ostream<Char, CharTraits>& os, const std::deque<Value>& values) {
399  __print_sequence_container(os, values.begin(), values.end());
400  }
401 };
402 
403 template <typename Char, typename CharTraits, typename Value>
404 struct __tunit_value_printer<Char, CharTraits, std::forward_list<Value>> {
405  static void print(std::basic_ostream<Char, CharTraits>& os, const std::forward_list<Value>& values) {
406  __print_sequence_container(os, values.begin(), values.end());
407  }
408 };
409 
410 template <typename Char, typename CharTraits, typename Value>
411 struct __tunit_value_printer<Char, CharTraits, std::list<Value>> {
412  static void print(std::basic_ostream<Char, CharTraits>& os, const std::list<Value>& values) {
413  __print_sequence_container(os, values.begin(), values.end());
414  }
415 };
416 
417 template <typename Char, typename CharTraits, typename Value>
418 struct __tunit_value_printer<Char, CharTraits, std::initializer_list<Value>> {
419  static void print(std::basic_ostream<Char, CharTraits>& os, const std::initializer_list<Value>& values) {
420  __print_sequence_container(os, values.begin(), values.end());
421  }
422 };
423 
424 template <typename Char, typename CharTraits, typename Value>
425 struct __tunit_value_printer<Char, CharTraits, std::vector<Value>> {
426  static void print(std::basic_ostream<Char, CharTraits>& os, const std::vector<Value>& values) {
427  __print_sequence_container(os, values.begin(), values.end());
428  }
429 };
430 
431 template <typename Char, typename CharTraits, typename Iterator>
432 std::basic_ostream<Char, CharTraits>& __print_associative_container(std::basic_ostream<Char, CharTraits>& os, const Iterator& begin, const Iterator& end) {
433  os << "{";
434  bool first = true;
435  for (Iterator it = begin; it != end; ++it) {
436  if (!first) os << ", ";
437  __tunit_value_printer<Char, CharTraits, typename std::iterator_traits<Iterator>::value_type>::print(os, *it);
438  first = false;
439  }
440  return os << "}";
441 }
442 
443 template <typename Char, typename CharTraits, typename Key, typename Value>
444 struct __tunit_value_printer<Char, CharTraits, std::map<Key, Value>> {
445  static void print(std::basic_ostream<Char, CharTraits>& os, const std::map<Key, Value>& values) {
446  __print_associative_container(os, values.begin(), values.end());
447  }
448 };
449 
450 template <typename Char, typename CharTraits, typename Key, typename Value>
451 struct __tunit_value_printer<Char, CharTraits, std::multimap<Key, Value>> {
452  static void print(std::basic_ostream<Char, CharTraits>& os, const std::multimap<Key, Value>& values) {
453  __print_associative_container(os, values.begin(), values.end());
454  }
455 };
456 
457 template <typename Char, typename CharTraits, typename Value>
458 struct __tunit_value_printer<Char, CharTraits, std::multiset<Value>> {
459  static void print(std::basic_ostream<Char, CharTraits>& os, const std::multiset<Value>& values) {
460  __print_associative_container(os, values.begin(), values.end());
461  }
462 };
463 
464 template <typename Char, typename CharTraits, typename Value>
465 struct __tunit_value_printer<Char, CharTraits, std::set<Value>> {
466  static void print(std::basic_ostream<Char, CharTraits>& os, const std::set<Value>& values) {
467  __print_associative_container(os, values.begin(), values.end());
468  }
469 };
470 
471 template <typename Char, typename CharTraits, typename Key, typename Value>
472 struct __tunit_value_printer<Char, CharTraits, std::unordered_map<Key, Value>> {
473  static void print(std::basic_ostream<Char, CharTraits>& os, const std::unordered_map<Key, Value>& values) {
474  __print_associative_container(os, values.begin(), values.end());
475  }
476 };
477 
478 template <typename Char, typename CharTraits, typename Key, typename Value>
479 struct __tunit_value_printer<Char, CharTraits, std::unordered_multimap<Key, Value>> {
480  static void print(std::basic_ostream<Char, CharTraits>& os, const std::unordered_multimap<Key, Value>& values) {
481  __print_associative_container(os, values.begin(), values.end());
482  }
483 };
484 
485 template <typename Char, typename CharTraits, typename Value>
486 struct __tunit_value_printer<Char, CharTraits, std::unordered_multiset<Value>> {
487  static void print(std::basic_ostream<Char, CharTraits>& os, const std::unordered_multiset<Value>& values) {
488  __print_associative_container(os, values.begin(), values.end());
489  }
490 };
491 
492 template <typename Char, typename CharTraits, typename Value>
493 struct __tunit_value_printer<Char, CharTraits, std::unordered_set<Value>> {
494  static void print(std::basic_ostream<Char, CharTraits>& os, const std::unordered_set<Value>& values) {
495  __print_associative_container(os, values.begin(), values.end());
496  }
497 };
498 
499 template <typename Char, typename CharTraits, typename Type>
500 std::basic_ostream<Char, CharTraits>& operator<<(std::basic_ostream<Char, CharTraits>& os, const Type& value) {
501  __tunit_value_printer<Char, CharTraits, Type>::print(os, value);
502  return os;
503 }
504 
505 template <typename Char, typename CharTraits, typename Type>
506 std::basic_ostream<Char, CharTraits>& operator<<(std::basic_ostream<Char, CharTraits>& os, const Type* value) {
507  __tunit_value_printer<Char, CharTraits, Type>::print(os, value);
508  return os;
509 }
510 
511 template <typename Char, typename CharTraits, typename Type>
512 std::basic_ostream<Char, CharTraits>& operator<<(std::basic_ostream<Char, CharTraits>& os, Type* value) {
513  __tunit_value_printer<Char, CharTraits, Type>::print(os, value);
514  return os;
515 }
516 
517 inline std::string __tunit_to_string(const std::string& value) {
518  std::stringstream ss;
519  ss << "\"" << value << "\"";
520  return ss.str();
521 }
522 
523 inline std::string __tunit_to_string(const char* value) {
524  std::stringstream ss;
525  ss << "\"" << value << "\"";
526  return ss.str();
527 }
528 
529 template <typename TValue>
530 inline std::string __tunit_to_string(const TValue& value) {
531  std::stringstream ss;
532  ss << value;
533  return ss.str();
534 }
535 
536 template <typename TValue>
537 inline std::string __tunit_to_string(const TValue* value) {
538  std::stringstream ss;
539  ss << value;
540  return ss.str();
541 }