Iterable
Concepts

## Description

The `Iterable` concept represents data structures supporting external iteration.

Intuitively, an `Iterable` can be seen as a kind of container whose elements can be pulled out one at a time. An `Iterable` also provides a way to know when the container is empty, i.e. when there are no more elements to pull out.

Whereas `Foldable` represents data structures supporting internal iteration with the ability to accumulate a result, the `Iterable` concept allows inverting the control of the iteration. This is more flexible than `Foldable`, since it allows iterating over only some part of the structure. This, in turn, allows `Iterable` to work on infinite structures, while trying to fold such a structure would never finish.

## Minimal complete definition

`at`, `drop_front` and `is_empty`

## The linearization of an <tt>Iterable</tt>

Intuitively, for an `Iterable` structure `xs`, the linearization of `xs` is the sequence of all the elements in `xs` as if they had been put in a (possibly infinite) list:

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

The `n`th element of the linearization of an `Iterable` can be accessed with the `at` function. In other words, `at(xs, n) == xn`.

Note that this notion is precisely the extension of the linearization notion of `Foldable`s to the infinite case. This notion is useful for expressing various properties of `Iterable`s, and is used for that elsewhere in the documentation.

## Compile-time <tt>Iterable</tt>s

A compile-time `Iterable` is an `Iterable` for which `is_empty` returns a compile-time `Logical`. These structures allow iteration to be done at compile-time, in the sense that the "loop" doing the iteration can be unrolled because the total length of the structure is kown at compile-time.

In particular, note that being a compile-time `Iterable` has nothing to do with being finite or infinite. For example, it would be possible to create a sequence representing the Pythagorean triples as `integral_constant`s. Such a sequence would be infinite, but iteration on the sequence would still be done at compile-time. However, if one tried to iterate over all the elements of the sequence, the compiler would loop indefinitely, in contrast to your program looping indefinitely if the sequence was a runtime one.

In the current version of the library, only compile-time `Iterable`s are supported. While it would be possible in theory to support runtime `Iterable`s, doing it efficiently is the subject of some research. In particular, follow this issue for the current status of runtime `Iterable`s.

## Laws

First, we require the equality of two `Iterable`s to be related to the equality of the elements in their linearizations. More specifically, if `xs` and `ys` are two `Iterable`s of data type `It`, then

xs == ys => at(xs, i) == at(ys, i) for all i
boost::hana::at
constexpr auto at
Returns the nth element of an iterable.
Definition: at.hpp:50
boost::hana::all
constexpr auto all
Returns whether all the keys of the structure are true-valued.
Definition: all.hpp:30

This conveys that two `Iterable`s must have the same linearization in order to be considered equal.

Secondly, since every `Iterable` is also a `Searchable`, we require the models of `Iterable` and `Searchable` to be consistent. This is made precise by the following laws. For any `Iterable` `xs` with a linearization of `[x1, x2, x3, ...]`,

any_of(xs, equal.to(z)) <=> xi == z
boost::hana::equal
constexpr auto equal
Returns a Logical representing whether x is equal to y.
Definition: equal.hpp:64
boost::hana::any_of
constexpr auto any_of
Returns whether any key of the structure satisfies the predicate.
Definition: any_of.hpp:37

for some finite index `i`. Furthermore,

find_if(xs, pred) == just(the first xi such that pred(xi) is satisfied)
boost::hana::first
constexpr auto first
Returns the first element of a pair.
Definition: first.hpp:33
boost::hana::find_if
constexpr auto find_if
Finds the value associated to the first key satisfying a predicate.
Definition: find_if.hpp:41

or `nothing` if no such `xi` exists.

## Refined concepts

