NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
check_type.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_TYPEINFO_CHECK_TYPE_HPP__
2#define NEFORCE_CORE_TYPEINFO_CHECK_TYPE_HPP__
3
17
18#include <typeinfo>
20NEFORCE_BEGIN_NAMESPACE__
22NEFORCE_BEGIN_INNER__
23
31class output {
32private:
33 bool is_compact_{true};
34 string& str_;
35
36 template <typename T>
37 static NEFORCE_CONSTEXPR20 bool check_empty(const T& /*unused*/) noexcept {
38 return false;
39 }
40 static NEFORCE_CONSTEXPR20 bool check_empty(const char* value) noexcept {
41 return value == nullptr || value[0] == 0;
42 }
43
44 template <typename T>
45 NEFORCE_CONSTEXPR20 void out(const T& value) {
46 if (this->check_empty(value)) {
47 return;
48 }
49 if (!this->is_compact_) {
50 str_ += " ";
51 }
52 this->str_ += to_string(value);
53 this->is_compact_ = false;
54 }
55
56public:
57 NEFORCE_CONSTEXPR20 output(string& str) noexcept :
58 str_(str) {}
59
60 NEFORCE_CONSTEXPR20 output& operator()() noexcept { return *this; }
61
62 NEFORCE_CONSTEXPR20 output& compact() noexcept {
63 this->is_compact_ = true;
64 return *this;
65 }
66
67 template <typename T1, typename... T>
68 NEFORCE_CONSTEXPR20 output& operator()(const T1& value, const T&... args) {
69 this->out(value);
70 return operator()(args...);
71 }
72};
73
81template <bool IsStart>
82struct bracket {
83 output& out_;
84
85 NEFORCE_CONSTEXPR20 bracket(output& out, const char* /*unused*/ = nullptr) :
86 out_(out) {
87 out_("(").compact();
88 }
89
90 NEFORCE_CONSTEXPR20 ~bracket() {
91 try {
92 out_.compact()(")");
93 // NOLINTNEXTLINE(bugprone-empty-catch)
94 } catch (...) {
95 // ignore
96 }
97 }
98};
99
100template <>
101struct bracket<false> {
102 NEFORCE_CONSTEXPR20 bracket(output& out, const char* str = nullptr) { out(str); }
103};
104
112template <size_t N = 0>
113struct bound {
114private:
115 template <size_t NN>
116 NEFORCE_CONSTEXPR20 enable_if_t<NN == 0> __bound_dispatch() const {
117 out_("[]");
118 return;
119 }
120
121 template <size_t NN>
122 NEFORCE_CONSTEXPR20 enable_if_t<NN != 0> __bound_dispatch() const {
123 out_("[").compact()(NN).compact()("]");
124 return;
125 }
126
127public:
128 output& out_;
129
130 NEFORCE_CONSTEXPR20 bound(output& out) :
131 out_(out) {}
132
133 NEFORCE_CONSTEXPR20 ~bound() { __bound_dispatch<N>(); }
134};
135
142struct at_destruct {
143 output& out_;
144 const char* str_;
145
146 NEFORCE_CONSTEXPR20 at_destruct(output& out, const char* str = nullptr) noexcept :
147 out_(out),
148 str_(str) {}
149
150 NEFORCE_CONSTEXPR20 ~at_destruct() {
151 try {
152 out_(str_);
153 // NOLINTNEXTLINE(bugprone-empty-catch)
154 } catch (...) {
155 // ignore
156 }
157 }
158
159 NEFORCE_CONSTEXPR20 void set_str(const char* str = nullptr) noexcept { str_ = str; }
160};
161
162
163#ifdef NEFORCE_COMPILER_GNUC
164
170string NEFORCE_API real_symbol_name(string name);
171
172#endif
173
174
183template <typename T, bool IsBase = false>
184struct check {
185 output out_;
186
187 NEFORCE_CONSTEXPR20 check(const output& out) :
188 out_(out) {
189#ifdef NEFORCE_COMPILER_GNUC
191 out_(real_symbol_name(typeid(FinT).name()));
192#else
193 out_(typeid(T).name());
194#endif
195 }
196};
197
203template <typename T, bool IsBase>
204struct check<T[], IsBase> : check<T, true> {
205 using base_t = check<T, true>;
206 using base_t::out_;
207
208 bound<> bound_;
209 bracket<IsBase> bracket_;
210
211 NEFORCE_CONSTEXPR20 check(const output& out) :
212 base_t(out),
213 bound_(out_),
214 bracket_(out_) {}
215};
216
217#define CHECK_TYPE__(OPT) \
218 template <typename T, bool IsBase> \
219 struct check<T OPT, IsBase> : check<T, true> { \
220 using base_t = check<T, true>; \
221 using base_t::out_; \
222 \
223 NEFORCE_CONSTEXPR20 check(const output& out) : \
224 base_t(out) { \
225 out_(#OPT); \
226 } \
227 };
228
229CHECK_TYPE__(const)
230CHECK_TYPE__(volatile)
231CHECK_TYPE__(const volatile)
232CHECK_TYPE__(&)
233CHECK_TYPE__(&&)
234CHECK_TYPE__(*)
235#undef CHECK_TYPE__
236
237
238template <bool IsStart, typename... P>
239struct parameter;
240
249template <bool IsStart, typename P1, typename... P>
250struct parameter<IsStart, P1, P...> {
251 output& out_;
252
253 NEFORCE_CONSTEXPR20 parameter(output& out) noexcept :
254 out_(out) {}
255
256 NEFORCE_CONSTEXPR20 ~parameter() {
257 [this](bracket<IsStart>&&) {
258 check<P1>{out_};
259 parameter<false, P...>{out_.compact()};
260 }(bracket<IsStart>{out_, ","});
261 }
262};
263
268template <bool IsStart>
269struct parameter<IsStart> {
270 output& out_;
271
272 NEFORCE_CONSTEXPR20 parameter(output& out) noexcept :
273 out_(out) {}
274
275 NEFORCE_CONSTEXPR20 ~parameter() { bracket<IsStart>{out_}; }
276};
277
278
279#define CHECK_TYPE_ARRAY__(CV_OPT, BOUND_OPT, ...) \
280 template <typename T, bool IsBase __VA_ARGS__> \
281 struct check<T CV_OPT[BOUND_OPT], IsBase> : check<T CV_OPT, !is_array_v<T>> { \
282 using base_t = check<T CV_OPT, !is_array_v<T>>; \
283 using base_t::out_; \
284 \
285 bound<BOUND_OPT> bound_; \
286 bracket<IsBase> bracket_; \
287 \
288 NEFORCE_CONSTEXPR20 check(const output& out) : \
289 base_t(out), \
290 bound_(out_), \
291 bracket_(out_) {} \
292 };
293
294#define CHECK_TYPE_ARRAY_CV__(BOUND_OPT, ...) \
295 CHECK_TYPE_ARRAY__(, BOUND_OPT, , ##__VA_ARGS__) \
296 CHECK_TYPE_ARRAY__(const, BOUND_OPT, , ##__VA_ARGS__) \
297 CHECK_TYPE_ARRAY__(volatile, BOUND_OPT, , ##__VA_ARGS__) \
298 CHECK_TYPE_ARRAY__(const volatile, BOUND_OPT, , ##__VA_ARGS__)
299
300#ifdef NEFORCE_COMPILER_GNUC
301CHECK_TYPE_ARRAY_CV__(0)
302#endif
303CHECK_TYPE_ARRAY_CV__(N, size_t N)
304CHECK_TYPE_ARRAY__(const, , )
305CHECK_TYPE_ARRAY__(volatile, , )
306CHECK_TYPE_ARRAY__(const volatile, , )
307
308#undef CHECK_TYPE_ARRAY__
309#undef CHECK_TYPE_ARRAY_CV__
310
317template <typename T, bool IsBase, typename... P>
318struct check<T(P...), IsBase> : check<T, true> {
319 using base_t = check<T, true>;
320 using base_t::out_;
321
322 parameter<true, P...> parameter_;
323 bracket<IsBase> bracket_;
324
325 NEFORCE_CONSTEXPR20 check(const output& out) :
326 base_t(out),
327 parameter_(out_),
328 bracket_(out_) {}
329};
330
337template <typename T, bool IsBase, typename C>
338struct check<T C::*, IsBase> : check<T, true> {
339 using base_t = check<T, true>;
340 using base_t::out_;
341
342 NEFORCE_CONSTEXPR20 check(const output& out) :
343 base_t(out) {
344 check<C>{out_};
345 out_.compact()("::*");
346 }
347};
348
356template <typename T, bool IsBase, typename C, typename... P>
357struct check<T (C::*)(P...), IsBase> : check<T(P...), true> {
358 using base_t = check<T(P...), true>;
359 using base_t::out_;
360
361 NEFORCE_CONSTEXPR20 check(const output& out) :
362 base_t(out) {
363 check<C>{out_};
364 out_.compact()("::*");
365 }
366};
367
368#define CHECK_TYPE_MEM_FUNC__(...) \
369 template <typename T, bool IsBase, typename C, typename... P> \
370 struct check<T (C::*)(P...) __VA_ARGS__, IsBase> { \
371 at_destruct cv_; \
372 check<T(P...), true> base_; \
373 output& out_ = base_.out_; \
374 \
375 NEFORCE_CONSTEXPR20 check(const output& out) : \
376 cv_(base_.out_), \
377 base_(out) { \
378 cv_.set_str(#__VA_ARGS__); \
379 check<C>{out_}; \
380 out_.compact()("::*"); \
381 } \
382 };
383
384CHECK_TYPE_MEM_FUNC__(const)
385CHECK_TYPE_MEM_FUNC__(volatile)
386CHECK_TYPE_MEM_FUNC__(const volatile)
387#undef CHECK_TYPE_MEM_FUNC__
388
389NEFORCE_END_INNER__
391
397
403template <typename T>
404NEFORCE_CONSTEXPR20 string check_type() {
405 string str;
406 inner::check<T>{str};
407 return _NEFORCE move(str);
408}
409 // CheckType
411
412NEFORCE_END_NAMESPACE__
413#endif // NEFORCE_CORE_TYPEINFO_CHECK_TYPE_HPP__
constexpr string check_type()
检查类型并返回可读字符串
typename remove_function_qualifiers< T >::type remove_function_qualifiers_t
remove_function_qualifiers的便捷别名
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
bool name(char *buffer, size_t size)
获取当前线程名称
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
constexpr string to_string(const CharT &c)
将字符转换为普通字符串
数值类型包装类