Boost.Hana  1.6.0 Your standard library for metaprogramming
Sequence

## Description

The Sequence concept represents generic index-based sequences.

Compared to other abstract concepts, the Sequence concept is very specific. It represents generic index-based sequences. The reason why such a specific concept is provided is because there are a lot of models that behave exactly the same while being implemented in wildly different ways. It is useful to regroup all those data types under the same umbrella for the purpose of generic programming.

In fact, models of this concept are not only similar. They are actually isomorphic, in a sense that we define below, which is a fancy way of rigorously saying that they behave exactly the same to an external observer.

## Minimal complete definition

Iterable, Foldable, and make

The Sequence concept does not provide basic methods that could be used as a minimal complete definition; instead, it borrows methods from other concepts and add laws to them. For this reason, it is necessary to specialize the Sequence metafunction in Hana's namespace to tell Hana that a type is indeed a Sequence. Explicitly specializing the Sequence metafunction can be seen like a seal saying "this data type satisfies the additional laws of a Sequence", since those can't be checked by Hana automatically.

## Laws

The laws for being a Sequence are simple, and their goal is to restrict the semantics that can be associated to the functions provided by other concepts. First, a Sequence must be a finite Iterable (thus a Foldable too). Secondly, for a Sequence tag S, make<S>(x1, ..., xn) must be an object of tag S and whose linearization is [x1, ..., xn]. This basically ensures that objects of tag S are equivalent to their linearization, and that they can be created from such a linearization (with make).

While it would be possible in theory to handle infinite sequences, doing so complicates the implementation of many algorithms. For simplicity, the current version of the library only handles finite sequences. However, note that this does not affect in any way the potential for having infinite Searchables and Iterables.

## Refined concepts

1. Comparable (definition provided automatically)
Two Sequences are equal if and only if they contain the same number of elements and their elements at any given index are equal.
// 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)
namespace hana = boost::hana;
static_assert(hana::make_tuple(1, 2, 3) == hana::make_tuple(1, 2, 3), "");
BOOST_HANA_CONSTANT_CHECK(hana::make_tuple(1, 2, 3) != hana::make_tuple(1, 2, 3, 4));
int main() { }
2. Orderable (definition provided automatically)
Sequences are ordered using the traditional lexicographical ordering.
// 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)
namespace hana = boost::hana;
static_assert(hana::make_tuple(1, 2, 3) < hana::make_tuple(2, 3, 4), "");
static_assert(hana::make_tuple(1, 2, 3) < hana::make_tuple(1, 2, 3, 4), "");
int main() { }
3. Functor (definition provided automatically)
Sequences implement transform as the mapping of a function over each element of the sequence. This is somewhat equivalent to what std::transform does to ranges of iterators. Also note that mapping a function over an empty sequence returns an empty sequence and never applies the function, as would be expected.
// 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 <sstream>
#include <string>
namespace hana = boost::hana;
auto to_string = [](auto x) {
std::ostringstream ss;
ss << x;
return ss.str();
};
int main() {
hana::transform(hana::make_tuple(1, '2', "345", std::string{"67"}), to_string) ==
hana::make_tuple("1", "2", "345", "67")
);
}
4. Applicative (definition provided automatically)
First, lifting a value into a Sequence is the same as creating a singleton sequence containing that value. Second, applying a sequence of functions to a sequence of values will apply each function to all the values in the sequence, and then return a list of all the results. In other words,
ap([f1, ..., fN], [x1, ..., xM]) == [
f1(x1), ..., f1(xM),
...
fN(x1), ..., fN(xM)
]
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 <tuple>
namespace hana = boost::hana;
static_assert(hana::lift<hana::tuple_tag>('x') == hana::make_tuple('x'), "");
static_assert(hana::equal(hana::lift<hana::ext::std::tuple_tag>('x'), std::make_tuple('x')), "");
constexpr auto f = hana::make_pair;
constexpr auto g = hana::flip(hana::make_pair);
static_assert(
hana::ap(hana::make_tuple(f, g), hana::make_tuple(1, 2, 3), hana::make_tuple('a', 'b'))
==
hana::make_tuple(
f(1, 'a'), f(1, 'b'), f(2, 'a'), f(2, 'b'), f(3, 'a'), f(3, 'b'),
g(1, 'a'), g(1, 'b'), g(2, 'a'), g(2, 'b'), g(3, 'a'), g(3, 'b')
)
, "");
int main() { }
5. Monad (definition provided automatically)
First, flatenning a Sequence takes a sequence of sequences and concatenates them to get a larger sequence. In other words,
flatten([[a1, ..., aN], ..., [z1, ..., zM]]) == [
a1, ..., aN, ..., z1, ..., zM
]
This acts like a std::tuple_cat function, except it receives a sequence of sequences instead of a variadic pack of sequences to flatten.
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)
namespace hana = boost::hana;
static_assert(
hana::flatten(hana::make_tuple(
hana::make_tuple(1, 2),
hana::make_tuple(3, 4),
hana::make_tuple(hana::make_tuple(5, 6))
))
== hana::make_tuple(1, 2, 3, 4, hana::make_tuple(5, 6))
, "");
int main() { }
Also note that the model of Monad for Sequences can be seen as modeling nondeterminism. A nondeterministic computation can be modeled as a function which returns a sequence of possible results. In this line of thought, chaining a sequence of values into such a function will return a sequence of all the possible output values, i.e. a sequence of all the values applied to all the functions in the sequences.
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 <type_traits>
#include <utility>
namespace hana = boost::hana;
// Using the tuple Monad, we generate all the possible combinations of
// cv-qualifiers and reference qualifiers. Then, we use the optional
// Monad to make sure that our generic function can be called with
// arguments of any of those types.
// cv_qualifiers : type -> tuple(type)
auto cv_qualifiers = [](auto t) {
return hana::make_tuple(
t,
hana::traits::add_const(t),
hana::traits::add_volatile(t),
hana::traits::add_volatile(hana::traits::add_const(t))
);
};
// ref_qualifiers : type -> tuple(type)
auto ref_qualifiers = [](auto t) {
return hana::make_tuple(
hana::traits::add_lvalue_reference(t),
hana::traits::add_rvalue_reference(t)
);
};
auto possible_args = cv_qualifiers(hana::type_c<int>) | ref_qualifiers;
possible_args == hana::make_tuple(
hana::type_c<int&>,
hana::type_c<int&&>,
hana::type_c<int const&>,
hana::type_c<int const&&>,
hana::type_c<int volatile&>,
hana::type_c<int volatile&&>,
hana::type_c<int const volatile&>,
hana::type_c<int const volatile&&>
)
);
struct some_function {
template <typename T>
void operator()(T&&) const { }
};
int main() {
hana::for_each(possible_args, [](auto t) {
using T = typename decltype(t)::type;
static_assert(decltype(hana::is_valid(some_function{})(std::declval<T>())){},
"some_function should be callable with any type of argument");
});
}
6. MonadPlus (definition provided automatically)
Sequences are models of the MonadPlus concept by considering the empty sequence as the unit of concat, and sequence concatenation as concat.
// 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 <string>
namespace hana = boost::hana;
using namespace std::string_literals;
BOOST_HANA_CONSTANT_CHECK(hana::empty<hana::tuple_tag>() == hana::make_tuple());
static_assert(hana::append(hana::make_tuple(1, '2', 3.3), nullptr)
== hana::make_tuple(1, '2', 3.3, nullptr), "");
int main() {
hana::concat(hana::make_tuple(1, '2', 3.3), hana::make_tuple("abcdef"s)) ==
hana::make_tuple(1, '2', 3.3, "abcdef"s)
);
}
7. Foldable
The model of Foldable for Sequences is uniquely determined by the model of Iterable.
// 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 <sstream>
namespace hana = boost::hana;
auto to_string = [](auto x) {
std::ostringstream ss;
ss << x;
return ss.str();
};
auto show = [](auto x, auto y) {
return "(" + to_string(x) + " + " + to_string(y) + ")";
};
int main() {
hana::fold_left(hana::make_tuple(2, "3", '4'), "1", show) == "(((1 + 2) + 3) + 4)"
);
}
8. Iterable
The model of Iterable for Sequences corresponds to iteration over each element of the sequence, in order. This model is not provided automatically, and it is in fact part of the minimal complete definition for the Sequence concept.
// 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)
namespace hana = boost::hana;
static_assert(hana::front(hana::make_tuple(1, '2', 3.3)) == 1, "");
static_assert(hana::drop_front(hana::make_tuple(1, '2', 3.3)) == hana::make_tuple('2', 3.3), "");
BOOST_HANA_CONSTANT_CHECK(!hana::is_empty(hana::make_tuple(1, '2', 3.3)));
int main() { }
9. Searchable (definition provided automatically)
Searching through a Sequence is equivalent to just searching through a list of the values it contains. The keys and the values on which the search is performed are both the elements of the sequence.
// 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 <string>
namespace hana = boost::hana;
using namespace std::string_literals;
int main() {
hana::find_if(hana::make_tuple(1, '2', 3.3, "abc"s), hana::is_a<std::string>) == hana::just("abc"s)
);
"abc"s ^hana::in^ hana::make_tuple(1, '2', 3.3, "abc"s)
);
}

