11#include <forward_list>
17#include <system_error>
21#include <unordered_map>
22#include <unordered_set>
28extern std::unordered_map<std::type_index, std::function<std::string(std::any
const&)>> __any_stringer__;
41template <
typename char_t,
typename char_traits_t>
42inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::exception& value) {
43 return os <<
"exception: " << value.what();
46template <
typename char_t,
typename char_traits_t,
typename value_t>
47inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::optional<value_t>& value) {
48 if (!value.has_value())
return os <<
"(null)";
49 return os <<
'(' << value.value() <<
')';
52template <
typename char_t,
typename char_traits_t,
typename type1_t,
typename type2_t>
53inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::pair<type1_t, type2_t>& value) {
54 return os <<
'(' << value.first <<
',' <<
' ' << value.second <<
')';
57template<
typename char_t,
typename char_traits_t,
typename type_t,
unsigned n_t,
unsigned last_t>
58struct __xtd_console_tuple_printer {
59 static void print(std::basic_ostream<char_t, char_traits_t>& os,
const type_t& value) {
60 os << std::get<n_t>(value) <<
',' <<
' ';
61 __xtd_console_tuple_printer < char_t, char_traits_t, type_t, n_t + 1, last_t >::print(os, value);
65template<
typename char_t,
typename char_traits_t,
typename type_t,
unsigned n_t>
66struct __xtd_console_tuple_printer<char_t, char_traits_t, type_t, n_t, n_t> {
67 static void print(std::basic_ostream<char_t, char_traits_t>& os,
const type_t& value) {
68 os << std::get<n_t>(value);
72template <
typename char_t,
typename char_traits_t,
typename ... types_t>
73inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::tuple<types_t ...>& value) {
75 __xtd_console_tuple_printer < char_t, char_traits_t, std::tuple<types_t ...>, 0,
sizeof...(types_t) - 1 >::print(os, value);
88template <
typename char_t,
typename char_traits_t,
typename iterator_t>
89inline std::basic_ostream<char_t, char_traits_t>& __xtd_console_print_sequence_container(std::basic_ostream<char_t, char_traits_t>& os,
const iterator_t& begin,
const iterator_t& end) {
92 for (iterator_t it = begin; it !=
end; ++it) {
93 if (!first) os <<
',' <<
' ';
100template <
typename char_t,
typename char_traits_t,
typename type_t,
size_t size_t>
101inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::array<type_t, size_t>& values) {
102 return __xtd_console_print_sequence_container(os, values.begin(), values.end());
105template <
typename char_t,
typename char_traits_t,
typename type_t,
class allocator_t = std::allocator<type_t>>
106inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::deque<type_t, allocator_t>& values) {
107 return __xtd_console_print_sequence_container(os, values.begin(), values.end());
110template <
typename char_t,
typename char_traits_t,
typename type_t,
class allocator_t = std::allocator<type_t>>
111inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::forward_list<type_t, allocator_t>& values) {
112 return __xtd_console_print_sequence_container(os, values.begin(), values.end());
115template <
typename char_t,
typename char_traits_t,
typename type_t>
116inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::initializer_list<type_t>& values) {
117 return __xtd_console_print_sequence_container(os, values.begin(), values.end());
120template <
typename char_t,
typename char_traits_t,
typename type_t,
class allocator_t = std::allocator<type_t>>
121inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::list<type_t, allocator_t>& values) {
122 return __xtd_console_print_sequence_container(os, values.begin(), values.end());
125template <
typename char_t,
typename char_traits_t,
typename type_t>
126inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::valarray<type_t>& values) {
127 return __xtd_console_print_sequence_container(os, std::begin(values), std::end(values));
130template <
typename char_t,
typename char_traits_t,
typename type_t,
class allocator_t = std::allocator<type_t>>
131inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::vector<type_t, allocator_t>& values) {
132 return __xtd_console_print_sequence_container(os, values.begin(), values.end());
135template <
typename char_t,
typename char_traits_t,
typename iterator_t>
136inline std::basic_ostream<char_t, char_traits_t>& __xtd_console_print_associative_container(std::basic_ostream<char_t, char_traits_t>& os,
const iterator_t& begin,
const iterator_t& end) {
139 for (iterator_t it = begin; it !=
end; ++it) {
140 if (!first) os <<
", ";
147template <
typename char_t,
typename char_traits_t,
typename key_t,
typename value_t,
typename compare_t = std::less<key_t>,
typename allocator_t = std::allocator<std::pair<const key_t, value_t>>>
148inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::map<key_t, value_t, compare_t, allocator_t>& values) {
149 return __xtd_console_print_associative_container(os, values.begin(), values.end());
152template <
typename char_t,
typename char_traits_t,
typename key_t,
typename value_t,
typename compare_t = std::less<key_t>,
typename allocator_t = std::allocator<std::pair<const key_t, value_t>>>
153inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::multimap<key_t, value_t, compare_t, allocator_t>& values) {
154 return __xtd_console_print_associative_container(os, values.begin(), values.end());
157template <
typename char_t,
typename char_traits_t,
typename key_t,
typename compare_t = std::less<key_t>,
typename allocator_t = std::allocator<key_t>>
158inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::multiset<key_t, compare_t, allocator_t>& values) {
159 return __xtd_console_print_associative_container(os, values.begin(), values.end());
162template <
typename char_t,
typename char_traits_t,
typename key_t,
typename compare_t = std::less<key_t>,
typename allocator_t = std::allocator<key_t>>
163inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::set<key_t, compare_t, allocator_t>& values) {
164 return __xtd_console_print_associative_container(os, values.begin(), values.end());
167template <
typename char_t,
typename char_traits_t,
typename key_t,
typename value_t,
typename pred_t = std::equal_to<key_t>,
typename allocator_t = std::allocator<std::pair<const key_t, value_t>>>
168inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::unordered_map<key_t, value_t, pred_t, allocator_t>& values) {
169 return __xtd_console_print_associative_container(os, values.begin(), values.end());
172template <
typename char_t,
typename char_traits_t,
typename key_t,
typename value_t,
typename pred_t = std::equal_to<key_t>,
typename allocator_t = std::allocator<std::pair<const key_t, value_t>>>
173inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::unordered_multimap<key_t, value_t, pred_t, allocator_t>& values) {
174 return __xtd_console_print_associative_container(os, values.begin(), values.end());
177template <
typename char_t,
typename char_traits_t,
typename key_t,
typename pred_t = std::equal_to<key_t>,
typename allocator_t = std::allocator<key_t>>
178std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::unordered_multiset<key_t, pred_t, allocator_t>& values) {
179 return __xtd_console_print_associative_container(os, values.begin(), values.end());
182template <
typename char_t,
typename char_traits_t,
typename key_t,
typename pred_t = std::equal_to<key_t>,
typename allocator_t = std::allocator<key_t>>
183inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::unordered_set<key_t, pred_t, allocator_t>& values) {
184 return __xtd_console_print_associative_container(os, values.begin(), values.end());
187template <
typename char_t,
typename char_traits_t>
188inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::error_category& value) {
189 return os <<
"(" << value.name() <<
")";
192template <
typename char_t,
typename char_traits_t>
193inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os,
const std::error_code& value) {
194 return os <<
"(value = " << value.value() <<
"category= " << value.category().name() <<
")";
197template <
typename char_t,
typename char_traits_t>
198inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os, std::any value) {
199 auto it = __any_stringer__.find(std::type_index(value.type()));
200 if (it == __any_stringer__.cend())
return os <<
"(unregistered)";
201 return os << it->second(value);