Doc. no.: N4334
Date: 2014-11-21
Project: Programming Language C++, Library Working Group
Reply-to: Zhihao Yuan <zy at miator dot net>

Wording for bool_constant

Rationale see https://issues.isocpp.org/show_bug.cgi?id=51.

This wording is relative to N4140.

Modify 20.10.2 [meta.type.synop]:

namespace std {
  // 20.10.3, helper class:
  template <class T, T v> struct integral_constant;
template <bool B>
using bool_constant = integral_constant<bool, B>;
 
typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;
typedef bool_constant<true> true_type;
typedef bool_constant<false> false_type;

Modify 20.10.3 [meta.help]:

namespace std {
  template <class T, T v>
  struct integral_constant {

  };
template <bool B>
using bool_constant = integral_constant<bool, B>;
 
typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;
typedef bool_constant<true> true_type;
typedef bool_constant<false> false_type;
}

The class template integral_constant, alias template bool_constant, and its associated typedefs true_type and false_type are used as base classes to define the interface for various type traits.

Modify Table 49 in 20.10.4.3 [meta.unary.prop]:

template <class T>
struct is_signed;
If is_arithmetic<T>::value is true, the same result as integral_constant<bool, T(-1) < T(0)>::value bool_constant<T(-1) < T(0)>::value ; otherwise, false
template <class T>
struct is_unsigned;
If is_arithmetic<T>::value is true, the same result as integral_constant<bool, T(0) < T(-1)>::value bool_constant<T(0) < T(-1)>::value ; otherwise, false

Modify 20.11.5 [ratio.comparison]:

template <class R1, class R2> struct ratio_equal
: integral_constant<bool, see below> { };
: bool_constant<see below> { };

If R1::num == R2::num and R1::den == R2::den, ratio_equal<R1, R2> shall be derived from integral_constant<bool, true> bool_constant<true> ; otherwise it shall be derived from integral_constant<bool, false> bool_constant<false> .

template <class R1, class R2> struct ratio_not_equal
: integral_constant<bool, !ratio_equal<R1, R2>::value> { };
: bool_constant<!ratio_equal<R1, R2>::value> { };
template <class R1, class R2> struct ratio_less
: integral_constant<bool, see below> { };
: bool_constant<see below> { };

If R1::num * R2::den < R2::num * R1::den, ratio_less<R1, R2> shall be derived from integral_constant<bool, true> bool_constant<true> ; otherwise it shall be derived from integral_constant<bool, false> bool_constant<false> . Implementations may use other algorithms to compute this relationship to avoid overflow. If overflow occurs, the program is ill-formed.

template <class R1, class R2> struct ratio_less_equal
: integral_constant<bool, !ratio_less<R2, R1>::value> { };
template <class R1, class R2> struct ratio_greater
: integral_constant<bool, ratio_less<R2, R1>::value> { };
template <class R1, class R2> struct ratio_greater_equal
: integral_constant<bool, !ratio_less<R1, R2>::value> { };
template <class R1, class R2> struct ratio_less_equal
: bool_constant<!ratio_less<R2, R1>::value> { };
template <class R1, class R2> struct ratio_greater
: bool_constant<ratio_less<R2, R1>::value> { };
template <class R1, class R2> struct ratio_greater_equal
: bool_constant<!ratio_less<R1, R2>::value> { };

Acknowledgments

Thanks Tony Van Eerd for bringing this to the reflector.