## Concrete models

hana::tuple

## Variables

constexpr auto boost::hana::cartesian_product
Computes the cartesian product of a sequence of sequences.Given a sequence of sequences, cartesian_product returns a new sequence of sequences containing the cartesian product of the original sequences. For this method to finish, a finite number of finite sequences must be provided. More...

constexpr auto boost::hana::drop_back
Drop the last n elements of a finite sequence, and return the rest.Given a finite Sequence xs with a linearization of [x1, ..., xm] and a non-negative IntegralConstant n, drop_back(xs, n) is a sequence with the same tag as xs whose linearization is [x1, ..., xm-n]. If n is not given, it defaults to an IntegralConstant with a value equal to 1. More...

constexpr auto boost::hana::group
Group adjacent elements of a sequence that all respect a binary predicate, by default equality.Given a finite Sequence and an optional predicate (by default equal), group returns a sequence of subsequences representing groups of adjacent elements that are "equal" with respect to the predicate. In other words, the groups are such that the predicate is satisfied when it is applied to any two adjacent elements in that group. The sequence returned by group is such that the concatenation of its elements is equal to the original sequence, which is equivalent to saying that the order of the elements is not changed. More...

constexpr insert_t boost::hana::insert {}
Insert a value at a given index in a sequence.Given a sequence, an index and an element to insert, insert inserts the element at the given index. More...

constexpr auto boost::hana::insert_range
Insert several values at a given index in a sequence.Given a sequence, an index and any Foldable containing elements to insert, insert_range inserts the elements in the Foldable at the given index of the sequence. More...

constexpr auto boost::hana::intersperse
Insert a value between each pair of elements in a finite sequence.Given a finite Sequence xs with a linearization of [x1, x2, ..., xn], intersperse(xs, z) is a new sequence with a linearization of [x1, z, x2, z, x3, ..., xn-1, z, xn]. In other words, it inserts the z element between every pair of elements of the original sequence. If the sequence is empty or has a single element, intersperse returns the sequence as-is. In all cases, the sequence must be finite. More...

constexpr auto boost::hana::partition
Partition a sequence based on a predicate.Specifically, returns an unspecified Product whose first element is a sequence of the elements satisfying the predicate, and whose second element is a sequence of the elements that do not satisfy the predicate. More...

constexpr auto boost::hana::permutations
Return a sequence of all the permutations of the given sequence.Specifically, permutations(xs) is a sequence whose elements are permutations of the original sequence xs. The permutations are not guaranteed to be in any specific order. Also note that the number of permutations grows very rapidly as the length of the original sequence increases. The growth rate is O(length(xs)!); with a sequence xs of length only 8, permutations(xs) contains over 40 000 elements! More...

constexpr auto boost::hana::remove_at
Remove the element at a given index from a sequence.remove_at returns a new sequence identical to the original, except that the element at the given index is removed. Specifically, remove_at([x0, ..., xn-1, xn, xn+1, ..., xm], n) is a new sequence equivalent to [x0, ..., xn-1, xn+1, ..., xm]. More...

template<std::size_t n>
constexpr auto boost::hana::remove_at_c
Equivalent to remove_at; provided for convenience. More...

constexpr auto boost::hana::remove_range
Remove the elements inside a given range of indices from a sequence.remove_range returns a new sequence identical to the original, except that elements at indices in the provided range are removed. Specifically, remove_range([x0, ..., xn], from, to) is a new sequence equivalent to [x0, ..., x_from-1, x_to, ..., xn]. More...

template<std::size_t from, std::size_t to>
constexpr auto boost::hana::remove_range_c
Equivalent to remove_range; provided for convenience. More...

constexpr auto boost::hana::reverse
Reverse a sequence.Specifically, reverse(xs) is a new sequence containing the same elements as xs, except in reverse order. More...

constexpr auto boost::hana::scan_left
Fold a Sequence to the left and return a list containing the successive reduction states.Like fold_left, scan_left reduces a sequence to a single value using a binary operation. However, unlike fold_left, it builds up a sequence of the intermediary results computed along the way and returns that instead of only the final reduction state. Like fold_left, scan_left can be used with or without an initial reduction state. More...

constexpr auto boost::hana::scan_right
Fold a Sequence to the right and return a list containing the successive reduction states.Like fold_right, scan_right reduces a sequence to a single value using a binary operation. However, unlike fold_right, it builds up a sequence of the intermediary results computed along the way and returns that instead of only the final reduction state. Like fold_right, scan_right can be used with or without an initial reduction state. More...

constexpr auto boost::hana::slice
Extract the elements of a Sequence at the given indices.Given an arbitrary sequence of indices, slice returns a new sequence of the elements of the original sequence that appear at those indices. In other words,. More...

template<std::size_t from, std::size_t to>
constexpr auto boost::hana::slice_c
Shorthand to slice a contiguous range of elements.slice_c is simply a shorthand to slice a contiguous range of elements. In particular, slice_c<from, to>(xs) is equivalent to slice(xs, range_c<std::size_t, from, to>), which simply slices all the elements of xs contained in the half-open interval delimited by [from, to). Like for slice, the indices used with slice_c are 0-based and they must be in the bounds of the sequence being sliced. More...

constexpr auto boost::hana::sort
Sort a sequence, optionally based on a custom predicate.Given a Sequence and an optional predicate (by default less), sort returns a new sequence containing the same elements as the original, except they are ordered in such a way that if x comes before y in the sequence, then either predicate(x, y) is true, or both predicate(x, y) and predicate(y, x) are false. More...

constexpr auto boost::hana::span
Returns a Product containing the longest prefix of a sequence satisfying a predicate, and the rest of the sequence.The first component of the returned Product is a sequence for which all elements satisfy the given predicate. The second component of the returned Product is a sequence containing the remainder of the argument. Both or either sequences may be empty, depending on the input argument. More specifically,. More...

constexpr auto boost::hana::take_back
Returns the last n elements of a sequence, or the whole sequence if the sequence has less than n elements.Given a Sequence xs and an IntegralConstant n, take_back(xs, n) is a new sequence containing the last n elements of xs, in the same order. If length(xs) <= n, the whole sequence is returned and no error is triggered. More...

