解析c++ range实现(二),meta

2021/01/30 c++ range

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),调用的结果也是其参数T
  • id_t : 其参数T的别称,用在非推导的环境下
  • is_trait : 利用sfinae实现的,通过判断类型具不具有::type来判断其是不是trait,返回std::integral_constant
  • is_callable : 利用sfinae实现的,通过判断类型具不具有::invoke来判断其是不是编译期类型函数,返回std::integral_constant
  • make_integer_sequencemake_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 >= end
      • repeat : cur*2 <= end
      • recurse : other
    • constexpr std::size_t detail::range_distance_(T begin, T end) : 在begin<=end的前提下,直接将end-begin转化为size_t
    • template <std::size_t End, typename State, indices_strategy_ Status_> struct detail::make_indices_ : 用于创建一个已有State,目标为Endindex_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和其模板参数,使用deferdetail::defer_detail::_t_t来延迟获取其结果::type
  • defer_trait : 给定一个接受T类型模板参数的trait,使用deferdetail::defer_i_detail::_t_t来延迟获取其结果::type
  • compose : 将多个编译器类型函数复合成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_t
  • if_c : 接受list<bool_<If>,Args...>作为参数的conditional_t(指定了if的结果)
  • fold : 接受一个listStateFn,构造出一个包装在defer里的形如Fn(Fn(...Fn(State,T0)...,TN-2),TN-1)的类型
  • accumulate : fold的别名
  • reverse_fold : 接受一个listStateFn,构造出一个包装在defer里的形如Fn(Fn(...Fn(State,TN-1)...,T1),T0)的类型
  • npos : 一个表示找不到结果的值(实际是std::integral_constant类型)
  • list : 一个可以包裹任意多类型的模板类,其内含有::type(值为其自身),和::size()(返回其含的模板参数的个数)
  • size : 获取一个listsize,返回的是一个std::integral_constant
  • concat : 将多个list合为一个list
  • join : 将一个由多个list构成的list合并为一个list
  • transform : 将一个list<Args...>Fn构成的list作为参数,返回一个list,其中每个元素都将list<Args...>中对应元素传入Fn后得到的结果。亦可以传入两个list<Args...>,那么新的list的元素就是以两个list<Args...>中的对应元素同时传入Fn后得到的结果
  • repeat_n_c : 返回一个含有NT类型的list
  • repeat_n : 功能与repeat_n_c相同,不过接受的Nstd::integral_constant
  • at_c : 返回一个list中下标为N的类型
  • at : 功能与at_c相同,不过接受的Nstd::integral_constant
  • drop_c : 返回一个新的list,其不含有原list的前N个元素
  • drop : 功能与drop_c相同,不过接受的Nstd::integral_constant
  • front : 返回list的首元素
  • back : 返回list的尾元素
  • push_front : 将一些元素加到list的首部,返回这个新的list
  • pop_front : 返回一个list,其是原list移去首元素得到的。
  • push_back : 将一些元素加到list的末尾,返回这个新的list
  • empty : 判断一个list是不是空的,返回一个std::integral_constant
  • pair : 只含两个元素的list
  • first : 返回pair的第一个元素
  • second : 返回pair的第二个元素
  • find_index : 返回list中第一个与T相同的元素的下标,其类型为std::integral_constant
  • reverse_find_index : 返回list中最后一个与T相同的元素的下标,其类型为std::integral_constant
  • find : 返回一个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_constant
  • count_if : 返回一个list中有多少个元素被传入Fn将返回true,结果是std::integral_constant
  • filter : 返回一个list,其是所有原list中所有被传入Fn将返回true的元素所构成的
  • for_each : 将一个list的每个元素都传入Fn做调用(这个Fn不是编译期类型函数)
  • transpose : 返回一个二维的list转置后的二维list
  • zip_with : 给定一个二维list和一个编译期类型函数Fn,将这个二维list中的每一个list都当作其对应位置模板参数的取值,将这些取值按照一维list的长度,分次传给Fn,将这些结果放到要返回的新的list中。
  • zip : transpose的别名
  • as_list : 利用apply的规则,将一个类型T变成一个list
  • reverse : 返回一个翻转后的list
  • not_fn : 返回一个新的编译期类型函数,其将原函数的返回值取反
  • all_of : 返回是不是list的所有值都满足调用Fn返回true,结果是std::integral_constant
  • any_of : 返回是不是存在list的任意一个值满足调用Fn返回true,结果是std::integral_constant
  • none_of : 返回是不是list的所有值都不满足调用Fn返回true,结果是std::integral_constant
  • in : 返回list中有没有T元素,结果是std::integral_constant
  • inherit : 返回一个继承了list中所有类型的类型
  • unique : 根据原list,返回一个去除重复元素的list
  • partition : 根据list中的元素被传入Fn后返回的是不是true,返回一个新的pair<list,list>,其中第一个list里全是能返回true的元素,第二个list中全是返回false的元素。
  • sort : 利用Fn作为比较函数,对list做快排,返回排序后的list
  • lambda : 编译期类型函数层面的lambda表达式
  • var : 用于在let中定义编译期类型变量
  • let : 可以在其中定义编译期类型变量的块表达式
  • cartesian_product : 给定一个listlist,求这些list中的list的笛卡尔积
  • add_const_if_c : 给定一个bool值,如果其为true,返回一个能将T类型变成const T的编译期类型函数
  • add_const_if : 功能与add_const_if_c相同,不过接受的bool Ifstd::integral_constant
  • const_if_c : 接受一个bool IfT类型,返回add_const_if_c<If>::invoke<T>
  • const_if : 功能与const_if_c相同,不过接受的bool Ifstd::integral_constant
  • detail::atoi_ : 将字符转换成数字,返回std::integral_constant
  • detail::operator ""_z : 利用detail::atoi_将形如123_z的表达式转化为size_tstd::integral_constant
  • std_vector,std_map,std_... : 对STL模板容器的支持,为这些容器添加了编译期类型函数的形式
Show Disqus Comments

Search

    welcome to visit my github

    creatorlxd's github

    Table of Contents