1. `Searchable` (free model)
   Any `Iterable` gives rise to a model of `Searchable`, where the keys and the values are both the elements in the structure. Searching for a key is just doing a linear search through the elements of the structure.
   // Copyright Louis Dionne 2013-2017
   // Distributed under the Boost Software License, Version 1.0.
   // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
   #include <boost/hana/assert.hpp>
   #include <boost/hana/ext/std/integral_constant.hpp>
   #include <boost/hana/find.hpp>
   #include <boost/hana/find_if.hpp>
   #include <boost/hana/functional/compose.hpp>
   #include <boost/hana/integral_constant.hpp>
   #include <boost/hana/optional.hpp>
   #include <boost/hana/tuple.hpp>
   #include <boost/hana/type.hpp>
   #include <type_traits>
   namespace hana = boost::hana;
   // First get the type of the object, and then call the trait on it.
   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)
   , "");
   BOOST_HANA_CONSTANT_CHECK(
   hana::find_if(hana::make_tuple(1.0, 2, '3'), is_class)
   ==
   hana::nothing
   );
   BOOST_HANA_CONSTANT_CHECK(
   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>)
   );
   BOOST_HANA_CONSTANT_CHECK(
   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() { }
   assert.hpp
   Defines macros to perform different kinds of assertions.
   compose.hpp
   Defines boost::hana::compose.
   integral_constant.hpp
   Adapts std::integral_constant for use with Hana.
   find.hpp
   Defines boost::hana::find.
   find_if.hpp
   Defines boost::hana::find_if.
   boost::hana::find
   constexpr auto find
   Finds the value associated to the given key in a structure.
   Definition: find.hpp:44
   BOOST_HANA_CONSTANT_CHECK
   #define BOOST_HANA_CONSTANT_CHECK(...)
   Equivalent to BOOST_HANA_CONSTANT_ASSERT, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTI...
   Definition: assert.hpp:239
   boost::hana::compose
   constexpr auto compose
   Return the composition of two functions or more.
   Definition: compose.hpp:52
   integral_constant.hpp
   Defines boost::hana::integral_constant.
   boost::hana
   Namespace containing everything in the library.
   Definition: accessors.hpp:20
   optional.hpp
   Defines boost::hana::optional.
   tuple.hpp
   Defines boost::hana::tuple.
   type.hpp
   Defines boost::hana::type and related utilities.
2. `Foldable` for finite `Iterable`s
   Every finite `Iterable` gives rise to a model of `Foldable`. For these models to be consistent, we require the models of both `Foldable` and `Iterable` to have the same linearization.

Note
  As explained above, `Iterable`s are also `Searchable`s and their models have to be consistent. By the laws presented here, it also means that the `Foldable` model for finite `Iterable`s has to be consistent with the `Searchable` model.

For convenience, finite `Iterable`s must only provide a definition of `length` to model the `Foldable` concept; defining the more powerful `unpack` or `fold_left` is not necessary (but still possible). The default implementation of `unpack` derived from `Iterable` + `length` uses the fact that `at(xs, i)` denotes the `i`th element of `xs`'s linearization, and that the linearization of a finite `Iterable` must be the same as its linearization as a `Foldable`.

## Concrete models

`hana::tuple`, `hana::string`, `hana::range`

## Variables

constexpr auto | boost::hana::at
| Returns the `n`th element of an iterable. More...
template<std::size_t n>
constexpr auto | boost::hana::at_c
| Equivalent to `at`; provided for convenience. More...
constexpr auto | boost::hana::back
| Returns the last element of a non-empty and finite iterable. More...
constexpr auto | boost::hana::drop_front
| Drop the first `n` elements of an iterable, and return the rest. More...
constexpr auto | boost::hana::drop_front_exactly
| Drop the first `n` elements of an iterable, and return the rest. More...
constexpr auto | boost::hana::drop_while
| Drop elements from an iterable up to, but excluding, the first element for which the `predicate` is not satisfied. More...
constexpr auto | boost::hana::front
| Returns the first element of a non-empty iterable. More...
constexpr auto | boost::hana::index_if
| Finds the value associated to the first key satisfying a predicate. More...
constexpr auto | boost::hana::is_empty
| Returns whether the iterable is empty. More...

## Variable Documentation

## at

constexpr auto boost::hana::at

constexpr

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

Initial value:
= [](auto&& xs, auto const& n) -> decltype(auto) {
return tag-dispatched;
}

Returns the `n`th element of an iterable.

Given an `Iterable` and an `IntegralConstant` index, `at` returns the element located at the index in the linearization of the iterable. Specifically, given an iterable `xs` with a linearization of `[x1, ..., xN]`, `at(xs, k)` is equivalent to `xk`.

If the `Iterable` actually stores the elements it contains, `at` is required to return a lvalue reference, a lvalue reference to const or a rvalue reference to the matching element, where the type of reference must match that of the iterable passed to `at`. If the `Iterable` does not store the elements it contains (i.e. it generates them on demand), this requirement is dropped.

Parameters

  xs | The iterable in which an element is retrieved. The iterable must contain at least `n + 1` elements.
  n | A non-negative `IntegralConstant` representing the 0-based index of the element to return. It is an error to call `at` with an index that out of bounds of the iterable.

## Example

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <boost/hana/at.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/tuple.hpp>
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() { }
at.hpp
Defines boost::hana::at and boost::hana::at_c.

## at_c

template<std::size_t n>

constexpr auto boost::hana::at_c

constexpr

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

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

Equivalent to `at`; provided for convenience.

Note
  `hana::at_c<n>` is an overloaded function, not a function object. Hence, it can't be passed to higher-order algorithms. This is done for compile-time performance reasons.

## Example

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <boost/hana/at.hpp>
#include <boost/hana/tuple.hpp>
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>`

Initial value:
= [](auto&& xs) -> decltype(auto) {
return tag-dispatched;
}

Returns the last element of a non-empty and finite iterable.

Given a non-empty and finite iterable `xs` with a linearization of `[x1, ..., xN]`, `back(xs)` is equal to `xN`. Equivalently, `back(xs)` must be equivalent to `at_c<N-1>(xs)`, and that regardless of the value category of `xs` (`back` must respect the reference semantics of `at`).

## Example

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <boost/hana/back.hpp>
#include <boost/hana/tuple.hpp>
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() { }
back.hpp
Defines boost::hana::back.
boost::hana::back
constexpr auto back
Returns the last element of a non-empty and finite iterable.
Definition: back.hpp:32

## drop_front

constexpr auto boost::hana::drop_front

constexpr

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

Initial value:
= [](auto&& xs[, auto const& n]) {
return tag-dispatched;
}

Drop the first `n` elements of an iterable, and return the rest.

Given an `Iterable` `xs` with a linearization of `[x1, x2, ...]` and a non-negative `IntegralConstant` `n`, `drop_front(xs, n)` is an iterable with the same tag as `xs` whose linearization is `[xn+1, xn+2, ...]`. In particular, note that this function does not mutate the original iterable in any way. If `n` is not given, it defaults to an `IntegralConstant` with a value equal to `1`.

In case `length(xs) <= n`, `drop_front` will simply drop the whole iterable without failing, thus returning an empty iterable. This is different from `drop_front_exactly`, which expects `n <= length(xs)` but can be better optimized because of this additional guarantee.

Parameters

  xs | The iterable from which elements are dropped.
  n | A non-negative `IntegralConstant` representing the number of elements to be dropped from the iterable. If `n` is not given, it defaults to an `IntegralConstant` with a value equal to `1`.

## Example

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <boost/hana/assert.hpp>
#include <boost/hana/drop_front.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/tuple.hpp>
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) is equivalent to drop_front(xs, size_t<1>)
static_assert(hana::drop_front(xs) == hana::make_tuple('1', 2.0), "");
int main() { }
drop_front.hpp
Defines boost::hana::drop_front.
equal.hpp
Defines boost::hana::equal.
boost::hana::drop_front
constexpr auto drop_front
Drop the first n elements of an iterable, and return the rest.
Definition: drop_front.hpp:47

## drop_front_exactly

constexpr auto boost::hana::drop_front_exactly

constexpr

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

Initial value:
= [](auto&& xs[, auto const& n]) {
return tag-dispatched;
}

Drop the first `n` elements of an iterable, and return the rest.

Given an `Iterable` `xs` with a linearization of `[x1, x2, ...]` and a non-negative `IntegralConstant` `n`, `drop_front_exactly(xs, n)` is an iterable with the same tag as `xs` whose linearization is `[xn+1, xn+2, ...]`. In particular, note that this function does not mutate the original iterable in any way. If `n` is not given, it defaults to an `IntegralConstant` with a value equal to `1`.

It is an error to use `drop_front_exactly` with `n > length(xs)`. This additional guarantee allows `drop_front_exactly` to be better optimized than the `drop_front` function, which allows `n > length(xs)`.

Parameters

  xs | The iterable from which elements are dropped.
  n | A non-negative `IntegralConstant` representing the number of elements to be dropped from the iterable. In addition to being non-negative, `n` must be less than or equal to the number of elements in `xs`. If `n` is not given, it defaults to an `IntegralConstant` with a value equal to `1`.

## Example

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <boost/hana/assert.hpp>
#include <boost/hana/drop_front_exactly.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/tuple.hpp>
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) is equivalent to drop_front_exactly(xs, size_t<1>)
static_assert(hana::drop_front_exactly(xs) == hana::make_tuple('1', 2.0), "");
int main() { }
drop_front_exactly.hpp
Defines boost::hana::drop_front_exactly.
boost::hana::drop_front_exactly
constexpr auto drop_front_exactly
Drop the first n elements of an iterable, and return the rest.
Definition: drop_front_exactly.hpp:48

## drop_while

constexpr auto boost::hana::drop_while

constexpr

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

Initial value:
= [](auto&& iterable, auto&& predicate) {
return tag-dispatched;
}

Drop elements from an iterable up to, but excluding, the first element for which the `predicate` is not satisfied.

Specifically, `drop_while` returns an iterable containing all the elements of the original iterable except for those in the range delimited by [`head`, `e`), where `head` is the first element and `e` is the first element for which the `predicate` is not satisfied. If the iterable is not finite, the `predicate` has to return a false- valued `Logical` at a finite index for this method to return.

Parameters

  iterable | The iterable from which elements are dropped.
  predicate | A function called as `predicate(x)`, where `x` is an element of the structure, and returning a `Logical` representing whether `x` should be dropped from the structure. In the current version of the library, `predicate` should return a compile-time `Logical`.

## Example

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <boost/hana/assert.hpp>
#include <boost/hana/drop_while.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/less.hpp>
#include <boost/hana/negate.hpp>
#include <boost/hana/range.hpp>
#include <boost/hana/tuple.hpp>
namespace hana = boost::hana;
using namespace hana::literals;
auto negative = [](auto x) {
return x < hana::int_c<0>;
};
BOOST_HANA_CONSTANT_CHECK(
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>)
);
BOOST_HANA_CONSTANT_CHECK(
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() { }
drop_while.hpp
Defines boost::hana::drop_while.
boost::hana::drop_while
constexpr auto drop_while
Drop elements from an iterable up to, but excluding, the first element for which the predicate is not...
Definition: drop_while.hpp:44
less.hpp
Defines boost::hana::less.
negate.hpp
Defines boost::hana::negate.
range.hpp
Defines boost::hana::range.

## front

constexpr auto boost::hana::front

constexpr

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

Initial value:
= [](auto&& xs) -> decltype(auto) {
return tag-dispatched;
}

Returns the first element of a non-empty iterable.

Given a non-empty Iterable `xs` with a linearization of `[x1, ..., xN]`, `front(xs)` is equal to `x1`. If `xs` is empty, it is an error to use this function. Equivalently, `front(xs)` must be equivalent to `at_c<0>(xs)`, and that regardless of the value category of `xs` (`front` must respect the reference semantics of `at`).

## Example

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <boost/hana/front.hpp>
#include <boost/hana/tuple.hpp>
namespace hana = boost::hana;
static_assert(hana::front(hana::make_tuple(1, '2', 3.3, nullptr)) == 1, "");
int main() { }
front.hpp
Defines boost::hana::front.
boost::hana::front
constexpr auto front
Returns the first element of a non-empty iterable.
Definition: front.hpp:32

## index_if

constexpr auto boost::hana::index_if

constexpr

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

Initial value:
= [](auto&& xs, auto&& predicate) {
return tag-dispatched;
}

Finds the value associated to the first key satisfying a predicate.

Given an `Iterable` structure `xs` and a predicate `pred`, `index_if(xs, pred)` returns a `hana::optional` containing an `IntegralConstant` of the index of the first element that satisfies the predicate or nothing if no element satisfies the predicate.

Parameters

  xs | The structure to be searched.
  predicate | A function called as `predicate(x)`, where `x` is an element of the `Iterable` structure and returning whether `x` is the element being searched for. In the current version of the library, the predicate has to return an `IntegralConstant` holding a value that can be converted to `bool`.

## Example

// 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 http://boost.org/LICENSE_1_0.txt)
#include <boost/hana/core/is_a.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/index_if.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/optional.hpp>
#include <boost/hana/tuple.hpp>
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() { }
is_a.hpp
Defines boost::hana::is_a and boost::hana::is_an.
boost::hana::index_if
constexpr auto index_if
Finds the value associated to the first key satisfying a predicate.
Definition: index_if.hpp:43
index_if.hpp
Defines boost::hana::index_if.

## is_empty

constexpr auto boost::hana::is_empty

constexpr

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

Initial value:
= [](auto const& xs) {
return tag-dispatched;
}

Returns whether the iterable is empty.

Given an `Iterable` `xs`, `is_empty` returns whether `xs` contains no more elements. In other words, it returns whether trying to extract the tail of `xs` would be an error. In the current version of the library, `is_empty` must return an `IntegralConstant` holding a value convertible to `bool`. This is because only compile-time `Iterable`s are supported right now.

## Example

// Copyright Louis Dionne 2013-2017
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#include <boost/hana/assert.hpp>
#include <boost/hana/is_empty.hpp>
#include <boost/hana/not.hpp>
#include <boost/hana/tuple.hpp>
namespace hana = boost::hana;
BOOST_HANA_CONSTANT_CHECK(!hana::is_empty(hana::make_tuple(1, '2')));
BOOST_HANA_CONSTANT_CHECK( hana::is_empty(hana::make_tuple()));
int main() { }
boost::hana::is_empty
constexpr auto is_empty
Returns whether the iterable is empty.
Definition: is_empty.hpp:33
is_empty.hpp
Defines boost::hana::is_empty.
not.hpp
Defines boost::hana::not_.