compile time value -> index calculation

Discussion in 'C++' started by Christof Warlich, May 9, 2008.

  1. 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
    }
    Christof Warlich, May 9, 2008
    #1
    1. Advertising

  2. Christof Warlich

    gnuyuva Guest

    On May 9, 4:29 pm, Christof Warlich <>
    wrote:
    > 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.
    gnuyuva, May 9, 2008
    #2
    1. Advertising

  3. 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.
    Christof Warlich, May 9, 2008
    #3
  4. Christof Warlich

    gnuyuva Guest

    On May 9, 6:06 pm, Christof Warlich <>
    wrote:
    > 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' ;-)
    gnuyuva, May 10, 2008
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. flamesrock
    Replies:
    8
    Views:
    434
    Hendrik van Rooyen
    Nov 24, 2006
  2. Nagaraj
    Replies:
    1
    Views:
    835
    Lionel B
    Mar 1, 2007
  3. Carter
    Replies:
    2
    Views:
    488
    Carter
    Mar 4, 2009
  4. ngoc
    Replies:
    5
    Views:
    166
    Tad McClellan
    May 11, 2006
  5. Tomasz Chmielewski

    sorting index-15, index-9, index-110 "the human way"?

    Tomasz Chmielewski, Mar 4, 2008, in forum: Perl Misc
    Replies:
    4
    Views:
    266
    Tomasz Chmielewski
    Mar 4, 2008
Loading...

Share This Page