Skip to content

Commit ef8740e

Browse files
committed
Review generic stream output operators
1 parent 2689a54 commit ef8740e

File tree

1 file changed

+77
-60
lines changed

1 file changed

+77
-60
lines changed

src/xtd.core/include/xtd/generic_stream_output.hpp

Lines changed: 77 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <unordered_set>
2424
#include <utility>
2525
#include <valarray>
26+
#include <variant>
2627
#include <vector>
2728

2829
/// @cond
@@ -34,37 +35,45 @@ inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream
3435
}
3536

3637
template<class char_t, class char_traits_t, class value_t>
38+
requires xtd::stream_insertable<value_t>
3739
inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os, const std::optional<value_t>& value) {
38-
if constexpr(xtd::stream_insertable<value_t>) {
39-
if (!value.has_value()) return os << "(null)";
40-
return os << '(' << value.value() << ')';
41-
} else return os << "(unregistered)";
40+
if (!value.has_value()) return os << "(null)";
41+
return os << '(' << value.value() << ')';
42+
}
43+
44+
template<class char_t, class char_traits_t, class value_t>
45+
requires (!xtd::stream_insertable<value_t>)
46+
inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os, const std::optional<value_t>&) {
47+
return os << "(unregistered)";
4248
}
4349

4450
template<class char_t, class char_traits_t, class type1_t, class type2_t>
51+
requires xtd::stream_insertable<type1_t> && xtd::stream_insertable<type2_t>
4552
inline 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) {
4653
return os << '(' << value.first << ',' << ' ' << value.second << ')';
4754
}
4855

56+
template<class char_t, class char_traits_t, class type1_t, class type2_t>
57+
requires (!xtd::stream_insertable<type1_t> || !xtd::stream_insertable<type2_t>)
58+
inline 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) {
59+
return os << "(, )";
60+
}
61+
4962
template<class char_t, class char_traits_t, class type_t, unsigned n_t, unsigned last_t>
63+
requires xtd::stream_insertable<decltype(std::get<n_t>(std::declval<type_t>()))>
5064
struct __xtd_console_tuple_printer {
51-
static void print(std::basic_ostream < char_t, char_traits_t >& os, const type_t& value) {
52-
os << std::get < n_t > (value) << ',' << ' ';
53-
__xtd_console_tuple_printer < char_t, char_traits_t, type_t, n_t + 1, last_t >::print(os, value);
65+
static void print(std::basic_ostream<char_t, char_traits_t>& os, const type_t& value) {
66+
os << std::get<n_t>(value);
67+
if constexpr (n_t < last_t) os << ", ";
68+
if constexpr (n_t < last_t)
69+
__xtd_console_tuple_printer<char_t, char_traits_t, type_t, n_t + 1, last_t>::print(os, value);
5470
}
5571
};
5672

57-
template < class char_t, class char_traits_t, class type_t, unsigned n_t >
58-
struct __xtd_console_tuple_printer < char_t, char_traits_t, type_t, n_t, n_t > {
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-
}
62-
};
63-
64-
template < class char_t, class char_traits_t, class ...types_t >
65-
inline std::basic_ostream < char_t, char_traits_t >& operator <<(std::basic_ostream < char_t, char_traits_t >& os, const std::tuple < types_t ... >& value) {
73+
template<class char_t, class char_traits_t, class ...types_t>
74+
inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os, const std::tuple<types_t ... >& value) {
6675
os << '(';
67-
__xtd_console_tuple_printer < char_t, char_traits_t, std::tuple < types_t ...>, 0, sizeof...(types_t) - 1 >::print(os, value);
76+
__xtd_console_tuple_printer<char_t, char_traits_t, std::tuple<types_t...>, 0, sizeof...(types_t) - 1>::print(os, value);
6877
return os << ')';
6978
}
7079

@@ -77,112 +86,120 @@ inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream
7786
return os;
7887
}*/
7988

