Boost.Hana  1.7.1
你的元编程标准库
可迭代

描述

Iterable 概念表示支持外部迭代的数据结构。

直观地,Iterable 可以被视为一种容器,其元素可以一个接一个地被提取出来。Iterable 还提供了一种方法来知道容器何时为空,即当没有更多元素可以提取出来时。

虽然 Foldable 表示支持内部迭代并能够累积结果的数据结构,但 Iterable 概念允许反转迭代的控制。这比 Foldable 更灵活,因为它允许仅迭代结构的某些部分。这反过来又允许 Iterable 处理无限结构,而尝试折叠这样的结构将永远无法完成。

最小完整定义

atdrop_frontis_empty

<tt>Iterable</tt> 的线性化

直观地说,对于 Iterable 结构 xsxs线性化xs 中所有元素的序列,就像它们被放入一个(可能是无限的)列表中一样。

linearization(xs) = [x1, x2, x3, ...]

可以使用 at 函数访问 Iterable 线性化的第 n 个元素。换句话说,at(xs, n) == xn

请注意,这个概念正是将 Foldable线性化概念扩展到无限情况。这个概念对于表达 Iterable 的各种属性很有用,并且在文档的其他地方也为此目的使用。

编译时 <tt>Iterable</tt>

编译时 Iterable 是一个 Iterable,其中 is_empty 返回一个编译时 Logical。这些结构允许在编译时进行迭代,因为执行迭代的“循环”可以展开,因为结构的总长度在编译时是已知的。

特别是,请注意,成为编译时 Iterable 与是有限的还是无限的无关。例如,可以创建一个表示毕达哥拉斯三元组的序列作为 integral_constant。这样的序列将是无限的,但对序列的迭代仍然将在编译时完成。但是,如果尝试迭代序列的所有元素,编译器将无限循环,这与如果序列是运行时序列,则程序无限循环形成对比。

在库的当前版本中,仅支持编译时 Iterable虽然从理论上讲可以支持运行时 Iterable,但高效地做到这一点是某些研究的主题。特别是,请关注此问题以了解运行时 Iterable 的当前状态。

法则

首先,我们要求两个 Iterable 的相等性与它们线性化中元素的相等性相关。更具体地说,如果 xsys 是数据类型为 It 的两个 Iterable,则

xs == ys => at(xs, i) == at(ys, i) for all i
constexpr auto at
返回可迭代对象的第 n 个元素。
定义:at.hpp:50
constexpr auto all
返回结构的所有键是否都为真值。
定义:all.hpp:30

这传达了两个 Iterable 必须具有相同的线性化才能被视为相等。

其次,由于每个 Iterable 也是一个 Searchable,我们要求 IterableSearchable 的模型一致。以下法则对此进行了精确说明。对于任何 Iterable xs,其线性化为 [x1, x2, x3, ...]

any_of(xs, equal.to(z)) <=> xi == z
constexpr auto equal
返回一个表示 x 是否等于 y 的 Logical。
定义:equal.hpp:64
constexpr auto any_of
返回结构中是否有任何键满足谓词。
定义:any_of.hpp:37

对于某些有限索引 i。此外,

find_if(xs, pred) == just(the first xi such that pred(xi) is satisfied)
constexpr auto first
返回一个对的第一个元素。
定义:first.hpp:33
constexpr auto find_if
查找与满足谓词的第一个键关联的值。
定义:find_if.hpp:41

或者如果不存在这样的 xi 则返回 nothing

