BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslmf_integralconstant

Macros

#define BSL_DEPRECATE_TRUE_FALSE_TYPE_VALUE
 

Variables

static const t_TYPE bsl::integral_constant< t_TYPE, t_VAL >::value = t_VAL
 
static const bool bsl::integral_constant< bool, t_VAL >::value = t_VAL
 
static BSL_DEPRECATE_TRUE_FALSE_TYPE_VALUE const bool bsl::integral_constant< bool, t_VAL >::VALUE = t_VAL
 

Detailed Description

Outline

Purpose

Provide a mapping from integral constants to unique types.

Classes

See also

Description

This component describes a simple class template, bsl::integral_constant, that is used to map an integer constant to a C++ type. integral_constant<t_TYPE, t_VAL> generates a unique type for each distinct compile-time integral t_TYPE and constant integer t_VAL parameter. That is, instantiations with different integer types and values form distinct types, so that integral_constant<int, 0> is a different type from integral_constant<int, 1>, which is also distinct from integral_constant<unsigned, 1>, and so on. This mapping of integer values to types allows for "overloading by value", i.e., multiple functions with the same name can be overloaded on the "value" of an integral_constant argument, provided that the value is known at compile-time. The typedefs bsl::true_type and bsl::false_type map the predicate values true and false to C++ types that are frequently useful for compile-time algorithms.

Usage

This section illustrates intended usage of this component

Example 1: Compile-Time Function Dispatching

The most common use of this structure is to perform compile-time function dispatching based on a compile-time calculation. Often the calculation is nothing more than a simple predicate, allowing us to select one of two functions based on whether the predicate holds. The following function, doSomething, uses a fast implementation (e.g., using memcpy) if the parameterized type allows for such operations, otherwise it will use a more generic and slower implementation (e.g., using the copy constructor). This example uses the types true_type and false_type, which are simple typedefs for integral_constant<bool, true> and integral_constant<bool, false>, respectively.

template <class t_T>
int doSomethingImp(t_T *t, bsl::true_type)
{
// slow, generic implementation
// ...
(void) t;
return 11;
}
template <class t_T>
int doSomethingImp(t_T *t, bsl::false_type)
{
// fast implementation that works only for some types of 't_T'
// ...
(void) t;
return 55;
}
template <bool IsSlow, class t_T>
int doSomething(t_T *t)
{
// Dispatch to an implementation depending on the (compile-time)
// value of 'IsSlow'.
return doSomethingImp(t, bsl::integral_constant<bool, IsSlow>());
}

For some parameter types, the fast version of doSomethingImp is not legal. The power of this approach is that the compiler will not attempt semantic analysis on the implementation that does not match the appropriate integral_constant argument.

int main()
{
int r;
int i;
r = doSomething<false>(&i); // select fast version for int
assert(55 == r);
double m;
r = doSomething<true>(&m); // select slow version for double
assert(11 == r);
return 0;
}

Example 2: Base Class For Metafunctions

Hard-coding the value of an integral_constant is not especially useful. Rather, integral_constant is typically used as the base class for "metafunction" classes, classes that yield the value of compile-time properties, including properties that are associated with types, rather than with values. For example, the following metafunction can be used at compile time to determine whether a type is a floating point type:

template <class t_TYPE> struct IsFloatingPoint : bsl::false_type { };
template <> struct IsFloatingPoint<float> : bsl::true_type { };
template <> struct IsFloatingPoint<double> : bsl::true_type { };
template <> struct IsFloatingPoint<long double> : bsl::true_type { };

The value IsFloatingPoint<int>::value is false and IsFloatingPoint<double>::value is true. The integral_constant base class has a member type, type, that refers to itself and is inherited by IsFloatingPoint. Thus IsFloatingPoint<float>::type is true_type and IsFloatingPoint<char>::type is false_type. IsFloatingPoint is an a member of a common category of metafunctions known as "type traits" because they express certain properties (traits) of a type. Using this metafunction, we can rewrite the doSomething function from first example so that it does not require the user to specify the IsSlow template argument:

template <class t_T>
int doSomething2(t_T *t)
{
// Automatically detect whether to use slow or fast imp.
const bool isSlow = IsFloatingPoint<t_T>::value;
return doSomethingImp(t, bsl::integral_constant<bool, isSlow>());
}
int main()
{
int r;
int i;
r = doSomething2(&i); // select fast version for int
assert(55 == r);
double m;
r = doSomething2(&m); // select slow version for double
assert(11 == r);
return 0;
}

Macro Definition Documentation

◆ BSL_DEPRECATE_TRUE_FALSE_TYPE_VALUE

#define BSL_DEPRECATE_TRUE_FALSE_TYPE_VALUE
Value:
BSLS_DEPRECATE_FEATURE("bsl", "legacy_true_and_false_VALUE", \
"use standard, lower-case, 'value' instead")
#define BSLS_DEPRECATE_FEATURE(UOR, FEATURE, MESSAGE)
Definition bsls_deprecatefeature.h:319

Variable Documentation

◆ value [1/2]

template<class t_TYPE , t_TYPE t_VAL>
const t_TYPE bsl::integral_constant< t_TYPE, t_VAL >::value = t_VAL
static

◆ value [2/2]

template<bool t_VAL>
const bool bsl::integral_constant< bool, t_VAL >::value = t_VAL
static

◆ VALUE

template<bool t_VAL>
const bool bsl::integral_constant< bool, t_VAL >::VALUE = t_VAL
static