80-
template < class char_t, class char_traits_t, class iterator_t >
81-
inline 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) {
82-
os << '[';
83-
bool first = true;
89+
template<class char_t, class char_traits_t, class iterator_t>
90+
requires xtd::stream_insertable<std::iter_value_t<iterator_t>>
91+
inline void __xtd_console_print_container(std::basic_ostream<char_t, char_traits_t>& os, const iterator_t& begin, const iterator_t& end) {
8492
for (iterator_t it = begin; it != end; ++it) {
85-
if (!first) os << ',' << ' ';
93+
if (it != begin) os << ',' << ' ';
8694
os << *it;
87-
first = false;
8895
}
96+
}
97+
98+
template<class char_t, class char_traits_t, class iterator_t>
99+
requires (!xtd::stream_insertable<std::iter_value_t<iterator_t>>)
100+
inline void __xtd_console_print_container(std::basic_ostream<char_t, char_traits_t>& os, const iterator_t& begin, const iterator_t& end) {
101+
for (iterator_t it = begin; it != end; ++it) {
102+
if (it != begin) os << ',' << ' ';
103+
os << " ";
104+
}
105+
}
106+
107+
template<class char_t, class char_traits_t, class iterator_t>
108+
inline 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) {
109+
os << '[';
110+
__xtd_console_print_container(os, begin, end);
89111
return os << ']';
90112
}
91113

92-
template < class char_t, class char_traits_t, class type_t, size_t size_t >
93-
inline 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) {
114+
template<class char_t, class char_traits_t, class type_t, size_t size_t>
115+
inline 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) {
94116
return __xtd_console_print_sequence_container(os, values.begin(), values.end());
95117
}
96118

97-
template < class char_t, class char_traits_t, class type_t, class allocator_t = std::allocator < type_t>>
98-
inline 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) {
119+
template<class char_t, class char_traits_t, class type_t, class allocator_t = std::allocator < type_t>>
120+
inline 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) {
99121
return __xtd_console_print_sequence_container(os, values.begin(), values.end());
100122
}
101123

102-
template < class char_t, class char_traits_t, class type_t, class allocator_t = std::allocator < type_t>>
103-
inline 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) {
124+
template<class char_t, class char_traits_t, class type_t, class allocator_t = std::allocator<type_t>>
125+
inline 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) {
104126
return __xtd_console_print_sequence_container(os, values.begin(), values.end());
105127
}
106128

107-
template < class char_t, class char_traits_t, class type_t >
108-
inline 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) {
129+
template<class char_t, class char_traits_t, class type_t>
130+
inline 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) {
109131
return __xtd_console_print_sequence_container(os, values.begin(), values.end());
110132
}
111133

112-
template < class char_t, class char_traits_t, class type_t, class allocator_t = std::allocator < type_t>>
113-
inline 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) {
134+
template<class char_t, class char_traits_t, class type_t, class allocator_t = std::allocator<type_t>>
135+
inline 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) {
114136
return __xtd_console_print_sequence_container(os, values.begin(), values.end());
115137
}
116138

117-
template < class char_t, class char_traits_t, class type_t >
118-
inline std::basic_ostream < char_t, char_traits_t >& operator <<(std::basic_ostream < char_t, char_traits_t >& os, const std::valarray < type_t >& values) {
139+
template<class char_t, class char_traits_t, class type_t>
140+
inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os, const std::valarray<type_t>& values) {
119141
return __xtd_console_print_sequence_container(os, std::begin(values), std::end(values));
120142
}
121143

122-
template < class char_t, class char_traits_t, class type_t, class allocator_t = std::allocator < type_t>>
123-
inline 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) {
144+
template<class char_t, class char_traits_t, class type_t, class allocator_t = std::allocator<type_t>>
145+
inline 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) {
124146
return __xtd_console_print_sequence_container(os, values.begin(), values.end());
125147
}
126148

127-
template < class char_t, class char_traits_t, class iterator_t >
128-
inline 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) {
129-
os << "{";
130-
bool first = true;
131-
for (iterator_t it = begin; it != end; ++it) {
132-
if (!first) os << ", ";
133-
os << *it;
134-
first = false;
135-
}
136-
return os << "}";
149+
template<class char_t, class char_traits_t, class iterator_t>
150+
inline 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) {
151+
os << '{';
152+
__xtd_console_print_container(os, begin, end);
153+
return os << '}';
137154
}
138155