template<std::size_t n>
constexpr auto boost::hana::take_back_c
Equivalent to take_back; provided for convenience. More...

constexpr auto boost::hana::take_front
Returns the first n elements of a sequence, or the whole sequence if the sequence has less than n elements.Given a Sequence xs and an IntegralConstant n, take_front(xs, n) is a new sequence containing the first n elements of xs, in the same order. If length(xs) <= n, the whole sequence is returned and no error is triggered. More...

template<std::size_t n>
constexpr auto boost::hana::take_front_c
Equivalent to take_front; provided for convenience. More...

constexpr auto boost::hana::take_while
Take elements from a sequence while the predicate is satisfied.Specifically, take_while returns a new sequence containing the longest prefix of xs in which all the elements satisfy the given predicate. More...

template<typename S >
constexpr auto boost::hana::unfold_left
Dual operation to fold_left for sequences.While fold_left reduces a structure to a summary value from the left, unfold_left builds a sequence from a seed value and a function, starting from the left. More...

template<typename S >
constexpr auto boost::hana::unfold_right
Dual operation to fold_right for sequences.While fold_right reduces a structure to a summary value from the right, unfold_right builds a sequence from a seed value and a function, starting from the right. More...

constexpr auto boost::hana::unique
Removes all consecutive duplicate elements from a Sequence.Given a Sequence and an optional binary predicate, unique returns a new sequence containing only the first element of every subrange of the original sequence whose elements are all equal. In other words, it turns a sequence of the form [a, a, b, c, c, c, d, d, d, a] into a sequence [a, b, c, d, a]. The equality of two elements is determined by the provided predicate, or by equal if no predicate is provided. More...

constexpr auto boost::hana::zip
Zip one sequence or more.Given n sequences s1, ..., sn, zip produces a sequence whose i-th element is a tuple of (s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip produces a sequence of the form. More...

constexpr auto boost::hana::zip_shortest
Zip one sequence or more.Given n sequences s1, ..., sn, zip_shortest produces a sequence whose i-th element is a tuple of (s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip_shortest produces a sequence of the form. More...

constexpr auto boost::hana::zip_shortest_with
Zip one sequence or more with a given function.Given a n-ary function f and n sequences s1, ..., sn, zip_shortest_with produces a sequence whose i-th element is f(s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip_shortest_with produces a sequence of the form. More...

constexpr auto boost::hana::zip_with
Zip one sequence or more with a given function.Given a n-ary function f and n sequences s1, ..., sn, zip_with produces a sequence whose i-th element is f(s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip_with produces a sequence of the form. More...

## ◆ cartesian_product

 constexpr auto boost::hana::cartesian_product

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

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

Computes the cartesian product of a sequence of sequences.Given a sequence of sequences, cartesian_product returns a new sequence of sequences containing the cartesian product of the original sequences. For this method to finish, a finite number of finite sequences must be provided.

Note
All the sequences must have the same tag, and that tag must also match that of the top-level sequence.

## Signature

Given a Sequence S(T), the signature is

$\mathtt{cartesian\_product} : S(S(T)) \to S(S(T))$

Parameters
 xs A sequence of sequences of which the cartesian product is computed.

## 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)
namespace hana = boost::hana;
constexpr auto tuples = hana::make_tuple(
hana::make_tuple(1, 2, 3),
hana::make_tuple('a', 'b'),
hana::make_tuple(hana::type_c<int>, hana::type_c<char>)
);
constexpr auto prod = hana::make_tuple(
hana::make_tuple(1, 'a', hana::type_c<int>),
hana::make_tuple(1, 'a', hana::type_c<char>),
hana::make_tuple(1, 'b', hana::type_c<int>),
hana::make_tuple(1, 'b', hana::type_c<char>),
hana::make_tuple(2, 'a', hana::type_c<int>),
hana::make_tuple(2, 'a', hana::type_c<char>),
hana::make_tuple(2, 'b', hana::type_c<int>),
hana::make_tuple(2, 'b', hana::type_c<char>),
hana::make_tuple(3, 'a', hana::type_c<int>),
hana::make_tuple(3, 'a', hana::type_c<char>),
hana::make_tuple(3, 'b', hana::type_c<int>),
hana::make_tuple(3, 'b', hana::type_c<char>)
);
static_assert(hana::cartesian_product(tuples) == prod, "");
int main() { }

## ◆ drop_back

 constexpr auto boost::hana::drop_back

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

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

Drop the last n elements of a finite sequence, and return the rest.Given a finite Sequence xs with a linearization of [x1, ..., xm] and a non-negative IntegralConstant n, drop_back(xs, n) is a sequence with the same tag as xs whose linearization is [x1, ..., xm-n]. If n is not given, it defaults to an IntegralConstant with a value equal to 1.

In case length(xs) <= n, drop_back will simply drop the whole sequence without failing, thus returning an empty sequence.

Parameters
 xs The sequence from which elements are dropped. n A non-negative IntegralConstant representing the number of elements to be dropped from the end of the sequence. 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)
namespace hana = boost::hana;
constexpr auto xs = hana::make_tuple(0, '1', 2.0);
static_assert(hana::drop_back(xs, hana::size_c<0>) == xs, "");
static_assert(hana::drop_back(xs, hana::size_c<1>) == hana::make_tuple(0, '1'), "");
static_assert(hana::drop_back(xs, hana::size_c<2>) == hana::make_tuple(0), "");
BOOST_HANA_CONSTANT_CHECK(hana::drop_back(xs, hana::size_c<3>) == hana::make_tuple());
BOOST_HANA_CONSTANT_CHECK(hana::drop_back(xs, hana::size_c<4>) == hana::make_tuple());
static_assert(hana::drop_back(xs) == hana::make_tuple(0, '1'), "");
int main() { }

## ◆ group

 constexpr auto boost::hana::group

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

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

Group adjacent elements of a sequence that all respect a binary predicate, by default equality.Given a finite Sequence and an optional predicate (by default equal), group returns a sequence of subsequences representing groups of adjacent elements that are "equal" with respect to the predicate. In other words, the groups are such that the predicate is satisfied when it is applied to any two adjacent elements in that group. The sequence returned by group is such that the concatenation of its elements is equal to the original sequence, which is equivalent to saying that the order of the elements is not changed.

If no predicate is provided, adjacent elements in the sequence must all be compile-time Comparable.

## Signature

Given a Sequence s with tag S(T), an IntegralConstant Bool holding a value of type bool, and a predicate $$pred : T \times T \to Bool$$, group has the following signatures. For the variant with a provided predicate,

$\mathtt{group} : S(T) \times (T \times T \to Bool) \to S(S(T))$

for the variant without a custom predicate, T is required to be Comparable. The signature is then

$\mathtt{group} : S(T) \to S(S(T))$

Parameters
 xs The sequence to split into groups. predicate A binary function called as predicate(x, y), where x and y are adjacent elements in the sequence, whether both elements should be in the same group (subsequence) of the result. In the current version of the library, the result returned by predicate must be an IntegralConstant holding a value of a type convertible to bool. Also, predicate has to define an equivalence relation as defined by the Comparable concept. When this predicate is not provided, it defaults to equal, which requires the comparison of any two adjacent elements in the sequence to return a boolean IntegralConstant.

## Syntactic sugar (group.by)

group can be called in a third way, which provides a nice syntax especially when working with the comparing combinator:

group.by(predicate, xs) == group(xs, predicate)
group.by(predicate) == group(-, predicate)

where group(-, predicate) denotes the partial application of group to predicate.

## 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)
namespace hana = boost::hana;
// group without a predicate
hana::group(hana::make_tuple(hana::int_c<1>, hana::long_c<1>, hana::type_c<int>, hana::char_c<'x'>, hana::char_c<'x'>))
== hana::make_tuple(
hana::make_tuple(hana::int_c<1>, hana::long_c<1>),
hana::make_tuple(hana::type_c<int>),
hana::make_tuple(hana::char_c<'x'>, hana::char_c<'x'>)
)
);
// group with a predicate
constexpr auto tuples = hana::make_tuple(
hana::range_c<int, 0, 1>,
hana::range_c<int, 0, 2>,
hana::range_c<int, 1, 3>,
hana::range_c<int, 2, 6>
);
== hana::make_tuple(
hana::make_tuple(
hana::range_c<int, 0, 1>
),
hana::make_tuple(
hana::range_c<int, 0, 2>,
hana::range_c<int, 1, 3>
),
hana::make_tuple(
hana::range_c<int, 2, 6>
)
)
);
// group.by is syntactic sugar
static_assert(
hana::group.by(hana::comparing(hana::typeid_),
hana::make_tuple(1, 2, 3, 'x', 'y', 4.4, 5.5))
== hana::make_tuple(
hana::make_tuple(1, 2, 3),
hana::make_tuple('x', 'y'),
hana::make_tuple(4.4, 5.5)
)
, "");
int main() { }

## ◆ insert

 constexpr auto boost::hana::insert {}
related

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

Insert a value at a given index in a sequence.Given a sequence, an index and an element to insert, insert inserts the element at the given index.

Parameters
 xs The sequence in which a value should be inserted. n The index at which an element should be inserted. This must be a non-negative Constant of an integral type, and it must also be true that n < length(xs) if xs is a finite sequence. element The element to insert in the sequence.

## 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 <string>
namespace hana = boost::hana;
using namespace hana::literals;
using namespace std::literals;
int main() {
auto xs = hana::make_tuple("Hello"s, "world!"s);
hana::insert(xs, 1_c, " "s) == hana::make_tuple("Hello"s, " "s, "world!"s)
);
}

