#ifndef _STATIC_H_
#define _STATIC_H_
//静态反射库(C++26提案中出现C++静态反射)
//但是C++能通过一些现有的手段实现静态反射,这里尝试一下写一个C++的静态反射

//验证宏的参数个数

//这个也很有意思,用了64个占位符号,

#define EMPTY_MACRO_CHECK(...) __VA_ARGS__ EMPTY_MACRO_CHECK_1     //用于实现判断参数个数是不是零个,如果是0个将返回一个全空的字符串
#define EMPTY_MACRO_CHECK_1(...) #__VA_ARGS__  


#define GET_NTR_AGR(   \
    _1,_2,_3,_4,_5,_6,_7,_8,_9,_10, \
    _11,_12,_13,_14,_15,_16,_17,_18, \
    _19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,\
    _31,_32,_33,_34,_35,_36,_37,_38,_39,\
    _40,_41,_42,_43,_44,_45,_46,_47,_48,_49,\
    _50,_51,_52,_53,_54,_55,_56,_57,_58,_59, \
    _60,_61,_62,_63,_64,n,...)n

#define GET_ARG_COUNT(...)  GET_NTR_AGR(__VA_ARGS__,                    \
            64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, \
            48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, \
            32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, \
            16, 15, 14, 13, 12, 11, 10, 9,  8,  7,  6,  5,  4,  3,  2,  1,0 ) \



//接下来一个计算结构体的参数类型的泛型


struct Any_type
{
    template<typename T>
    operator T();                      //即代表在模板中Any_type结构体可以转换为任意类型(当然,这个只能在编译期的模板中使用)
                                        //这是C++模板的一个很重要的特性,即C++在模板中不会关注这个类型能否这样进行转换,也不关注是怎么进行转换的
                                        //(这也是为什么这个函数连函数体都可以没有)
                                        //C++模板推导过程中只关注这个函数的转换的类型结果是什么
                                        //同时也可以引出另一个特性,即C++模板推导中使用一个函数的返回值作为推导依据时,同样C++也只关注返回值类型是什么
                                        //同时C++的特化是做惰性特化,在运行期不调用的函数根本不会进行特化
                                        //这也就是为什么这个函数可以存在且运行期不会报错的原因,因为C++根本没有生成这个模板函数的实例
                                        //下面就是一个例子
};



/******************************************
 * 加上第二个前置的知识SFINAE(Substitution failure is not an error)
 * 首先一言以蔽之,这实际上可以理解为模板的重载
 * 这几个词确实很抽象
 * 一个一个解释Substitution指的是模板匹配的过程
 * failure失败,歧义主要出现在这里
 * 在计算机程序中的失败和现实中不太一样
 * 看一个例子(if语句)
 *int a=0;
 *if(a==1)
 * a++;
 *if(a==0)
 * a--;
 * 首先在if(a==1)中会匹配失败(failure)
 * 但是会继续去匹配if(a==0)即failure is not error
 * 
 *  
 * ******************************************/
// template <typename T,typename ... Args>
// consteval int CountMember(Args&&... args)       等价写法
template <typename T>
consteval int CountMember(auto&&... Args)
{
    if constexpr(!requires{T{Args...};})
    {
        return sizeof...(Args)-1;
    }
    else{
        return CountMember<T>(Args... , Any_type{});           //递归添加一个额外的参数
    }
}

#endif