1#ifndef MSTL_CORE_TYPEINFO_CHECK_TYPE_HPP__
2#define MSTL_CORE_TYPEINFO_CHECK_TYPE_HPP__
3#include "../utility/packages.hpp"
4#ifdef MSTL_COMPILER_GNUC__
17 static MSTL_CONSTEXPR20
bool check_empty(
const T&) {
return false; }
18 static MSTL_CONSTEXPR20
bool check_empty(
const char* val) {
return !val || val[0] == 0; }
21 MSTL_CONSTEXPR20
void out(
const T& val) {
22 if (this->check_empty(val))
return;
23 if (!this->is_compact_) sr_ +=
" ";
24 this->sr_ += to_string(val);
25 this->is_compact_ =
false;
29 MSTL_CONSTEXPR20 output(
string& sr) : is_compact_(true), sr_(sr) {}
30 MSTL_CONSTEXPR20 output& operator ()() {
return *
this; }
31 MSTL_CONSTEXPR20 output& compact(){
32 this->is_compact_ =
true;
36 template <
typename T1,
typename... T>
37 MSTL_CONSTEXPR20 output& operator ()(
const T1& val,
const T&... args) {
39 return operator ()(args...);
46 MSTL_CONSTEXPR20 bracket(output& out,
const char* =
nullptr) : out_(out) {
49 MSTL_CONSTEXPR20 ~bracket() {
54struct bracket<false> {
55 MSTL_CONSTEXPR20 bracket(output& out,
const char* str =
nullptr) { out(str); }
58template <
size_t N = 0>
61 template <
size_t NN, enable_if_t<NN == 0,
int> = 0>
62 MSTL_CONSTEXPR20
void __bound_dispatch()
const { out_(
"[]"); }
63 template <
size_t NN, enable_if_t<NN != 0,
int> = 0>
64 MSTL_CONSTEXPR20
void __bound_dispatch()
const { out_(
"[").compact()(NN).compact()(
"]"); }
69 MSTL_CONSTEXPR20 bound(output& out) : out_(out) {}
70 MSTL_CONSTEXPR20 ~bound() {
71 __bound_dispatch<N>();
75template <bool,
typename... P>
78template <
bool IsStart>
79struct parameter<IsStart> {
82 MSTL_CONSTEXPR20 parameter(output& out) : out_(out) {}
83 MSTL_CONSTEXPR20 ~parameter() { bracket<IsStart> { out_ }; }
87template <
typename T,
bool IsBase = false>
91 MSTL_CONSTEXPR20 check(
const output& out) : out_(out) {
92#ifdef MSTL_COMPILER_GNUC__
93 auto deleter = [](
char* p) {
if (p) std::free(p); };
95 _MSTL unique_ptr<char,
decltype(deleter)> real_name {
96 ::abi::__cxa_demangle(
typeid(FinT).name(),
nullptr,
nullptr,
nullptr), deleter
98 out_(real_name.get());
100 out_(
typeid(T).name());
105template <
typename T,
bool IsBase>
106struct check<T[], IsBase> : check<T, true> {
107 using base_t = check<T, true>;
110 bracket<IsBase> bracket_;
112 MSTL_CONSTEXPR20 check(
const output& out) : base_t(out), bound_(out_), bracket_(out_) {}
115#define CHECK_TYPE__(OPT) \
116 template <typename T, bool IsBase> \
117 struct check<T OPT, IsBase> : check<T, true> { \
118 using base_t = check<T, true>; \
119 using base_t::out_; \
120 MSTL_CONSTEXPR20 check(const output& out) : base_t(out) { out_(#OPT); } \
124CHECK_TYPE__(volatile)
125CHECK_TYPE__(const volatile)
132template <
bool IsStart,
typename P1,
typename... P>
133struct parameter<IsStart, P1, P...> {
135 MSTL_CONSTEXPR20 parameter(output& out) : out_(out) {}
136 MSTL_CONSTEXPR20 ~parameter() {
137 [
this](bracket<IsStart>&&) {
139 parameter<
false, P...> { out_.compact() };
140 } (bracket<IsStart> { out_,
"," });
144#define CHECK_TYPE_ARRAY__(CV_OPT, BOUND_OPT, ...) \
145 template <typename T, bool IsBase __VA_ARGS__> \
146 struct check<T CV_OPT [BOUND_OPT], IsBase> : check<T CV_OPT, !is_array_v<T>> { \
147 using base_t = check<T CV_OPT, !is_array_v<T>>; \
148 using base_t::out_; \
149 bound<BOUND_OPT> bound_; \
150 bracket<IsBase> bracket_; \
151 MSTL_CONSTEXPR20 check(const output& out) : base_t(out) \
157#define CHECK_TYPE_ARRAY_CV__(BOUND_OPT, ...) \
158 CHECK_TYPE_ARRAY__(, BOUND_OPT, ,##__VA_ARGS__) \
159 CHECK_TYPE_ARRAY__(const, BOUND_OPT, ,##__VA_ARGS__) \
160 CHECK_TYPE_ARRAY__(volatile, BOUND_OPT, ,##__VA_ARGS__) \
161 CHECK_TYPE_ARRAY__(const volatile, BOUND_OPT, ,##__VA_ARGS__)
163#ifdef MSTL_COMPILE_GNUC__
164CHECK_TYPE_ARRAY_CV__(0)
166CHECK_TYPE_ARRAY_CV__(N,
size_t N)
167CHECK_TYPE_ARRAY__(
const, , )
168CHECK_TYPE_ARRAY__(volatile, , )
169CHECK_TYPE_ARRAY__(const volatile, , )
171#undef CHECK_TYPE_ARRAY__
172#undef CHECK_TYPE_ARRAY_CV__
174template <
typename T,
bool IsBase,
typename... P>
175struct check<T(P...), IsBase> : check<T, true> {
176 using base_t = check<T, true>;
178 parameter<
true, P...> parameter_;
179 bracket<IsBase> bracket_;
181 MSTL_CONSTEXPR20 check(
const output& out)
182 : base_t(out), parameter_(out_), bracket_(out_) {}
185template <
typename T,
bool IsBase,
typename C>
186struct check<T C::*, IsBase> : check<T, true> {
187 using base_t = check<T, true>;
190 MSTL_CONSTEXPR20 check(
const output& out) : base_t(out) {
192 out_.compact()(
"::*");
196template <
typename T,
bool IsBase,
typename C,
typename... P>
197struct check<T(C::*)(P...), IsBase> : check<T(P...), true> {
198 using base_t = check<T(P...),
true>;
201 MSTL_CONSTEXPR20 check(
const output& out) : base_t(out) {
203 out_.compact()(
"::*");
211 MSTL_CONSTEXPR20 at_destruct(output& out,
const char* str =
nullptr): out_(out), str_(str) {}
212 MSTL_CONSTEXPR20 ~at_destruct() { out_(str_); }
213 MSTL_CONSTEXPR20
void set_str(
const char* str =
nullptr) { str_ = str; }
216#define CHECK_TYPE_MEM_FUNC__(...) \
217 template <typename T, bool IsBase, typename C, typename... P> \
218 struct check<T(C::*)(P...) __VA_ARGS__, IsBase> { \
220 check<T(P...), true> base_; \
221 output& out_ = base_.out_; \
222 MSTL_CONSTEXPR20 check(const output& out) \
223 : cv_(base_.out_), base_(out) { \
224 cv_.set_str(#__VA_ARGS__); \
226 out_.compact()("::*"); \
230CHECK_TYPE_MEM_FUNC__(
const)
231CHECK_TYPE_MEM_FUNC__(volatile)
232CHECK_TYPE_MEM_FUNC__(const volatile)
233#undef CHECK_TYPE_MEM_FUNC__
238MSTL_CONSTEXPR20
string check_type() {
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_INNER__
结束inner命名空间
#define _INNER
inner命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_INNER__
开始inner命名空间
typename remove_function_qualifiers< T >::type remove_function_qualifiers_t
remove_function_qualifiers的便捷别名