## ◆ insert_range

 constexpr auto boost::hana::insert_range

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

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

Insert several values at a given index in a sequence.Given a sequence, an index and any Foldable containing elements to insert, insert_range inserts the elements in the Foldable at the given index of the sequence.

Parameters
 xs The sequence in which values should be inserted. n The index at which elements should be inserted. This must be a non-negative Constant of an integral type, and it must also be true that n < length(xs) if xs is a finite sequence. elements A Foldable containing elements to insert in the sequence.

## 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 <string>
namespace hana = boost::hana;
using namespace hana::literals;
using namespace std::literals;
int main() {
auto xs = hana::make_tuple("Hello"s, "world!"s);
hana::insert_range(xs, 1_c, hana::make_tuple(1, 2, 3)) == hana::make_tuple("Hello"s, 1, 2, 3, "world!"s)
);
}

## ◆ intersperse

 constexpr auto boost::hana::intersperse

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

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

Insert a value between each pair of elements in a finite sequence.Given a finite Sequence xs with a linearization of [x1, x2, ..., xn], intersperse(xs, z) is a new sequence with a linearization of [x1, z, x2, z, x3, ..., xn-1, z, xn]. In other words, it inserts the z element between every pair of elements of the original sequence. If the sequence is empty or has a single element, intersperse returns the sequence as-is. In all cases, the sequence must be finite.

Parameters
 xs The sequence in which a value is interspersed. z The value to be inserted between every pair of elements of the sequence.

## 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)
namespace hana = boost::hana;
static_assert(hana::intersperse(hana::make_tuple(1, '2', 3.3), 'x') == hana::make_tuple(1, 'x', '2', 'x', 3.3), "");
BOOST_HANA_CONSTANT_CHECK(hana::intersperse(hana::make_tuple(), 'x') == hana::make_tuple());
int main() { }

## ◆ partition

 constexpr auto boost::hana::partition

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

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

Partition a sequence based on a predicate.Specifically, returns an unspecified Product whose first element is a sequence of the elements satisfying the predicate, and whose second element is a sequence of the elements that do not satisfy the predicate.

## Signature

Given a Sequence S(T), an IntegralConstant Bool holding a value of type bool, and a predicate $$T \to Bool$$, partition has the following signature:

$\mathtt{partition} : S(T) \times (T \to Bool) \to S(T) \times S(T)$

Parameters
 xs The sequence to be partitioned. predicate A function called as predicate(x) for each element x in the sequence, and returning whether x should be added to the sequence in the first component or in the second component of the resulting pair. In the current version of the library, predicate must return an IntegralConstant holding a value convertible to bool.

## Syntactic sugar (partition.by)

partition can be called in an alternate way, which provides a nice syntax in some cases where the predicate is short:

partition.by(predicate, xs) == partition(xs, predicate)
partition.by(predicate) == partition(-, predicate)

where partition(-, predicate) denotes the partial application of partition to predicate.

## 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 <type_traits>
namespace hana = boost::hana;
hana::partition(hana::tuple_c<int, 1, 2, 3, 4, 5, 6, 7>, [](auto x) {
return x % hana::int_c<2> != hana::int_c<0>;
})
==
hana::make_pair(
hana::tuple_c<int, 1, 3, 5, 7>,
hana::tuple_c<int, 2, 4, 6>
)
);
hana::partition(hana::tuple_t<void, int, float, char, double>, hana::trait<std::is_floating_point>)
==
hana::make_pair(
hana::tuple_t<float, double>,
hana::tuple_t<void, int, char>
)
);
// partition.by is syntactic sugar
hana::partition.by(hana::trait<std::is_floating_point>,
hana::tuple_t<void, int, float, char, double>)
==
hana::make_pair(
hana::tuple_t<float, double>,
hana::tuple_t<void, int, char>
)
);
int main() { }

## ◆ permutations

 constexpr auto boost::hana::permutations

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

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

Return a sequence of all the permutations of the given sequence.Specifically, permutations(xs) is a sequence whose elements are permutations of the original sequence xs. The permutations are not guaranteed to be in any specific order. Also note that the number of permutations grows very rapidly as the length of the original sequence increases. The growth rate is O(length(xs)!); with a sequence xs of length only 8, permutations(xs) contains over 40 000 elements!

## 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)
namespace hana = boost::hana;
BOOST_HANA_CONSTEXPR_LAMBDA auto is_permutation_of = hana::curry<2>([](auto xs, auto perm) {
});
int main() {
hana::make_tuple(
hana::make_tuple('1', 2, 3.0),
hana::make_tuple('1', 3.0, 2),
hana::make_tuple(2, '1', 3.0),
hana::make_tuple(2, 3.0, '1'),
hana::make_tuple(3.0, '1', 2),
hana::make_tuple(3.0, 2, '1')
),
is_permutation_of(hana::make_tuple('1', 2, 3.0))
)
);
}

## ◆ remove_at

 constexpr auto boost::hana::remove_at

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

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

Remove the element at a given index from a sequence.remove_at returns a new sequence identical to the original, except that the element at the given index is removed. Specifically, remove_at([x0, ..., xn-1, xn, xn+1, ..., xm], n) is a new sequence equivalent to [x0, ..., xn-1, xn+1, ..., xm].

Note
The behavior is undefined if the index is out of the bounds of the sequence.
Parameters
 xs A sequence from which an element is to be removed. n An non-negative IntegralConstant representing the index of the element to be removed from the sequence. The behavior is undefined if that index is not in the bounds of the sequence.

## 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)
namespace hana = boost::hana;
constexpr auto xs = hana::make_tuple(0, '1', 2.2, 3u);
static_assert(hana::remove_at(xs, hana::size_c<2>) == hana::make_tuple(0, '1', 3u), "");
int main() { }

