On 10 Oct 2003 14:22:39 -0700,
ak****@yahoo.com (Anil) wrote:
I'm trying to come up with a way to improve upon the following.
enum Label_Type
{
Label1,
Label2,
// ...
};
enum Key_Transform_Type
{
key1_key3,
key2_key4,
// ...
};
// key to scheme mapping
Key1 => { Label1, Label2, Label3, Label5, Label7 };
Key2 => { Label4, Label6, Label7 };
// map for converting from schemeA to schemeB
{ Key1, Key2, key1_key2 }
{ Key3, Key4, key3_key4 }
class test
{
// array of values referenced by labels
};
const test& test::operator = ( const test& src )
{
// ...
Key_Transform_Type TransformType = GetTransformType(
src.GetKeyType(), GetKeyType() );
switch ( TransformType )
{
case key1_key2:
Value(Label4) = src.Value(Label1) + src.Value(Label3);
Value(Label6) = src.Value(Label2) + src.Value(Label5);
Value(Label7) = src.Value(Label7);
break;
// handle other cases
}
return (*this);
}
The basic problem is to convert values in one scheme to another and it
has to be 'fast' as well. The code is littered with switch/case
statements and there're quite a few conversion scenarios.
Since the conversion is known at compile time, could templates be used
to express the relationship between the various schemes?
Any ideas?
This won't solve _all_ of your problem, only the enum value -> associated
value.
Look at <url: http://home.no.net/dubjai/03/code/RangeMap.h> (note: 4 spaces
per tab) and usage in file [choice4/choice4.cpp] in the same directory. I
forgot to put my name, copyright etc. in that code, it's just part of a small
Norwegian tutorial in development, but I say here it's lesser GNU license.
This does away with switches and provides Pascal-like once-only checking at
initialization time (not compile time, but initialization time, e.g. first
call of a function that contains a static constant), like
enum LineWidthSpec{ width0, width1, width2, width4, width8 };
SimpleRange<LineWidthSpec> const LineWidthSpec_range( width0, width8 );
static unsigned lineWidthFrom( LineWidthSpec aWidthSpec )
{
typedef RangeMap<LineWidthSpec, unsigned> ToWidthMap;
static ToWidthMap::IndexAndValue const indexValuePairs[] =
{
{ width0, 0 },
{ width1, 1 },
{ width2, 2 },
{ width4, 4 },
{ width8, 8 }
}; // indexValuePairs
static ToWidthMap const values( LineWidthSpec_range, indexValuePairs );
return values[aWidthSpec];
} // lineWidthFrom
where at first call of lineWidthFrom it's checked that (1) all enum values
are present, and (2) no enum value is present more than once. Each index
operation also checks that the argument is in range. A non-checking index
operation should perhaps also be provided, I didn't bother... ;-)
Hth.