Console Library 4.7.0
A header-only library that makes C++ simple
Loading...
Searching...
No Matches
sfinae.h
Go to the documentation of this file.
1
8
9/*
10Copyright (c) 2026 MrXie1109
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files (the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions:
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29*/
30
31#pragma once
32#include <type_traits>
33#include <iterator>
34#include <random>
35#include "outfwd.h"
36
37namespace console
38{
44
50 template <class T, class = void>
51 struct is_container : std::false_type
52 {
53 };
54
56 template <class T>
57 struct is_container<
58 T, typename std::enable_if<
59 sizeof(decltype(std::begin(std::declval<T>()))) &&
60 sizeof(decltype(std::end(std::declval<T>())))>::type>
61 : std::true_type
62 {
63 };
65
72 template <class F, class = void, class... Args>
73 struct is_callable : std::false_type
74 {
75 };
76
78 template <class F, class... Args>
79 struct is_callable<F,
80 typename std::enable_if<
81 std::is_convertible<
82 decltype(std::declval<F>()(std::declval<Args>()...)),
83 void>::value>::type,
84 Args...>
85 : std::true_type
86 {
87 };
89
95 template <class T, class = void>
96 struct is_iterator : std::false_type
97 {
98 };
99
101 template <class T>
102 struct is_iterator<T, typename std::enable_if<
103 sizeof(
104 typename std::iterator_traits<T>::
105 iterator_category)>::type>
106 : std::true_type
107 {
108 };
110
117 template <class T, class Idx, class = void>
118 struct has_subscript : std::false_type
119 {
120 };
121
123 template <class T, class Idx>
124 struct has_subscript<T, Idx,
125 typename std::enable_if<
126 sizeof(decltype(std::declval<T>()
127 [std::declval<Idx>()]))>::type>
128 : std::true_type
129 {
130 };
132
138 template <class T, class = void>
139 struct is_string : std::false_type
140 {
141 };
142
143 // 各种指针字符串特化
145 template <>
146 struct is_string<char *> : std::true_type
147 {
148 };
149 template <>
150 struct is_string<signed char *> : std::true_type
151 {
152 };
153 template <>
154 struct is_string<unsigned char *> : std::true_type
155 {
156 };
157 template <>
158 struct is_string<wchar_t *> : std::true_type
159 {
160 };
161 template <>
162 struct is_string<char16_t *> : std::true_type
163 {
164 };
165 template <>
166 struct is_string<char32_t *> : std::true_type
167 {
168 };
169 template <>
170 struct is_string<const char *> : std::true_type
171 {
172 };
173 template <>
174 struct is_string<const signed char *> : std::true_type
175 {
176 };
177 template <>
178 struct is_string<const unsigned char *> : std::true_type
179 {
180 };
181 template <>
182 struct is_string<const wchar_t *> : std::true_type
183 {
184 };
185 template <>
186 struct is_string<const char16_t *> : std::true_type
187 {
188 };
189 template <>
190 struct is_string<const char32_t *> : std::true_type
191 {
192 };
193
194 template <class CharT, class Traits, class Alloc>
195 struct is_string<std::basic_string<CharT, Traits, Alloc>> : std::true_type
196 {
197 };
198
199#if __cplusplus >= 201703L
200 template <class CharT, class Traits>
201 struct is_string<std::basic_string_view<CharT, Traits>> : std::true_type
202 {
203 };
204#endif
206
212 template <class T, class = void>
213 struct is_printable : std::false_type
214 {
215 };
216
218 template <class T>
219 struct is_printable<T, typename std::enable_if<
220 sizeof(
221 decltype(std::declval<std::ostream &>()
222 << std::declval<T>()))>::type>
223 : std::true_type
224 {
225 };
227
233 template <class T, class = void>
234 struct is_char : std::false_type
235 {
236 };
237
238 // 字符类型特化
240 template <>
241 struct is_char<char> : std::true_type
242 {
243 };
244 template <>
245 struct is_char<signed char> : std::true_type
246 {
247 };
248 template <>
249 struct is_char<unsigned char> : std::true_type
250 {
251 };
252 template <>
253 struct is_char<wchar_t> : std::true_type
254 {
255 };
256 template <>
257 struct is_char<char16_t> : std::true_type
258 {
259 };
260 template <>
261 struct is_char<char32_t> : std::true_type
262 {
263 };
265
271 template <typename T, typename = void>
272 struct uniform_distribution_impl;
273
276 template <typename T>
277 struct uniform_distribution_impl<T, typename std::enable_if<std::is_integral<T>::value>::type>
278 {
279 using type = std::uniform_int_distribution<T>;
280 };
281
283 template <typename T>
284 struct uniform_distribution_impl<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
285 {
286 using type = std::uniform_real_distribution<T>;
287 };
289
290 // 便利别名模板(enable_if 快捷方式)
294 template <class T>
295 using enable_if_container =
296 typename std::enable_if<is_container<T>::value>::type;
297
301 template <class T>
302 using enable_if_not_container =
303 typename std::enable_if<!is_container<T>::value>::type;
304
308 template <class F, class... Args>
309 using enable_if_callable =
310 typename std::enable_if<is_callable<F, Args...>::value>::type;
311
315 template <class F, class... Args>
316 using enable_if_not_callable =
317 typename std::enable_if<!is_callable<F, Args...>::value>::type;
318
322 template <class T>
323 using enable_if_iterator =
324 typename std::enable_if<is_iterator<T>::value>::type;
325
329 template <class T>
330 using enable_if_not_iterator =
331 typename std::enable_if<!is_iterator<T>::value>::type;
332
336 template <class T>
337 using enable_if_string =
338 typename std::enable_if<is_string<
339 typename std::decay<T>::type>::value>::type;
340
344 template <class T>
345 using enable_if_not_string =
346 typename std::enable_if<!is_string<
347 typename std::decay<T>::type>::value>::type;
348
352 template <class T>
353 using enable_if_printable =
354 typename std::enable_if<is_printable<T>::value>::type;
355
359 template <class T>
360 using enable_if_not_printable =
361 typename std::enable_if<!is_printable<T>::value>::type;
362
366 template <class T>
367 using enable_if_char = typename std::enable_if<is_char<
368 typename std::decay<T>::type>::value>::type;
369
373 template <class T>
374 using enable_if_not_char = typename std::enable_if<!is_char<
375 typename std::decay<T>::type>::value>::type;
376
380 template <typename T>
381 using uniform_distribution_t = typename uniform_distribution_impl<T>::type;
382 // end of sfinae group
384}
本库所有组件所在的顶层命名空间。
@ F
Definition kb.h:58
@ T
Definition kb.h:72
为 STL 容器提供输出流运算符的前向声明。
检测类型是否支持下标操作符(如 T[Idx])。
Definition sfinae.h:119
检测类型是否可作为函数对象以给定参数调用(返回 void 或可转换为 void)。
Definition sfinae.h:74
检测类型是否为容器(支持 std::begin 和 std::end)。
Definition sfinae.h:52
检测类型是否为迭代器(具有 iterator_category)。
Definition sfinae.h:97
检测类型是否支持输出到 std::ostream(即定义了 operator<<)。
Definition sfinae.h:214
检测类型是否为字符串类型(char*、stdstring、std::string_view 等)。
Definition sfinae.h:140