## ◆ remove_at_c

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

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

Initial value:
= [](auto&& xs) {
return hana::remove_at(forwarded(xs), hana::size_c<n>);
}
constexpr auto remove_at
Remove the element at a given index from a sequence.remove_at returns a new sequence identical to the...
Definition: remove_at.hpp:46

Equivalent to remove_at; provided for convenience.

## 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)
namespace hana = boost::hana;
constexpr auto xs = hana::make_tuple(0, '1', 2.2, 3u);
static_assert(hana::remove_at_c<2>(xs) == hana::make_tuple(0, '1', 3u), "");
int main() { }

## ◆ remove_range

 constexpr auto boost::hana::remove_range

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

Initial value:
= [](auto&& xs, auto const& from, auto const& to) {
return tag-dispatched;
}
constexpr auto to
Converts an object from one data type to another.
Definition: to.hpp:97

Remove the elements inside a given range of indices from a sequence.remove_range returns a new sequence identical to the original, except that elements at indices in the provided range are removed. Specifically, remove_range([x0, ..., xn], from, to) is a new sequence equivalent to [x0, ..., x_from-1, x_to, ..., xn].

Note
The behavior is undefined if the range contains any index out of the bounds of the sequence.
Parameters
 xs A sequence from which elements are removed. [from,to) An half-open interval of IntegralConstants representing the indices of the elements to be removed from the sequence. The IntegralConstants in the half-open interval must be non-negative and in the bounds of the sequence. The half-open interval must also be valid, meaning that from <= to.

## 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)
namespace hana = boost::hana;
constexpr auto xs = hana::make_tuple(0, '1', 2.2, 3u, 4, 5.5);
static_assert(hana::remove_range(xs, hana::size_c<2>, hana::size_c<4>) == hana::make_tuple(0, '1', 4, 5.5), "");
int main() { }

## ◆ remove_range_c

template<std::size_t from, std::size_t to>
 constexpr auto boost::hana::remove_range_c

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

Initial value:
= [](auto&& xs) {
return hana::remove_range(forwarded(xs), hana::size_c<from>, hana::size_c<to>);
}
constexpr auto remove_range
Remove the elements inside a given range of indices from a sequence.remove_range returns a new sequen...
Definition: remove_range.hpp:49

Equivalent to remove_range; provided for convenience.

## 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)
namespace hana = boost::hana;
constexpr auto xs = hana::make_tuple(0, '1', 2.2, 3u, 4, 5.5);
static_assert(hana::remove_range_c<2, 4>(xs) == hana::make_tuple(0, '1', 4, 5.5), "");
int main() { }

## ◆ reverse

 constexpr auto boost::hana::reverse

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

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

Reverse a sequence.Specifically, reverse(xs) is a new sequence containing the same elements as xs, except in reverse order.

Parameters
 xs The sequence to reverse.

## 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)
namespace hana = boost::hana;
static_assert(hana::reverse(hana::make_tuple(1, '2', 3.3)) == hana::make_tuple(3.3, '2', 1), "");
int main() { }

## ◆ scan_left

 constexpr auto boost::hana::scan_left

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

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

Fold a Sequence to the left and return a list containing the successive reduction states.Like fold_left, scan_left reduces a sequence to a single value using a binary operation. However, unlike fold_left, it builds up a sequence of the intermediary results computed along the way and returns that instead of only the final reduction state. Like fold_left, scan_left can be used with or without an initial reduction state.

When the sequence is empty, two things may arise. If an initial state was provided, a singleton list containing that state is returned. Otherwise, if no initial state was provided, an empty list is returned. In particular, unlike for fold_left, using scan_left on an empty sequence without an initial state is not an error.

More specifically, scan_left([x1, ..., xn], state, f) is a sequence whose ith element is equivalent to fold_left([x1, ..., xi], state, f). The no-state variant is handled in an analogous way. For illustration, consider this left fold on a short sequence:

fold_left([x1, x2, x3], state, f) == f(f(f(state, x1), x2), x3)

The analogous sequence generated with scan_left will be

scan_left([x1, x2, x3], state, f) == [
state,
f(state, x1),
f(f(state, x1), x2),
f(f(f(state, x1), x2), x3)
]

Similarly, consider this left fold (without an initial state) on a short sequence:

fold_left([x1, x2, x3, x4], f) == f(f(f(x1, x2), x3), x4)

The analogous sequence generated with scan_left will be

scan_left([x1, x2, x3, x4], f) == [
x1,
f(x1, x2),
f(f(x1, x2), x3),
f(f(f(x1, x2), x3), x4)
]
Parameters
 xs The sequence to scan from the left. state The (optional) initial reduction state. f A binary function called as f(state, x), where state is the result accumulated so far and x is an element in the sequence. If no initial state is provided, f is called as f(x1, x2), where x1 and x2 are both elements of the sequence.

## 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 <sstream>
namespace hana = boost::hana;
auto to_string = [](auto x) {
std::ostringstream ss;
ss << x;
return ss.str();
};
auto f = [](auto state, auto element) {
return "f(" + to_string(state) + ", " + to_string(element) + ")";
};
int main() {
// with initial state
BOOST_HANA_RUNTIME_CHECK(hana::scan_left(hana::make_tuple(2, "3", '4'), 1, f) == hana::make_tuple(
1,
"f(1, 2)",
"f(f(1, 2), 3)",
"f(f(f(1, 2), 3), 4)"
));
// without initial state
BOOST_HANA_RUNTIME_CHECK(hana::scan_left(hana::make_tuple(1, "2", '3'), f) == hana::make_tuple(
1,
"f(1, 2)",
"f(f(1, 2), 3)"
));
}

## ◆ scan_right

 constexpr auto boost::hana::scan_right

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

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

Fold a Sequence to the right and return a list containing the successive reduction states.Like fold_right, scan_right reduces a sequence to a single value using a binary operation. However, unlike fold_right, it builds up a sequence of the intermediary results computed along the way and returns that instead of only the final reduction state. Like fold_right, scan_right can be used with or without an initial reduction state.

When the sequence is empty, two things may arise. If an initial state was provided, a singleton list containing that state is returned. Otherwise, if no initial state was provided, an empty list is returned. In particular, unlike for fold_right, using scan_right on an empty sequence without an initial state is not an error.

More specifically, scan_right([x1, ..., xn], state, f) is a sequence whose ith element is equivalent to fold_right([x1, ..., xi], state, f). The no-state variant is handled in an analogous way. For illustration, consider this right fold on a short sequence:

fold_right([x1, x2, x3], state, f) == f(x1, f(x2, f(x3, state)))

The analogous sequence generated with scan_right will be

scan_right([x1, x2, x3], state, f) == [
f(x1, f(x2, f(x3, state))),
f(x2, f(x3, state)),
f(x3, state),
state
]

Similarly, consider this right fold (without an initial state) on a short sequence:

fold_right([x1, x2, x3, x4], f) == f(x1, f(x2, f(x3, x4)))

The analogous sequence generated with scan_right will be

scan_right([x1, x2, x3, x4], f) == [
f(x1, f(x2, f(x3, x4))),
f(x2, f(x3, x4)),
f(x3, x4),
x4
]
Parameters
 xs The sequence to scan from the right. state The (optional) initial reduction state. f A binary function called as f(x, state), where state is the result accumulated so far and x is an element in the sequence. When no initial state is provided, f is called as f(x1, x2), where x1 and x2 are elements of the sequence.

