 # Boost Users :

Subject: Re: [Boost-users] Needs advices on design ( mpl or processor )
From: Allan Nielsen (a_at_[hidden])
Date: 2012-01-07 03:42:20

On Sat, Jan 7, 2012 at 1:54 AM, Larry Evans <cppljevans_at_[hidden]> 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.

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