/*! * @file new_object_list.h * @brief Definition of a dynamically allocating ClassID * */ #ifndef _NEW_OBJECT_LIST_H #define _NEW_OBJECT_LIST_H #include "type_info.h" #include #include #include #include #define NewObjectListDeclaration(ClassName) \ static NewObjectList objectList #define NewObjectListDefinition(ClassName) \ NewObjectList ClassName::objectList(#ClassName) class NewObjectListBase { public: class IteratorBase { }; public: int id() const { return _id; }; const std::string& name() const { return _name; }; bool operator==(int id) const { return _id == id; }; bool operator==(const std::string& name) const { return _name == name; }; /// Comparing operators. bool compareName(const NewObjectListBase& more) const { return this->_name < more.name(); }; bool compareID(const NewObjectListBase& more) const { return this->_id < more.id(); }; virtual void debug() const = 0; static unsigned int classCount() { return _idCounter; }; static const std::string& IDToString(int classID); static int StringToID(const std::string& className); static const std::list& getClassNames(); virtual void unregisterObject(std::list _iterators) = 0; protected: NewObjectListBase(const std::string& className); virtual ~NewObjectListBase(); private: NewObjectListBase(const NewObjectListBase&); static bool classNameExists(const std::string& className); protected: typedef std::set cSet; //!< The Generic Set. typedef std::vector cVector; //!< The int _id; //!< The ID of the class. std::string _name; //!< The Name of the Class. cVector _typeOfList; //!< A List of all classes this class is derived of, and the class itself, ordered by age of addition. cSet _typeOfSet; //!< A Set of all classes this is derived from and the class itself (for isA). private: static int _idCounter; //!< A counter, that gives all classes a Unique ClassID. Access to this Variable is to be Thread-Safe. static cSet* _classes; //!< A Set of all the classes in existance. static std::list _classNames; //!< A list of all the registered ClassNames. }; ///////////////////////// //// TEMPLATISATION ///// ///////////////////////// //! Defines a ObjectsList handler for objects of type T. /** * @note The Class must define the compare with const std::string& operator for this to work. */ template class NewObjectList : public NewObjectListBase { public: typedef std::list list; typedef typename list::iterator iterator; typedef typename list::const_iterator const_iterator; class Iterator : public NewObjectListBase::IteratorBase { public: Iterator(iterator it) { it = it; } typename NewObjectList::iterator it; }; public: NewObjectList(const std::string& name); ~NewObjectList(); T* getObject(const std::string& name) const; inline const list& objects() const { return _objects; }; NewObjectListBase::IteratorBase* registerObject(T* object, NewObjectListBase* objectList); void unregisterObject(const IteratorBase& iterator); virtual void unregisterObject(std::list _iterators) = 0; virtual void debug() const; private: //! the copy constructor will be hidden. NewObjectList(const NewObjectList& definer) {}; private: list _objects; }; ///////////////////////// //// IMPLEMENTATION ///// ///////////////////////// template NewObjectList::NewObjectList(const std::string& name) : NewObjectListBase(name) {} template NewObjectList::~NewObjectList() { // assert(_objects.empty()); } template T* NewObjectList::getObject(const std::string& name) const { iterator it = std::find(this->_objects.begin(), this->_objects.end(), name); if (it != this->_objects.end()) return *it; else return NULL; } template NewObjectListBase::IteratorBase* NewObjectList::registerObject(T* object, NewObjectListBase* objectList) { if(this->_typeOfList.empty()) { this->_typeOfList.push_back(objectList); } this->_objects.push_front(object); return new Iterator(this->_objects.begin()); } template void NewObjectList::unregisterObject(const IteratorBase& iterator) { this->_objects.erase(static_cast(iterator)); //_objects.erase(std::find(_objects.begin(), _objects.end(), object)); } #include template void NewObjectList::debug() const { const_iterator it; for (it = this->_objects.begin(); it != this->_objects.end(); ++it) { std::cout << (*it)->name() << std::endl; } } #endif /* _NEW_OBJECT_LIST_H */