
On Sat, Jan 7, 2012 at 1:54 AM, Larry Evans <cppljevans@suddenlink.net> wrote:
On 01/06/12 16:19, Allan Nielsen wrote:
My problem is not to calculate the actually size, but move the calculation from the instantiation into the definition of the library. I have not idea what this means. Please clarify.
First of all, thanks for your input. I will try to illustrate my design problem in a more simple example: struct TagA { enum Size { size = 4 }; enum E { A0 = 0, A1 = 1, A2 = 2, A3 = 3, }; }; struct TagB { enum Size { size = 4 }; enum E { B0 = 0, B1 = 1, B2 = 2, B3 = 3, }; }; struct TagC { enum Size { size = 4 }; enum E { C0 = 0, C1 = 1, C2 = 2, C3 = 3, }; }; // Simple edition of CompressedEnum, but has the same problem template<typename T, int OFFSET> struct CompressedEnum { enum O { offset = OFFSET }; enum S { size = T::size }; T get( ) { ... } }; // Simple edition of CompressedEnums, but has the same problem template < typename B0, typename B1, typename B2 > struct CompressedEnums: public B0, B1, B2 { template < typename T> get() { ... } }; void example1() { // As you see, the expresions for calculating the offset get quite long, // and are not easy to maintain. C< CompressedEnum<tagA, 1>, CompressedEnum<tagB, CompressedEnum<tagA, 1>::offset * CompressedEnum<tagA, 1>::size >, CompressedEnum<tagC, CompressedEnum<tagB, CompressedEnum<tagA, 1>::offset * CompressedEnum<tagA, 1>::size >::offset * CompressedEnum<tagB, CompressedEnum<tagA, 1>::offset * CompressedEnum<tagA, 1>::size >::size > > c1; } void example2() { // same as example1 but more readable. Here the offset expresions are much more // readable: B::size * B::offset. But I would still like to avoid this in the // usage of the code. #define A CompressedEnum<tagA, 1> #define B CompressedEnum<tagB, A::size * A::offset> #define C CompressedEnum<tagC, B::size * B::offset> C< A, B, C > c1; } //////////////////////////////////////////////////////////////////////////// // A solution to the problem can be expressed in c++0x (I think): template<typename T, int OFFSET> struct CompressedEnum { enum O { offset = OFFSET }; enum S { size = T::size }; T get( ) { ... } }; #define B0_ B0< 1 > #define B1_ B1< B0_::size * B0::offset > #define B2_ B2< B1_::size * B1::offset > template < template <int O> class B0, template <int O> class B1, template <int O> class B2 > struct CompressedEnums: public B0_, B1_, B2_ { template < typename T> get() { ... } }; template <int N> using AA = CompressedEnum<tagA, N> template <int N> using BB = CompressedEnum<tagB, N> template <int N> using CC = CompressedEnum<tagC, N> void example3() { // same as example1 and example2, but needs a c++11 compiler C< AA, BB, CC > c1; } In the c++11 code the offset calculation appears in the CompressedEnums class instead of in the type definition, which is much more user friendly. The problem is that this requirer a c++11 compiler which is not available at the project where I intend to use this. I'm therefor looking for a way to achieve the same (or similar) interface which does not need c++11. Best regards Allan W. Nielsen