MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
console.hpp
1#ifndef MSTL_CORE_SYSTEM_CONSOLE_HPP__
2#define MSTL_CORE_SYSTEM_CONSOLE_HPP__
3#include "../async/mutex.hpp"
4#include "../utility/color.hpp"
7
8template <typename T, typename = void>
9struct io_base;
10
11
12class MSTL_API sys_console {
13public:
14 struct console_size {
15 int width;
16 int height;
17
18 explicit console_size(const int w = 0, const int h = 0)
19 : width(w), height(h) {}
20
21 MSTL_NODISCARD bool operator ==(const console_size& other) const noexcept {
22 return width == other.width && height == other.height;
23 }
24 MSTL_NODISCARD bool operator !=(const console_size& other) const noexcept {
25 return !(*this == other);
26 }
27 };
28
29private:
30#ifdef MSTL_PLATFORM_WINDOWS__
31 ::HANDLE out_{INVALID_HANDLE_VALUE};
32 ::HANDLE in_{INVALID_HANDLE_VALUE};
33
34 ::COORD saved_cursor_pos_{0, 0};
35#else
36 int out_{-1};
37 int in_{-1};
38#endif
39 mutable mutex mutex_{};
40 console_size last_size_{0, 0};
41
42private:
43 void print_string_unsafe(const string& str) const { print_string_unsafe(str.view()); }
44 void print_string_unsafe(string_view str) const;
45 void print_string_unsafe(const char* str) const { print_string_unsafe(string_view{str}); }
46
47 void set_color_unsafe(const color& color, bool use_256_color) const;
48 void typewriter_print_unsafe(string_view text, milliseconds delay_per_char, bool with_sound) const;
49
50 string readln_unsafe() const;
51 string read_unsafe() const;
52 char read_char_unsafe() const;
53
54 void flush_unsafe() const;
55
56 void beep_unsafe() const;
57 void flash_screen_unsafe() const;
58
59 void fade_effect_unsafe(string_view text,
60 const color& from, const color& to,
61 milliseconds duration, bool is_fade_in) const;
62
63private:
64 sys_console();
65
66public:
67 sys_console(const sys_console&) = delete;
68 sys_console& operator =(const sys_console&) = delete;
69 sys_console(sys_console&&) = delete;
70 sys_console& operator =(sys_console&&) = delete;
71
72 ~sys_console() = default;
73
74 static sys_console& instance() {
75 static sys_console console;
76 return console;
77 }
78
79 void flush();
80
81 void print_string(const string& str);
82 void print_string(const string_view& str);
83 void print_string(const char* str);
84
85 void println();
86
87 string read();
88 string readln();
89 char read_char();
90
91 template <typename T>
92 void print(const T& value) {
93 io_base<T>::write(*this, value);
94 }
95
96 template <typename... Args>
97 void printf(const string_view fmt, Args&&... args) {
98 lock<mutex> lock(mutex_);
99 this->print_string_unsafe(_MSTL format(fmt, _MSTL forward<Args>(args)...));
100 }
101
102 template <typename T>
103 void printc(const color& color, const T& value) {
104 set_color(color, false);
105 io_base<T>::write(*this, value);
106 reset_color();
107 }
108
109 template <typename T>
110 T read() {
111 package_t<T> obj;
112 io_base<T>::read(*this, obj);
113 return obj.value();
114 }
115
116 template <typename T, enable_if_t<is_packaged_v<T>, int> = 0>
117 void read(T& value) {
118 package_t<T> obj;
119 io_base<package_t<T>>::read(*this, obj);
120 value = _MSTL move(static_cast<T>(obj));
121 }
122
123 template <typename T, enable_if_t<!is_packaged_v<T>, int> = 0>
124 void read(T& value) {
125 io_base<T>::read(*this, value);
126 }
127
128 template <typename T>
129 T readln() {
130 package_t<T> obj;
131 io_base<T>::readln(*this, obj);
132 return obj.value();
133 }
134
135 template <typename T, enable_if_t<is_packaged_v<T>, int> = 0>
136 void readln(T& value) {
137 package_t<T> obj;
138 io_base<package_t<T>>::readln(*this, obj);
139 value = _MSTL move(static_cast<T>(obj));
140 }
141
142 template <typename T, enable_if_t<!is_packaged_v<T>, int> = 0>
143 void readln(T& value) {
144 io_base<T>::readln(*this, value);
145 }
146
147 void clear();
148 void pause(string_view msg = "Press any char to continue...");
149 bool confirmation(string_view prompt = "Are you sure? (y/n): ", char yes = 'y', char no = 'n');
150 string password(string_view prompt = "Password: ", char mask = '*', bool show_length = false);
151
152 void set_color(const integer32& color);
153 void set_color(const color& color, bool use_256_color = true);
154 void set_background_color(const color& color, bool use_256_color = true);
155 void reset_color();
156
157 void progress_bar(
158 double percentage, int width = 50, bool show_percentage = true,
159 char fill_char = '#', char empty_char = ' ');
160
161 void set_cursor_position(int row, int column);
162 void save_cursor_position();
163 void restore_cursor_position();
164 void hide_cursor();
165 void show_cursor();
166
167 console_size get_console_size() const;
168 bool is_terminal_resized();
169
170 bool supports_colors() const;
171 bool supports_truecolor() const;
172 bool supports_unicode() const;
173 bool is_interactive() const;
174
175 string console_type() const;
176
177 void typewriter_print(string_view text,
178 milliseconds delay_per_char = milliseconds(50),
179 bool with_sound = false);
180
181 void typewriter_println(string_view text,
182 milliseconds delay_per_char = milliseconds(50),
183 bool with_sound = false);
184
185 void beep();
186 void flash_screen();
187
188 void notification(string_view message,
189 milliseconds duration = milliseconds(2000),
190 bool play_sound = true);
191
192 void fade_in(string_view text,
193 milliseconds duration = milliseconds(1000),
194 const color& start_color = color::black(),
195 const color& end_color = color::white());
196
197 void fade_out(string_view text,
198 milliseconds duration = milliseconds(1000),
199 const color& start_color = color::white(),
200 const color& end_color = color::black());
201
202 void fade_in_out(string_view text,
203 milliseconds in_duration = milliseconds(500),
204 milliseconds hold_duration = milliseconds(1000),
205 milliseconds out_duration = milliseconds(500));
206};
207
208
209#ifdef MSTL_STANDARD_20__
210template <typename T>
211struct io_base<T, enable_if_t<is_base_of_v<_MSTL_RANGES view_base<T>, T>>> {
212 static void write(sys_console& console, const T& value) {
213 string result;
214 if (value.begin() == value.end()) {
215 result = "[]";
216 } else {
217 result += "[ ";
218 for (auto iter = value.begin(); iter != value.end(); ++iter) {
219 if (iter != value.begin()) result += ", ";
220 result += to_string(*iter);
221 }
222 result += " ]";
223 }
224 console.print_string(result.view());
225 }
226};
227#endif
228
229template <typename T>
230struct io_base<T, enable_if_t<is_base_of_v<istringify<T>, T> && !is_base_of_v<iobject<T>, T>>> {
231 static void write(sys_console& console, const T& value) {
232 console.print_string(value.to_string());
233 }
234};
235
236template <typename T>
237struct io_base<T, enable_if_t<is_base_of_v<icollector<T>, T>>> {
238 static void write(sys_console& console, const T& value) {
239 console.print_string(to_string(value));
240 }
241};
242
243template <typename T>
244struct io_base<T, enable_if_t<is_base_of_v<iobject<T>, T>>> {
245 static void write(sys_console& console, const T& value) {
246 console.print_string(value.to_string());
247 }
248 static void read(sys_console& console, T& value) {
249 value = iobject<T>::parse(console.read().view());
250 }
251 static void readln(sys_console& console, T& value) {
252 value = iobject<T>::parse(console.readln().view());
253 }
254};
255
256template <typename T>
257struct io_base<T, enable_if_t<is_packaged_v<T>>> {
258 static void write(sys_console& console, const T& value) {
259 console.print_string(_MSTL to_string(value));
260 }
261 static void read(sys_console& console, T& value) {
262 value = package_t<T>::parse(console.read().view());
263 }
264 static void readln(sys_console& console, T& value) {
265 value = package_t<T>::parse(console.readln().view());
266 }
267};
268
269template <typename T>
270struct io_base<T, enable_if_t<is_null_pointer_v<T>>> {
271 static void write(sys_console& console, nullptr_t) {
272 console.print_string(_MSTL to_string(nullptr));
273 }
274};
275
276template <typename T>
277struct io_base<T, enable_if_t<is_pointer_v<T> && !is_cstring_v<T>>> {
278 static void write(sys_console& console, const T& value) {
279 console.print_string(_MSTL to_string(value));
280 }
281};
282
283template <typename T, size_t N>
284struct io_base<T[N], enable_if_t<is_character_v<T>>> {
285 static void write(sys_console& console, const T(& value)[N]) {
286 console.print_string(_MSTL to_string(value));
287 }
288};
289
290template <typename T, size_t N>
291struct io_base<const T[N], enable_if_t<is_character_v<T>>> {
292 static void write(sys_console& console, const T(& value)[N]) {
293 console.print_string(_MSTL to_string(value));
294 }
295};
296
297template <typename T>
298struct io_base<T*, enable_if_t<is_character_v<T>>> {
299 static void write(sys_console& console, const T* value) {
300 console.print_string(_MSTL to_string(value));
301 }
302};
303
304template <typename CharT, typename Traits>
305struct io_base<basic_string_view<CharT, Traits>> {
306 static void write(sys_console& console, const basic_string_view<CharT, Traits>& value) {
307 console.print_string(_MSTL to_string(value));
308 }
309};
310
311template <typename CharT, typename Traits, typename Alloc>
312struct io_base<basic_string<CharT, Traits, Alloc>> {
313 static void write(sys_console& console, const basic_string<CharT, Traits, Alloc>& value) {
314 console.print_string(_MSTL to_string(value));
315 }
316};
317
318template <typename T>
319struct io_base<T, enable_if_t<is_unbounded_array_v<T>>> {
320 static void write(sys_console& console, const T& value) {
321 console.print_string(_MSTL to_string(value));
322 }
323};
324
325template <typename T>
326struct io_base<T, enable_if_t<is_bounded_array_v<T> && !is_cstring_v<T>>> {
327 static void write(sys_console& console, const T& value) {
328 console.print_string(_MSTL to_string(value));
329 }
330};
331
332template <typename T>
333struct io_base<T, enable_if_t<is_base_of_v<exception, T>>> {
334 static void write(sys_console& console, const T& value) {
335 io_base<string>::write(console, _MSTL to_string(value));
336 }
337};
338
339template <typename IfEmpty, typename T, bool Compressed>
340struct io_base<compressed_pair<IfEmpty, T, Compressed>> {
341 static void write(sys_console& console, const compressed_pair<IfEmpty, T, Compressed>& value) {
342 io_base<string>::write(console, _MSTL to_string(value));
343 }
344};
345
346template <typename T1, typename T2>
347struct io_base<pair<T1, T2>> {
348 static void write(sys_console& console, const pair<T1, T2>& value) {
349 io_base<string>::write(console, _MSTL to_string(value));
350 }
351};
352
353template <typename... Args> struct io_base<tuple<Args...>> {
354 static void write(sys_console &console, const tuple<Args...> &value) {
355 io_base<string>::write(console, _MSTL to_string(value));
356 }
357};
358
359
360static sys_console& console = sys_console::instance();
361
362
363#ifndef MSTL_STANDARD_17__
364
366MSTL_ALWAYS_INLINE_INLINE void print_rests() {}
367
368template <typename First, typename... Rests>
369void print_rests(const First& first, const Rests&... rests) {
370 console.print(" ");
371 console.print<remove_cvref_t<First>>(first);
372 _INNER print_rests(rests...);
373}
374
375MSTL_ALWAYS_INLINE_INLINE void printc_rests(const color&) {}
376
377template <typename First, typename... Rests>
378void printc_rests(const color& color, const First& first, const Rests&... rests) {
379 console.print(" ");
380 console.printc<remove_cvref_t<First>>(color, first);
381 _INNER printc_rests(color, rests...);
382}
384
385template <typename This>
386void print(const This& t) {
387 console.print<remove_cvref_t<This>>(t);
388}
389
390template <typename This, typename... Rests>
391void print(const This& t, const Rests&... rests) {
392 console.print<remove_cvref_t<This>>(t);
393 _INNER print_rests(rests...);
394}
395
396template <typename This>
397void printc(const color& color, const This& t) {
398 console.print<remove_cvref_t<This>>(color, t);
399}
400
401template <typename This, typename... Rests>
402void printc(const color& color, const This& t, const Rests&... rests) {
403 console.printc<remove_cvref_t<This>>(color, t);
404 _INNER printc_rests(color, rests...);
405}
406
407MSTL_ALWAYS_INLINE_INLINE void println() {
408 console.println();
409}
410
411template <typename This>
412void println(const This& t) {
413 console.print<remove_cvref_t<This>>(t);
414 println();
415}
416
417template <typename This, typename... Rests>
418void println(const This& t, const Rests&... rests) {
419 console.print<remove_cvref_t<This>>(t);
420 _INNER print_rests(rests...);
421 println();
422}
423
424template <typename This, typename ...Rests>
425void printcln(const color& color, const This& t, const Rests&... rests) {
426 console.printc<remove_cvref_t<This>>(color, t);
427 _INNER printc_rests(color, rests...);
428 println();
429}
430
431#else
432
433template <typename This, typename ...Rests>
434void print(const This& t, const Rests&... r) {
435 console.print<remove_cvref_t<This>>(t);
436 ((console.print(" "), console.print<remove_cvref_t<Rests>>(r)), ...);
437}
438
439template <typename This, typename ...Rests>
440void printc(const color& color, const This& t, const Rests&... r) {
441 console.printc<remove_cvref_t<This>>(color, t);
442 ((console.print(" "), console.printc<remove_cvref_t<Rests>>(color, r)), ...);
443}
444
445MSTL_ALWAYS_INLINE_INLINE void println() {
446 console.println();
447}
448
449template <typename This, typename ...Rests>
450void println(const This& t, const Rests&... r) {
451 console.print<remove_cvref_t<This>>(t);
452 ((console.print(" "), console.print<remove_cvref_t<Rests>>(r)), ...);
453 println();
454}
455
456template <typename This, typename ...Rests>
457void printcln(const color& color, const This& t, const Rests&... r) {
458 console.printc<remove_cvref_t<This>>(color, t);
459 ((console.print(" "), console.printc<remove_cvref_t<Rests>>(color, r)), ...);
460 println();
461}
462
463#endif
464
465template <typename... Args>
466void printf(const string_view fmt, Args&&... args) {
467 console.printf(fmt, _MSTL forward<Args>(args)...);
468}
469
470template <typename... Args>
471void printfln(const string_view fmt, Args&&... args) {
472 console.printf(fmt, _MSTL forward<Args>(args)...);
473 println();
474}
475
477#endif // MSTL_CORE_SYSTEM_CONSOLE_HPP__
MSTL持续时间类型
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
typename package< T >::type package_t
package的便捷别名
decltype(nullptr) nullptr_t
空指针类型
duration< int64_t, milli > milliseconds
毫秒持续时间
bool operator!=(const function< Res(Args...)> &f, nullptr_t null) noexcept
不等于空指针比较
bool operator==(const function< Res(Args...)> &f, nullptr_t null) noexcept
等于空指针比较
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_INNER__
结束inner命名空间
#define _INNER
inner命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define _MSTL_RANGES
ranges命名空间前缀
#define MSTL_BEGIN_INNER__
开始inner命名空间
typename remove_cvref< T >::type remove_cvref_t
remove_cvref的便捷别名
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result)
移动范围元素
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
MSTL互斥锁
压缩对主模板,使用EBCO优化
异常基类
集合器接口模板
存储两个值的元组对