Meta
meta里的东西很多,没法一一地去解释,所以我先选取一些使用得比较多的内容来加以分析。
namespace
meta主要有三个部分的名空间meta,meta::detail,meta::lazy,其中暴露出去的主要是meta名空间,而实现则放在detail中,lazy名空间放的都是特殊的、适用于lazy情况下的功能实现。我将主要分析meta中的内容。lazy中的功能多半是meta中的功能的defer修饰后的版本。
meta部分
nil_: 空类型,主要用于后续的sfinae_t: 用于获取trait类型的::type_v: 用于获取std::integral_constant这样的编译期常量的值bool_ int_ ...: 用于创建对应类型std::integral_constant的模板inc dec plus minus ...: 处理std::integral_constant的编译期类型函数,实际是编译期计算的工具。其返回的也是std::integral_constant。template <META_TYPE_CONSTRAINT(invocable) Fn, typename... Args> invoke: 调用Fn::template invoke<Args...>,应该是为了调用编译期类型函数。template <typename T> struct id: 一种特殊的trait,其总是返回其参数T,其同时也是可调用的一个编译期类型函数(其内含::invoke),调用的结果也是其参数Tid_t: 其参数T的别称,用在非推导的环境下is_trait: 利用sfinae实现的,通过判断类型具不具有::type来判断其是不是trait,返回std::integral_constantis_callable: 利用sfinae实现的,通过判断类型具不具有::invoke来判断其是不是编译期类型函数,返回std::integral_constantmake_integer_sequence和make_index_sequence的实现部分,是为了兼容c++14以下的c++版本。detail::indices_strategy_: 表示索引策略的枚举类型,有done,repeat,recurse三种取值constexpr detail::indices_strategy_ detail::strategy_(std::size_t cur, std::size_t end): 根据给定的参数,返回索引策略indices_stragtegy_,其划分大致为下:done:cur >= endrepeat:cur*2 <= endrecurse:other
constexpr std::size_t detail::range_distance_(T begin, T end): 在begin<=end的前提下,直接将end-begin转化为size_ttemplate <std::size_t End, typename State, indices_strategy_ Status_> struct detail::make_indices_: 用于创建一个已有State,目标为End的index_sequence即([0,1,2,...,N-1]的序列,这里N=End),而Status_则是用来判断如何构造这个序列,其值可用前文的strategy_来取得。repeat代表将当前State整个叠加到自身,而recurse则是加上距离目标序列缺失的部分内容。这样,整个构造过程的复杂度就是O(log(N))的。其结果放在其内::type中。template <typename T, T, typename> struct detail::coerce_indices_: 其原始意义不是很明确,但是其的一个偏特化实现template <typename T, T Offset, std::size_t... Values> struct coerce_indices_<T, Offset, index_sequence<Values...>>实现了将index_sequence的所有值都加上一个Offset的功能。其结果也放在其内的::type中。integer_sequence: 类型为T的编译期的整数序列index_sequence: 类型为std::size_t的编译期序列,实际上是integer_sequence的特殊版本template <typename, typename> struct detail::concat_indices_: 其特化的版本表明,其主要功能是将两个index_sequence合并,实际上就是第二部分的index_sequence每个元素都加上前一个的size。make_integer_sequence: 生成一个元素类型为T的[0,1,2,...,N-1]的integer_sequence。make_index_sequence: 生成一个size_t的[0,1,2,...,N-1]的index_sequence
defer: 给定一个模板C,返回id<C<Ts...>>类型defer_i: 给定一个接受若干相同类型模板参数的模板D,返回id<D<Is...>>defer_trait: 给定一个trait和其模板参数,使用defer、detail::defer_和detail::_t_t来延迟获取其结果::typedefer_trait: 给定一个接受T类型模板参数的trait,使用defer、detail::defer_i_和detail::_t_t来延迟获取其结果::typecompose: 将多个编译器类型函数复合成F1(F2(...(Fn(Ts...)))的形式quote: 将一个模板包装成一个带有::invoke的编译期类型函数quote_i: 将一个接受T类型模板参数的模板包装成一个带有::invoke的编译期类型函数quote_trait: 将一个trait模板类(带有::type)包装成一个带有::invoke的编译期类型函数quote_trait_i: 将一个接受T类型模板参数的trait模板类(带有::type)包装成一个带有::invoke的编译期类型函数bind_front: 绑定一个编译期类型函数的前半部分参数bind_back: 绑定一个编译期类型函数的后半部分参数apply: 给定一个带有::invoke的编译期类型函数Fn,和一个类型L,其会根据几种情况去利用L中的类型信息去调用Fn(invoke)L=Ret(Args...):lazy::invoke<Fn,Ret,Args...>L=T<Ts...>:lazy::invoke<Fn,Ts...>L=std::integer_sequence<T, Is...>:lazy::invoke<Fn,std::integral_constant<T, Is>...>
curry: 给定一个带有::invoke的编译期类型函数Fn和一个返回值为列表类型(形如list<Args...>)的带有::invoke的编译期类型函数Q,返回一个以Q调用后返回的列表类型为参数去调用Fn的带有::invoke的编译期类型函数uncurry: 给定一个带有::invoke的编译期类型函数Fn,返回一个接受列表类型(形如list<Args...>)的参数去解包调用Fn的带有::invoke的编译期类型函数flip: 将模板参数列表的第一项和第二项交换位置,然后去调用Fn(Fn是带有::invoke的编译期类型函数)template<typename Fn,typename Gs...> on: 生成一个带有::invoke的编译期类型函数,其通过传递其自身的模板参数表给compose<Gs...>,将最终得到的模板参数表给Fn调用。template<bool If,typename Then,typename Eles> conditional_t: 通过编译期bool型常量,来确定是哪个类型if_: 接受list<Args...>作为参数的conditional_tif_c: 接受list<bool_<If>,Args...>作为参数的conditional_t(指定了if的结果)fold: 接受一个list、State和Fn,构造出一个包装在defer里的形如Fn(Fn(...Fn(State,T0)...,TN-2),TN-1)的类型accumulate:fold的别名reverse_fold: 接受一个list、State和Fn,构造出一个包装在defer里的形如Fn(Fn(...Fn(State,TN-1)...,T1),T0)的类型npos: 一个表示找不到结果的值(实际是std::integral_constant类型)list: 一个可以包裹任意多类型的模板类,其内含有::type(值为其自身),和::size()(返回其含的模板参数的个数)size: 获取一个list的size,返回的是一个std::integral_constantconcat: 将多个list合为一个listjoin: 将一个由多个list构成的list合并为一个listtransform: 将一个list<Args...>和Fn构成的list作为参数,返回一个list,其中每个元素都将list<Args...>中对应元素传入Fn后得到的结果。亦可以传入两个list<Args...>,那么新的list的元素就是以两个list<Args...>中的对应元素同时传入Fn后得到的结果repeat_n_c: 返回一个含有N个T类型的listrepeat_n: 功能与repeat_n_c相同,不过接受的N是std::integral_constantat_c: 返回一个list中下标为N的类型at: 功能与at_c相同,不过接受的N是std::integral_constantdrop_c: 返回一个新的list,其不含有原list的前N个元素drop: 功能与drop_c相同,不过接受的N是std::integral_constantfront: 返回list的首元素back: 返回list的尾元素push_front: 将一些元素加到list的首部,返回这个新的listpop_front: 返回一个list,其是原list移去首元素得到的。push_back: 将一些元素加到list的末尾,返回这个新的listempty: 判断一个list是不是空的,返回一个std::integral_constantpair: 只含两个元素的listfirst: 返回pair的第一个元素second: 返回pair的第二个元素find_index: 返回list中第一个与T相同的元素的下标,其类型为std::integral_constantreverse_find_index: 返回list中最后一个与T相同的元素的下标,其类型为std::integral_constantfind: 返回一个list,其是将原list中第一个T元素前的元素全部删去后的结果,如果原list没有T元素,则返回空list。reverse_find: 返回一个list,其是将原list中最后一个T元素前的元素全部删去后的结果,如果原list没有T元素,则返回空list。find_if: 返回一个list,其是将原list中将第一个传入Fn将返回true的元素前的元素全部删去后的结果,如果原list没有满足条件的元素,则返回空list。reverse_find_if: 返回一个list,其是将原list中将最后一个传入Fn将返回true的元素前的元素全部删去后的结果,如果原list没有满足条件的元素,则返回空list。replace: 返回一个list,其是原list中所有T元素都被替换成U后的结果replace_if: 返回一个list,其是原list中所有被传入Fn将返回true的元素都被替换成U后的结果count: 返回一个list中有多少个T元素,是std::integral_constantcount_if: 返回一个list中有多少个元素被传入Fn将返回true,结果是std::integral_constantfilter: 返回一个list,其是所有原list中所有被传入Fn将返回true的元素所构成的for_each: 将一个list的每个元素都传入Fn做调用(这个Fn不是编译期类型函数)transpose: 返回一个二维的list转置后的二维listzip_with: 给定一个二维list和一个编译期类型函数Fn,将这个二维list中的每一个list都当作其对应位置模板参数的取值,将这些取值按照一维list的长度,分次传给Fn,将这些结果放到要返回的新的list中。zip:transpose的别名as_list: 利用apply的规则,将一个类型T变成一个listreverse: 返回一个翻转后的listnot_fn: 返回一个新的编译期类型函数,其将原函数的返回值取反all_of: 返回是不是list的所有值都满足调用Fn返回true,结果是std::integral_constantany_of: 返回是不是存在list的任意一个值满足调用Fn返回true,结果是std::integral_constantnone_of: 返回是不是list的所有值都不满足调用Fn返回true,结果是std::integral_constantin: 返回list中有没有T元素,结果是std::integral_constantinherit: 返回一个继承了list中所有类型的类型unique: 根据原list,返回一个去除重复元素的listpartition: 根据list中的元素被传入Fn后返回的是不是true,返回一个新的pair<list,list>,其中第一个list里全是能返回true的元素,第二个list中全是返回false的元素。sort: 利用Fn作为比较函数,对list做快排,返回排序后的listlambda: 编译期类型函数层面的lambda表达式var: 用于在let中定义编译期类型变量let: 可以在其中定义编译期类型变量的块表达式cartesian_product: 给定一个list的list,求这些list中的list的笛卡尔积add_const_if_c: 给定一个bool值,如果其为true,返回一个能将T类型变成const T的编译期类型函数add_const_if: 功能与add_const_if_c相同,不过接受的bool If是std::integral_constantconst_if_c: 接受一个bool If和T类型,返回add_const_if_c<If>::invoke<T>const_if: 功能与const_if_c相同,不过接受的bool If是std::integral_constantdetail::atoi_: 将字符转换成数字,返回std::integral_constantdetail::operator ""_z: 利用detail::atoi_将形如123_z的表达式转化为size_t的std::integral_constantstd_vector,std_map,std_...: 对STL模板容器的支持,为这些容器添加了编译期类型函数的形式