M
mathieu
Hello there,
I am playing around with template metaprograming: I am trying to
redefines my own types. But I am facing a small issue, where I cannot
describe the whole implementation in one single class. Instead I have
to separate implementation for binary and ascii in two different
classes as I don't know how to use the traits technique for
constructors.
Any pointers very welcome !
Mathieu
Ps: My goal is collapse MyASCIITypes and MyTypes in one single
templated class.
Full source is:
#include <iostream> // cout
#include <sstream> // istringstream
typedef enum {
ASCII= 0,
BINARY
} Modes;
// Define my types
typedef enum {
Type1 = 1,
Type2,
Type3,
Type4,
} Types;
// Defines my value multiplicity
typedef enum {
VM1,
VM2,
VM3,
VM4,
VM5,
VM6,
VM8,
} VMTypes;
// Mapping from Enum type to a Mode
template<int T> struct EnumTypeToMode;
template<> struct EnumTypeToMode<Type1>
{ enum { Mode = ASCII }; };
template<> struct EnumTypeToMode<Type2>
{ enum { Mode = BINARY }; };
template<> struct EnumTypeToMode<Type3>
{ enum { Mode = BINARY }; };
template<> struct EnumTypeToMode<Type4>
{ enum { Mode = ASCII }; };
// Mapping from Enum type to a real type
template<int T> struct TypeEnumToType;
template<> struct TypeEnumToType<Type1>
{ typedef float Type; };
template<> struct TypeEnumToType<Type2>
{ typedef double Type; };
template<> struct TypeEnumToType<Type3>
{ typedef int Type; };
template<> struct TypeEnumToType<Type4>
{ typedef unsigned int Type; };
template<int T> struct ValueEnumToLength;
template<> struct ValueEnumToLength<VM1>
{ enum { Len = 1 }; };
template<> struct ValueEnumToLength<VM2>
{ enum { Len = 2 }; };
template<> struct ValueEnumToLength<VM3>
{ enum { Len = 3 }; };
template<> struct ValueEnumToLength<VM4>
{ enum { Len = 4 }; };
template<> struct ValueEnumToLength<VM5>
{ enum { Len = 5 }; };
template<> struct ValueEnumToLength<VM6>
{ enum { Len = 6 }; };
template<> struct ValueEnumToLength<VM8>
{ enum { Len = 8 }; };
// forward declaration
template<int T> class ModeImplementation;
// Definition of my type
template<int Type, int Size>
class MyTypes
{
public:
typename TypeEnumToType<Type>::Type
Data[ValueEnumToLength<Size>::Len];
int GetLength() const {
return ValueEnumToLength<Size>::Len;
}
void Print() const {
ModeImplementation< EnumTypeToMode<Type>::Mode >:
rint(Data,
GetLength());
}
};
// Implementation for Mode=ASCII
template<> class ModeImplementation<ASCII>
{
public:
template <typename T>
static inline void Print(const T array[], const int len) {
std::cout << "ASCII:" << array[0]; // garantee to be >1
for(int i=1; i<len; ++i)
std::cout << "," << array;
std::cout << std::endl;
}
};
// Implementation for Mode=BINARY
template<> class ModeImplementation<BINARY>
{
public:
template <typename T>
static inline void Print(const T array[], const int len) {
std::cout << "BINARY:" << array[0];
for(int i=1; i<len; ++i)
std::cout << "," << array;
std::cout << std::endl;
}
};
template<int Type, int Size>
class MyASCIITypes : public MyTypes<Type,Size>
{
public:
MyASCIITypes(const char array[])
{
const int length = ValueEnumToLength<Size>::Len;
std::istringstream is(array);
int i = 0;
while( is >> this->Data[i++] );
assert( length == i-1 );
}
};
int main()
{
MyTypes<Type4,VM4> t_bin = { 1, 2, 3, 4 };
t_bin.Print();
MyASCIITypes<Type3,VM4> t_text = "1 2 3 4";
t_text.Print();
return 0;
}
I am playing around with template metaprograming: I am trying to
redefines my own types. But I am facing a small issue, where I cannot
describe the whole implementation in one single class. Instead I have
to separate implementation for binary and ascii in two different
classes as I don't know how to use the traits technique for
constructors.
Any pointers very welcome !
Mathieu
Ps: My goal is collapse MyASCIITypes and MyTypes in one single
templated class.
Full source is:
#include <iostream> // cout
#include <sstream> // istringstream
typedef enum {
ASCII= 0,
BINARY
} Modes;
// Define my types
typedef enum {
Type1 = 1,
Type2,
Type3,
Type4,
} Types;
// Defines my value multiplicity
typedef enum {
VM1,
VM2,
VM3,
VM4,
VM5,
VM6,
VM8,
} VMTypes;
// Mapping from Enum type to a Mode
template<int T> struct EnumTypeToMode;
template<> struct EnumTypeToMode<Type1>
{ enum { Mode = ASCII }; };
template<> struct EnumTypeToMode<Type2>
{ enum { Mode = BINARY }; };
template<> struct EnumTypeToMode<Type3>
{ enum { Mode = BINARY }; };
template<> struct EnumTypeToMode<Type4>
{ enum { Mode = ASCII }; };
// Mapping from Enum type to a real type
template<int T> struct TypeEnumToType;
template<> struct TypeEnumToType<Type1>
{ typedef float Type; };
template<> struct TypeEnumToType<Type2>
{ typedef double Type; };
template<> struct TypeEnumToType<Type3>
{ typedef int Type; };
template<> struct TypeEnumToType<Type4>
{ typedef unsigned int Type; };
template<int T> struct ValueEnumToLength;
template<> struct ValueEnumToLength<VM1>
{ enum { Len = 1 }; };
template<> struct ValueEnumToLength<VM2>
{ enum { Len = 2 }; };
template<> struct ValueEnumToLength<VM3>
{ enum { Len = 3 }; };
template<> struct ValueEnumToLength<VM4>
{ enum { Len = 4 }; };
template<> struct ValueEnumToLength<VM5>
{ enum { Len = 5 }; };
template<> struct ValueEnumToLength<VM6>
{ enum { Len = 6 }; };
template<> struct ValueEnumToLength<VM8>
{ enum { Len = 8 }; };
// forward declaration
template<int T> class ModeImplementation;
// Definition of my type
template<int Type, int Size>
class MyTypes
{
public:
typename TypeEnumToType<Type>::Type
Data[ValueEnumToLength<Size>::Len];
int GetLength() const {
return ValueEnumToLength<Size>::Len;
}
void Print() const {
ModeImplementation< EnumTypeToMode<Type>::Mode >:
GetLength());
}
};
// Implementation for Mode=ASCII
template<> class ModeImplementation<ASCII>
{
public:
template <typename T>
static inline void Print(const T array[], const int len) {
std::cout << "ASCII:" << array[0]; // garantee to be >1
for(int i=1; i<len; ++i)
std::cout << "," << array;
std::cout << std::endl;
}
};
// Implementation for Mode=BINARY
template<> class ModeImplementation<BINARY>
{
public:
template <typename T>
static inline void Print(const T array[], const int len) {
std::cout << "BINARY:" << array[0];
for(int i=1; i<len; ++i)
std::cout << "," << array;
std::cout << std::endl;
}
};
template<int Type, int Size>
class MyASCIITypes : public MyTypes<Type,Size>
{
public:
MyASCIITypes(const char array[])
{
const int length = ValueEnumToLength<Size>::Len;
std::istringstream is(array);
int i = 0;
while( is >> this->Data[i++] );
assert( length == i-1 );
}
};
int main()
{
MyTypes<Type4,VM4> t_bin = { 1, 2, 3, 4 };
t_bin.Print();
MyASCIITypes<Type3,VM4> t_text = "1 2 3 4";
t_text.Print();
return 0;
}