Boost.Hana  1.7.1 Your standard library for metaprogramming
boost::hana::integral_constant< T, v > Struct Template Reference

## Description

### template<typename T, T v> struct boost::hana::integral_constant< T, v >

Compile-time value of an integral type.

An integral_constant is an object that represents a compile-time integral value. As the name suggests, hana::integral_constant is basically equivalent to std::integral_constant, except that hana::integral_constant also provide other goodies to make them easier to use, like arithmetic operators and similar features. In particular, hana::integral_constant is guaranteed to inherit from the corresponding std::integral_constant, and hence have the same members and capabilities. The sections below explain the extensions to std::integral_constant provided by hana::integral_constant.

## Arithmetic operators

hana::integral_constant provides arithmetic operators that return hana::integral_constants to ease writing compile-time arithmetic:

BOOST_HANA_CONSTANT_CHECK(hana::int_c<1> + hana::int_c<3> == hana::int_c<4>);
// Mixed-type operations are supported, but only when it involves a
// promotion, and not a conversion that could be lossy.
BOOST_HANA_CONSTANT_CHECK(hana::size_c<3> * hana::ushort_c<5> == hana::size_c<15>);
BOOST_HANA_CONSTANT_CHECK(hana::llong_c<15> == hana::int_c<15>);
#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

It is pretty important to realize that these operators return other integral_constants, not normal values of an integral type. Actually, all those operators work pretty much in the same way. Simply put, for an operator @,

integral_constant<T, x>{} @ integral_constant<T, y>{} == integral_constant<T, x @ y>{}

The fact that the operators return Constants is very important because it allows all the information that's known at compile-time to be conserved as long as it's only used with other values known at compile-time. It is also interesting to observe that whenever an integral_constant is combined with a normal runtime value, the result will be a runtime value (because of the implicit conversion). In general, this gives us the following table

left operand right operand result
integral_constant integral_constant integral_constant
integral_constant runtime runtime
runtime integral_constant runtime
runtime runtime runtime

The full range of provided operators is

• Arithmetic: binary +, binary -, /, *, %, unary +, unary -
• Bitwise: ~, &, |, ^, <<, >>
• Comparison: ==, !=, <, <=, >, >=
• Logical: ||, &&, !

## Construction with user-defined literals

integral_constants of type long long can be created with the _c user-defined literal, which is contained in the literals namespace:

using namespace hana::literals; // contains the _c suffix
BOOST_HANA_CONSTANT_CHECK(1234_c == hana::llong_c<1234>);
BOOST_HANA_CONSTANT_CHECK(-1234_c == hana::llong_c<-1234>);
BOOST_HANA_CONSTANT_CHECK(1_c + (3_c * 4_c) == hana::llong_c<1 + (3 * 4)>);

## Modeled concepts

1. Constant and IntegralConstant
An integral_constant is a model of the IntegralConstant concept in the most obvious way possible. Specifically,
constexpr auto value
Return the compile-time value associated to a constant.
Definition: value.hpp:54
The model of Constant follows naturally from the model of IntegralConstant, i.e.
value<integral_constant<T, v>>() == v // of type T
2. Comparable, Orderable, Logical, Monoid, Group, Ring, and EuclideanRing, Hashable
Those models are exactly those provided for Constants, which are documented in their respective concepts.

## Synopsis of associated functions

template<typename T , T v>
constexpr integral_constant< T, v > integral_c {}
Creates an integral_constant holding the given compile-time value. More...

template<char ... c>
constexpr auto operator""_c ()
Creates a hana::integral_constant from a literal. More...

## Friends

template<typename X , typename Y >
constexpr friend auto operator+ (X &&x, Y &&y)
Equivalent to hana::plus

template<typename X , typename Y >
constexpr friend auto operator- (X &&x, Y &&y)
Equivalent to hana::minus

template<typename X >
constexpr friend auto operator- (X &&x)
Equivalent to hana::negate

template<typename X , typename Y >
constexpr friend auto operator* (X &&x, Y &&y)
Equivalent to hana::mult

template<typename X , typename Y >
constexpr friend auto operator/ (X &&x, Y &&y)
Equivalent to hana::div

template<typename X , typename Y >
constexpr friend auto operator% (X &&x, Y &&y)
Equivalent to hana::mod

template<typename X , typename Y >
constexpr friend auto operator== (X &&x, Y &&y)
Equivalent to hana::equal

template<typename X , typename Y >
constexpr friend auto operator!= (X &&x, Y &&y)
Equivalent to hana::not_equal

template<typename X , typename Y >
constexpr friend auto operator|| (X &&x, Y &&y)
Equivalent to hana::or_

template<typename X , typename Y >
constexpr friend auto operator&& (X &&x, Y &&y)
Equivalent to hana::and_

template<typename X >
constexpr friend auto operator! (X &&x)
Equivalent to hana::not_

template<typename X , typename Y >
constexpr friend auto operator< (X &&x, Y &&y)
Equivalent to hana::less

