纯粹的模板元编程库
#include"meta_object_traits.hpp"
#include<iostream>
using namespace meta_typelist;//该命名空间定义元编程流
using namespace list_common_object;//包含一些通用的元输入, 输出流
using namespace collector;//元收集流一个完整meta_stream需要包括其输入流, 输出流. 输入流读取一个类型列表, 并向输出流所绑定的类型列表输出. 输入流,输出流都是元对象, 任意元对象都可以成为输出流,他们拥有相同的调用接口 但是需要注意的输入流必须是拥有返回值的元对象, 即 meta_ret_object
using l = meta_iota<9>;
//简单输入流
using miss = meta_istream<l>;
//简单输出流
//selectable_list作为容器,该容器不一定是空容器
using v = meta_ostream<selectable_list<>>;
//定义元流
using mstream =
meta_stream<
v,//to
miss//from
>;
using ms1 = mstream::update;
using ms2 = ms1::update;
using ms3 = ms2::update;
mstream:
输入流中的列表 = struct exp_repeat::meta_array<0,1,2,3,4,5,6,7,8,9>
输出流中的列表 = struct exp_repeat::meta_array<>
元流的缓存,下一个要操作的类型 = struct exp_repeat::Idx<0>
ms1:
输入流中的列表 = struct exp_repeat::meta_array<1,2,3,4,5,6,7,8,9>
输出流中的列表 = struct exp_repeat::meta_array<0>
元流的缓存,下一个要操作的类型 = struct exp_repeat::Idx<1>
ms2:
输入流中的列表 = struct exp_repeat::meta_array<2,3,4,5,6,7,8,9>
输出流中的列表 = struct exp_repeat::meta_array<0,1>
元流的缓存,下一个要操作的类型 = struct exp_repeat::Idx<2>ms3: 输入流中的列表 = struct exp_repeat::meta_array<3,4,5,6,7,8,9> 输出流中的列表 = struct exp_repeat::meta_array<0,1,2> 元流的缓存,下一个要操作的类型 = struct exp_repeat::Idx<3>
using m_even_filter_os = meta_appendable_filter_o<selectable_list<>, even_filter>;
using m_filter_stream = meta_stream<m_even_filter_os, miss>;
当该元流传输时,实际上在发生以下情况:
using mfs1 = m_filter_stream::update;
using mfs2 = mfs1::update;
using mfs3 = mfs2::update;//...使用 while_constexpr 追踪转移的过程:
while_constexpr<
meta_all_transfer_o<m_even_filter_os, miss>
>{}.recursively_invoke([]<typename mso_t>{
print_ms<mso_t>("mso status");
});mso status:
输入流中的列表 = struct exp_repeat::meta_array<1,2,3,4,5,6,7,8,9>
输出流中的列表 = struct exp_repeat::meta_array<>
元流的缓存,下一个要操作的类型 = struct exp_repeat::Idx<1>
mso status:
输入流中的列表 = struct exp_repeat::meta_array<2,3,4,5,6,7,8,9>
输出流中的列表 = struct exp_repeat::meta_array<1>
元流的缓存,下一个要操作的类型 = struct exp_repeat::Idx<2>
mso status:
输入流中的列表 = struct exp_repeat::meta_array<3,4,5,6,7,8,9>
输出流中的列表 = struct exp_repeat::meta_array<1>
元流的缓存,下一个要操作的类型 = struct exp_repeat::Idx<3>
mso status:
输入流中的列表 = struct exp_repeat::meta_array<4,5,6,7,8,9>
输出流中的列表 = struct exp_repeat::meta_array<1,3>
元流的缓存,下一个要操作的类型 = struct exp_repeat::Idx<4>
mso status:
输入流中的列表 = struct exp_repeat::meta_array<5,6,7,8,9>
输出流中的列表 = struct exp_repeat::meta_array<1,3>
元流的缓存,下一个要操作的类型 = struct exp_repeat::Idx<5>
mso status:
输入流中的列表 = struct exp_repeat::meta_array<6,7,8,9>
输出流中的列表 = struct exp_repeat::meta_array<1,3,5>
元流的缓存,下一个要操作的类型 = struct exp_repeat::Idx<6>
mso status:
输入流中的列表 = struct exp_repeat::meta_array<7,8,9>
输出流中的列表 = struct exp_repeat::meta_array<1,3,5>
元流的缓存,下一个要操作的类型 = struct exp_repeat::Idx<7>
mso status:
输入流中的列表 = struct exp_repeat::meta_array<8,9>
输出流中的列表 = struct exp_repeat::meta_array<1,3,5,7>
元流的缓存,下一个要操作的类型 = struct exp_repeat::Idx<8>
mso status:
输入流中的列表 = struct exp_repeat::meta_array<9>
输出流中的列表 = struct exp_repeat::meta_array<1,3,5,7>
元流的缓存,下一个要操作的类型 = struct exp_repeat::Idx<9>
mso status:
输入流中的列表 = struct exp_repeat::meta_array<>
输出流中的列表 = struct exp_repeat::meta_array<1,3,5,7,9>
元流的缓存,下一个要操作的类型 = struct no_exist_type
用以支持 meta_object中的 meta_looper循环 元流对象是一个定时器元对象 meta_timer_object
一个简单的mso
using simple_mo =
meta_stream_o<
3,//update 的次数
v,//输出流
miss//输入流
>;mso 传输
using mso_final_t = meta_stream_transfer<simple_mo>;//最终的类型,即meta_stream::to::type
using mso_mo = meta_stream_transfer_mo<simple_mo>;//传输后的元流
using mso_timer = meta_stream_transfer_timer<simple_mo>;//传输之后的定时器对象
print_ms<mso_mo>("mso_mo");mso_mo:
输入流中的列表 = struct exp_repeat::meta_array<3,4,5,6,7,8,9>
输出流中的列表 = struct exp_repeat::meta_array<0,1,2>
元流的缓存,下一个要操作的类型 = struct exp_repeat::Idx<3>重置元流对象的计数器,但元流中的状态不会改变
using mso2_mo = meta_stream_transfer_mo<mso_timer::reset<3>>;
print_ms<mso2_mo>("mso2_mo");
mso2_mo:
输入流中的列表 = struct exp_repeat::meta_array<6,7,8,9>
输出流中的列表 = struct exp_repeat::meta_array<0,1,2,3,4,5>
元流的缓存,下一个要操作的类型 = struct exp_repeat::Idx<6>快捷创建全部转移的流
using all_filter_mo = meta_all_transfer_o<
m_even_filter_os,//带有过滤器的输出流
miss//元输入流
>;
using filtered_mo = meta_stream_transfer_mo<all_filter_mo>;
print_ms<filtered_mo>("filtered_mo");相当于
using all_filter_mo = meta_stream_o<exp_size<typename miss::type>, m_even_filter_os, miss>; using my_loop = make_loop<
meta_value_limiter_i_co<9>,
meta_idx_inc_gen_o<3>
>;
using collected_mo = meta_collect_ostream<my_loop>;
std::cout << "\n以下代码展示collector的收集过程:\n";
constexpr while_constexpr<collected_mo> w_{};
w_.recursively_invoke(
[]<typename idx_t>{
std::cout << typeid(meta_to_array<stream_final_t<idx_t>>).name() << '\n';
}
);
std::cout << "\n使用collector::collect可以直接得到最终类型,创建了由3~9的元数组\n";
type_str<meta_to_array<collector::collect<my_loop>>>();以下代码展示collector的收集过程:
struct exp_repeat::meta_array<3>
struct exp_repeat::meta_array<3,4>
struct exp_repeat::meta_array<3,4,5>
struct exp_repeat::meta_array<3,4,5,6>
struct exp_repeat::meta_array<3,4,5,6,7>
struct exp_repeat::meta_array<3,4,5,6,7,8>
struct exp_repeat::meta_array<3,4,5,6,7,8,9>
使用collector::collect可以直接得到最终类型,创建了由3~9的元数组
struct exp_repeat::meta_array<3,4,5,6,7,8,9>需要注意的是:
- 收集者会收集每次循环产生的结果,并将这一序列的结果变成一个输入流
- 收集者不仅可以收集元循环,也可以收集元流传输的结果
- 需要注意的是,如果你不是有意要这么做,被收集的元流中请不要使用meta_ostream做输出流
- 因为每次传输的结果都会被收集,结果将是一系列的meta_ostream
- 若只想收集每次产生的结果,应使用 meta_replace_o 来作为输出流
std::string str{};
int cnt{ 0 };
auto plus_in_pair = [&](auto &&...args)
{
std::tuple tp{ std::forward<decltype(args)>(args)... };
static_assert(!(sizeof...(args) % 2), "error, must not have even args counts");
using stride_iss = meta_stride_istream<2, meta_iota<sizeof...(args) - 1>>;
using pair_indices = collect<meta_all_transfer_o<meta_replace_o, stride_iss>>;
template_func_execute_launcher(pair_indices{},
[&]<typename idx_1, typename idx_2>(exp_list<idx_1, idx_2>, auto& rtp) {
constexpr std::size_t I1 = idx_1::value;
constexpr std::size_t I2 = idx_2::value;
if constexpr (I1 == 0) {
str = str + std::get<I1>(rtp);
}
else {
str = str + " + " + std::get<I1>(rtp);
}
cnt += std::get<I2>(rtp);
}, tp);
};
plus_in_pair("A", 1, "B", 2, "C", 3, "D", 4, "E", 5);
std::cout << str << " = " << cnt << std::endl;A + B + C + D + E = 15