You can avoid O(n^3) complexity to O(n) by using cascade template methods with single switch-case in it:
#include <iostream>
using namespace std;
class CompositeBase
{
public:
virtual void print( std::ostream& o_out ) = 0;
};
template< typename C1, typename C2, typename C3 >
class Composite : public CompositeBase
{
public:
void print( std::ostream& o_out )
{
o_out << typeid(*this).name();
}
private:
C1 component1;
C2 component2;
C3 component3;
};
class Component0 {};
class Component1 {};
class Component2 {};
class Component3 {};
class Component4 {};
class Component5 {};
class Component6 {};
class Component7 {};
class Component8 {};
class Component9 {};
template<typename C1,typename C2,typename C3>
CompositeBase *CreateComposite0()
{
return new Composite<C1,C2,C3>();
}
template<typename C1,typename C2>
CompositeBase *CreateComposite1(int c3)
{
switch(c3)
{
case 0: return CreateComposite0<C1,C2,Component0>();
case 1: return CreateComposite0<C1,C2,Component1>();
case 2: return CreateComposite0<C1,C2,Component2>();
case 3: return CreateComposite0<C1,C2,Component3>();
case 4: return CreateComposite0<C1,C2,Component4>();
case 5: return CreateComposite0<C1,C2,Component5>();
case 6: return CreateComposite0<C1,C2,Component6>();
case 7: return CreateComposite0<C1,C2,Component7>();
case 8: return CreateComposite0<C1,C2,Component8>();
case 9: return CreateComposite0<C1,C2,Component9>();
default: return 0;
}
}
template<typename C1>
CompositeBase *CreateComposite2(int c2, int c3)
{
switch(c2)
{
case 0: return CreateComposite1<C1,Component0>(c3);
case 1: return CreateComposite1<C1,Component1>(c3);
case 2: return CreateComposite1<C1,Component2>(c3);
case 3: return CreateComposite1<C1,Component3>(c3);
case 4: return CreateComposite1<C1,Component4>(c3);
case 5: return CreateComposite1<C1,Component5>(c3);
case 6: return CreateComposite1<C1,Component6>(c3);
case 7: return CreateComposite1<C1,Component7>(c3);
case 8: return CreateComposite1<C1,Component8>(c3);
case 9: return CreateComposite1<C1,Component9>(c3);
default: return 0;
}
}
CompositeBase *CreateComposite(int c1,int c2, int c3)
{
switch(c1)
{
case 0: return CreateComposite2<Component0>(c2,c3);
case 1: return CreateComposite2<Component1>(c2,c3);
case 2: return CreateComposite2<Component2>(c2,c3);
case 3: return CreateComposite2<Component3>(c2,c3);
case 4: return CreateComposite2<Component4>(c2,c3);
case 5: return CreateComposite2<Component5>(c2,c3);
case 6: return CreateComposite2<Component6>(c2,c3);
case 7: return CreateComposite2<Component7>(c2,c3);
case 8: return CreateComposite2<Component8>(c2,c3);
case 9: return CreateComposite2<Component9>(c2,c3);
default: return 0;
}
}
int main()
{
CompositeBase* base1 = CreateComposite(4,5,6);
CompositeBase* base2 = CreateComposite(8,2,0);
base1->print(cout);
cout << endl;
base2->print(cout);
return 0;
}
Just for fun you can use boost proprocessor for O(1) complexity
#include <iostream>
#include <boost/preprocessor/repetition.hpp>
using namespace std;
class CompositeBase
{
public:
virtual void print( std::ostream& o_out ) = 0;
};
template< typename C1, typename C2, typename C3 >
class Composite : public CompositeBase
{
public:
void print( std::ostream& o_out )
{
o_out << typeid(*this).name();
}
private:
C1 component1;
C2 component2;
C3 component3;
};
#define DIM 10
#define COMPONENT_DECLARATION(z,n,unused) class BOOST_PP_CAT(Component,n) {};
BOOST_PP_REPEAT(DIM,COMPONENT_DECLARATION, ~)
#undef COMPONENT_DECLARATION
template<typename C1,typename C2,typename C3>
CompositeBase *CreateComposite0()
{
return new Composite<C1,C2,C3>();
}
template<typename C1,typename C2>
CompositeBase *CreateComposite1(int c3)
{
#define COMPOSITE(z,n,unused) case n: return CreateComposite0<C1,C2,BOOST_PP_CAT(Component,n)>();
switch(c3)
{
BOOST_PP_REPEAT(DIM,COMPOSITE,~)
default: return 0;
}
#undef COMPOSITE
}
template<typename C1>
CompositeBase *CreateComposite2(int c2, int c3)
{
#define COMPOSITE(z,n,unused) case n: return CreateComposite1<C1,BOOST_PP_CAT(Component,n)>(c3);
switch(c2)
{
BOOST_PP_REPEAT(DIM,COMPOSITE,~)
default: return 0;
}
#undef COMPOSITE
}
CompositeBase *CreateComposite(int c1,int c2, int c3)
{
#define COMPOSITE(z,n,unused) case n: return CreateComposite2<BOOST_PP_CAT(Component,n)>(c2,c3);
switch(c1)
{
BOOST_PP_REPEAT(DIM,COMPOSITE,~)
default: return 0;
}
#undef COMPOSITE
}
#undef DIM
int main()
{
CompositeBase* base1 = CreateComposite(4,5,6);
CompositeBase* base2 = CreateComposite(8,2,0);
base1->print(cout);
cout << endl;
base2->print(cout);
return 0;
}
In any case, I'd recommend to avoid these solutions if possible.