细化概念

  1. Searchable(免费模型)
    任何 Iterable 都会产生一个 Searchable 模型,其中键和值都是结构中的元素。搜索键只是对结构的元素进行线性搜索。
    // Copyright Louis Dionne 2013-2017
    // Distributed under the Boost Software License, Version 1.0.
    // (See accompanying file LICENSE.md or copy at https://boost.ac.cn/LICENSE_1_0.txt)
    #include <type_traits>
    namespace hana = boost::hana;
    // 首先获取对象的类型,然后在其上调用特性。
    constexpr auto is_integral = hana::compose(hana::trait<std::is_integral>, hana::typeid_);
    constexpr auto is_class = hana::compose(hana::trait<std::is_class>, hana::typeid_);
    static_assert(
    hana::find_if(hana::make_tuple(1.0, 2, '3'), is_integral)
    ==
    hana::just(2)
    , "");
    hana::find_if(hana::make_tuple(1.0, 2, '3'), is_class)
    ==
    hana::nothing
    );
    hana::find(hana::make_tuple(hana::int_c<1>, hana::char_c<'c'>, hana::type_c<void>), hana::type_c<void>)
    ==
    hana::just(hana::type_c<void>)
    );
    hana::find(hana::make_tuple(hana::int_c<1>, hana::char_c<'c'>, hana::type_c<void>), hana::type_c<int>)
    ==
    hana::nothing
    );
    int main() { }
    定义宏以执行不同类型的断言。
    定义 boost::hana::compose。
    调整 std::integral_constant 以供 Hana 使用。
    定义 boost::hana::find。
    定义 boost::hana::find_if。
    constexpr auto find
    在结构中查找与给定键关联的值。
    定义:find.hpp:44
    #define BOOST_HANA_CONSTANT_CHECK(...)
    等效于 BOOST_HANA_CONSTANT_ASSERT,但不受 BOOST_HANA_CONFIG_DISABLE_ASSERTI... 的影响。
    定义:assert.hpp:239
    constexpr auto compose
    返回两个或多个函数的组合。
    定义:compose.hpp:52
    定义 boost::hana::integral_constant。
    包含库中所有内容的命名空间。
    定义:accessors.hpp:20
    定义 boost::hana::optional。
    定义 boost::hana::tuple。
    定义 boost::hana::type 和相关的实用程序。
  2. 有限 IterableFoldable
    每个有限 Iterable 都会产生一个 Foldable 模型。为了使这些模型保持一致,我们要求 FoldableIterable 的模型具有相同的线性化。
注意
如上所述,Iterable 也是 Searchable,并且它们的模型必须保持一致。根据此处提供的法则,这也意味着有限 IterableFoldable 模型必须与 Searchable 模型保持一致。

为方便起见,有限 Iterable 必须仅提供 length 的定义来建模 Foldable 概念;定义更强大的 unpackfold_left 不是必需的(但仍然可以)。从 Iterable + length 派生的 unpack 的默认实现利用了 at(xs, i) 表示 xs 线性化的第 i 个元素这一事实,以及有限 Iterable 的线性化必须与其作为 Foldable 的线性化相同这一事实。

具体模型

hana::tuplehana::stringhana::range

变量

constexpr auto boost::hana::at
 返回可迭代对象的第 n 个元素。更多...
 
template<std::size_t n>
constexpr auto boost::hana::at_c
 等效于 at;为了方便提供。更多...
 
constexpr auto boost::hana::back
 返回非空且有限的可迭代对象的最后一个元素。更多...
 
constexpr auto boost::hana::drop_front
 删除可迭代对象的前 n 个元素,并返回其余元素。更多...
 
constexpr auto boost::hana::drop_front_exactly
 删除可迭代对象的前 n 个元素,并返回其余元素。更多...
 
constexpr auto boost::hana::drop_while
 从可迭代对象中删除元素,直到但不包括第一个不满足predicate的元素。更多...
 
constexpr auto boost::hana::front
 返回非空可迭代对象的第一个元素。更多...
 
constexpr auto boost::hana::index_if
 查找与满足谓词的第一个键关联的值。更多...
 
constexpr auto boost::hana::is_empty
 返回可迭代对象是否为空。更多...
 

变量文档

◆ at

constexpr auto boost::hana::at
constexpr

#include <boost/hana/fwd/at.hpp>

初始值
= [](auto&& xs, auto const& n) -> decltype(auto) {
return tag-dispatched;
}

返回可迭代对象中的第 n 个元素。

给定一个 Iterable 和一个 IntegralConstant 索引,at 返回可迭代对象线性化中位于该索引处的元素。具体来说,给定一个可迭代对象 xs,其线性化为 [x1, ..., xN]at(xs, k) 等价于 xk

如果 Iterable 实际上存储了它包含的元素,则 at 必须返回左值引用、const 的左值引用或匹配元素的右值引用,其中引用的类型必须与传递给 at 的可迭代对象的类型匹配。如果 Iterable 不存储它包含的元素(即它按需生成它们),则此要求将被放弃。

