00001 // Primary maintainer for this file: David J. Berg 00002 00003 #ifdef INVT_USE_CPPOX//we need c++ 0X features for this to work 00004 #ifndef GENERICITEM_H_DEFINED 00005 #define GENERICITEM_H_DEFINED 00006 00007 #include "GenericUtils/ProcessFunctor.H" 00008 #include <memory> 00009 00010 // ###################################################################### 00011 // GenericItem allows one to abtract the type away of a container and its 00012 // contained type, so that one can have a container of containers 00013 // of heterogenious types. 00014 // 00015 // Optionally (and what makes this class useful) the template can take a number 00016 // of additionaly types, which are the types of a ProcessFunctor which can 00017 // operate on the generic data in the item. The ProcessFunctor is designed to 00018 // handle the different types of data in the GenericItem. See ProcessFunctor.H 00019 // for details, and the example in test-generics.C 00020 // ###################################################################### 00021 template <template <typename...> class C, typename... FunctorTypes> 00022 class GenericItemBase 00023 { 00024 public: 00025 // allow anyone to destroy this class 00026 virtual ~GenericItemBase() { }; 00027 00028 // default destructor, copy, and assign Ok 00029 00030 //process an item with the functor 00031 virtual void runProcessFunctor(ProcessFunctor<C, FunctorTypes...>& func, const bool convert = false) = 0; 00032 00033 protected: 00034 //we don't want just anybody to create, or copy our generic feature 00035 GenericItemBase() { }; 00036 GenericItemBase(const GenericItemBase& rhs) { }; 00037 void operator=(const GenericItemBase& rhs) { }; 00038 }; 00039 00040 // ###################################################################### 00041 // Lets implement a GenericItem with a template type 00042 // ###################################################################### 00043 template <template <typename...> class C, typename T, typename... FunctorTypes> 00044 class GenericItemImpl : public GenericItemBase<C, FunctorTypes...> 00045 { 00046 public: 00047 //construct with data, no default constructor. 00048 GenericItemImpl(const C<T>& item) : itsItem(item) { }; 00049 00050 // default destructor, copy, and assign Ok 00051 00052 //process an item with the functor 00053 void runProcessFunctor(ProcessFunctor<C, FunctorTypes...>& func, const bool convert = false) 00054 { func(itsItem, convert); } 00055 00056 private: 00057 C<T> itsItem; 00058 }; 00059 00060 // ###################################################################### 00061 // A class to represent a GenericItem 00062 // ###################################################################### 00063 template <template <typename...> class C, typename... FunctorTypes> 00064 class GenericItem 00065 { 00066 public: 00067 //create a feature 00068 template <class T> 00069 static GenericItem make(const C<T>& item) 00070 { 00071 GenericItem fs; 00072 fs.itsGenItem.reset(new GenericItemImpl<C, T, FunctorTypes...>(item)); 00073 return fs; 00074 } 00075 00076 //default copy constructor, destructor and assignment Ok 00077 00078 //process an item with the functor 00079 void runProcessFunctor(ProcessFunctor<C, FunctorTypes...>& func, const bool convert = false) 00080 { 00081 itsGenItem->runProcessFunctor(func, convert); 00082 }; 00083 00084 private: 00085 //dont allow construction directly, use static create functions 00086 GenericItem() : itsGenItem() { }; 00087 00088 std::shared_ptr<GenericItemBase<C, FunctorTypes...> > itsGenItem;//a pointer to our GenericItem 00089 }; 00090 00091 #endif 00092 #endif