1#ifndef NEFORCE_CORE_TYPEINFO_CHECK_TYPE_HPP__
2#define NEFORCE_CORE_TYPEINFO_CHECK_TYPE_HPP__
20NEFORCE_BEGIN_NAMESPACE__
33 bool is_compact_{
true};
37 static NEFORCE_CONSTEXPR20
bool check_empty(
const T& )
noexcept {
40 static NEFORCE_CONSTEXPR20
bool check_empty(
const char* value)
noexcept {
41 return value ==
nullptr || value[0] == 0;
45 NEFORCE_CONSTEXPR20
void out(
const T& value) {
46 if (this->check_empty(value)) {
49 if (!this->is_compact_) {
53 this->is_compact_ =
false;
57 NEFORCE_CONSTEXPR20 output(
string& str) noexcept :
60 NEFORCE_CONSTEXPR20 output& operator()() noexcept {
return *
this; }
62 NEFORCE_CONSTEXPR20 output& compact() noexcept {
63 this->is_compact_ =
true;
67 template <
typename T1,
typename... T>
68 NEFORCE_CONSTEXPR20 output& operator()(
const T1& value,
const T&... args) {
70 return operator()(args...);
81template <
bool IsStart>
85 NEFORCE_CONSTEXPR20 bracket(output& out,
const char* =
nullptr) :
90 NEFORCE_CONSTEXPR20 ~bracket() {
101struct bracket<false> {
102 NEFORCE_CONSTEXPR20 bracket(output& out,
const char* str =
nullptr) { out(str); }
112template <
size_t N = 0>
123 out_(
"[").compact()(NN).compact()(
"]");
130 NEFORCE_CONSTEXPR20 bound(output& out) :
133 NEFORCE_CONSTEXPR20 ~bound() { __bound_dispatch<N>(); }
146 NEFORCE_CONSTEXPR20 at_destruct(output& out,
const char* str =
nullptr) noexcept :
150 NEFORCE_CONSTEXPR20 ~at_destruct() {
159 NEFORCE_CONSTEXPR20
void set_str(
const char* str =
nullptr) noexcept { str_ = str; }
163#ifdef NEFORCE_COMPILER_GNUC
170string NEFORCE_API real_symbol_name(
string name);
183template <
typename T,
bool IsBase = false>
187 NEFORCE_CONSTEXPR20 check(
const output& out) :
189#ifdef NEFORCE_COMPILER_GNUC
191 out_(real_symbol_name(
typeid(FinT).
name()));
193 out_(
typeid(T).
name());
203template <
typename T,
bool IsBase>
204struct check<T[], IsBase> : check<T, true> {
205 using base_t = check<T, true>;
209 bracket<IsBase> bracket_;
211 NEFORCE_CONSTEXPR20 check(
const output& out) :
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_; \
223 NEFORCE_CONSTEXPR20 check(const output& out) : \
230CHECK_TYPE__(volatile)
231CHECK_TYPE__(const volatile)
238template <
bool IsStart,
typename... P>
249template <
bool IsStart,
typename P1,
typename... P>
250struct parameter<IsStart, P1, P...> {
253 NEFORCE_CONSTEXPR20 parameter(output& out) noexcept :
256 NEFORCE_CONSTEXPR20 ~parameter() {
257 [
this](bracket<IsStart>&&) {
259 parameter<
false, P...>{out_.compact()};
260 }(bracket<IsStart>{out_,
","});
268template <
bool IsStart>
269struct parameter<IsStart> {
272 NEFORCE_CONSTEXPR20 parameter(output& out) noexcept :
275 NEFORCE_CONSTEXPR20 ~parameter() { bracket<IsStart>{out_}; }
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_; \
285 bound<BOUND_OPT> bound_; \
286 bracket<IsBase> bracket_; \
288 NEFORCE_CONSTEXPR20 check(const output& out) : \
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__)
300#ifdef NEFORCE_COMPILER_GNUC
301CHECK_TYPE_ARRAY_CV__(0)
303CHECK_TYPE_ARRAY_CV__(N,
size_t N)
304CHECK_TYPE_ARRAY__(
const, , )
305CHECK_TYPE_ARRAY__(volatile, , )
306CHECK_TYPE_ARRAY__(const volatile, , )
308#undef CHECK_TYPE_ARRAY__
309#undef CHECK_TYPE_ARRAY_CV__
317template <
typename T,
bool IsBase,
typename... P>
318struct check<T(P...), IsBase> : check<T, true> {
319 using base_t = check<T, true>;
322 parameter<
true, P...> parameter_;
323 bracket<IsBase> bracket_;
325 NEFORCE_CONSTEXPR20 check(
const output& out) :
337template <
typename T,
bool IsBase,
typename C>
338struct check<T C::*, IsBase> : check<T, true> {
339 using base_t = check<T, true>;
342 NEFORCE_CONSTEXPR20 check(
const output& out) :
345 out_.compact()(
"::*");
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>;
361 NEFORCE_CONSTEXPR20 check(
const output& out) :
364 out_.compact()(
"::*");
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> { \
372 check<T(P...), true> base_; \
373 output& out_ = base_.out_; \
375 NEFORCE_CONSTEXPR20 check(const output& out) : \
378 cv_.set_str(#__VA_ARGS__); \
380 out_.compact()("::*"); \
384CHECK_TYPE_MEM_FUNC__(
const)
385CHECK_TYPE_MEM_FUNC__(volatile)
386CHECK_TYPE_MEM_FUNC__(const volatile)
387#undef CHECK_TYPE_MEM_FUNC__
406 inner::check<T>{str};
407 return _NEFORCE
move(str);
412NEFORCE_END_NAMESPACE__
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)
将字符转换为普通字符串