一个现代 C++ 元编程库。它提供了操作异构序列的高级算法,允许以自然语法编写类型级计算,提供了内省用户定义类型的工具等等。
本次发布
依赖项
Boost.Hana

你的元编程标准库
概述
#include <boost/hana.hpp>
#include <cassert>
#include <string>
namespace hana = boost::hana;
using namespace hana::literals;
struct Fish { std::string name; };
struct Cat { std::string name; };
struct Dog { std::string name; };
int main() {
// Sequences capable of holding heterogeneous objects, and algorithms
// to manipulate them.
auto animals = hana::make_tuple(Fish{"Nemo"}, Cat{"Garfield"}, Dog{"Snoopy"});
auto names = hana::transform(animals, [](auto a) {
return a.name;
});
assert(hana::reverse(names) == hana::make_tuple("Snoopy", "Garfield", "Nemo"));
// No compile-time information is lost: even if `animals` can't be a
// constant expression because it contains strings, its length is constexpr.
static_assert(hana::length(animals) == 3u, "");
// Computations on types can be performed with the same syntax as that of
// normal C++. Believe it or not, everything is done at compile-time.
auto animal_types = hana::make_tuple(hana::type_c<Fish*>, hana::type_c<Cat&>, hana::type_c<Dog*>);
auto animal_ptrs = hana::filter(animal_types, [](auto a) {
return hana::traits::is_pointer(a);
});
static_assert(animal_ptrs == hana::make_tuple(hana::type_c<Fish*>, hana::type_c<Dog*>), "");
// And many other goodies to make your life easier, including:
// 1. Access to elements in a tuple with a sane syntax.
static_assert(animal_ptrs[0_c] == hana::type_c<Fish*>, "");
static_assert(animal_ptrs[1_c] == hana::type_c<Dog*>, "");
// 2. Unroll loops at compile-time without hassle.
std::string s;
hana::int_c<10>.times([&]{ s += "x"; });
// equivalent to s += "x"; s += "x"; ... s += "x";
// 3. Easily check whether an expression is valid.
// This is usually achieved with complex SFINAE-based tricks.
auto has_name = hana::is_valid([](auto&& x) -> decltype((void)x.name) { });
static_assert(has_name(animals[0_c]), "");
static_assert(!has_name(1), "");
}
文档
您可以在线浏览文档,网址是 http://boostorg.github.io/hana。文档涵盖了您需要的所有内容,包括安装库、解释 Hana 是什么以及如何使用它的教程,以及包含示例的广泛参考部分。本文档的其余部分主要面向希望自行开发该库的人员,而不是用户。
可以通过检出 gh-pages 分支来获取文档的离线副本。为避免覆盖当前目录,您可以将 gh-pages 分支克隆到一个子目录中,例如 doc/html。
git clone http://github.com/boostorg/hana --branch=gh-pages --depth=1 doc/html
发出此命令后,doc/html 将包含与在线提供的完全相同的静态网站。请注意,Git 会自动忽略 doc/html,因此更新文档不会污染您的索引。
Hacking on Hana
设置 Hana 的开发环境很容易。首先,您需要安装 CMake。完成此操作后,您可以 cd 到项目根目录并设置构建目录。
mkdir build
cmake -S . -B build
有时,您会想指定一个自定义编译器,因为系统自带的编译器太旧了。
cmake -S . -B build -DCMAKE_CXX_COMPILER=/path/to/compiler
通常,这会很好地工作。但是,在一些较旧的系统上,默认提供的标准库和/或编译器不支持 C++14。如果您的系统是这种情况,wiki 提供了更多关于在不同系统上进行设置的信息。
通常,Hana 会尝试查找您系统上的 Boost 头文件。如果您没有它们也没关系;在这种情况下,一些需要 Boost 头文件的测试将被禁用。但是,如果您希望 Hana 使用自定义的 Boost 安装,您可以指定此自定义安装的路径。
cmake -S . -B build -DCMAKE_CXX_COMPILER=/path/to/compiler -DBOOST_ROOT=/path/to/boost
您现在可以构建并运行单元测试和示例了。
cmake --build build --target check
您应该意识到,编译单元测试会消耗大量时间和内存,尤其是外部适配器的测试。这是因为 Hana 的单元测试非常彻底,而且其他库中的异构序列往往在编译时性能非常差。
还有一些可选目标,仅在计算机上安装了所需软件时才启用。例如,生成文档需要安装 Doxygen。在 CMake 生成步骤中,每当禁用一个可选目标时,都会打印一条信息性消息。您可以安装任何缺失的软件,然后重新运行 CMake 生成来更新可用目标的列表。
提示
您可以使用
help目标来获取所有可用目标的列表。
如果您想添加单元测试或示例,只需在 test/ 或 example/ 中添加一个源文件,然后重新运行 CMake 生成步骤,以便构建系统知道新的源文件。假设从项目根目录到新源文件的相对路径是 path/to/file.cpp。当您重新运行 CMake 生成步骤时,将创建一个名为 path.to.file 的新目标,同时也会创建一个同名的测试。因此,
cmake --build build --target path.to.file # Builds the program associated to path/to/file.cpp
ctest --test-dir build -R path.to.file # Runs the program as a test
Sublime Text 用户技巧
如果您使用提供的 hana.sublime-project 文件,您可以选择 “[Hana] Build current file” 构建系统。当查看一个与目标相关联的文件(如测试或示例)时,您可以通过按 ⌘B 来编译它,或者通过 ⇧⌘B 来编译并运行它。
项目组织
该项目被组织在几个子目录中。
benchmark目录包含编译时和运行时基准测试,以确保库的速度正如宣传的那样。基准测试代码主要以 eRuby 模板的形式编写。这些模板用于生成 C++ 文件,然后这些文件会在收集编译和执行统计信息时被编译。cmake目录包含构建系统所需的各种 CMake 模块和其他脚本。doc目录包含生成文档所需的配置文件。doc/html子目录会被 Git 自动忽略;您可以方便地将文档的本地副本存储在其中,方法是将gh-pages分支克隆到该目录,如上所述。example目录包含教程和参考文档中所有示例的源代码。include目录包含库本身,它是纯头文件库。test目录包含所有单元测试的源代码。
贡献
请参阅 CONTRIBUTING.md。
License
请参阅 LICENSE.md。
发布
发布现在完全通过 Boost 发布流程进行。Hana 没有单独的发布,因为该库现在已经相当稳定。