One can define a static array at compile time as follows:
const std::size_t size = 5;
unsigned int list[size] = { 1, 2, 3, 4, 5 };
Question 1 - Is it possible by using various kinds of metaprogramming techniques to assign these values "programmatically" at compile time?
Question 2 - Assuming all the values in the array are to be the same barr a few, is it possible to selectively assign values at compile time in a programmatic manner?
eg:
const std::size_t size = 7;
unsigned int list[size] = { 0, 0, 2, 3, 0, 0, 0 };
- Solutions using C++0x are welcome
- The array may be quite large, few hundred elements long
- The array for now will only consist of POD types
- It can also be assumed the size of the array will be known beforehand, in a static compile-time compliant manner.
- Solutions must be in C++ (no script, no macros, no pp or code generator based solutions pls)
UPDATE: Georg Fritzsche's solution is amazing, needs a little work to get it compiling on msvc and intel compilers, but nonetheless a very interesting approach to the problem.
Do you really need to do it at compiler time? It would be much easier to do at static initialization time. You could do something like this.
You could push the lists outside of the structs if you wanted but I thought it was a bit cleaner like this.
Something like Boost.Assignment could work for standard containers. If you really need to use arrays, you can use it along Boost.Array.
from boost,
Will generate a list of sorted numbers from 1 to 5 at compile time. For the second, you mention no criteria for which values would be changed. I'm pretty sure you can't undef then redef a new var once a list is created.
Well your requirements are so vague it's difficult to do anything about them... The main issue is of course: where do those value come from ?
Anyway a build in C++ can be thought of as 4 steps:
If you wish to rule out the script generation, then you're left with 2 alternatives: Preprocessing and Meta-template programming.
There is just no way I know of for meta-template programming to do the trick here, because as far as I know it's not possible to concatenate two arrays at compile time. Thus we are left with the savior of the day: Preprocessor Programming
I would suggest using a full-fledged library to help us out: Boost.Preprocessor.
Of particular interest here:
Now if only we knew where to pick the values from, we could give more meaningful examples.
How about building a nested struct using templates, and casting that as an array of the right type. The example below works for me, but I have a feeling I'm either treading in or walking very close to undefined behaviour.
And of course you could argue that the array is not initialised at compile time (which I think is impossible) but the values that will go into the array are calculated at compile time, and you can access them as you would a normal array... I think that's as close as you can get.
The closest you can get is using C++0x features to initialize local or member arrays of templates from a variadic template argument list.
This is of course limited by the maximum template instantiation depth and wether that actually makes a notable difference in your case would have to be measured.
Example:
Usage for your
1..5
case: