Boost::hana

背景

时间线

cpp的计算分为4个象限,运行时计算,编译时计算,异构计算和类型计算。Hana的目的是合并第三象限和第四象限的计算。Hana是一个功能齐全的异构算法和容器库,,提供了一种将任何类型计算转化为其等效的异构计算的方法,这就允许异构计算的机制全部重用于类型计算。

一些入门用法

类型标签

// 类型和值的转化
auto quote_type = hana::type_c<Quote>;     // 类型 → 值
using QuoteType = typename decltype(+hana::type_c<Quote>)::type;  // 值 → 类型

// 比较
hana::type_c<Quote> == hana::type_c<Trade>;  // false(编译期结果)

编译期容器

// tuple 
auto types = hana::make_tuple(hana::type_c<Quote>, hana::type_c<Trade>);

// map
auto map = hana::make_map(
    hana::make_pair(hana::type_c<Quote>, 100),    // key 是类型,value 是运行时值
    hana::make_pair(hana::type_c<Trade>, 200)
);

// pair
hana::make_pair("key", 42);

// set
hana::make_set(hana::type_c<Quote>, hana::type_c<Trade>);

// range
hana::make_range(hana::int_c<0>, hana::int_c<10>);

编译期常量

hana::int_c<42>;       // 整数常量
hana::bool_c<true>;    // 布尔常量
hana::size_c<10>;      // size_t 常量
"hello"_s;             // 字符串常量

使用方法

容器访问

// tuple 按 index 访问
auto t = hana::make_tuple(10, 20, 30);

hana::at(t, hana::int_c<0>);   // 10

// map 按 key 访问
auto m = hana::make_map(
    hana::make_pair(hana::type_c<Quote>, 100),
    hana::make_pair(hana::type_c<Trade>, 200)
);
hana::at_key(m, hana::type_c<Quote>);  // 100
// 等价于 m[hana::type_c<Quote>]

遍历

hana::for_each(hana::make_tuple(1, 2.0, "hi"), [](auto x) {
    std::cout << x << std::endl;
});

变换

auto result = hana::transform(hana::make_tuple(1, 2, 3), [](auto x) {
    return x * 2;  // → tuple(2, 4, 6)
});

查找

auto opt = hana::find_if(tuple, [](auto x) {
    return x > 2;
});  // 返回 hana::just(...) 或 hana::nothing

展开

hana::unpack(hana::make_tuple(1, 2, 3), [](auto... args) {
    return (args + ...);  // 1+2+3 → 6,参数个数在编译期确定
});

过滤

auto result = hana::filter(hana::make_tuple(1, 2.0, 3, 4.0), [](auto x) {
    return hana::traits::is_integral(hana::type_c<decltype(x)>);
});

归约

auto sum = hana::fold(hana::make_tuple(1, 2, 3), 0, [](auto acc, auto x) {
    return acc + x;
});

zip

auto t1 = hana::make_tuple(1, 2, 3);
auto t2 = hana::make_tuple("a", "b", "c");

hana::zip(t1, t2); 
// → tuple(pair(1,"a"), pair(2,"b"), pair(3,"c"))

concat

hana::concat(hana::make_tuple(1, 2), hana::make_tuple(3, 4));
// → tuple(1, 2, 3, 4)

编译期控制流

if — 编译期分支

hana::if_(condition, then_value, else_value);

auto result = hana::if_(hana::true_c, 1, 2);   // 1
auto result = hana::if_(hana::false_c, 1, 2);  // 2

while — 编译期循环

hana::while_(predicate, state, body);

auto result = hana::while_(predicate, initial_state, [](auto state) {
    return next_state;
});

Maybe 类型

// Maybe 类型
auto has_ts = hana::just("update_time"_s);  // 有值
auto no_ts  = hana::nothing;                 // 无值

hana::is_just(has_ts);   // true_c
hana::is_just(no_ts);    // false_c
hana::is_nothing(no_ts); // true_c

结构体反射

// 定义类型
struct Quote {
    double bid_price;
    double ask_price;
};
BOOST_HANA_ADAPT_STRUCT(Quote, bid_price, ask_price);

// 获取字段
hana::for_each(hana::accessors<Quote>(), [](auto field) {
    auto name = hana::first(field);    // "bid_price"
    auto getter = hana::second(field); // 成员指针
});

还有一种写法:

// 定义类型
BOOST_HANA_DEFINE_STRUCT(Quote,
    (double, bid_price),
    (double, ask_price)
);

// 获取字段
hana::for_each(hana::accessors<Quote>(), [](auto field) {
    auto name = hana::first(field);    // "bid_price"
    auto getter = hana::second(field); // 成员指针
});

参考

https://github.com/freezestudio/hana.zh/blob/master/hana-zh.md

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注