constant

Many C++ libraries including the standard one have inconsistent interfaces for values known at runtime or compilation time. For example:

  • Element access at the given position: array[2] and std::get<2>(tuple).

  • First elements of a span: span.first(2) and span.first<2>().

Unfortunately, it’s impossible to support syntax tuple[2], because 2 has type int, not std::integral_constant<int, 2>, and the result type can be different for different indices. The best thing we can do is to support syntax tuple[2_c] with the help of constant_literals.

Throughout the library, ac::constant is used for return and parameter types when they are known at compilation time to achieve consistent interfaces. Labeling a function as constexpr isn’t enough, because it doesn’t guarantee that the function result can always be computed at compilation time, and detecting that isn’t trivial. Standard facilities such as std::true_type can still be used for type traits.

Reference

template<auto X>
struct constant : public std::integral_constant<decltype(X), X>

ac::constant is an analog of std::integral_constant that provides a member constant value equal to X. The difference is:

  • Value type doesn’t have to be specified explicitly. Instead of std::integral_constant<color, color::yellow> one can write ac::constant<color::yellow> to avoid repretition.

  • As a result, compilation errors are shorter and easier to read.

  • TODO:

  • All constexpr operations applied to ac::constant also produce a constant. For example, -ac::constant<1>{} results in ac::constant<-1>{}.

template<bool B>
using ac::bool_constant = constant<B>
template<bool B>
auto ac::bool_c = bool_constant<B>{}
template<int N>
using ac::int_constant = constant<N>
template<int N>
auto ac::int_c = int_constant<N>{}
template<size_t N>
using ac::size_constant = constant<N>
template<size_t N>
auto ac::size_c = size_constant<N>{}

Constant detection utilities

template<class T>
struct is_constant

Provides a member constant bool value indicating whether T is a specialization of ac::constant.

template<class T>
bool ac::is_constant_v = is_constant<T>::value

Source code

Tests