template<typename X , typename Y >
constexpr friend auto operator> (X &&x, Y &&y)
Equivalent to hana::greater

template<typename X , typename Y >
constexpr friend auto operator<= (X &&x, Y &&y)
Equivalent to hana::less_equal

template<typename X , typename Y >
constexpr friend auto operator>= (X &&x, Y &&y)
Equivalent to hana::greater_equal

## Static Public Member Functions

template<typename F >
static constexpr void times (F &&f)
Call a function n times. More...

## ◆ integral_c

template<typename T , T v>
template<typename T , T v>
 constexpr integral_constant integral_c {}
related

Creates an integral_constant holding the given compile-time value.

Specifically, integral_c<T, v> is a hana::integral_constant holding the compile-time value v of an integral type T.

Template Parameters
 T The type of the value to hold in the integral_constant. It must be an integral type. v The integral value to hold in the integral_constant.

## Example

BOOST_HANA_CONSTANT_CHECK(hana::integral_c<int, 2> == hana::int_c<2>);
static_assert(decltype(hana::integral_c<int, 2>)::value == 2, "");

## ◆ operator""_c()

template<char ... c>
 constexpr auto operator""_c ( )
related

Creates a hana::integral_constant from a literal.

The literal is parsed at compile-time and the result is returned as a llong<...>.

Note
We use llong<...> instead of ullong<...> because using an unsigned type leads to unexpected behavior when doing stuff like -1_c. If we used an unsigned type, -1_c would be something like ullong<-1> which is actually ullong<something huge>.

## Example

using namespace hana::literals; // contains the _c suffix
BOOST_HANA_CONSTANT_CHECK(1234_c == hana::llong_c<1234>);
BOOST_HANA_CONSTANT_CHECK(-1234_c == hana::llong_c<-1234>);
BOOST_HANA_CONSTANT_CHECK(1_c + (3_c * 4_c) == hana::llong_c<1 + (3 * 4)>);

## ◆ times()

template<typename T , T v>
template<typename F >
 static constexpr void boost::hana::integral_constant< T, v >::times ( F && f )
staticconstexpr

Call a function n times.

times allows a nullary function to be invoked n times:

static constexpr void times(F &&f)
Call a function n times.
Definition: integral_constant.hpp:168

should be expanded by any decent compiler to

f(); f(); f();

This can be useful in several contexts, e.g. for loop unrolling:

std::string s;
for (char c = 'x'; c <= 'z'; ++c)
hana::int_<5>::times([&] { s += c; });
BOOST_HANA_RUNTIME_CHECK(s == "xxxxxyyyyyzzzzz");
#define BOOST_HANA_RUNTIME_CHECK(...)
Equivalent to BOOST_HANA_RUNTIME_ASSERT, but not influenced by the BOOST_HANA_CONFIG_DISABLE_ASSERTIO...
Definition: assert.hpp:209

Note that times is really a static function object, not just a static function. This allows int_<n>::times to be passed to higher-order algorithms:

std::string s;
auto functions = hana::make_tuple(
[&] { s += "x"; },
[&] { s += "y"; },
[&] { s += "z"; }
);
hana::for_each(functions, hana::int_<5>::times);
BOOST_HANA_RUNTIME_CHECK(s == "xxxxxyyyyyzzzzz");
constexpr auto for_each
Perform an action on each element of a foldable, discarding the result each time.
Definition: for_each.hpp:39

Also, since static members can be accessed using both the . and the :: syntax, one can take advantage of this (loophole?) to call times on objects just as well as on types:

std::string s;
for (char c = 'x'; c <= 'z'; ++c)
hana::int_c<5>.times([&] { s += c; });
BOOST_HANA_RUNTIME_CHECK(s == "xxxxxyyyyyzzzzz");
Note
times is equivalent to the hana::repeat function, which works on an arbitrary IntegralConstant.

Sometimes, it is also useful to know the index we're at inside the function. This can be achieved by using times.with_index:

std::vector<int> v;
hana::int_<5>::times.with_index([&](auto index) { v.push_back(index); });
BOOST_HANA_RUNTIME_CHECK(v == std::vector<int>{0, 1, 2, 3, 4});

Remember that times is a function object, and hence it can have subobjects. with_index is just a function object nested inside times, which allows for this nice little interface. Also note that the indices passed to the function are integral_constants; they are known at compile-time. Hence, we can do compile-time stuff with them, like indexing inside a tuple:

constexpr auto xs = hana::tuple_c<int, 0, 1, 2>;
hana::int_<3>::times.with_index([xs](auto index) {
BOOST_HANA_CONSTANT_CHECK(xs[index] == index);
});
Note
times.with_index(f) guarantees that the calls to f will be done in order of ascending index. In other words, f will be called as f(0), f(1), f(2), etc., but with integral_constants instead of normal integers. Side effects can also be done in the function passed to times and times.with_index.