参数
xs从中检索元素的可迭代对象。可迭代对象必须至少包含 n + 1 个元素。
n一个非负的 IntegralConstant,表示要返回的元素的基于 0 的索引。使用超出可迭代对象范围的索引调用 at 是错误的。

例子

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at https://boost.ac.cn/LICENSE_1_0.txt)
namespace hana = boost::hana;
constexpr auto xs = hana::make_tuple(0, '1', 2.0);
static_assert(hana::at(xs, hana::size_t<0>{}) == 0, "");
static_assert(hana::at(xs, hana::size_t<1>{}) == '1', "");
static_assert(hana::at(xs, hana::size_t<2>{}) == 2.0, "");
int main() { }
定义 boost::hana::at 和 boost::hana::at_c。

◆ at_c

template<std::size_t n>
constexpr auto boost::hana::at_c
constexpr

#include <boost/hana/fwd/at.hpp>

初始值
= [](auto&& xs) {
return hana::at(forwarded(xs), hana::size_c<n>);
}

等价于 at;为了方便提供。

注意
hana::at_c<n> 是一个重载函数,而不是函数对象。因此,它不能传递给高阶算法。这是出于编译时性能原因。

例子

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at https://boost.ac.cn/LICENSE_1_0.txt)
namespace hana = boost::hana;
constexpr auto xs = hana::make_tuple(0, '1', 2.0);
static_assert(hana::at_c<0>(xs) == 0, "");
static_assert(hana::at_c<1>(xs) == '1', "");
static_assert(hana::at_c<2>(xs) == 2.0, "");
int main() { }

◆ back

constexpr auto boost::hana::back
constexpr

#include <boost/hana/fwd/back.hpp>

初始值
= [](auto&& xs) -> decltype(auto) {
return tag-dispatched;
}

返回非空且有限的可迭代对象的最后一个元素。

给定一个非空且有限的可迭代对象 xs,其线性化为 [x1, ..., xN]back(xs) 等于 xN。等效地,back(xs) 必须等价于 at_c<N-1>(xs),并且无论 xs 的值类别如何(back 必须尊重 at 的引用语义)。

例子

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at https://boost.ac.cn/LICENSE_1_0.txt)
namespace hana = boost::hana;
static_assert(hana::back(hana::make_tuple(1, '2', 3.3)) == 3.3, "");
static_assert(hana::back(hana::make_tuple(1, '2', 3.3, nullptr)) == nullptr, "");
int main() { }
定义 boost::hana::back。
constexpr auto back
返回非空且有限的可迭代对象的最后一个元素。
定义: back.hpp:32

◆ drop_front

constexpr auto boost::hana::drop_front
constexpr

#include <boost/hana/fwd/drop_front.hpp>

初始值
= [](auto&& xs[, auto const& n]) {
return tag-dispatched;
}

丢弃可迭代对象的前 n 个元素,并返回其余元素。

给定一个 Iterable xs,其线性化为 [x1, x2, ...] 和一个非负的 IntegralConstant ndrop_front(xs, n) 是一个与 xs 具有相同标签的可迭代对象,其线性化为 [xn+1, xn+2, ...]。特别要注意,此函数不会以任何方式修改原始可迭代对象。如果未给出 n,则默认为值为 1IntegralConstant

如果 length(xs) <= n,则 drop_front 将简单地丢弃整个可迭代对象而不失败,从而返回一个空的可迭代对象。这与 drop_front_exactly 不同,后者期望 n <= length(xs),但由于此额外保证,可以更好地优化。

参数
xs从中丢弃元素的可迭代对象。
n一个非负的 IntegralConstant,表示要从可迭代对象中丢弃的元素数量。如果未给出 n,则默认为值为 1IntegralConstant

