一个现代 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 是什么以及如何使用它的教程,以及包含示例的广泛参考部分。此 README 的其余部分主要面向希望开发该库的人员,而不是其用户。
可以通过签出 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
,因此更新文档不会弄乱您的索引。
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 没有单独的发布,因为该库现在已经相当稳定。