Console Library 8.0.0
A header-only library that makes C++ simple
Loading...
Searching...
No Matches
sfinae.h
Go to the documentation of this file.
1
9
10/*
11Copyright (c) 2026 MrXie1109
12
13Permission is hereby granted, free of charge, to any person obtaining a copy
14of this software and associated documentation files (the "Software"), to deal
15in the Software without restriction, including without limitation the rights
16to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17copies of the Software, and to permit persons to whom the Software is
18furnished to do so, subject to the following conditions:
19
20The above copyright notice and this permission notice shall be included in all
21copies or substantial portions of the Software.
22
23THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29SOFTWARE.
30*/
31
32#pragma once
33#include <iterator>
34#include <random>
35#include <type_traits>
36
37#include "../io/outfwd.h"
38
39namespace console {
45
49 template <typename... Args>
50 using void_t = void;
51
57 template <class T, class = void>
58 struct is_container : std::false_type {};
59
61 template <class T>
62 struct is_container<T,
63 void_t<decltype(std::begin(std::declval<T>())),
64 decltype(std::end(std::declval<T>()))>> : std::true_type {};
66
67 template <class, class = void>
68 struct is_callable_impl : std::false_type {};
69
70 template <class F, class... Args>
71 struct is_callable_impl<F(Args...),
72 void_t<decltype(std::declval<F>()(std::declval<Args>()...))>>
73 : std::true_type {};
74
81 template <class F, class... Args>
82 using is_callable = is_callable_impl<F(Args...), void>;
83
89 template <class T, class = void>
90 struct is_iterator : std::false_type {};
91
93 template <class T>
94 struct is_iterator<T,
95 void_t<typename std::iterator_traits<T>::iterator_category>>
96 : std::true_type {};
98
105 template <class T, class Idx, class = void>
106 struct has_subscript : std::false_type {};
107
109 template <class T, class Idx>
110 struct has_subscript<T,
111 Idx,
112 void_t<decltype(std::declval<T>()[std::declval<Idx>()])>>
113 : std::true_type {};
115
122 template <class T, class = void>
123 struct is_string : std::false_type {};
124
125 // 各种指针字符串特化
127 template <>
128 struct is_string<char *> : std::true_type {};
129 template <>
130 struct is_string<signed char *> : std::true_type {};
131 template <>
132 struct is_string<unsigned char *> : std::true_type {};
133 template <>
134 struct is_string<wchar_t *> : std::true_type {};
135 template <>
136 struct is_string<const char *> : std::true_type {};
137 template <>
138 struct is_string<const signed char *> : std::true_type {};
139 template <>
140 struct is_string<const unsigned char *> : std::true_type {};
141 template <>
142 struct is_string<const wchar_t *> : std::true_type {};
143
144 template <class CharT, class Traits, class Alloc>
145 struct is_string<std::basic_string<CharT, Traits, Alloc>> : std::true_type {
146 };
147
148#if __cplusplus >= 201703L
149 template <class CharT, class Traits>
150 struct is_string<std::basic_string_view<CharT, Traits>> : std::true_type {};
151#endif
153
159 template <class T, class = void>
160 struct is_printable : std::false_type {};
161
163 template <class T>
164 struct is_printable<T,
165 void_t<decltype(std::declval<std::ostream &>()
166 << std::declval<const T &>())>> : std::true_type {};
168
176 template <class CharT, class Traits, class T, class = void>
177 struct is_basic_printable : std::false_type {};
178
180 template <class CharT, class Traits, class T>
181 struct is_basic_printable<CharT,
182 Traits,
183 T,
184 void_t<decltype(std::declval<std::basic_ostream<CharT, Traits> &>()
185 << std::declval<const T &>())>> : std::true_type {};
187
189 template <class T>
192
198 template <class T, class = void>
199 struct is_char : std::false_type {};
200
201 // 字符类型特化
203 template <>
204 struct is_char<char> : std::true_type {};
205 template <>
206 struct is_char<signed char> : std::true_type {};
207 template <>
208 struct is_char<unsigned char> : std::true_type {};
209 template <>
210 struct is_char<wchar_t> : std::true_type {};
211
213
219 template <typename T, typename = void>
221
224 template <typename T>
226 typename std::enable_if<std::is_integral<T>::value>::type> {
227 using type = std::uniform_int_distribution<T>;
228 };
229
231 template <typename T>
233 typename std::enable_if<std::is_floating_point<T>::value>::type> {
234 using type = std::uniform_real_distribution<T>;
235 };
237
243 template <class T, class = void>
244 struct is_generator : std::false_type {};
245
247 template <class T>
248 struct is_generator<T,
249 void_t<std::is_same<decltype(std::declval<T>().done()), bool>,
250 decltype(std::declval<T>().current()),
251 decltype(std::declval<T>().advance()),
252 typename T::value_type>> : std::true_type {};
254
258 template <class F, class... Args>
259 using enable_if_callable =
260 typename std::enable_if<is_callable<F, Args...>::value>::type;
261
265 template <class F, class... Args>
267 typename std::enable_if<!is_callable<F, Args...>::value>::type;
268
272 template <class T>
273 using enable_if_iterator =
274 typename std::enable_if<is_iterator<T>::value>::type;
275
279 template <class T>
281 typename std::enable_if<!is_iterator<T>::value>::type;
282
286 template <class T>
287 using enable_if_string = typename std::enable_if<
289
293 template <class T>
294 using enable_if_not_string = typename std::enable_if<
296
300 template <class T>
301 using enable_if_printable =
302 typename std::enable_if<is_printable<T>::value>::type;
303
307 template <class T>
309 typename std::enable_if<!is_printable<T>::value>::type;
310
314 template <class T>
315 using enable_if_char = typename std::enable_if<
317
321 template <class T>
322 using enable_if_not_char = typename std::enable_if<
324
328 template <typename T>
330
334 template <class T>
335 using enable_if_generator =
336 typename std::enable_if<is_generator<T>::value>::type;
337
341 template <class T>
343 typename std::enable_if<!is_generator<T>::value>::type;
344
345 // ———— basic_printable enable_if 别名 ————
346
350 template <class CharT, class Traits, class T>
352 typename std::enable_if<is_basic_printable<CharT,
353 Traits,
354 typename std::decay<T>::type>::value>::type;
355
359 template <class T>
360 using enable_if_w_printable = typename std::enable_if<
362 // end of sfinae group
364}
typename std::enable_if< is_basic_printable< CharT, Traits, typename std::decay< T >::type >::value >::type enable_if_basic_printable
启用若 T(decay 后)对给定字符流可打印。
Definition sfinae.h:350
typename uniform_distribution_impl< T >::type uniform_distribution_t
取得对印类型所对应的均匀分布。
Definition sfinae.h:328
typename std::enable_if<!is_printable< T >::value >::type enable_if_not_printable
启用若 T 不可打印。
Definition sfinae.h:307
typename std::enable_if< is_callable< F, Args... >::value >::type enable_if_callable
启用若 F 可以 Args... 参数调用。
Definition sfinae.h:258
is_basic_printable< wchar_t, std::char_traits< wchar_t >, T > is_w_printable
is_basic_printable<wchar_t, ...> 的简写。
Definition sfinae.h:190
typename std::enable_if< is_iterator< T >::value >::type enable_if_iterator
启用若 T 是迭代器。
Definition sfinae.h:272
typename std::enable_if< is_generator< T >::value >::type enable_if_generator
启用若 T 是生成器。
Definition sfinae.h:334
typename std::enable_if< is_string< typename std::decay< T >::type >::value >::type enable_if_string
启用若 T(decay 后)是字符串类型。
Definition sfinae.h:286
void void_t
C++11 兼容的 void_t 实现。
Definition sfinae.h:50
typename std::enable_if<!is_generator< T >::value >::type enable_if_not_generator
启用若 T 不是生成器。
Definition sfinae.h:341
typename std::enable_if< !is_char< typename std::decay< T >::type >::value >::type enable_if_not_char
启用若 T(decay 后)不是字符类型。
Definition sfinae.h:321
typename std::enable_if< is_char< typename std::decay< T >::type >::value >::type enable_if_char
启用若 T(decay 后)是字符类型。
Definition sfinae.h:314
typename std::enable_if<!is_callable< F, Args... >::value >::type enable_if_not_callable
启用若 F 不可以 Args... 参数调用。
Definition sfinae.h:265
is_callable_impl< F(Args...), void > is_callable
Definition sfinae.h:82
typename std::enable_if< !is_string< typename std::decay< T >::type >::value >::type enable_if_not_string
启用若 T(decay 后)不是字符串类型。
Definition sfinae.h:293
typename std::enable_if< is_printable< T >::value >::type enable_if_printable
启用若 T 可打印。
Definition sfinae.h:300
typename std::enable_if< is_w_printable< typename std::decay< T >::type >::value >::type enable_if_w_printable
启用若 T(decay 后)对 wchar_t 流可打印。
Definition sfinae.h:359
typename std::enable_if<!is_iterator< T >::value >::type enable_if_not_iterator
启用若 T 不是迭代器。
Definition sfinae.h:279
本库所有组件所在的顶层命名空间。
@ T
Definition kb.h:99
为 STL 容器提供输出流运算符的前向声明。
检测类型是否支持下标操作符(如 T[Idx])。
Definition sfinae.h:106
检测类型是否支持输出到指定字符类型的流(即定义了 operator<<)。
Definition sfinae.h:177
Definition sfinae.h:68
检测类型是否为字符类型(char、wchar_t 等)。
Definition sfinae.h:198
检测类型是否为容器(支持 std::begin 和 std::end)。
Definition sfinae.h:58
检测类型是否为生成器(具有 done()、current()、advance() 接口)。
Definition sfinae.h:243
检测类型是否为迭代器(具有 iterator_category)。
Definition sfinae.h:90
检测类型是否支持输出到 std::ostream(即定义了 operator<<)。
Definition sfinae.h:160
检测类型是否为字符串类型(char*、stdstring、std::string_view 等)。
Definition sfinae.h:123
取得适配分布的主模板。
Definition sfinae.h:219