For this entry, I would like to introduce the `type_traits`

header file. This file contains utility templates that greatly simplify work when writing template-based libraries. This is especially true for libraries that employ template meta-programming. The header file is available with C++ TR1 and above. This library provides tools to identify types, their qualifying properties and even peel-off properties one-by-one programmatically at compile-time. There are also transformation meta-functions that provide basic meta-programming operations such as a compile-time conditional.

The definitions in `type_traits`

will save us a lot of time implementing Alchemy. As I introduce some of the tools that are available in the header, I will also demonstrate how these operations can be implemented. This will help you understand how to construct variations of the same type of solution when applying it in a different context. As an example of this, I will create a construct that behaves similarly to the tertiary operator, but is evaluated at compile-time.

## Types and Values

Creating C++ template meta-programs are essentially functional programs. Functional programs compute with mathematical expressions. You will receive the same result each time you call a function with a specific set of parameters. As expressions are declarative, state and mutable data are generally avoided. Meta-programs are structured in a way to require the compiler to calculate the results of the expressions as part of compilation. The two constructs that we have to work with are integer constants, to hold calculation results, and types, which we can use like function calls.

## Define a Value

Meta-program constants are declared and initialized statically. Therefore, these values are limited to integer-types. We cannot use `string `

literals or floating-points because these types of `static `

constants cannot be initialized in place with the `class `

or `struct `

definition. Sometimes, you will see code declared with enumerations. I believe this is to prevent meta-programming objects from using space. It is possible for users to take the address of `static `

constants, and if this occurs, the compiler must allocate space for the constant, even if the object is never instantiated. It is not possible to take the address of an enumeration declaration. Therefore no memory must be allocated when an enumeration is used.

Since I started using `type_traits`

, I don't worry about it so much. I use the `integral_constant`

template to define values. By convention, values are given the name `value`

. This is important in generic programming to allow the object development to remain loosely coupled and independent of the design of other objects. The example below demonstrates how the `integral_constant`

is typically used. Please note that all of these constructs live in the `std::`

namespace, which I will be omitting in these examples.

```
// Implement the pow function to calculate
// exponent multiplication in a meta-function.
template < size_t BaseT, size_t ExpT >
struct Pow
: integral_constant< size_t,
BaseT * Pow< BaseT , ExpT-1>::value >
{ };
// Specialization: Terminator for exp 1.
template < size_t BaseT >
struct Pow< BaseT, 1 >
: integral_constant< size_t, BaseT >
{ };
// Specialization: Special case for exp 0.
template < size_t BaseT >
struct Pow< BaseT, 0 >
: integral_constant< size_t, 1 >
{ };
```

Call (Instantiate) our meta-function:

`int x = Result< 3,3 >::value; // 27`

### integral_constant

All that is required to implement the `integral_constant`

, is a definition of a `static `

constant in the template `struct`

. `Struct`

s are generally used because of their default `public `

member access. Here is the most basic implementation:

```
template < typename T,
T ValT>
struct integral_constant
{
static const T value = ValT;
};
```

Yes it's that simple. The implementation in the C++ Standard Library goes a little bit further for convenience. Just as with the STL Containers, `typedef`

s are created for the `value_type`

and `type`

of the object. There is also a value conversion operator to implicitly convert the object to the `value_type`

. Here is the complete implementation:

```
template < typename T,
T ValT>
struct integral_constant
{
typedef T value_type;
typedef integral_constant< T, ValT> type;
static const T value = ValT;
operator value_type() const
{
return value;
}
};
```

Two `typedef`

s have been created to reduce the amount of code required to perform Boolean logic with meta-programs:

```
typedef integral_constant< bool, true > true_type;
typedef integral_constant< bool, false > false_type;
```

## Compile-time Decisions

With meta-programming, there is only one way to define a variable, and there are many ways to create decision making logic. Let's start with one that is very useful for making decisions.

### is_same

This template allows you to test if two types are the same type.

```
template < typename T,
typename U >
struct is_same
: false_type
{ };
// Specialization: When types are the same
template < typename T >
struct is_same< T,T >
: true_type
{ };
```

The compiler always looks for the *best* fit. That way, when multiple templates would be suitable, only the best match will be selected, if that is possible. In this case, the best match for when both types are the exact same, is our specialization that indicates `true`

.

### conditional

It's time to define a branching construct to enable us to make choices based on type. The `conditional`

template is the moral equivalent of the `if`

-statement for imperative C++.

```
// The default implementation represents false
template < bool Predicate,
typename T,
typename F >
struct conditional
{
typedef F type;
};
// Specialization: Handles true
template < typename T,
typename F >
struct conditional < true, T, F >
{
typedef T type;
};
```

## Applying These Techniques

I have just demonstrated how three of the constructs defined in the `type_traits`

header could be implemented. The techniques used to implement these constructs are used repeatedly to create solutions for evermore complex problems. I would like to demonstrate a construct that I use quite often in my own code, which is both built upon the templates I just discussed, and implemented with the same techniques used to implement those templates.

### value_if

While the `conditional`

template will define a type based on the result a Boolean expression, I commonly want to conditionally define a value based on the result of a Boolean expression. Therefore, I implemented the `value_if`

template. This makes use of the `integral_constant`

template and a similar implementation as was used to create the `conditional`

template. This gives me another tool to simplify the complex parametric expressions that I often encounter.

```
template < bool Predicate,
typename T,
T TrueValue,
T FalseValue >
struct value_if
: integral_constant< T, FalseValue >
{ };
// Specialization: True Case
template < typename T,
T TrueValue,
T FalseValue >
struct value_if < true, T, TrueValue, FalseValue >
: integral_constant< T, TrueValue >
{ };
```

## Summary

I just introduced you to the `type_traits`

header in C++. If you have not yet discovered this header, you should check it out. It can be very useful, even if you are not creating template meta-programs. Here is a reference link to the header from cppreference.com[^].

With the basic constructs that I introduced in this entry, I should now be able to create more sophisticated ways to interact with the Typelist[^] that I previously discussed for Alchemy. With the simple techniques used above, we should be able to implement template expressions that will query a `Typelist `

type by index, get the size of the type at an index, and similarly calculate the offset in bytes from the beginning of the `Typelist`

. The offset will be one of the most important pieces of information to know for the Alchemy implementation.