例子

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at https://boost.ac.cn/LICENSE_1_0.txt)
namespace hana = boost::hana;
constexpr auto xs = hana::make_tuple(0, '1', 2.0);
static_assert(hana::drop_front(xs, hana::size_c<0>) == xs, "");
static_assert(hana::drop_front(xs, hana::size_c<1>) == hana::make_tuple('1', 2.0), "");
static_assert(hana::drop_front(xs, hana::size_c<2>) == hana::make_tuple(2.0), "");
BOOST_HANA_CONSTANT_CHECK(hana::drop_front(xs, hana::size_c<3>) == hana::make_tuple());
BOOST_HANA_CONSTANT_CHECK(hana::drop_front(xs, hana::size_c<4>) == hana::make_tuple());
// drop_front(xs) 等价于 drop_front(xs, size_t<1>)
static_assert(hana::drop_front(xs) == hana::make_tuple('1', 2.0), "");
int main() { }
定义 boost::hana::drop_front。
定义 boost::hana::equal。
constexpr auto drop_front
丢弃可迭代对象的前 n 个元素,并返回其余元素。
定义: drop_front.hpp:47

◆ drop_front_exactly

constexpr auto boost::hana::drop_front_exactly
constexpr

#include <boost/hana/fwd/drop_front_exactly.hpp>

初始值
= [](auto&& xs[, auto const& n]) {
return tag-dispatched;
}

丢弃可迭代对象的前 n 个元素,并返回其余元素。

给定一个 Iterable xs,其线性化为 [x1, x2, ...] 和一个非负的 IntegralConstant ndrop_front_exactly(xs, n) 是一个与 xs 具有相同标签的可迭代对象,其线性化为 [xn+1, xn+2, ...]。特别要注意,此函数不会以任何方式修改原始可迭代对象。如果未给出 n,则默认为值为 1IntegralConstant

使用 n > length(xs)drop_front_exactly 是错误的。此额外保证允许 drop_front_exactly 比允许 n > length(xs)drop_front 函数更好地优化。

参数
xs从中丢弃元素的可迭代对象。
n一个非负的 IntegralConstant,表示要从可迭代对象中丢弃的元素数量。除了是非负数之外,n 还必须小于或等于 xs 中的元素数量。如果未给出 n,则默认为值为 1IntegralConstant

例子

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at https://boost.ac.cn/LICENSE_1_0.txt)
namespace hana = boost::hana;
constexpr auto xs = hana::make_tuple(0, '1', 2.0);
static_assert(hana::drop_front_exactly(xs, hana::size_c<1>) == hana::make_tuple('1', 2.0), "");
static_assert(hana::drop_front_exactly(xs, hana::size_c<2>) == hana::make_tuple(2.0), "");
BOOST_HANA_CONSTANT_CHECK(hana::drop_front_exactly(xs, hana::size_c<3>) == hana::make_tuple());
// drop_front_exactly(xs) 等价于 drop_front_exactly(xs, size_t<1>)
static_assert(hana::drop_front_exactly(xs) == hana::make_tuple('1', 2.0), "");
int main() { }
定义 boost::hana::drop_front_exactly。
constexpr auto drop_front_exactly
丢弃可迭代对象的前 n 个元素,并返回其余元素。
定义: drop_front_exactly.hpp:48

◆ drop_while

constexpr auto boost::hana::drop_while
constexpr

#include <boost/hana/fwd/drop_while.hpp>

初始值
= [](auto&& iterable, auto&& predicate) {
return tag-dispatched;
}

丢弃可迭代对象中的元素,直到但不包括第一个不满足 predicate 的元素。

具体来说,drop_while 返回一个可迭代对象,其中包含原始可迭代对象的所有元素,除了 [head, e) 范围内的元素,其中 head 是第一个元素,e 是第一个不满足 predicate 的元素。如果可迭代对象不是有限的,则此方法需要在有限的索引处返回一个假值的 Logical 才能返回。

参数
iterable从中丢弃元素的可迭代对象。
predicate一个函数,调用方式为 predicate(x),其中 x 是结构的元素,并返回一个 Logical,表示是否应从结构中丢弃 x。在库的当前版本中,predicate 应返回一个编译时 Logical

