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:
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
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;
Modeled concepts
Constant and IntegralConstant
An integral_constant is a model of the IntegralConstant concept in the most obvious way possible. Specifically, The model of Constant follows naturally from the model of IntegralConstant, i.e. value<integral_constant<T, v>>() == v
Comparable, Orderable, Logical, Monoid, Group, Ring, and EuclideanRing, Hashable
Those models are exactly those provided for Constants, which are documented in their respective concepts.
|
| template<bool b> |
| using | bool_ = integral_constant< bool, b > |
| |
| using | true_ = bool_< true > |
| |
| using | false_ = bool_< false > |
| |
| template<char c> |
| using | char_ = integral_constant< char, c > |
| |
| template<short i> |
| using | short_ = integral_constant< short, i > |
| |
| template<unsigned short i> |
| using | ushort_ = integral_constant< unsigned short, i > |
| |
| template<int i> |
| using | int_ = integral_constant< int, i > |
| |
| template<unsigned int i> |
| using | uint = integral_constant< unsigned int, i > |
| |
| template<long i> |
| using | long_ = integral_constant< long, i > |
| |
| template<unsigned long i> |
| using | ulong = integral_constant< unsigned long, i > |
| |
| template<long long i> |
| using | llong = integral_constant< long long, i > |
| |
| template<unsigned long long i> |
| using | ullong = integral_constant< unsigned long long, i > |
| |
| template<std::size_t i> |
| using | size_t = integral_constant< std::size_t, i > |
| |
| template<typename T , T v> |
| constexpr integral_constant< T, v > | integral_c {} |
| | Creates an integral_constant holding the given compile-time value. More...
|
| |
| template<bool b> |
| constexpr bool_< b > | bool_c {} |
| |
| constexpr auto | true_c = bool_c<true> |
| |
| constexpr auto | false_c = bool_c<false> |
| |
| template<char c> |
| constexpr char_< c > | char_c {} |
| |
| template<short i> |
| constexpr short_< i > | short_c {} |
| |
| template<unsigned short i> |
| constexpr ushort_< i > | ushort_c {} |
| |
| template<int i> |
| constexpr int_< i > | int_c {} |
| |
| template<unsigned int i> |
| constexpr uint< i > | uint_c {} |
| |
| template<long i> |
| constexpr long_< i > | long_c {} |
| |
| template<unsigned long i> |
| constexpr ulong< i > | ulong_c {} |
| |
| template<long long i> |
| constexpr llong< i > | llong_c {} |
| |
| template<unsigned long long i> |
| constexpr ullong< i > | ullong_c {} |
| |
| template<std::size_t i> |
| constexpr size_t< i > | size_c {} |
| |
| template<char... c> |
| constexpr auto | operator""_c () |
| | Creates a hana::integral_constant from a literal. More...
|
| |
|
|
template<typename X , typename Y > |
| constexpr auto | operator+ (X &&x, Y &&y) |
| | Equivalent to hana::plus
|
| |
|
template<typename X , typename Y > |
| constexpr auto | operator- (X &&x, Y &&y) |
| | Equivalent to hana::minus
|
| |
|
template<typename X > |
| constexpr auto | operator- (X &&x) |
| | Equivalent to hana::negate
|
| |
|
template<typename X , typename Y > |
| constexpr auto | operator* (X &&x, Y &&y) |
| | Equivalent to hana::mult
|
| |
|
template<typename X , typename Y > |
| constexpr auto | operator/ (X &&x, Y &&y) |
| | Equivalent to hana::div
|
| |
|
template<typename X , typename Y > |
| constexpr auto | operator% (X &&x, Y &&y) |
| | Equivalent to hana::mod
|
| |
|
template<typename X , typename Y > |
| constexpr auto | operator== (X &&x, Y &&y) |
| | Equivalent to hana::equal
|
| |
|
template<typename X , typename Y > |
| constexpr auto | operator!= (X &&x, Y &&y) |
| | Equivalent to hana::not_equal
|
| |
|
template<typename X , typename Y > |
| constexpr auto | operator|| (X &&x, Y &&y) |
| | Equivalent to hana::or_
|
| |
|
template<typename X , typename Y > |
| constexpr auto | operator&& (X &&x, Y &&y) |
| | Equivalent to hana::and_
|
| |
|
template<typename X > |
| constexpr auto | operator! (X &&x) |
| | Equivalent to hana::not_
|
| |
|
template<typename X , typename Y > |
| constexpr auto | operator< (X &&x, Y &&y) |
| | Equivalent to hana::less
|
| |
|
template<typename X , typename Y > |
| constexpr auto | operator> (X &&x, Y &&y) |
| | Equivalent to hana::greater
|
| |
|
template<typename X , typename Y > |
| constexpr auto | operator<= (X &&x, Y &&y) |
| | Equivalent to hana::less_equal
|
| |
|
template<typename X , typename Y > |
| constexpr auto | operator>= (X &&x, Y &&y) |
| | Equivalent to hana::greater_equal
|
| |
template<typename T, T v>
template<typename F >
Call a function n times.
times allows a nullary function to be invoked n times:
should be expanded by any decent compiler to
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; });
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"; }
);
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; });
- 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); });
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) {
});
- 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.