您的元编程标准库
# 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
,因此更新文档不会污染您的索引。
让自己开始在 Hana 上工作很容易。首先,您需要安装 CMake。完成此操作后,您可以cd
到项目的根目录并设置构建目录:
mkdir build
cmake -S . -B build
有时,您需要指定自定义编译器,因为系统的编译器太旧了:
cmake -S . -B build -DCMAKE_CXX_COMPILER=/path/to/compiler
通常,这会很好地工作。但是,在某些较旧的系统上,默认提供的标准库和/或编译器不支持 C++14。如果您遇到这种情况,维基百科上有更多有关在不同系统上进行设置的信息。
通常,如果您的系统上有 Boost 标头,Hana 会尝试查找它们。如果你没有它们也没关系;在这种情况下,一些需要 Boost 标头的测试将被禁用。但是,如果您希望 Hana 使用 Boost 的自定义安装,您可以指定此自定义安装的路径:
cmake -S . -B build -DCMAKE_CXX_COMPILER=/path/to/compiler -DBOOST_ROOT=/path/to/boost
您现在可以构建并运行单元测试和示例:
cmake --build build --target check
您应该意识到,编译单元测试非常耗时且消耗 RAM,尤其是外部适配器的测试。这是因为 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 编译然后运行它。
该项目由几个子目录组成。
doc/html
子目录会被 Git 自动忽略;您可以通过将gh-pages
分支克隆到该目录中来方便地存储文档的本地副本,如上所述。请参阅 CONTRIBUTING.md。
请参阅 LICENSE.md。
现在,发布仅通过 Boost 发布流程完成。 Hana 没有单独的版本,因为该库现在相当稳定。