# More C++ Idioms/Int-To-Type

Int-To-Type [edit | edit source]

### Intent[edit | edit source]

- To treat an integral constant as a type at compile-time.
- To achieve static call dispatch based on constant integral values.

### Also Known As[edit | edit source]

Integral constant wrappers

### Motivation[edit | edit source]

Function overloading in C++ is based on different types, which prevents compile-time integral constants taking part into function overload resolution. There are at least two different mechanisms to perform static dispatching based on integral constants. First is enable-if idiom and the other one is the int-to-type idiom described below.

### Solution and Sample Code[edit | edit source]

A simple template, initially described in Dr. Dobb's Journal by Andrei Alexandrescu provides a solution to this idiom.

```
template <int I>
struct Int2Type
{
enum { value = I };
};
```

The above template creates different types for different integer values used to instantiate the template. For example, *Int2Type<5>* is a different type from *Int2Type<10>*. Moreover, the integral parameter is saved in the associated constant *value*. As each integral constant results in a different type, this simple template can be used for static dispatching based on integral constants as shown below.

Consider an *Array* class that encapsulates a fixed size array very similar to that of the standard array class from TR1. In fact, our Array class is implemented as a derived class of the standard TR1 array class with the only difference of a *sort* function.

We intend to dispatch sort function at compile-time based on the size of the array to achieve some performance optimizations. For example, sorting an array of size zero or one should be a no-op. Similarly, arrays smaller than size 50 should be sorted using the insertion-sort algorithm whereas as larger arrays should be sorted using the quick-sort algorithm because insertion-sort algorithm is often more efficient than quick-sort algorithm for small data size. Note that, this selection of the sorting algorithm can be trivially done using run-time *if* condition. However, int-to-type idiom is used to achieve the same effect at compile-time as shown below.

```
#include <iostream>
#include <array>
template <int I>
struct Int2Type
{
enum { value = I };
};
template <class T, unsigned int N>
class Array : public std::array <T, N>
{
enum AlgoType { NOOP, INSERTION_SORT, QUICK_SORT };
static const int algo = (N==0) ? NOOP :
(N==1) ? NOOP :
(N<50) ? INSERTION_SORT : QUICK_SORT;
void sort (Int2Type<NOOP>) { std::cout << "NOOP\n"; }
void sort (Int2Type<INSERTION_SORT>) { std::cout << "INSERTION_SORT\n"; }
void sort (Int2Type<QUICK_SORT>) { std::cout << "QUICK_SORT\n"; }
public:
void sort()
{
sort (Int2Type<algo>());
}
};
int main(void)
{
Array<int, 1> a;
a.sort(); // No-op!
Array<int, 400> b;
b.sort(); // Quick sort
}
```

Few more associated types and constants can be defined with *Int2Type* template to increase its usability. For example, enumeration *value* is used to retrieve the integer constant associated with the type. Finally, other typedefs such as, *next* and *previous* are used to find other types *in order* such that *Int2Type<7>::next* is the same type as *Int2Type<9>::previous*.

```
template <int I>
struct Int2Type
{
enum { value = I };
typedef int value_type;
typedef Int2Type<I> type;
typedef Int2Type<I+1> next;
typedef Int2Type<I-1> previous;
};
```

### Known Uses[edit | edit source]

- Integral constant wrappers (bool_, int_, long_) in Boost.MPL
- Dimensional Analysis
- std::integral_constant

### Related Idioms[edit | edit source]

### References[edit | edit source]

[1] Generic<Programming>: Mappings between Types and Values -- Andrei Alexandrescu