## 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 <sstream>
namespace hana = boost::hana;
auto to_string = [](auto x) {
std::ostringstream ss;
ss << x;
return ss.str();
};
auto f = [](auto element, auto state) {
return "f(" + to_string(element) + ", " + to_string(state) + ")";
};
int main() {
// with initial state
BOOST_HANA_RUNTIME_CHECK(hana::scan_right(hana::make_tuple(1, "2", '3'), 4, f) == hana::make_tuple(
"f(1, f(2, f(3, 4)))",
"f(2, f(3, 4))",
"f(3, 4)",
4
));
// without initial state
BOOST_HANA_RUNTIME_CHECK(hana::scan_right(hana::make_tuple(1, "2", '3'), f) == hana::make_tuple(
"f(1, f(2, 3))",
"f(2, 3)",
'3'
));
}

## ◆ slice

 constexpr auto boost::hana::slice

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

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

Extract the elements of a Sequence at the given indices.Given an arbitrary sequence of indices, slice returns a new sequence of the elements of the original sequence that appear at those indices. In other words,.

slice([x1, ..., xn], [i1, ..., ik]) == [x_i1, ..., x_ik]

The indices do not have to be ordered or contiguous in any particular way, but they must not be out of the bounds of the sequence. It is also possible to specify the same index multiple times, in which case the element at this index will be repeatedly included in the resulting sequence.

Parameters
 xs The sequence from which a subsequence is extracted. indices A compile-time Foldable containing non-negative IntegralConstants representing the indices. The indices are 0-based, and they must all be in bounds of the xs sequence. Note that any Foldable will really do (no need for an Iterable, for example); the linearization of the indices is used to determine the order of the elements included in the slice.

## 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)
namespace hana = boost::hana;
using namespace hana::literals;
// Slice a contiguous range
constexpr auto xs = hana::make_tuple(0, '1', 2.2, 3_c, hana::type_c<float>);
static_assert(
hana::slice(xs, hana::tuple_c<std::size_t, 1, 2, 3>) ==
hana::make_tuple('1', 2.2, 3_c)
, "");
// A more complex example with a non-contiguous range
constexpr auto letters = hana::to_tuple(hana::range_c<char, 'a', 'z'>);
constexpr auto indices = hana::to_tuple(hana::make_range(hana::size_c<0>, hana::length(letters)));
auto even_indices = hana::filter(indices, [](auto n) {
return n % hana::size_c<2> == hana::size_c<0>;
});
hana::slice(letters, even_indices) == hana::tuple_c<char,
'a', 'c', 'e', 'g', 'i', 'k', 'm', 'o', 'q', 's', 'u', 'w', 'y'
>
);
int main() { }

## ◆ slice_c

template<std::size_t from, std::size_t to>
 constexpr auto boost::hana::slice_c

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

Initial value:
= [](auto&& xs) {
return hana::slice(forwarded(xs), hana::range_c<std::size_t, from, to>);
}
constexpr auto slice
Extract the elements of a Sequence at the given indices.Given an arbitrary sequence of indices,...
Definition: slice.hpp:53

Shorthand to slice a contiguous range of elements.slice_c is simply a shorthand to slice a contiguous range of elements. In particular, slice_c<from, to>(xs) is equivalent to slice(xs, range_c<std::size_t, from, to>), which simply slices all the elements of xs contained in the half-open interval delimited by [from, to). Like for slice, the indices used with slice_c are 0-based and they must be in the bounds of the sequence being sliced.

Template Parameters
 from The index of the first element in the slice. to One-past the index of the last element in the slice. It must hold that from <= to.

## 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)
namespace hana = boost::hana;
static_assert(
hana::slice_c<1, 3>(hana::make_tuple(1, '2', 3.3, hana::type_c<float>))
==
hana::make_tuple('2', 3.3)
, "");
int main() { }

## ◆ sort

 constexpr auto boost::hana::sort

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

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

Sort a sequence, optionally based on a custom predicate.Given a Sequence and an optional predicate (by default less), sort returns a new sequence containing the same elements as the original, except they are ordered in such a way that if x comes before y in the sequence, then either predicate(x, y) is true, or both predicate(x, y) and predicate(y, x) are false.

Also note that the sort is guaranteed to be stable. Hence, if x comes before y in the original sequence and both predicate(x, y) and predicate(y, x) are false, then x will come before y in the resulting sequence.

If no predicate is provided, the elements in the sequence must all be compile-time Orderable.

## Signature

Given a Sequence S(T), a boolean IntegralConstant Bool and a binary predicate $$T \times T \to Bool$$, sort has the following signatures. For the variant with a provided predicate,

$\mathtt{sort} : S(T) \times (T \times T \to Bool) \to S(T)$

for the variant without a custom predicate, T is required to be Orderable. The signature is then

$\mathtt{sort} : S(T) \to S(T)$

Parameters
 xs The sequence to sort. predicate A function called as predicate(x, y) for two elements x and y of the sequence, and returning a boolean IntegralConstant representing whether x is to be considered less than y, i.e. whether x should appear before y in the resulting sequence. More specifically, predicate must define a strict weak ordering on the elements of the sequence. When the predicate is not specified, this defaults to less. In the current version of the library, the predicate has to return an IntegralConstant holding a value convertible to a bool.

## Syntactic sugar (sort.by)

sort can be called in a third way, which provides a nice syntax especially when working with the ordering combinator:

sort.by(predicate, xs) == sort(xs, predicate)
sort.by(predicate) == sort(-, predicate)

where sort(-, predicate) denotes the partial application of sort to predicate.

## 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 <string>
namespace hana = boost::hana;
using namespace hana::literals;
using namespace std::literals;
// sort without a predicate
hana::sort(hana::make_tuple(1_c, -2_c, 3_c, 0_c)) ==
hana::make_tuple(-2_c, 0_c, 1_c, 3_c)
);
// sort with a predicate
hana::sort(hana::make_tuple(1_c, -2_c, 3_c, 0_c), hana::greater) ==
hana::make_tuple(3_c, 1_c, 0_c, -2_c)
);
int main() {
// sort.by is syntactic sugar
auto tuples = hana::make_tuple(
hana::make_tuple(2_c, 'x', nullptr),
hana::make_tuple(1_c, "foobar"s, hana::int_c<4>)
);
== hana::make_tuple(
hana::make_tuple(1_c, "foobar"s, hana::int_c<4>),
hana::make_tuple(2_c, 'x', nullptr)
)
);
}

## ◆ span

 constexpr auto boost::hana::span

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

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

Returns a Product containing the longest prefix of a sequence satisfying a predicate, and the rest of the sequence.The first component of the returned Product is a sequence for which all elements satisfy the given predicate. The second component of the returned Product is a sequence containing the remainder of the argument. Both or either sequences may be empty, depending on the input argument. More specifically,.

span(xs, predicate) == make_pair(take_while(xs, predicate),
drop_while(xs, predicate))

except that make_pair may be an arbitrary Product.

## Signature

Given a Sequence S(T), a Logical Bool and a predicate $$T \to Bool$$, span has the following signature:

$\mathtt{span} : S(T) \times (T \to Bool) \to S(T) \times S(T)$

Parameters
 xs The sequence to break into two parts. predicate A function called as predicate(x), where x is an element of the sequence, and returning a Logical. In the current implementation of the library,predicatehas to return a compile-timeLogical.

## Syntactic sugar (span.by)

span can be called in an alternate way, which provides a nice syntax in some cases where the predicate is short:

span.by(predicate, xs) == span(xs, predicate)
span.by(predicate) == span(-, predicate)

where span(-, predicate) denotes the partial application of span to predicate.

