this is related to my last thread "help with implementing strategy pattern"... but i hope thats fine...
ive had a sitation alot of times where i have to define a function several times but with different amount of variables...
template <class T> boost::shared_ptr<T> Create(std::string id)
{}
template <class T, typename P0> boost::shared_ptr<T> Create(std::string id, P0 p0)
{}
template <class T, typename P0, typename P1> boost::shared_ptr<T> Create(std::string id, P0 p0, P1 p1)
{}
etc...
but to write it like sthis to at least 8 parameters is not practical... especially when u have to change somehting
to solve this i use some preprocessor tricks... to auto generate all these
it would work like this...
CreateGenerator.h
#include "GeneratorMacro.h"
template <class T, ENUM_GENERATOR_TYPENAME_PARAMS> boost::shared_ptr<T> Create(std::string id, ENUM_GENERATOR_PARAMS)
GeneratorMacro.h
/***************************************
AUTOMATIC CODE GENERATION MACROS
----------------------------------------
Automaticly generated parameters are formatted
P0 p0, P1 p1 etc...
By: Robert Nagy
****************************************/
#include "boost/preprocessor.hpp"
#include "loki/TypeList.h"
#define GENERATE(text, n) text
#ifndef GENERATOR_COUNT
#define GENERATOR_COUNT 0
#endif
#define ENUM_DEFAULT_PARAMS(n) BOOST_PP_ENUM_PARAMS(n, P)
#define ENUM_DEFAULT_PARAMSLOW(n) BOOST_PP_ENUM_PARAMS(n, p)
#define ENUM_DEFAULT_TYPENAME_PARAMS(n) BOOST_PP_ENUM_PARAMS(n, typename P)
#define ENUM_DEFAULT_BINARY_PARAMS(n) BOOST_PP_ENUM_BINARY_PARAMS(n, P, p)
#define DEFAULT_REPEAT(n, x, text) BOOST_PP_REPEAT(n, x, params)
#undef ENUM_GENERATOR_PARAMS
#undef ENUM_GENERATOR_PARAMSLOW
#undef ENUM_GENERATOR_TYPENAME_PARAMS
#undef ENUM_GENERATOR_BINARY_PARAMS
#undef GENERATOR_REPEAT
#undef GENERATOR_TYPELIST
#if GENERATOR_COUNT == 0
#define ENUM_GENERATOR_TYPENAME_PARAMS
#define ENUM_GENERATOR_PARAMS
#define ENUM_GENERATOR_PARAMSLOW
#define ENUM_GENERATOR_BINARY_PARAMS
#define GENERATOR_REPEAT(x, text)
#define GENERATOR_GENERATOR_TYPELIST
#undef GENERATOR_COUNT
#define GENERATOR_COUNT 1
#elif GENERATOR_COUNT == 1
#define ENUM_GENERATOR_PARAMS BOOST_PP_ENUM_PARAMS(1, P)
#define ENUM_GENERATOR_PARAMSLOW BOOST_PP_ENUM_PARAMS(1, p)
#define ENUM_GENERATOR_TYPENAME_PARAMS BOOST_PP_ENUM_PARAMS(1, typename P)
#define ENUM_GENERATOR_BINARY_PARAMS BOOST_PP_ENUM_BINARY_PARAMS(1, P, p)
#define GENERATOR_REPEAT(x, text) BOOST_PP_REPEAT(1, x, params)
#define GENERATOR_TYPELIST LOKI_TYPELIST_1(P0)
#undef GENERATOR_COUNT
#define GENERATOR_COUNT 2
#elif GENERATOR_COUNT == 2
#define ENUM_GENERATOR_PARAMS BOOST_PP_ENUM_PARAMS(2, P)
#define ENUM_GENERATOR_PARAMSLOW BOOST_PP_ENUM_PARAMS(2, p)
#define ENUM_GENERATOR_TYPENAME_PARAMS BOOST_PP_ENUM_PARAMS(2, typename P)
#define ENUM_GENERATOR_BINARY_PARAMS BOOST_PP_ENUM_BINARY_PARAMS(2, P, p)
#define GENERATOR_REPEAT(x, text) BOOST_PP_REPEAT(2, x, params)
#define GENERATOR_TYPELIST LOKI_TYPELIST_2(P0, P1)
#undef GENERATOR_COUNT
#define GENERATOR_COUNT 3
#elif GENERATOR_COUNT == 3
#define ENUM_GENERATOR_PARAMS BOOST_PP_ENUM_PARAMS(3, P)
#define ENUM_GENERATOR_PARAMSLOW BOOST_PP_ENUM_PARAMS(3, p)
#define ENUM_GENERATOR_TYPENAME_PARAMS BOOST_PP_ENUM_PARAMS(3, typename P)
#define ENUM_GENERATOR_BINARY_PARAMS BOOST_PP_ENUM_BINARY_PARAMS(3, P, p)
#define GENERATOR_REPEAT(x, text) BOOST_PP_REPEAT(3, x, params)
#define GENERATOR_TYPELIST LOKI_TYPELIST_3(P0, P1, P2)
#undef GENERATOR_COUNT
#define GENERATOR_COUNT 4
#elif GENERATOR_COUNT == 4
#define ENUM_GENERATOR_PARAMS BOOST_PP_ENUM_PARAMS(4, P)
#define ENUM_GENERATOR_PARAMSLOW BOOST_PP_ENUM_PARAMS(4, p)
#define ENUM_GENERATOR_TYPENAME_PARAMS BOOST_PP_ENUM_PARAMS(4, typename P)
#define ENUM_GENERATOR_BINARY_PARAMS BOOST_PP_ENUM_BINARY_PARAMS(4, P, p)
#define GENERATOR_REPEAT(x, text) BOOST_PP_REPEAT(4, x, params)
#define GENERATOR_TYPELIST LOKI_TYPELIST_4(P0, P1, P2, P3)
#undef GENERATOR_COUNT
#define GENERATOR_COUNT 5
#elif GENERATOR_COUNT == 5
#define ENUM_GENERATOR_PARAMS BOOST_PP_ENUM_PARAMS(5, P)
#define ENUM_GENERATOR_PARAMSLOW BOOST_PP_ENUM_PARAMS(5, p)
#define ENUM_GENERATOR_TYPENAME_PARAMS BOOST_PP_ENUM_PARAMS(5, typename P)
#define ENUM_GENERATOR_BINARY_PARAMS BOOST_PP_ENUM_BINARY_PARAMS(5, P, p)
#define GENERATOR_REPEAT(x, text) BOOST_PP_REPEAT(5, x, params)
#define GENERATOR_TYPELIST LOKI_TYPELIST_5(P0, P1, P2, P3, P4)
#undef GENERATOR_COUNT
#define GENERATOR_COUNT 6
#elif GENERATOR_COUNT == 6
#define ENUM_GENERATOR_PARAMS BOOST_PP_ENUM_PARAMS(6, P)
#define ENUM_GENERATOR_PARAMSLOW BOOST_PP_ENUM_PARAMS(6, p)
#define ENUM_GENERATOR_TYPENAME_PARAMS BOOST_PP_ENUM_PARAMS(6, typename P)
#define ENUM_GENERATOR_BINARY_PARAMS BOOST_PP_ENUM_BINARY_PARAMS(6, P, p)
#define GENERATOR_REPEAT(x, text) BOOST_PP_REPEAT(6, x, params)
#define GENERATOR_TYPELIST LOKI_TYPELIST_6(P0, P1, P2, P3, P4, P5)
#undef GENERATOR_COUNT
#define GENERATOR_COUNT 7
#elif GENERATOR_COUNT == 7
#define ENUM_GENERATOR_PARAMS BOOST_PP_ENUM_PARAMS(7, P)
#define ENUM_GENERATOR_PARAMSLOW BOOST_PP_ENUM_PARAMS(7, p)
#define ENUM_GENERATOR_TYPENAME_PARAMS BOOST_PP_ENUM_PARAMS(7, typename P)
#define ENUM_GENERATOR_BINARY_PARAMS BOOST_PP_ENUM_BINARY_PARAMS(7, P, p)
#define GENERATOR_REPEAT(x, text) BOOST_PP_REPEAT(7, x, params)
#define GENERATOR_TYPELIST LOKI_TYPELIST_7(P0, P1, P2, P3, P4, P5, P6)
#undef GENERATOR_COUNT
#define GENERATOR_COUNT 8
#elif GENERATOR_COUNT == 8
#define ENUM_GENERATOR_PARAMS BOOST_PP_ENUM_PARAMS(8, P)
#define ENUM_GENERATOR_PARAMSLOW BOOST_PP_ENUM_PARAMS(8, p)
#define ENUM_GENERATOR_TYPENAME_PARAMS BOOST_PP_ENUM_PARAMS(8, typename P)
#define ENUM_GENERATOR_BINARY_PARAMS BOOST_PP_ENUM_BINARY_PARAMS(8, P, p)
#define GENERATOR_REPEAT(x, text) BOOST_PP_REPEAT(8, x, params)
#define GENERATOR_TYPELIST LOKI_TYPELIST_8(P0, P1, P2, P3, P4, P5, P6, P7)
#undef GENERATOR_COUNT
#define GENERATOR_COUNT
#endif
CreateClass.h
template <class T> boost::shared_ptr<T> Create(std::string id)
{}
#include "GeneratorMacro.h"
#undef GENERATOR_COUNT
#define GENERATOR_COUNT 1
#include GENERATE("CreateGenerator.h",1)
#include GENERATE("CreateGenerator.h",2)
this would give me exactly the same code as above... but its ugly and i dont think its a good idea... would it be possible to do this another way?
something like
#define num_params
GENERATE(num_params)
{
template <class T, ENUM_GENERATOR_TYPENAME_PARAMS> boost::shared_ptr<T> Create(std::string id, ENUM_GENERATOR_PARAMS)
}
[Edited by - Dragon_Strike on February 17, 2008 5:33:48 AM]