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_constant
s to ease writing compile-time arithmetic:
It is pretty important to realize that these operators return other integral_constant
s, 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 Constant
s 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_constant
s 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 Constant
s, 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_constant
s; 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_constant
s instead of normal integers. Side effects can also be done in the function passed to times
and times.with_index
.