7 #include <forward_list> 8 #include <initializer_list> 13 #if !__APPLE__ || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101401 20 #include <type_traits> 22 #include <unordered_map> 23 #include <unordered_set> 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 {};
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) {
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) {
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) {
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) ?
"-..." :
"") <<
">";
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>());
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>());
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>());
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) {
96 static void print(std::basic_ostream<Char, CharTraits>& os,
const Value*
const & value) {
99 static void print(std::basic_ostream<Char, CharTraits>& os,
const Value& value) {
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();
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())
119 __tunit_value_printer<Char, CharTraits, Value>::print(os, value.value());
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 <<
"\"";
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());
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());
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());
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 <<
"\"";
160 static void print(std::basic_ostream<Char, CharTraits>& os,
const char* & value) {
161 os <<
"\"" << value <<
"\"";
164 static void print(std::basic_ostream<Char, CharTraits>& os,
char value) {
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 <<
"\"";
175 static void print(std::basic_ostream<Char, CharTraits>& os,
const char* & value) {
176 os <<
"\"" << value <<
"\"";
179 static void print(std::basic_ostream<Char, CharTraits>& os,
char value) {
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) {
188 for (
size_t index = 0; value[index] != L
'\0'; index++)
189 __tunit_value_printer<Char, CharTraits, char16_t>::print(os, value[index]);
193 static void print(std::basic_ostream<Char, CharTraits>& os,
const char16_t* & value) {
195 for (
size_t index = 0; value[index] != L
'\0'; index++)
196 __tunit_value_printer<Char, CharTraits, char16_t>::print(os, value[index]);
200 static void print(std::basic_ostream<Char, CharTraits>& os, char16_t value) {
202 os << static_cast<char>(value);
204 os <<
"\\x" << std::hex << static_cast<int>(value);
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) {
213 for (
size_t index = 0; value[index] != L
'\0'; index++)
214 __tunit_value_printer<Char, CharTraits, char16_t>::print(os, value[index]);
218 static void print(std::basic_ostream<Char, CharTraits>& os,
const char16_t* & value) {
220 for (
size_t index = 0; value[index] != L
'\0'; index++)
221 __tunit_value_printer<Char, CharTraits, char16_t>::print(os, value[index]);
225 static void print(std::basic_ostream<Char, CharTraits>& os, char16_t value) {
227 os << static_cast<char>(value);
229 os <<
"\\x" << std::hex << static_cast<int>(value);
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) {
238 for (
size_t index = 0; value[index] != L
'\0'; index++)
239 __tunit_value_printer<Char, CharTraits, char32_t>::print(os, value[index]);
243 static void print(std::basic_ostream<Char, CharTraits>& os,
const char32_t* & value) {
245 for (
size_t index = 0; value[index] != L
'\0'; index++)
246 __tunit_value_printer<Char, CharTraits, char32_t>::print(os, value[index]);
250 static void print(std::basic_ostream<Char, CharTraits>& os, char32_t value) {
252 os << static_cast<char>(value);
254 os <<
"\\x" << std::hex << static_cast<int>(value);
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) {
263 for (
size_t index = 0; value[index] != L
'\0'; index++)
264 __tunit_value_printer<Char, CharTraits, char32_t>::print(os, value[index]);
268 static void print(std::basic_ostream<Char, CharTraits>& os,
const char32_t* & value) {
270 for (
size_t index = 0; value[index] != L
'\0'; index++)
271 __tunit_value_printer<Char, CharTraits, char32_t>::print(os, value[index]);
275 static void print(std::basic_ostream<Char, CharTraits>& os, char32_t value) {
277 os << static_cast<char>(value);
279 os <<
"\\x" << std::hex << static_cast<int>(value);
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) {
288 for (
size_t index = 0; value[index] != L
'\0'; index++)
289 __tunit_value_printer<Char, CharTraits, wchar_t>::print(os, value[index]);
293 static void print(std::basic_ostream<Char, CharTraits>& os,
const wchar_t* & value) {
295 for (
size_t index = 0; value[index] != L
'\0'; index++)
296 __tunit_value_printer<Char, CharTraits, wchar_t>::print(os, value[index]);
300 static void print(std::basic_ostream<Char, CharTraits>& os,
wchar_t value) {
302 os << static_cast<char>(value);
304 os <<
"\\x" << std::hex << static_cast<int>(value);
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) {
313 for (
size_t index = 0; value[index] != L
'\0'; index++)
314 __tunit_value_printer<Char, CharTraits, wchar_t>::print(os, value[index]);
318 static void print(std::basic_ostream<Char, CharTraits>& os,
const wchar_t* & value) {
320 for (
size_t index = 0; value[index] != L
'\0'; index++)
321 __tunit_value_printer<Char, CharTraits, wchar_t>::print(os, value[index]);
325 static void print(std::basic_ostream<Char, CharTraits>& os,
wchar_t value) {
327 os << static_cast<char>(value);
329 os <<
"\\x" << std::hex << static_cast<int>(value);
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) {
338 __tunit_value_printer<Char, CharTraits, Type1>::print(os, value.first);
340 __tunit_value_printer<Char, CharTraits, Type2>::print(os, value.second);
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));
350 __tuple_printer<Char, CharTraits, Type, N + 1, Last>::print(os, value);
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));
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) {
365 __tuple_printer<Char, CharTraits, std::tuple<Types ...>, 0,
sizeof...(Types) - 1>::print(os, value);
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<>&) {
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) {
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);
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());
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());
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());
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());
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());
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());
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) {
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);
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());
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());
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());
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());
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());
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());
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());
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());
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);
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);
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);
517 inline std::string __tunit_to_string(
const std::string& value) {
518 std::stringstream ss;
519 ss <<
"\"" << value <<
"\"";
523 inline std::string __tunit_to_string(
const char* value) {
524 std::stringstream ss;
525 ss <<
"\"" << value <<
"\"";
529 template <
typename TValue>
530 inline std::string __tunit_to_string(
const TValue& value) {
531 std::stringstream ss;
536 template <
typename TValue>
537 inline std::string __tunit_to_string(
const TValue* value) {
538 std::stringstream ss;