We want to develop a compile-time loop structure that is flexible and allows to print templates and to unroll arbitrary loops index-wise.

The classical example for C++ meta-programming is to define a recursion formula by template parameter specialization. Implementing a meta-program to calculate the Nth Fibonacci number (see Wikipedia) could look like:

The primary template defines the recursion formula and two template-specializations for I=0 and I=1 introduce break conditions. A static constant value is defined for the template Fibo, to access the resulting value of the Fibonacci calculations. Thus, the Nth Fibonacci number can be read by `Fibo<N>::value`.

The same can be written using concepts-lite technique (in C++17, Technical specification, Tutorial) by formulating the recursion formula using a requires clause:

Here the order of definition has changed, i.e. at first we have implemented the break conditions and finally the recursion formula for all integer greater than 1. Thus, for negative indices we set the Fibonacci number to 0. To compile this code, currently you have to use the trunk version of gcc (HowTo: build gcc with concepts), with

In order to print all Fibonacci numbers from 0 to 50 one has to write a compile-time loop. By explicitly implementing a print-loop for the Fibo class this can be solved:

It instantiates the template `Print<I,N>` from an initial I to the (not included) upper bound N. Thus, we have to call

to print all Fibonacci numbers from 0 to 50. This loop is specialized for the Fibo class. A more general implementation takes a functor for the output operation instead:

The static functor PrintFibo implements a static method eval, that takes an integer template argument. In order to call this method in a templated Loop class, we have to explicitly specify that the method is templated:

where F corresponds to the PrintFibo class. The printing loop can be instantiated, by

Instead of calling a templated eval method by explicitly specifying the template parameter, we could implement a classical static functor, that takes an argument that represents the integral integer parameter, by using a helper class `int_`:

This is slightly simpler to use, by passing an instance of the `int_<I>` class to the eval method. So far, the class PrintFibo is passed as template argument. Thus, we have to use a static eval method in the functor. Classically functors implement an `operator()` to be called. In order to allow (dynamic) functors to be used in the compile-time loop, we modify the implementation slightly:

by passing the functor as argument to the `run()` method. Now, the loop can be instantiated by

This is much more flexible, but requires a functor that has a templated `operator()` with integer non-type parameter. So, we can not simply use lambda-expressions as functors. This is a heavy restriction and should be overcome. In order to do so, we change the implementation of the `int_` class slightly, by adding a constexpr cast operator:

This now allows to use `int_<I>` as template parameter for integer arguments and the loop can be instantiated using a generic lambda, that does not need to know its template parameter explicitly:

Adding some more tests and the flexibility to iterate forward, backward, or in stepsize greater than 1, and using concepts-lite as a tool for simplified implementation, we arrive at the final version:

Here, we have implemented the break condition with boolean template constraints for upper and lower bound. Instead of passing the functor by copy to the next iterate, it is now passed by universal reference. The `int_` template is changed to the standard compatible `std::integral_constant`, since this provides the used cast operator and some more attributes. But also the user-defined `int_` class can be used.

The loop can be used as follows:

Output:

``````Fibo<10>::value = 55
Fibo<9>::value = 34
Fibo<8>::value = 21
Fibo<7>::value = 13
Fibo<6>::value = 8
Fibo<5>::value = 5
Fibo<4>::value = 3
Fibo<3>::value = 2
Fibo<2>::value = 1
Fibo<1>::value = 1
``````