1#ifndef MSTL_CORE_SYSTEM_CONSOLE_HPP__
2#define MSTL_CORE_SYSTEM_CONSOLE_HPP__
4#include "../utility/color.hpp"
8template <
typename T,
typename =
void>
12class MSTL_API sys_console {
18 explicit console_size(
const int w = 0,
const int h = 0)
19 : width(w), height(h) {}
21 MSTL_NODISCARD
bool operator ==(
const console_size& other)
const noexcept {
22 return width == other.width && height == other.height;
24 MSTL_NODISCARD
bool operator !=(
const console_size& other)
const noexcept {
25 return !(*
this == other);
30#ifdef MSTL_PLATFORM_WINDOWS__
31 ::HANDLE out_{INVALID_HANDLE_VALUE};
32 ::HANDLE in_{INVALID_HANDLE_VALUE};
34 ::COORD saved_cursor_pos_{0, 0};
39 mutable mutex mutex_{};
40 console_size last_size_{0, 0};
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}); }
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;
50 string readln_unsafe()
const;
51 string read_unsafe()
const;
52 char read_char_unsafe()
const;
54 void flush_unsafe()
const;
56 void beep_unsafe()
const;
57 void flash_screen_unsafe()
const;
59 void fade_effect_unsafe(string_view text,
60 const color& from,
const color& to,
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;
72 ~sys_console() =
default;
74 static sys_console& instance() {
75 static sys_console console;
81 void print_string(
const string& str);
82 void print_string(
const string_view& str);
83 void print_string(
const char* str);
92 void print(
const T& value) {
93 io_base<T>::write(*
this, value);
96 template <
typename... Args>
97 void printf(
const string_view fmt, Args&&... args) {
98 lock<mutex> lock(mutex_);
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);
109 template <
typename T>
112 io_base<T>::read(*
this, obj);
116 template <
typename T, enable_if_t<is_packaged_v<T>,
int> = 0>
117 void read(T& value) {
119 io_base<package_t<T>>::read(*
this, obj);
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);
128 template <
typename T>
131 io_base<T>::readln(*
this, obj);
135 template <
typename T, enable_if_t<is_packaged_v<T>,
int> = 0>
136 void readln(T& value) {
138 io_base<package_t<T>>::readln(*
this, obj);
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);
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);
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);
158 double percentage,
int width = 50,
bool show_percentage =
true,
159 char fill_char =
'#',
char empty_char =
' ');
161 void set_cursor_position(
int row,
int column);
162 void save_cursor_position();
163 void restore_cursor_position();
167 console_size get_console_size()
const;
168 bool is_terminal_resized();
170 bool supports_colors()
const;
171 bool supports_truecolor()
const;
172 bool supports_unicode()
const;
173 bool is_interactive()
const;
175 string console_type()
const;
177 void typewriter_print(string_view text,
179 bool with_sound =
false);
181 void typewriter_println(string_view text,
183 bool with_sound =
false);
188 void notification(string_view message,
190 bool play_sound =
true);
192 void fade_in(string_view text,
194 const color& start_color = color::black(),
195 const color& end_color = color::white());
197 void fade_out(string_view text,
199 const color& start_color = color::white(),
200 const color& end_color = color::black());
202 void fade_in_out(string_view text,
209#ifdef MSTL_STANDARD_20__
212 static void write(sys_console& console,
const T& value) {
214 if (value.begin() == value.end()) {
218 for (
auto iter = value.begin(); iter != value.end(); ++iter) {
219 if (iter != value.begin()) result +=
", ";
220 result += to_string(*iter);
224 console.print_string(result.view());
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());
238 static void write(sys_console& console,
const T& value) {
239 console.print_string(to_string(value));
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());
248 static void read(sys_console& console, T& value) {
249 value = iobject<T>::parse(console.read().view());
251 static void readln(sys_console& console, T& value) {
252 value = iobject<T>::parse(console.readln().view());
258 static void write(sys_console& console,
const T& value) {
259 console.print_string(
_MSTL to_string(value));
261 static void read(sys_console& console, T& value) {
262 value = package_t<T>::parse(console.read().view());
264 static void readln(sys_console& console, T& value) {
265 value = package_t<T>::parse(console.readln().view());
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));
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));
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));
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));
299 static void write(sys_console& console,
const T* value) {
300 console.print_string(
_MSTL to_string(value));
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));
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));
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));
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));
334 static void write(sys_console& console,
const T& value) {
335 io_base<string>::write(console,
_MSTL to_string(value));
339template <
typename IfEmpty,
typename T,
bool 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));
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));
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));
360static sys_console& console = sys_console::instance();
363#ifndef MSTL_STANDARD_17__
366MSTL_ALWAYS_INLINE_INLINE
void print_rests() {}
368template <
typename First,
typename... Rests>
369void print_rests(
const First& first,
const Rests&... rests) {
372 _INNER print_rests(rests...);
375MSTL_ALWAYS_INLINE_INLINE
void printc_rests(
const color&) {}
377template <
typename First,
typename... Rests>
378void printc_rests(
const color& color,
const First& first,
const Rests&... rests) {
381 _INNER printc_rests(color, rests...);
385template <
typename This>
386void print(
const This& t) {
390template <
typename This,
typename... Rests>
391void print(
const This& t,
const Rests&... rests) {
393 _INNER print_rests(rests...);
396template <
typename This>
397void printc(
const color& color,
const This& t) {
401template <
typename This,
typename... Rests>
402void printc(
const color& color,
const This& t,
const Rests&... rests) {
404 _INNER printc_rests(color, rests...);
407MSTL_ALWAYS_INLINE_INLINE
void println() {
411template <
typename This>
412void println(
const This& t) {
417template <
typename This,
typename... Rests>
418void println(
const This& t,
const Rests&... rests) {
420 _INNER print_rests(rests...);
424template <
typename This,
typename ...Rests>
425void printcln(
const color& color,
const This& t,
const Rests&... rests) {
427 _INNER printc_rests(color, rests...);
433template <
typename This,
typename ...Rests>
434void print(
const This& t,
const Rests&... r) {
439template <
typename This,
typename ...Rests>
440void printc(
const color& color,
const This& t,
const Rests&... r) {
445MSTL_ALWAYS_INLINE_INLINE
void println() {
449template <
typename This,
typename ...Rests>
450void println(
const This& t,
const Rests&... r) {
456template <
typename This,
typename ...Rests>
457void printcln(
const color& color,
const This& t,
const Rests&... r) {
465template <
typename... Args>
466void printf(
const string_view fmt, Args&&... args) {
470template <
typename... Args>
471void printfln(
const string_view fmt, Args&&... args) {
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的便捷别名