139-
template < class char_t, class char_traits_t, class key_t, class value_t, class compare_t = std::less < key_t>, class allocator_t = std::allocator<std::pair<const key_t, value_t >>>
140-
inline 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) {
156+
template<class char_t, class char_traits_t, class key_t, class value_t, class compare_t = std::less <key_t>, class allocator_t = std::allocator<std::pair<const key_t, value_t>>>
157+
inline 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) {
141158
return __xtd_console_print_associative_container(os, values.begin(), values.end());
142159
}
143160

144-
template < class char_t, class char_traits_t, class key_t, class value_t, class compare_t = std::less < key_t>, class allocator_t = std::allocator<std::pair<const key_t, value_t >>>
145-
inline 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) {
161+
template<class char_t, class char_traits_t, class key_t, class value_t, class compare_t = std::less <key_t>, class allocator_t = std::allocator<std::pair<const key_t, value_t>>>
162+
inline 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) {
146163
return __xtd_console_print_associative_container(os, values.begin(), values.end());
147164
}
148165

149-
template < class char_t, class char_traits_t, class key_t, class compare_t = std::less < key_t>, class allocator_t = std::allocator<key_t >>
150-
inline 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) {
166+
template<class char_t, class char_traits_t, class key_t, class compare_t = std::less <key_t>, class allocator_t = std::allocator<key_t>>
167+
inline 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) {
151168
return __xtd_console_print_associative_container(os, values.begin(), values.end());
152169
}
153170

154171
template < class char_t, class char_traits_t, class key_t, class compare_t = std::less < key_t>, class allocator_t = std::allocator<key_t >>
155-
inline 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) {
172+
inline 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) {
156173
return __xtd_console_print_associative_container(os, values.begin(), values.end());
157174
}
158175

159176
template < class char_t, class char_traits_t, class key_t, class value_t, class pred_t = std::equal_to < key_t>, class allocator_t = std::allocator<std::pair<const key_t, value_t >>>
160-
inline 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) {
177+
inline 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) {
161178
return __xtd_console_print_associative_container(os, values.begin(), values.end());
162179
}
163180

164181
template < class char_t, class char_traits_t, class key_t, class value_t, class pred_t = std::equal_to < key_t>, class allocator_t = std::allocator<std::pair<const key_t, value_t >>>
165-
inline 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) {
182+
inline 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) {
166183
return __xtd_console_print_associative_container(os, values.begin(), values.end());
167184
}
168185

169186
template < class char_t, class char_traits_t, class key_t, class pred_t = std::equal_to < key_t>, class allocator_t = std::allocator<key_t >>
170-
std::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) {
187+
std::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) {
171188
return __xtd_console_print_associative_container(os, values.begin(), values.end());
172189
}
173190

174191
template < class char_t, class char_traits_t, class key_t, class pred_t = std::equal_to < key_t>, class allocator_t = std::allocator<key_t >>
175-
inline 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) {
192+
inline 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) {
176193
return __xtd_console_print_associative_container(os, values.begin(), values.end());
177194
}
178195

179196
template < class char_t, class char_traits_t >
180-
inline std::basic_ostream < char_t, char_traits_t >& operator <<(std::basic_ostream < char_t, char_traits_t >& os, const std::error_category& value) {
197+
inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os, const std::error_category& value) {
181198
return os << "(" << value.name() << ")";
182199
}
183200

184201
template < class char_t, class char_traits_t >
185-
inline std::basic_ostream < char_t, char_traits_t >& operator <<(std::basic_ostream < char_t, char_traits_t >& os, const std::error_code& value) {
202+
inline std::basic_ostream<char_t, char_traits_t>& operator <<(std::basic_ostream<char_t, char_traits_t>& os, const std::error_code& value) {
186203
return os << "(value = " << value.value() << "category= " << value.category().name() << ")";
187204
}
188205

0 commit comments

Comments
 (0)