compile time value -> index calculation

  • Thread starter Christof Warlich
  • Start date
C

Christof Warlich

Hi all,

in the following example, Index<unsigned int x>::value allows to calculate the "rounded up" index
from any "increasing" value during compile time. Unfortunately, the definition of the index - value
pairs does not really look nice.

The definition through an array would look much nicer, but does not work, see below.

As the definition of the index - value pairs are supposed to become part of the API, does anyone
have an idea how this could be beautified?

Thanks,

Christof

#include <iostream>
using namespace std;

// definition of the index - value pairs
template<unsigned int index> struct Value {};
template<> struct Value<0> {static const unsigned int value = 1;};
template<> struct Value<1> {static const unsigned int value = 10;};
template<> struct Value<2> {static const unsigned int value = 100;};
template<> struct Value<3> {static const unsigned int value = 1000;};
template<> struct Value<4> {static const unsigned int value = 10000;};

// much more readable than above, but does not work, see below
const unsigned int a[] = {1, 10, 100, 1000, 10000};

template<unsigned int size, unsigned int index = 0> struct Index {
static const unsigned int value = (size <= Value<index>::value ? index : Index<size, index +
1>::value);
// the following does not work, as even const arrays are not allowed to be used in const
expressions?!
//static const unsigned int value = (size <= a[index] ? index : Index<size, index + 1>::value);
};
// needed to terminate recursion, would be nice if it could be calculate from the index - value
definitions from above
template<unsigned int size> struct Index<size, 5> {
static const unsigned int value = 0xffffffff;
};

int main(void) {
cout << Value<0>::value << " " << Value< 3>::value << " " << Value< 4>::value << endl;
cout << Index<0>::value << " " << Index<100>::value << " " << Index<6000>::value << endl;
//cout << Value<8>::value << endl; // gives a compiler error as intended
cout << hex << Index<10001>::value << endl; // would be nice if this gives a compiler error too
}
 
G

gnuyuva

Hi all,

As the definition of the index - value pairs are supposed to become part of the API, does anyone
have an idea how this could be beautified?

Thanks,

Christof

#include <iostream>
using namespace std;

// definition of the index - value pairs
template<unsigned int index> struct Value {};
template<> struct Value<0> {static const unsigned int value = 1;};
template<> struct Value<1> {static const unsigned int value = 10;};
template<> struct Value<2> {static const unsigned int value = 100;};
template<> struct Value<3> {static const unsigned int value = 1000;};
template<> struct Value<4> {static const unsigned int value = 10000;};

use recursive templates.

enum { multiplier = 10 };

template <unsigned int index> struct value
{
static const long long int this_value = value< index-1>::this_value
* multiplier;
}

template <> struct value<0> { enum { this_value = 1 }; } //
termination condition.

since the depth of template recursion is limited (say 17 is the upper
limit)
template <> struct value<17> {}; // let there be compilation error.
 
C

Christof Warlich

gnuyuva said:
use recursive templates.

enum { multiplier = 10 };

template <unsigned int index> struct value
{
static const long long int this_value = value< index-1>::this_value
* multiplier;
}

template <> struct value<0> { enum { this_value = 1 }; } //
termination condition.

since the depth of template recursion is limited (say 17 is the upper
limit)
template <> struct value<17> {}; // let there be compilation error.

Thanks, but this is not what I was looking for.

I should have been more precise: I want to be able to define any arbitrary
indexed sequence of constant values, as long as the values are increasing.
Thus, this could be another example:

// definition of the index - value pairs
template<unsigned int index> struct Value {};
template<> struct Value<0> {static const unsigned int value = 27;};
template<> struct Value<1> {static const unsigned int value = 33;};
template<> struct Value<2> {static const unsigned int value = 815;};
template<> struct Value<3> {static const unsigned int value = 4711;};

Again, writing this with an array would be quite convenient:

const unsigned int a[] = {27, 33, 815, 4711};

but the array elements are obviously not allowed to be used in a constant
expression.

Sorry for making this not clear enough.
 
G

gnuyuva

gnuyuva schrieb:


use recursive templates.
enum { multiplier = 10 };
template <unsigned int index> struct value
{
static const long long int this_value = value< index-1>::this_value
* multiplier;
}
template <> struct value<0> { enum { this_value = 1 }; } //
termination condition.
since the depth of template recursion is limited (say 17 is the upper
limit)
template <> struct value<17> {}; // let there be compilation error.

Thanks, but this is not what I was looking for.

I should have been more precise: I want to be able to define any arbitrary
indexed sequence of constant values, as long as the values are increasing.
Thus, this could be another example:

// definition of the index - value pairs
template<unsigned int index> struct Value {};
template<> struct Value<0> {static const unsigned int value = 27;};
template<> struct Value<1> {static const unsigned int value = 33;};
template<> struct Value<2> {static const unsigned int value = 815;};
template<> struct Value<3> {static const unsigned int value = 4711;};

Again, writing this with an array would be quite convenient:

const unsigned int a[] = {27, 33, 815, 4711};

but the array elements are obviously not allowed to be used in a constant
expression.

Sorry for making this not clear enough.

Well, in that case you don't have any other go but to write them
manually. Maybe you can reduce your typing effort by writing a macro.
or wait till c++0x for 'constexpr' ;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top