#ifndef U_CORE_CLASSFACTORY_H #define U_CORE_CLASSFACTORY_H #include #include #include #include "Core/Mpl.h" #include "Core/MplSequenceCombiner.h" #include "Core/Types.h" namespace uLib { //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // RUNTIME CLASS FACTORY not usable yet... classes under development ! template < class BaseType, template class DerivedType, typename S1, typename S2 > class Factory2 { typedef Factory2 ThisClass; typedef void*(ThisClass::* newClassFn)(void *,void *); typedef std::vector newClassFnVector; typedef mpl::combine_view< mpl::vector > AlgView; template void * newClass(void *ob1, void *ob2 ) { DerivedType *out = new DerivedType; if(ob1) static_cast(*out) = *static_cast(ob1); if(ob2) static_cast(*out) = *static_cast(ob2); return out; } template < typename U, typename V > void addType() { m_map.push_back(&ThisClass::newClass< U,V >); } struct AddTypeSeqOp { AddTypeSeqOp( Factory2 *_p) : m_parent(_p) {} template < typename Seq > void operator()(Seq) { m_parent->addType< typename mpl::at >::type, typename mpl::at >::type > (); } Factory2 *m_parent; }; BaseType * create() { typename newClassFnVector::iterator itr = m_map.begin() + m_id0 + m_size1 * m_id1; return (BaseType *)(this->*(*itr))(m_algs[0], m_algs[1]); } public: Factory2() : m_id0(0), m_id1(0) { mpl::for_each< AlgView >(AddTypeSeqOp(this)); m_algs[0] = NULL; m_algs[1] = NULL; m_base = create(); } BaseType * operator -> () const { return m_base; } template < typename T > static inline int FindS1() { typedef typename mpl::find::type iter; return iter::pos::value; } template < typename T > static inline int FindS2() { typedef typename mpl::find::type iter; return iter::pos::value; } template < class A > void setA0 (A* alg) { m_algs[0] = alg; m_id0 = FindS1(); delete m_base; m_base = create(); } template < class A > void setA1 (A* alg) { m_algs[1] = alg; m_id1 = FindS2(); delete m_base; m_base = create(); } private: newClassFnVector m_map; int m_id0, m_id1; void * m_algs[2]; BaseType *m_base; static const int m_size1 = mpl::size::type::value; static const int m_size2 = mpl::size::type::value; }; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // generator // template static void * newClass() { return new T; } template static void * newClass2(void *a1,void *a2) { return new T(a1,a2); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Run time named class factory // template class NamedClassFactory { typedef void * (*_newClassfn)(); typedef std::map MapType; public: template void AddType(const char* name) { m_map.insert(std::make_pair(name, &newClass)); } BaseType *Create(const char *type) { typename MapType::iterator itr = m_map.find(type); return static_cast(itr->second()); } void List(std::ostream &o) { for(typename MapType::iterator itr = m_map.begin(); itr!=m_map.end(); itr++ ) o << itr->first << "\n"; } private: MapType m_map; }; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // MPL sequence registered class factory // template class RegisteredClassFactory { typedef void *(*_newClassfn)(); typedef std::vector<_newClassfn> TypeVectorType; struct AddTypeOp { AddTypeOp( RegisteredClassFactory *_p) : m_parent(_p) {} template void operator ()(U x) { m_parent->addType(); } RegisteredClassFactory *m_parent; }; template < typename T > void addType() { m_map.push_back(&newClass); } public: RegisteredClassFactory() { mpl::for_each(AddTypeOp(this)); } template < typename T > int Find() { typedef typename mpl::find::type iter; return iter::pos::value; } template < typename T > BaseType *Create() { int id = Find(); typename TypeVectorType::iterator itr = m_map.begin() + id; return (BaseType *)(*itr)(); } private: TypeVectorType m_map; }; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// template < class BaseType, template class DerivedType, typename S1 > class RegisteredClassFactory1 { typedef void*(*_newClassfn)(); typedef std::vector<_newClassfn> TypeVectorType; template < typename U > void addType() { m_map.push_back(&newClass< // BaseType, DerivedType >); } struct AddTypeSeqOp { AddTypeSeqOp( RegisteredClassFactory1 *_p) : m_parent(_p) {} template < typename Seq > void operator()(Seq) { m_parent->addType< typename mpl::at >::type > (); } RegisteredClassFactory1 *m_parent; }; typedef mpl::combine_view< mpl::vector > AlgView; public: RegisteredClassFactory1() { mpl::for_each< AlgView >(AddTypeSeqOp(this)); } template < typename T > static inline int FindS1() { typedef typename mpl::find::type iter; return iter::pos::value; } BaseType *Create(int id1) { typename TypeVectorType::iterator itr = m_map.begin() + id1; return (BaseType *)(*itr)(); } private: TypeVectorType m_map; static const int m_size1 = mpl::size::type::value; }; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// template < class BaseType, template class DerivedType, typename S1, typename S2 > class RegisteredClassFactory2 { typedef void*(*_newClassfn)(); typedef std::vector<_newClassfn> TypeVectorType; template < typename U, typename V > void addType() { m_map.push_back(&newClass< // BaseType, DerivedType >); } struct AddTypeSeqOp { AddTypeSeqOp( RegisteredClassFactory2 *_p) : m_parent(_p) {} template < typename Seq > void operator()(Seq) { m_parent->addType< typename mpl::at >::type, typename mpl::at >::type > (); } RegisteredClassFactory2 *m_parent; }; typedef mpl::combine_view< mpl::vector > AlgView; public: RegisteredClassFactory2() { mpl::for_each< AlgView >(AddTypeSeqOp(this)); } template < typename T > static inline int FindS1() { typedef typename mpl::find::type iter; return iter::pos::value; } template < typename T > static inline int FindS2() { typedef typename mpl::find::type iter; return iter::pos::value; } BaseType * Create(int id1, int id2) { typename TypeVectorType::iterator itr = m_map.begin() + id1 + m_size1 * id2; return (BaseType *)(*itr)(); } private: TypeVectorType m_map; static const int m_size1 = mpl::size::type::value; static const int m_size2 = mpl::size::type::value; }; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// template < class BaseType, template class DerivedType, typename S1, typename S2, typename S3 > class RegisteredClassFactory3 { typedef void*(*_newClassfn)(); typedef std::vector<_newClassfn> TypeVectorType; template < typename T1, typename T2, typename T3 > void addType() { m_map.push_back(&newClass< // BaseType, DerivedType >); } struct AddTypeSeqOp { AddTypeSeqOp( RegisteredClassFactory3 *_p) : m_parent(_p) {} template < typename Seq > void operator()(Seq) { m_parent->addType< typename mpl::at >::type, typename mpl::at >::type, typename mpl::at >::type > (); } RegisteredClassFactory3 *m_parent; }; typedef mpl::combine_view< mpl::vector > AlgView; public: RegisteredClassFactory3() { mpl::for_each< AlgView >(AddTypeSeqOp(this)); } template < typename T > static inline int FindS1() { typedef typename mpl::find::type iter; return iter::pos::value; } template < typename T > static inline int FindS2() { typedef typename mpl::find::type iter; return iter::pos::value; } template < typename T > static inline int FindS3() { typedef typename mpl::find::type iter; return iter::pos::value; } BaseType *Create(int id1, int id2, int id3) { typename TypeVectorType::iterator itr = m_map.begin() + id1 + m_size1 * id2 + m_size1 * m_size3 * id3; return (BaseType *)(*itr)(); } private: TypeVectorType m_map; static const int m_size1 = mpl::size::type::value; static const int m_size2 = mpl::size::type::value; static const int m_size3 = mpl::size::type::value; }; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// } // uLib #endif // CLASSFACTORY_H