例子

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at https://boost.ac.cn/LICENSE_1_0.txt)
namespace hana = boost::hana;
using namespace hana::literals;
auto negative = [](auto x) {
返回 x < hana::int_c<0>;
};
hana::drop_while(hana::make_range(hana::int_c<-3>, hana::int_c<6>), negative)
==
hana::make_range(hana::int_c<0>, hana::int_c<6>)
);
hana::drop_while(hana::make_tuple(1_c, -2_c, 4_c, 5_c), negative)
==
hana::make_tuple(1_c, -2_c, 4_c, 5_c)
);
int main() { }
定义 boost::hana::drop_while。
constexpr auto drop_while
从可迭代对象中丢弃元素,直至但不包括谓词不为… 的第一个元素。
定义: drop_while.hpp:44
定义 boost::hana::less。
定义 boost::hana::negate。
定义 boost::hana::range。

◆ front

constexpr auto boost::hana::front
constexpr

#include <boost/hana/fwd/front.hpp>

初始值
= [](auto&& xs) -> decltype(auto) {
return tag-dispatched;
}

返回非空可迭代对象的第一个元素。

给定一个非空的可迭代对象 xs,其线性化为 [x1, ..., xN]front(xs) 等于 x1。如果 xs 为空,则使用此函数是一个错误。等效地,front(xs) 必须等效于 at_c<0>(xs),并且无论 xs 的值类别如何(front 必须尊重 at 的引用语义)。

例子

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at https://boost.ac.cn/LICENSE_1_0.txt)
namespace hana = boost::hana;
static_assert(hana::front(hana::make_tuple(1, '2', 3.3, nullptr)) == 1, "");
int main() { }
定义 boost::hana::front。
constexpr auto front
返回非空可迭代对象的第一个元素。
定义: front.hpp:32

◆ index_if

constexpr auto boost::hana::index_if
constexpr

#include <boost/hana/fwd/index_if.hpp>

初始值
= [](auto&& xs, auto&& predicate) {
return tag-dispatched;
}

查找与满足谓词的第一个键关联的值。

给定一个 Iterable 结构 xs 和一个谓词 predindex_if(xs, pred) 返回一个 hana::optional,其中包含一个满足谓词的第一个元素的索引的 IntegralConstant,或者如果没有任何元素满足谓词则返回 nothing。

参数
xs要搜索的结构。
predicate一个作为 predicate(x) 调用的函数,其中 xIterable 结构的元素,并返回 x 是否为正在搜索的元素。在库的当前版本中,谓词必须返回一个 IntegralConstant,其中包含可以转换为 bool 的值。

例子

// Copyright Louis Dionne 2013-2017
// Copyright Jason Rice 2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at https://boost.ac.cn/LICENSE_1_0.txt)
namespace hana = boost::hana;
constexpr auto xs = hana::make_tuple(0, '1', 2.0);
static_assert(hana::index_if(xs, hana::is_an<int>) == hana::just(hana::size_c<0>), "");
static_assert(hana::index_if(xs, hana::is_a<char>) == hana::just(hana::size_c<1>), "");
static_assert(hana::index_if(xs, hana::is_a<double>) == hana::just(hana::size_c<2>), "");
static_assert(hana::index_if(xs, hana::is_a<hana::tuple_tag>) == hana::nothing, "");
int main() { }
定义 boost::hana::is_a 和 boost::hana::is_an。
constexpr auto index_if
查找与满足谓词的第一个键关联的值。
定义: index_if.hpp:43
定义 boost::hana::index_if。

◆ is_empty

constexpr auto boost::hana::is_empty
constexpr

#include <boost/hana/fwd/is_empty.hpp>

初始值
= [](auto const& xs) {
return tag-dispatched;
}

返回可迭代对象是否为空。

给定一个 Iterable xsis_empty 返回 xs 是否不包含更多元素。换句话说,它返回尝试提取 xs 的尾部是否会出错。在库的当前版本中,is_empty 必须返回一个 IntegralConstant,其中包含可转换为 bool 的值。这是因为现在只支持编译时 Iterable

例子

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at https://boost.ac.cn/LICENSE_1_0.txt)
namespace hana = boost::hana;
BOOST_HANA_CONSTANT_CHECK(!hana::is_empty(hana::make_tuple(1, '2')));
int main() { }
constexpr auto is_empty
返回可迭代对象是否为空。
定义: is_empty.hpp:33
定义 boost::hana::is_empty。
定义 boost::hana::not_。