## 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)
namespace hana = boost::hana;
constexpr auto xs = hana::make_tuple(hana::int_c<1>, hana::int_c<2>, hana::int_c<3>, hana::int_c<4>);
hana::span(xs, hana::less.than(hana::int_c<3>))
==
hana::make_pair(hana::make_tuple(hana::int_c<1>, hana::int_c<2>),
hana::make_tuple(hana::int_c<3>, hana::int_c<4>))
);
hana::span(xs, hana::less.than(hana::int_c<0>))
==
hana::make_pair(hana::make_tuple(), xs)
);
hana::span(xs, hana::less.than(hana::int_c<5>))
==
hana::make_pair(xs, hana::make_tuple())
);
// span.by is syntactic sugar
hana::span.by(hana::less.than(hana::int_c<3>), xs)
==
hana::make_pair(hana::make_tuple(hana::int_c<1>, hana::int_c<2>),
hana::make_tuple(hana::int_c<3>, hana::int_c<4>))
);
int main() { }

## ◆ take_back

 constexpr auto boost::hana::take_back

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

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

Returns the last n elements of a sequence, or the whole sequence if the sequence has less than n elements.Given a Sequence xs and an IntegralConstant n, take_back(xs, n) is a new sequence containing the last n elements of xs, in the same order. If length(xs) <= n, the whole sequence is returned and no error is triggered.

Parameters
 xs The sequence to take the elements from. n A non-negative IntegralConstant representing the number of elements to keep in the resulting sequence.

## 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)
namespace hana = boost::hana;
BOOST_HANA_CONSTANT_CHECK(hana::take_back(hana::make_tuple(1, '2', 3.3), hana::size_c<0>) == hana::make_tuple());
static_assert(hana::take_back(hana::make_tuple(1, '2', 3.3), hana::size_c<1>) == hana::make_tuple(3.3), "");
static_assert(hana::take_back(hana::make_tuple(1, '2', 3.3), hana::size_c<2>) == hana::make_tuple('2', 3.3), "");
static_assert(hana::take_back(hana::make_tuple(1, '2', 3.3), hana::size_c<3>) == hana::make_tuple(1, '2', 3.3), "");
static_assert(hana::take_back(hana::make_tuple(1, '2', 3.3), hana::size_c<4>) == hana::make_tuple(1, '2', 3.3), "");
int main() { }

## ◆ take_back_c

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

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

Initial value:
= [](auto&& xs) {
return hana::take_back(forwarded(xs), hana::size_c<n>);
}
constexpr auto take_back
Returns the last n elements of a sequence, or the whole sequence if the sequence has less than n elem...
Definition: take_back.hpp:42

Equivalent to take_back; provided for convenience.

## 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)
namespace hana = boost::hana;
static_assert(hana::take_back_c<2>(hana::make_tuple(1, '2', 3.3)) == hana::make_tuple('2', 3.3), "");
int main() { }

## ◆ take_front

 constexpr auto boost::hana::take_front

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

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

Returns the first n elements of a sequence, or the whole sequence if the sequence has less than n elements.Given a Sequence xs and an IntegralConstant n, take_front(xs, n) is a new sequence containing the first n elements of xs, in the same order. If length(xs) <= n, the whole sequence is returned and no error is triggered.

Parameters
 xs The sequence to take the elements from. n A non-negative IntegralConstant representing the number of elements to keep in the resulting sequence.

## 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)
namespace hana = boost::hana;
BOOST_HANA_CONSTANT_CHECK(hana::take_front(hana::make_tuple(1, '2', 3.3), hana::size_c<0>) == hana::make_tuple());
static_assert(hana::take_front(hana::make_tuple(1, '2', 3.3), hana::size_c<1>) == hana::make_tuple(1), "");
static_assert(hana::take_front(hana::make_tuple(1, '2', 3.3), hana::size_c<2>) == hana::make_tuple(1, '2'), "");
static_assert(hana::take_front(hana::make_tuple(1, '2', 3.3), hana::size_c<3>) == hana::make_tuple(1, '2', 3.3), "");
static_assert(hana::take_front(hana::make_tuple(1, '2', 3.3), hana::size_c<4>) == hana::make_tuple(1, '2', 3.3), "");
int main() { }

## ◆ take_front_c

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

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

Initial value:
= [](auto&& xs) {
return hana::take_front(forwarded(xs), hana::size_c<n>);
}
constexpr auto take_front
Returns the first n elements of a sequence, or the whole sequence if the sequence has less than n ele...
Definition: take_front.hpp:42

Equivalent to take_front; provided for convenience.

## 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)
namespace hana = boost::hana;
static_assert(hana::take_front_c<2>(hana::make_tuple(1, '2', 3.3)) == hana::make_tuple(1, '2'), "");
int main() { }

## ◆ take_while

 constexpr auto boost::hana::take_while

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

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

Take elements from a sequence while the predicate is satisfied.Specifically, take_while returns a new sequence containing the longest prefix of xs in which all the elements satisfy the given predicate.

Parameters
 xs The sequence to take elements from. predicate A function called as predicate(x), where x is an element of the sequence, and returning a Logical representing whether x should be included in the resulting sequence. In the current version of the library, predicate has to return a Constant 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)
namespace hana = boost::hana;
using namespace hana::literals;
hana::take_while(hana::tuple_c<int, 0, 1, 2, 3>, hana::less.than(2_c))
==
hana::tuple_c<int, 0, 1>
);
int main() { }

## ◆ unfold_left

template<typename S >
 constexpr auto boost::hana::unfold_left

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

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

Dual operation to fold_left for sequences.While fold_left reduces a structure to a summary value from the left, unfold_left builds a sequence from a seed value and a function, starting from the left.

## Signature

Given a Sequence S, an initial value state of tag I, an arbitrary Product P and a function $$f : I \to P(I, T)$$, unfold_left<S> has the following signature:

$\mathtt{unfold\_left}_S : I \times (I \to P(I, T)) \to S(T)$

Template Parameters
 S The tag of the sequence to build up.
Parameters
 state An initial value to build the sequence from. f A function called as f(state), where state is an initial value, and returning nothing if it is done producing the sequence. otherwise, just(make

(state, x)), where state is the new initial value used in the next call to f, x is an element to be appended to the resulting sequence, and P is an arbitrary Product.

## Fun fact

In some cases, unfold_left can undo a fold_left operation:

unfold_left<S>(fold_left(xs, state, f), g) == xs

if the following holds

g(f(x, y)) == just(make_pair(x, y))
g(state) == nothing

## 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)
namespace hana = boost::hana;
hana::unfold_left<hana::tuple_tag>(hana::int_c<10>, [](auto x) {
return hana::if_(x == hana::int_c<0>,
hana::nothing,
hana::just(hana::make_pair(x - hana::int_c<1>, x))
);
})
==
hana::tuple_c<int, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10>
);
int main() { }

## ◆ unfold_right

template<typename S >
 constexpr auto boost::hana::unfold_right

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

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

Dual operation to fold_right for sequences.While fold_right reduces a structure to a summary value from the right, unfold_right builds a sequence from a seed value and a function, starting from the right.

## Signature

Given a Sequence S, an initial value state of tag I, an arbitrary Product P and a function $$f : I \to P(T, I)$$, unfold_right<S> has the following signature:

$\mathtt{unfold\_right}_S : I \times (I \to P(T, I)) \to S(T)$

Template Parameters
 S The tag of the sequence to build up.
Parameters
 state An initial value to build the sequence from. f A function called as f(state), where state is an initial value, and returning nothing if it is done producing the sequence. otherwise, just(make

(x, state)), where state is the new initial value used in the next call to f, x is an element to be prepended to the resulting sequence, and P is an arbitrary Product.

## Fun fact

In some cases, unfold_right can undo a fold_right operation:

unfold_right<S>(fold_right(xs, state, f), g) == xs

if the following holds

