1#ifndef NEFORCE_CORE_TYPEINFO_CHECK_TYPE_HPP__
2#define NEFORCE_CORE_TYPEINFO_CHECK_TYPE_HPP__
20NEFORCE_BEGIN_NAMESPACE__
37 static NEFORCE_CONSTEXPR20
bool check_empty(
const T&)
noexcept {
40 static NEFORCE_CONSTEXPR20
bool check_empty(
const char* value)
noexcept {
return !value || value[0] == 0; }
43 NEFORCE_CONSTEXPR20
void out(
const T& value) {
44 if (this->check_empty(value)) {
47 if (!this->is_compact_) {
51 this->is_compact_ =
false;
55 NEFORCE_CONSTEXPR20 output(
string& str) noexcept :
59 NEFORCE_CONSTEXPR20 output& operator()() noexcept {
return *
this; }
61 NEFORCE_CONSTEXPR20 output& compact() noexcept {
62 this->is_compact_ =
true;
66 template <
typename T1,
typename... T>
67 NEFORCE_CONSTEXPR20 output& operator()(
const T1& value,
const T&... args) {
69 return operator()(args...);
80template <
bool IsStart>
84 NEFORCE_CONSTEXPR20 bracket(output& out,
const char* =
nullptr) :
89 NEFORCE_CONSTEXPR20 ~bracket() { out_.compact()(
")"); }
93struct bracket<false> {
94 NEFORCE_CONSTEXPR20 bracket(output& out,
const char* str =
nullptr) { out(str); }
104template <
size_t N = 0>
115 out_(
"[").compact()(NN).compact()(
"]");
122 NEFORCE_CONSTEXPR20 bound(output& out) :
125 NEFORCE_CONSTEXPR20 ~bound() { __bound_dispatch<N>(); }
138 NEFORCE_CONSTEXPR20 at_destruct(output& out,
const char* str =
nullptr) noexcept :
142 NEFORCE_CONSTEXPR20 ~at_destruct() { out_(str_); }
144 NEFORCE_CONSTEXPR20
void set_str(
const char* str =
nullptr) noexcept { str_ = str; }
148#ifdef NEFORCE_COMPILER_GNUC
155string NEFORCE_API real_symbol_name(
string name);
168template <
typename T,
bool IsBase = false>
172 NEFORCE_CONSTEXPR20 check(
const output& out) :
174#ifdef NEFORCE_COMPILER_GNUC
176 out_(real_symbol_name(
typeid(FinT).
name()));
178 out_(
typeid(T).
name());
188template <
typename T,
bool IsBase>
189struct check<T[], IsBase> : check<T, true> {
190 using base_t = check<T, true>;
194 bracket<IsBase> bracket_;
196 NEFORCE_CONSTEXPR20 check(
const output& out) :
202#define CHECK_TYPE__(OPT) \
203 template <typename T, bool IsBase> \
204 struct check<T OPT, IsBase> : check<T, true> { \
205 using base_t = check<T, true>; \
206 using base_t::out_; \
208 NEFORCE_CONSTEXPR20 check(const output& out) : \
215CHECK_TYPE__(volatile)
216CHECK_TYPE__(const volatile)
223template <
bool IsStart,
typename... P>
234template <
bool IsStart,
typename P1,
typename... P>
235struct parameter<IsStart, P1, P...> {
238 NEFORCE_CONSTEXPR20 parameter(output& out) noexcept :
241 NEFORCE_CONSTEXPR20 ~parameter() {
242 [
this](bracket<IsStart>&&) {
244 parameter<
false, P...>{out_.compact()};
245 }(bracket<IsStart>{out_,
","});
253template <
bool IsStart>
254struct parameter<IsStart> {
257 NEFORCE_CONSTEXPR20 parameter(output& out) noexcept :
260 NEFORCE_CONSTEXPR20 ~parameter() { bracket<IsStart>{out_}; }
264#define CHECK_TYPE_ARRAY__(CV_OPT, BOUND_OPT, ...) \
265 template <typename T, bool IsBase __VA_ARGS__> \
266 struct check<T CV_OPT[BOUND_OPT], IsBase> : check<T CV_OPT, !is_array_v<T>> { \
267 using base_t = check<T CV_OPT, !is_array_v<T>>; \
268 using base_t::out_; \
270 bound<BOUND_OPT> bound_; \
271 bracket<IsBase> bracket_; \
273 NEFORCE_CONSTEXPR20 check(const output& out) : \
279#define CHECK_TYPE_ARRAY_CV__(BOUND_OPT, ...) \
280 CHECK_TYPE_ARRAY__(, BOUND_OPT, , ##__VA_ARGS__) \
281 CHECK_TYPE_ARRAY__(const, BOUND_OPT, , ##__VA_ARGS__) \
282 CHECK_TYPE_ARRAY__(volatile, BOUND_OPT, , ##__VA_ARGS__) \
283 CHECK_TYPE_ARRAY__(const volatile, BOUND_OPT, , ##__VA_ARGS__)
285#ifdef NEFORCE_COMPILER_GNUC
286CHECK_TYPE_ARRAY_CV__(0)
288CHECK_TYPE_ARRAY_CV__(N,
size_t N)
289CHECK_TYPE_ARRAY__(
const, , )
290CHECK_TYPE_ARRAY__(volatile, , )
291CHECK_TYPE_ARRAY__(const volatile, , )
293#undef CHECK_TYPE_ARRAY__
294#undef CHECK_TYPE_ARRAY_CV__
302template <
typename T,
bool IsBase,
typename... P>
303struct check<T(P...), IsBase> : check<T, true> {
304 using base_t = check<T, true>;
307 parameter<
true, P...> parameter_;
308 bracket<IsBase> bracket_;
310 NEFORCE_CONSTEXPR20 check(
const output& out) :
322template <
typename T,
bool IsBase,
typename C>
323struct check<T C::*, IsBase> : check<T, true> {
324 using base_t = check<T, true>;
327 NEFORCE_CONSTEXPR20 check(
const output& out) :
330 out_.compact()(
"::*");
341template <
typename T,
bool IsBase,
typename C,
typename... P>
342struct check<T (C::*)(P...), IsBase> : check<T(P...), true> {
343 using base_t = check<T(P...),
true>;
346 NEFORCE_CONSTEXPR20 check(
const output& out) :
349 out_.compact()(
"::*");
353#define CHECK_TYPE_MEM_FUNC__(...) \
354 template <typename T, bool IsBase, typename C, typename... P> \
355 struct check<T (C::*)(P...) __VA_ARGS__, IsBase> { \
357 check<T(P...), true> base_; \
358 output& out_ = base_.out_; \
360 NEFORCE_CONSTEXPR20 check(const output& out) : \
363 cv_.set_str(#__VA_ARGS__); \
365 out_.compact()("::*"); \
369CHECK_TYPE_MEM_FUNC__(
const)
370CHECK_TYPE_MEM_FUNC__(volatile)
371CHECK_TYPE_MEM_FUNC__(const volatile)
372#undef CHECK_TYPE_MEM_FUNC__
391 inner::check<T>{str};
392 return _NEFORCE
move(str);
397NEFORCE_END_NAMESPACE__
NEFORCE_CONSTEXPR20 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)))
移动范围元素
NEFORCE_ALWAYS_INLINE_INLINE bool name(char *buffer, size_t size)
获取当前线程名称
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
NEFORCE_CONSTEXPR20 string to_string(const CharT &c)
将字符转换为普通字符串