Console Library 8.0.0
A header-only library that makes C++ simple
Loading...
Searching...
No Matches
output.h
Go to the documentation of this file.
1
12
13/*
14Copyright (c) 2026 MrXie1109
15
16Permission is hereby granted, free of charge, to any person obtaining a copy
17of this software and associated documentation files (the "Software"), to deal
18in the Software without restriction, including without limitation the rights
19to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20copies of the Software, and to permit persons to whom the Software is
21furnished to do so, subject to the following conditions:
22
23The above copyright notice and this permission notice shall be included in all
24copies or substantial portions of the Software.
25
26THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32SOFTWARE.
33*/
34
35#pragma once
36#include <cstddef>
37#include <iterator>
38
39#include "../core/sfinae.h"
40#include "../text/repr.h"
41
42namespace console {
52 template <class CharT, class Traits, class StrOrCharType>
53 typename std::enable_if<
56 put(std::basic_ostream<CharT, Traits> &os, StrOrCharType &&value) {
57 to_stream(value, os);
58 }
59
69 template <class CharT, class Traits, class OtherType>
70 typename std::enable_if<
71 !is_string<typename std::decay<OtherType>::type>::value
72 && !is_char<typename std::decay<OtherType>::type>::value>::type
73 put(std::basic_ostream<CharT, Traits> &os, OtherType &&value) {
74 repr(value, os);
75 }
76
82
92 template <class CharT, class Traits, class Cont>
93 inline std::basic_ostream<CharT, Traits> &cont_print_sequence(
94 std::basic_ostream<CharT, Traits> &os, const Cont &cont) {
95 if (begin(cont) == end(cont)) return os << CharT('[') << CharT(']');
96 auto it = begin(cont);
97 os << CharT('[');
98 repr(*it, os);
99 while (++it != end(cont)) {
100 os << CharT(','), os << CharT(' ');
101 repr(*it, os);
102 }
103 return os << CharT(']');
104 }
105
115 template <class CharT, class Traits, class Cont>
116 inline std::basic_ostream<CharT, Traits> &
117 cont_print_set(std::basic_ostream<CharT, Traits> &os, const Cont &cont) {
118 if (begin(cont) == end(cont)) return os << CharT('{') << CharT('}');
119 auto it = begin(cont);
120 os << CharT('{');
121 repr(*it, os);
122 while (++it != end(cont)) {
123 os << CharT(','), os << CharT(' ');
124 repr(*it, os);
125 }
126 return os << CharT('}');
127 }
128
140 template <class CharT, class Traits, class Cont>
141 inline std::basic_ostream<CharT, Traits> &
142 cont_print_map(std::basic_ostream<CharT, Traits> &os, const Cont &cont) {
143 if (begin(cont) == end(cont)) return os << CharT('{') << CharT('}');
144 auto it = begin(cont);
145 os << CharT('{');
146 repr(it->first, os);
147 os << CharT(':'), os << CharT(' ');
148 repr(it->second, os);
149 while (++it != end(cont)) {
150 os << CharT(','), os << CharT(' ');
151 repr(it->first, os);
152 os << CharT(':'), os << CharT(' ');
153 repr(it->second, os);
154 }
155 return os << CharT('}');
156 }
157
159
165
173 template <class CharT,
174 class Traits,
175 class Tuple,
176 size_t N = std::tuple_size<Tuple>::value>
183 static void
184 print(std::basic_ostream<CharT, Traits> &os, const Tuple &t) {
186 if (N > 1) os << CharT(','), os << CharT(' ');
187 repr(std::get<N - 1>(t), os);
188 }
189 };
190
194 template <class CharT, class Traits, class Tuple>
195 struct BasicTuplePrinter<CharT, Traits, Tuple, 1> {
196 static void
197 print(std::basic_ostream<CharT, Traits> &os, const Tuple &t) {
198 repr(std::get<0>(t), os);
199 }
200 };
201
205 template <class CharT, class Traits, class Tuple>
206 struct BasicTuplePrinter<CharT, Traits, Tuple, 0> {
207 static void print(std::basic_ostream<CharT, Traits> &, const Tuple &) {}
208 };
209
211 template <class Tuple, size_t N = std::tuple_size<Tuple>::value>
214
216
217 // ==================== 标准容器 operator<< 重载 ====================
218
224
226 template <class CharT, class Traits, class T>
227 inline std::basic_ostream<CharT, Traits> &operator<<(
228 std::basic_ostream<CharT, Traits> &os, const std::vector<T> &vec) {
230 }
231
233 template <class CharT, class Traits, class T>
234 inline std::basic_ostream<CharT, Traits> &operator<<(
235 std::basic_ostream<CharT, Traits> &os, const std::deque<T> &deq) {
237 }
238
240 template <class CharT, class Traits, class T>
241 inline std::basic_ostream<CharT, Traits> &
242 operator<<(std::basic_ostream<CharT, Traits> &os, const std::list<T> &lst) {
244 }
245
247 template <class CharT, class Traits, class T>
248 inline std::basic_ostream<CharT, Traits> &
249 operator<<(std::basic_ostream<CharT, Traits> &os,
250 const std::forward_list<T> &flst) {
251 return cont_print_sequence<CharT, Traits>(os, flst);
252 }
253
255 template <class CharT, class Traits, class T, size_t n>
256 inline std::basic_ostream<CharT, Traits> &operator<<(
257 std::basic_ostream<CharT, Traits> &os, const std::array<T, n> &arr) {
259 }
260
262 template <class CharT, class Traits, class T>
263 inline std::basic_ostream<CharT, Traits> &
264 operator<<(std::basic_ostream<CharT, Traits> &os, const std::set<T> &s) {
265 return cont_print_set<CharT, Traits>(os, s);
266 }
267
269 template <class CharT, class Traits, class K, class V>
270 inline std::basic_ostream<CharT, Traits> &
271 operator<<(std::basic_ostream<CharT, Traits> &os, const std::map<K, V> &m) {
272 return cont_print_map<CharT, Traits>(os, m);
273 }
274
276 template <class CharT, class Traits, class T>
277 inline std::basic_ostream<CharT, Traits> &operator<<(
278 std::basic_ostream<CharT, Traits> &os, const std::multiset<T> &ms) {
279 return cont_print_set<CharT, Traits>(os, ms);
280 }
281
283 template <class CharT, class Traits, class K, class V>
284 inline std::basic_ostream<CharT, Traits> &operator<<(
285 std::basic_ostream<CharT, Traits> &os, const std::multimap<K, V> &mm) {
286 return cont_print_map<CharT, Traits>(os, mm);
287 }
288
290 template <class CharT, class Traits, class T>
291 inline std::basic_ostream<CharT, Traits> &
292 operator<<(std::basic_ostream<CharT, Traits> &os,
293 const std::unordered_set<T> &us) {
294 return cont_print_set<CharT, Traits>(os, us);
295 }
296
298 template <class CharT, class Traits, class K, class V>
299 inline std::basic_ostream<CharT, Traits> &
300 operator<<(std::basic_ostream<CharT, Traits> &os,
301 const std::unordered_map<K, V> &um) {
302 return cont_print_map<CharT, Traits>(os, um);
303 }
304
306 template <class CharT, class Traits, class T>
307 inline std::basic_ostream<CharT, Traits> &
308 operator<<(std::basic_ostream<CharT, Traits> &os,
309 const std::unordered_multiset<T> &ums) {
310 return cont_print_set<CharT, Traits>(os, ums);
311 }
312
314 template <class CharT, class Traits, class K, class V>
315 inline std::basic_ostream<CharT, Traits> &
316 operator<<(std::basic_ostream<CharT, Traits> &os,
317 const std::unordered_multimap<K, V> &ump) {
318 return cont_print_map<CharT, Traits>(os, ump);
319 }
320
322 template <class CharT, class Traits, class T>
323 inline std::basic_ostream<CharT, Traits> &operator<<(
324 std::basic_ostream<CharT, Traits> &os, const std::valarray<T> &va) {
326 }
327
338 template <class CharT, class Traits, class T, class U>
339 inline std::basic_ostream<CharT, Traits> &operator<<(
340 std::basic_ostream<CharT, Traits> &os, const std::pair<T, U> &p) {
341 os << CharT('(');
342 repr(p.first, os);
343 os << CharT(','), os << CharT(' ');
344 repr(p.second, os);
345 return os << CharT(')');
346 }
347
357 template <class CharT, class Traits, class... Args>
358 inline std::basic_ostream<CharT, Traits> &operator<<(
359 std::basic_ostream<CharT, Traits> &os, const std::tuple<Args...> &t) {
360 os << CharT('(');
361 BasicTuplePrinter<CharT, Traits, std::tuple<Args...>>::print(os, t);
362 return os << CharT(')');
363 }
364
366
372
380 template <class T, size_t N>
381 inline std::array<T, N> to_array(const T (&ar)[N]) {
382 std::array<T, N> arr;
383 std::copy(ar, ar + N, arr.begin());
384 return arr;
385 }
386
394 template <class T, size_t N>
395 inline std::vector<T> to_vector(const T (&ar)[N]) {
396 std::vector<T> vec(N);
397 std::copy(ar, ar + N, vec.begin());
398 return vec;
399 }
400
402
420 template <class CharT = char, class Traits = std::char_traits<CharT>>
422 using string_type = std::basic_string<CharT, Traits>;
424 std::basic_ostream<CharT, Traits> &os;
427 bool isFlush;
428
429 public:
432 */
433 BasicOutput() :
434 os(std::cout), sep(string_type{1, CharT(' ')}),
435 end(string_type{1, CharT('\n')}), isFlush(true) {}
436
443 */
444 BasicOutput(std::basic_ostream<CharT, Traits> &o,
445 const string_type &s,
446 const string_type &e,
447 bool isF) : os(o), sep(s), end(e), isFlush(isF) {}
448
452 */
454 os << end;
455 if (isFlush) os << std::flush;
456 return *this;
457 }
458
465 template <class T>
466 BasicOutput &operator()(const T &t) {
467 put(os, t);
468 return operator()();
469 }
470
480 template <class T, class... Args>
481 BasicOutput &operator()(const T &t, const Args &...args) {
482 put(os, t);
483 os << sep;
484 return operator()(args...);
485 }
486
487 // fmt 成员函数声明(定义在 fmt.h 中)
488 template <typename... Args>
489 BasicOutput &fmt(const std::basic_string<CharT, Traits> &format_str,
490 const Args &...args);
491
492 template <typename... Args>
493 BasicOutput &fmt(const CharT *format_str, const Args &...args);
494 };
495
498
501
502 // ———— 全局实例 ————
503
506 */
507 inline BasicOutput<> &get_print() {
508 static BasicOutput<> instance;
509 return instance;
510 }
511
514 */
516 static BasicOutput<wchar_t> instance(
517 std::wcout, std::wstring(1, L' '), std::wstring(1, L'\n'), true);
518 return instance;
519 }
521 static BasicOutput<> &print
524}
灵活的输出控制类,支持链式调用和多种参数。
Definition output.h:420
std::basic_string< CharT, Traits > string_type
Definition output.h:421
BasicOutput & fmt(const std::basic_string< char, std::char_traits< char > > &format_str, const Args &...args)
string_type end
Definition output.h:425
BasicOutput & operator()()
Definition output.h:452
BasicOutput()
默认构造,输出到 std::cout,分隔符为空格,结尾为换行,并刷新。
Definition output.h:432
bool isFlush
Definition output.h:426
std::basic_ostream< char, std::char_traits< char > > & os
Definition output.h:423
string_type sep
Definition output.h:424
std::array< T, N > to_array(const T(&ar)[N])
将 C 风格数组转换为 std::array。
Definition output.h:380
std::vector< T > to_vector(const T(&ar)[N])
将 C 风格数组转换为 std::vector。
Definition output.h:394
std::basic_ostream< CharT, Traits > & cont_print_set(std::basic_ostream< CharT, Traits > &os, const Cont &cont)
输出集合容器(如 set, unordered_set)的内容,格式为 {a, b, c}。
Definition output.h:117
std::basic_ostream< CharT, Traits > & cont_print_map(std::basic_ostream< CharT, Traits > &os, const Cont &cont)
输出映射容器(如 map, unordered_map)的内容,格式为 {key: value, ...}。
Definition output.h:142
std::basic_ostream< CharT, Traits > & cont_print_sequence(std::basic_ostream< CharT, Traits > &os, const Cont &cont)
输出序列容器(如 vector, list)的内容,格式为 [a, b, c]。
Definition output.h:93
std::enable_if< is_string< typenamestd::decay< T >::type >::value >::type repr(T &&value, std::basic_ostream< CharT, Traits > &os=std::cout)
输出字符串类型(std::string, const char* 等)的表示,带双引号。
Definition repr.h:97
void to_stream(char ch, std::basic_ostream< CharT, Traits > &os)
将 ch 输出到流。
Definition strpp.h:574
BasicTuplePrinter< char, std::char_traits< char >, Tuple, N > TuplePrinter
BasicTuplePrinter<char> 的类型别名。
Definition output.h:212
本库所有组件所在的顶层命名空间。
BasicOutput< wchar_t > WOutput
BasicOutput<wchar_t> 的类型别名。
Definition output.h:499
@ N
Definition kb.h:93
@ T
Definition kb.h:99
@ L
Definition kb.h:91
BasicOutput< char > Output
BasicOutput<char> 的类型别名。
Definition output.h:496
BasicOutput< wchar_t > & get_wprint()
内部单例(wchar_t)。
Definition output.h:514
MultiArray< decltype(std::declval< T >()<< std::declval< U >()), Dims... > operator<<(const MultiArray< T, Dims... > &a, const MultiArray< U, Dims... > &b)
Definition multiarray.h:1607
static BasicOutput & print
全局输出对象,模仿 Python 的 print 函数。
Definition output.h:521
static BasicOutput< wchar_t > & wprint
全局宽字符输出。
Definition output.h:522
std::enable_if< is_string< typenamestd::decay< StrOrCharType >::type >::value||is_char< typenamestd::decay< StrOrCharType >::type >::value >::type put(std::basic_ostream< CharT, Traits > &os, StrOrCharType &&value)
Definition output.h:56
BasicOutput & get_print()
内部单例(char)。
Definition output.h:506
提供类似 Python 的 repr() 函数,用于生成对象的可读字符串表示。
提供编译期类型特征检测(SFINAE 工具), 用于判断容器、可调用对象、迭代器、下标访问、字符串、可打印类型、字符类型等。
static void print(std::basic_ostream< CharT, Traits > &, const Tuple &)
Definition output.h:207
static void print(std::basic_ostream< CharT, Traits > &os, const Tuple &t)
Definition output.h:197
递归打印 tuple 的辅助模板(主模板)。
Definition output.h:177
static void print(std::basic_ostream< CharT, Traits > &os, const Tuple &t)
递归打印 tuple 元素。
Definition output.h:184
检测类型是否为字符类型(char、wchar_t 等)。
Definition sfinae.h:198
检测类型是否为字符串类型(char*、stdstring、std::string_view 等)。
Definition sfinae.h:123