g(f(x, y)) == just(make_pair(x, y))
g(state) == nothing

## 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)
namespace hana = boost::hana;
hana::unfold_right<hana::tuple_tag>(hana::int_c<10>, [](auto x) {
return hana::if_(x == hana::int_c<0>,
hana::nothing,
hana::just(hana::make_pair(x, x - hana::int_c<1>))
);
})
==
hana::tuple_c<int, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1>
);
int main() { }

## ◆ unique

 constexpr auto boost::hana::unique

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

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

Removes all consecutive duplicate elements from a Sequence.Given a Sequence and an optional binary predicate, unique returns a new sequence containing only the first element of every subrange of the original sequence whose elements are all equal. In other words, it turns a sequence of the form [a, a, b, c, c, c, d, d, d, a] into a sequence [a, b, c, d, a]. The equality of two elements is determined by the provided predicate, or by equal if no predicate is provided.

## Signature

Given a Sequence S(T), a Logical Bool and a binary predicate $$T \times T \to Bool$$, unique has the following signature:

$\mathtt{unique} : S(T) \times (T \times T \to Bool) \to S(T)$

Parameters
 xs The sequence from which to remove consecutive duplicates. predicate A function called as predicate(x, y), where x and y are adjacent elements of the sequence, and returning a Logical representing whether x and y should be considered equal. predicate should define an equivalence relation over the elements of the sequence. In the current implementation of the library, predicate has to return a compile-time Logical. This parameter is optional; it defaults to equal if it is not provided, which then requires the elements of the sequence to be compile-time Comparable.

## Syntactic sugar (unique.by)

unique can be called in an alternate way, which provides a nice syntax, especially in conjunction with the comparing combinator:

unique.by(predicate, xs) == unique(xs, predicate)
unique.by(predicate) == unique(-, predicate)

where unique(-, predicate) denotes the partial application of unique to predicate.

## 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 <string>
namespace hana = boost::hana;
using namespace std::literals;
// unique without a predicate
constexpr auto types = hana::tuple_t<int, float, float, char, int, int, int, double>;
hana::unique(types) == hana::tuple_t<int, float, char, int, double>
);
int main() {
// unique with a predicate
auto objects = hana::make_tuple(1, 2, "abc"s, 'd', "efg"s, "hij"s, 3.4f);
hana::unique(objects, [](auto const& t, auto const& u) {
return hana::typeid_(t) == hana::typeid_(u);
})
== hana::make_tuple(1, "abc"s, 'd', "efg"s, 3.4f)
);
// unique.by is syntactic sugar
hana::unique.by(hana::comparing(hana::typeid_), objects) ==
hana::make_tuple(1, "abc"s, 'd', "efg"s, 3.4f)
);
}

## ◆ zip

 constexpr auto boost::hana::zip

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

Initial value:
= [](auto&& x1, ..., auto&& xn) {
return tag-dispatched;
}

Zip one sequence or more.Given n sequences s1, ..., sn, zip produces a sequence whose i-th element is a tuple of (s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip produces a sequence of the form.

[
make_tuple(s1[0], ..., sn[0]),
make_tuple(s1[1], ..., sn[1]),
...
make_tuple(s1[M], ..., sn[M])
]

where M is the length of the sequences, which are all assumed to have the same length. Assuming the sequences to all have the same size allows the library to perform some optimizations. To zip sequences that may have different lengths, zip_shortest should be used instead. Also note that it is an error to provide no sequence at all, i.e. zip expects at least one sequence.

## 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)
namespace hana = boost::hana;
static_assert(
hana::zip(hana::make_tuple(1, 'a'), hana::make_tuple(2, 3.3))
==
hana::make_tuple(hana::make_tuple(1, 2), hana::make_tuple('a', 3.3))
, "");
int main() { }

## ◆ zip_shortest

 constexpr auto boost::hana::zip_shortest

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

Initial value:
= [](auto&& x1, ..., auto&& xn) {
return tag-dispatched;
}

Zip one sequence or more.Given n sequences s1, ..., sn, zip_shortest produces a sequence whose i-th element is a tuple of (s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip_shortest produces a sequence of the form.

[
make_tuple(s1[0], ..., sn[0]),
make_tuple(s1[1], ..., sn[1]),
...
make_tuple(s1[M], ..., sn[M])
]

where M is the length of the shortest sequence. Hence, the returned sequence stops when the shortest input sequence is exhausted. If you know that all the sequences you are about to zip have the same length, you should use zip instead, since it can be more optimized. Also note that it is an error to provide no sequence at all, i.e. zip_shortest expects at least one sequence.

## 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)
namespace hana = boost::hana;
static_assert(
hana::zip_shortest(hana::make_tuple(1, 'a'), hana::make_tuple(2, 3.3), hana::make_tuple(3, 'c', "ignored"))
==
hana::make_tuple(hana::make_tuple(1, 2, 3), hana::make_tuple('a', 3.3, 'c'))
, "");
int main() { }

## ◆ zip_shortest_with

 constexpr auto boost::hana::zip_shortest_with

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

Initial value:
= [](auto&& f, auto&& x1, ..., auto&& xn) {
return tag-dispatched;
}

Zip one sequence or more with a given function.Given a n-ary function f and n sequences s1, ..., sn, zip_shortest_with produces a sequence whose i-th element is f(s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip_shortest_with produces a sequence of the form.

[
f(s1[0], ..., sn[0]),
f(s1[1], ..., sn[1]),
...
f(s1[M], ..., sn[M])
]

where M is the length of the shortest sequence. Hence, the returned sequence stops when the shortest input sequence is exhausted. If you know that all the sequences you are about to zip have the same length, you should use zip_with instead, since it can be more optimized. Also note that it is an error to provide no sequence at all, i.e. zip_shortest_with expects at least one sequence.

## 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)
namespace hana = boost::hana;
static_assert(
hana::zip_shortest_with(hana::mult, hana::make_tuple(1, 2, 3, 4), hana::make_tuple(5, 6, 7, 8, "ignored"))
==
hana::make_tuple(5, 12, 21, 32)
, "");
int main() { }

## ◆ zip_with

 constexpr auto boost::hana::zip_with

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

Initial value:
= [](auto&& f, auto&& x1, ..., auto&& xn) {
return tag-dispatched;
}

Zip one sequence or more with a given function.Given a n-ary function f and n sequences s1, ..., sn, zip_with produces a sequence whose i-th element is f(s1[i], ..., sn[i]), where sk[i] denotes the i-th element of the k-th sequence. In other words, zip_with produces a sequence of the form.

[
f(s1[0], ..., sn[0]),
f(s1[1], ..., sn[1]),
...
f(s1[M], ..., sn[M])
]

where M is the length of the sequences, which are all assumed to have the same length. Assuming the sequences to all have the same size allows the library to perform some optimizations. To zip sequences that may have different lengths, zip_shortest_with should be used instead. Also note that it is an error to provide no sequence at all, i.e. zip_with` expects at least one sequence.

## 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 <tuple>
#include <type_traits>
#include <utility>
namespace hana = boost::hana;
// Basic usage:
static_assert(
hana::zip_with(hana::mult, hana::make_tuple(1, 2, 3, 4), hana::make_tuple(5, 6, 7, 8))
==
hana::make_tuple(5, 12, 21, 32)
, "");
// Example of computing a tuple of all the common types of several tuples:
template<typename... Ts>
using common_tuple_t = typename decltype(
hana::metafunction<std::common_type>,
hana::transform(std::declval<Ts>(), hana::decltype_)...
),
hana::template_<std::tuple>
)
)::type;
static_assert(std::is_same<
common_tuple_t<
>,
>::value, "");
int main() { }