Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Mar 24, 2013, 6:08:42 PM (11 years ago)
Author:
landauf
Message:

moved static functions from Identifier.cc/h to IdentifierManager.cc/h (still static though)

File:
1 copied

Legend:

Unmodified
Added
Removed
  • code/branches/core6/src/libraries/core/class/IdentifierManager.h

    r9563 r9564  
    2828
    2929/**
    30     @defgroup Identifier Identifier
    31     @ingroup Class
     30    @file
     31    @ingroup Class Identifier
    3232*/
    3333
    34 /**
    35     @file
    36     @ingroup Class Identifier
    37     @brief Declaration of Identifier, definition of ClassIdentifier<T>; used to identify the class of an object.
    38 
    39     @anchor IdentifierExample
    40 
    41     An Identifier "identifies" the class of an object. It contains different information about
    42     the class: Its name and ID, a list of all instances of this class, a factory to create new
    43     instances of this class, and more.
    44 
    45     It also contains information about the inheritance of this class: It stores a list of the
    46     Identifiers of all parent-classes as well as a list of all child-classes. These relationships
    47     can be tested using functions like @c isA(), @c isChildOf(), @c isParentOf(), and more.
    48 
    49     Every Identifier is in fact a ClassIdentifier<T> (where T is the class that is identified
    50     by the Identifier), Identifier is just the common base-class.
    51 
    52     Example:
    53     @code
    54     MyClass* object = new MyClass();                                            // create an instance of MyClass
    55 
    56     object->getIdentifier()->getName();                                         // returns "MyClass"
    57 
    58     OrxonoxClass* other = object->getIdentifier()->fabricate(0);                // fabricates a new instance of MyClass
    59 
    60 
    61     // iterate through all objects of type MyClass:
    62     ObjectListBase* objects = object->getIdentifier()->getObjects();            // get a pointer to the object-list
    63     int count;
    64     for (Iterator<MyClass> it = objects.begin(); it != objects.end(); ++it)     // iterate through the objects
    65         ++count;
    66     orxout() << count << endl;                                                  // prints "2" because we created 2 instances of MyClass so far
    67 
    68 
    69     // test the class hierarchy
    70     object->getIdentifier()->isA(Class(MyClass));                               // returns true
    71     object->isA(Class(MyClass));                                                // returns true (short version)
    72 
    73     object->isA(Class(BaseClass));                                              // returns true if MyClass is a child of BaseClass
    74 
    75     Class(ChildClass)->isChildOf(object->getIdentifier());                      // returns true if ChildClass is a child of MyClass
    76     @endcode
    77 */
    78 
    79 #ifndef _Identifier_H__
    80 #define _Identifier_H__
     34#ifndef _IdentifierManager_H__
     35#define _IdentifierManager_H__
    8136
    8237#include "core/CorePrereqs.h"
    8338
    84 #include <cassert>
    8539#include <map>
    86 #include <set>
    8740#include <string>
    88 #include <typeinfo>
    89 #include <loki/TypeTraits.h>
    90 
    91 #include "util/Output.h"
    92 #include "core/object/MetaObjectList.h"
    93 #include "core/object/ObjectList.h"
    94 #include "core/object/ObjectListBase.h"
    95 #include "Super.h"
    9641
    9742namespace orxonox
    9843{
    99     // ###############################
    100     // ###       Identifier        ###
    101     // ###############################
    102     /**
    103         @brief The Identifier is used to identify the class of an object and to store information about the class.
     44    class _CoreExport IdentifierManager
     45    {
     46        friend class Identifier;
     47        template <class T> friend class ClassIdentifier;
    10448
    105         Each Identifier stores information about one class. The Identifier can then be used to identify
    106         this class. On the other hand it's also possible to get the corresponding Identifier of a class,
    107         for example by using the macro Class().
    108 
    109         @see See @ref IdentifierExample "Identifier.h" for more information and some examples.
    110 
    111         @note You can't directly create an Identifier, it's just the base-class of ClassIdentifier<T>.
    112     */
    113     class _CoreExport Identifier
    114     {
    11549        public:
    116             /// Returns the name of the class the Identifier belongs to.
    117             inline const std::string& getName() const { return this->name_; }
    118             void setName(const std::string& name);
    119 
    120             /// Returns the network ID to identify a class through the network.
    121             inline uint32_t getNetworkID() const { return this->networkID_; }
    122             void setNetworkID(uint32_t id);
    123 
    124             /// Returns the unique ID of the class.
    125             ORX_FORCEINLINE unsigned int getClassID() const { return this->classID_; }
    126 
    127             /// Returns the list of all existing objects of this class.
    128             inline ObjectListBase* getObjects() const { return this->objects_; }
    129 
    130             /// Sets the Factory.
    131             inline void addFactory(Factory* factory) { this->factory_ = factory; }
    132             /// Returns true if the Identifier has a Factory.
    133             inline bool hasFactory() const { return (this->factory_ != 0); }
    134 
    135             OrxonoxClass* fabricate(BaseObject* creator);
    136 
    137             /// Returns true if the class can be loaded through XML.
    138             inline bool isLoadable() const { return this->bLoadable_; }
    139             /// Set the class to be loadable through XML or not.
    140             inline void setLoadable(bool bLoadable) { this->bLoadable_ = bLoadable; }
    141 
    142             bool isA(const Identifier* identifier) const;
    143             bool isExactlyA(const Identifier* identifier) const;
    144             bool isChildOf(const Identifier* identifier) const;
    145             bool isDirectChildOf(const Identifier* identifier) const;
    146             bool isParentOf(const Identifier* identifier) const;
    147             bool isDirectParentOf(const Identifier* identifier) const;
    148 
    149 
    15050            /////////////////////////////
    15151            ////// Class Hierarchy //////
     
    15454
    15555            /// Returns true, if a branch of the class-hierarchy is being created, causing all new objects to store their parents.
    156             inline static bool isCreatingHierarchy() { return (hierarchyCreatingCounter_s > 0); }
    157 
    158             /// Returns the parents of the class the Identifier belongs to.
    159             inline const std::set<const Identifier*>& getParents() const { return this->parents_; }
    160             /// Returns the begin-iterator of the parents-list.
    161             inline std::set<const Identifier*>::const_iterator getParentsBegin() const { return this->parents_.begin(); }
    162             /// Returns the end-iterator of the parents-list.
    163             inline std::set<const Identifier*>::const_iterator getParentsEnd() const { return this->parents_.end(); }
    164 
    165             /// Returns the children of the class the Identifier belongs to.
    166             inline const std::set<const Identifier*>& getChildren() const { return this->children_; }
    167             /// Returns the begin-iterator of the children-list.
    168             inline std::set<const Identifier*>::const_iterator getChildrenBegin() const { return this->children_.begin(); }
    169             /// Returns the end-iterator of the children-list.
    170             inline std::set<const Identifier*>::const_iterator getChildrenEnd() const { return this->children_.end(); }
    171 
    172             /// Returns the direct parents of the class the Identifier belongs to.
    173             inline const std::set<const Identifier*>& getDirectParents() const { return this->directParents_; }
    174             /// Returns the begin-iterator of the direct-parents-list.
    175             inline std::set<const Identifier*>::const_iterator getDirectParentsBegin() const { return this->directParents_.begin(); }
    176             /// Returns the end-iterator of the direct-parents-list.
    177             inline std::set<const Identifier*>::const_iterator getDirectParentsEnd() const { return this->directParents_.end(); }
    178 
    179             /// Returns the direct children the class the Identifier belongs to.
    180             inline const std::set<const Identifier*>& getDirectChildren() const { return this->directChildren_; }
    181             /// Returns the begin-iterator of the direct-children-list.
    182             inline std::set<const Identifier*>::const_iterator getDirectChildrenBegin() const { return this->directChildren_.begin(); }
    183             /// Returns the end-iterator of the direct-children-list.
    184             inline std::set<const Identifier*>::const_iterator getDirectChildrenEnd() const { return this->directChildren_.end(); }
     56            inline static bool isCreatingHierarchy()
     57                { return (hierarchyCreatingCounter_s > 0); }
    18558
    18659
     
    19770
    19871            /// Returns the map that stores all Identifiers with their names.
    199             static inline const std::map<std::string, Identifier*>& getStringIdentifierMap() { return Identifier::getStringIdentifierMapIntern(); }
     72            static inline const std::map<std::string, Identifier*>& getStringIdentifierMap()
     73                { return IdentifierManager::getStringIdentifierMapIntern(); }
    20074            /// Returns a const_iterator to the beginning of the map that stores all Identifiers with their names.
    201             static inline std::map<std::string, Identifier*>::const_iterator getStringIdentifierMapBegin() { return Identifier::getStringIdentifierMap().begin(); }
     75            static inline std::map<std::string, Identifier*>::const_iterator getStringIdentifierMapBegin()
     76                { return IdentifierManager::getStringIdentifierMap().begin(); }
    20277            /// Returns a const_iterator to the end of the map that stores all Identifiers with their names.
    203             static inline std::map<std::string, Identifier*>::const_iterator getStringIdentifierMapEnd() { return Identifier::getStringIdentifierMap().end(); }
     78            static inline std::map<std::string, Identifier*>::const_iterator getStringIdentifierMapEnd()
     79                { return IdentifierManager::getStringIdentifierMap().end(); }
    20480
    20581            /// Returns the map that stores all Identifiers with their names in lowercase.
    206             static inline const std::map<std::string, Identifier*>& getLowercaseStringIdentifierMap() { return Identifier::getLowercaseStringIdentifierMapIntern(); }
     82            static inline const std::map<std::string, Identifier*>& getLowercaseStringIdentifierMap()
     83                { return IdentifierManager::getLowercaseStringIdentifierMapIntern(); }
    20784            /// Returns a const_iterator to the beginning of the map that stores all Identifiers with their names in lowercase.
    208             static inline std::map<std::string, Identifier*>::const_iterator getLowercaseStringIdentifierMapBegin() { return Identifier::getLowercaseStringIdentifierMap().begin(); }
     85            static inline std::map<std::string, Identifier*>::const_iterator getLowercaseStringIdentifierMapBegin()
     86                { return IdentifierManager::getLowercaseStringIdentifierMap().begin(); }
    20987            /// Returns a const_iterator to the end of the map that stores all Identifiers with their names in lowercase.
    210             static inline std::map<std::string, Identifier*>::const_iterator getLowercaseStringIdentifierMapEnd() { return Identifier::getLowercaseStringIdentifierMap().end(); }
     88            static inline std::map<std::string, Identifier*>::const_iterator getLowercaseStringIdentifierMapEnd()
     89                { return IdentifierManager::getLowercaseStringIdentifierMap().end(); }
    21190
    21291            /// Returns the map that stores all Identifiers with their IDs.
    213             static inline const std::map<uint32_t, Identifier*>& getIDIdentifierMap() { return Identifier::getIDIdentifierMapIntern(); }
     92            static inline const std::map<uint32_t, Identifier*>& getIDIdentifierMap()
     93                { return IdentifierManager::getIDIdentifierMapIntern(); }
    21494            /// Returns a const_iterator to the beginning of the map that stores all Identifiers with their IDs.
    215             static inline std::map<uint32_t, Identifier*>::const_iterator getIDIdentifierMapBegin() { return Identifier::getIDIdentifierMap().begin(); }
     95            static inline std::map<uint32_t, Identifier*>::const_iterator getIDIdentifierMapBegin()
     96                { return IdentifierManager::getIDIdentifierMap().begin(); }
    21697            /// Returns a const_iterator to the end of the map that stores all Identifiers with their IDs.
    217             static inline std::map<uint32_t, Identifier*>::const_iterator getIDIdentifierMapEnd() { return Identifier::getIDIdentifierMap().end(); }
    218 
    219 
    220             /////////////////////////
    221             ///// Config Values /////
    222             /////////////////////////
    223             virtual void updateConfigValues(bool updateChildren = true) const = 0;
    224 
    225             /// Returns true if this class has at least one config value.
    226             inline bool hasConfigValues() const { return this->bHasConfigValues_; }
    227 
    228             void addConfigValueContainer(const std::string& varname, ConfigValueContainer* container);
    229             ConfigValueContainer* getConfigValueContainer(const std::string& varname);
    230 
    231 
    232             ///////////////////
    233             ///// XMLPort /////
    234             ///////////////////
    235             /// Returns the map that stores all XMLPort params.
    236             inline const std::map<std::string, XMLPortParamContainer*>& getXMLPortParamMap() const { return this->xmlportParamContainers_; }
    237             /// Returns a const_iterator to the beginning of the map that stores all XMLPort params.
    238             inline std::map<std::string, XMLPortParamContainer*>::const_iterator getXMLPortParamMapBegin() const { return this->xmlportParamContainers_.begin(); }
    239             /// Returns a const_iterator to the end of the map that stores all XMLPort params.
    240             inline std::map<std::string, XMLPortParamContainer*>::const_iterator getXMLPortParamMapEnd() const { return this->xmlportParamContainers_.end(); }
    241 
    242             /// Returns the map that stores all XMLPort objects.
    243             inline const std::map<std::string, XMLPortObjectContainer*>& getXMLPortObjectMap() const { return this->xmlportObjectContainers_; }
    244             /// Returns a const_iterator to the beginning of the map that stores all XMLPort objects.
    245             inline std::map<std::string, XMLPortObjectContainer*>::const_iterator getXMLPortObjectMapBegin() const { return this->xmlportObjectContainers_.begin(); }
    246             /// Returns a const_iterator to the end of the map that stores all XMLPort objects.
    247             inline std::map<std::string, XMLPortObjectContainer*>::const_iterator getXMLPortObjectMapEnd() const { return this->xmlportObjectContainers_.end(); }
    248 
    249             void addXMLPortParamContainer(const std::string& paramname, XMLPortParamContainer* container);
    250             XMLPortParamContainer* getXMLPortParamContainer(const std::string& paramname);
    251 
    252             void addXMLPortObjectContainer(const std::string& sectionname, XMLPortObjectContainer* container);
    253             XMLPortObjectContainer* getXMLPortObjectContainer(const std::string& sectionname);
    254 
     98            static inline std::map<uint32_t, Identifier*>::const_iterator getIDIdentifierMapEnd()
     99                { return IdentifierManager::getIDIdentifierMap().end(); }
    255100
    256101        protected:
    257             Identifier();
    258             Identifier(const Identifier& identifier); // don't copy
    259             virtual ~Identifier();
    260 
    261102            static Identifier* getIdentifierSingleton(const std::string& name, Identifier* proposal);
    262             virtual void createSuperFunctionCaller() const = 0;
    263 
    264             void initializeClassHierarchy(std::set<const Identifier*>* parents, bool bRootClass);
    265103
    266104            /// Returns the map that stores all Identifiers with their names.
     
    271109            static std::map<uint32_t, Identifier*>& getIDIdentifierMapIntern();
    272110
    273             /// Returns the children of the class the Identifier belongs to.
    274             inline std::set<const Identifier*>& getChildrenIntern() const { return this->children_; }
    275             /// Returns the direct children of the class the Identifier belongs to.
    276             inline std::set<const Identifier*>& getDirectChildrenIntern() const { return this->directChildren_; }
    277 
    278             ObjectListBase* objects_;                                      //!< The list of all objects of this class
    279 
    280111        private:
    281112            /// Increases the hierarchyCreatingCounter_s variable, causing all new objects to store their parents.
    282             inline static void startCreatingHierarchy() { hierarchyCreatingCounter_s++; }
     113            inline static void startCreatingHierarchy()
     114                { hierarchyCreatingCounter_s++; }
    283115            /// Decreases the hierarchyCreatingCounter_s variable, causing the objects to stop storing their parents.
    284             inline static void stopCreatingHierarchy()  { hierarchyCreatingCounter_s--; }
     116            inline static void stopCreatingHierarchy()
     117                { hierarchyCreatingCounter_s--; }
    285118
    286119            static std::map<std::string, Identifier*>& getTypeIDIdentifierMap();
    287120
    288             void initialize(std::set<const Identifier*>* parents);
    289 
    290             std::set<const Identifier*> parents_;                          //!< The parents of the class the Identifier belongs to
    291             mutable std::set<const Identifier*> children_;                 //!< The children of the class the Identifier belongs to
    292 
    293             std::set<const Identifier*> directParents_;                    //!< The direct parents of the class the Identifier belongs to
    294             mutable std::set<const Identifier*> directChildren_;           //!< The direct children of the class the Identifier belongs to
    295 
    296             bool bCreatedOneObject_;                                       //!< True if at least one object of the given type was created (used to determine the need of storing the parents)
    297             bool bSetName_;                                                //!< True if the name is set
    298             bool bLoadable_;                                               //!< False = it's not permitted to load the object through XML
    299             std::string name_;                                             //!< The name of the class the Identifier belongs to
    300             Factory* factory_;                                             //!< The Factory, able to create new objects of the given class (if available)
    301121            static int hierarchyCreatingCounter_s;                         //!< Bigger than zero if at least one Identifier stores its parents (its an int instead of a bool to avoid conflicts with multithreading)
    302             uint32_t networkID_;                                           //!< The network ID to identify a class through the network
    303             const unsigned int classID_;                                   //!< Uniquely identifies a class (might not be the same as the networkID_)
    304122            static unsigned int classIDCounter_s;                          //!< Static counter for the unique classIDs
    305 
    306             bool bHasConfigValues_;                                        //!< True if this class has at least one assigned config value
    307             std::map<std::string, ConfigValueContainer*> configValues_;    //!< A map to link the string of configurable variables with their ConfigValueContainer
    308 
    309             std::map<std::string, XMLPortParamContainer*> xmlportParamContainers_;     //!< All loadable parameters
    310             std::map<std::string, XMLPortObjectContainer*> xmlportObjectContainers_;   //!< All attachable objects
    311123    };
    312 
    313     _CoreExport std::ostream& operator<<(std::ostream& out, const std::set<const Identifier*>& list);
    314 
    315 
    316     // ###############################
    317     // ###     ClassIdentifier     ###
    318     // ###############################
    319     /**
    320         @brief The ClassIdentifier is derived from Identifier and holds all class-specific functions and variables the Identifier cannot have.
    321 
    322         ClassIdentifier is a Singleton, which means that only one ClassIdentifier for a given type T exists.
    323         This makes it possible to store information about a class, sharing them with all
    324         objects of that class without defining static variables in every class.
    325 
    326         To be really sure that not more than exactly one object exists (even with libraries),
    327         ClassIdentifiers are stored in a static map in Identifier.
    328     */
    329     template <class T>
    330     class ClassIdentifier : public Identifier
    331     {
    332         #ifndef DOXYGEN_SHOULD_SKIP_THIS
    333           #define SUPER_INTRUSIVE_DECLARATION_INCLUDE
    334           #include "Super.h"
    335         #endif
    336 
    337         public:
    338             static ClassIdentifier<T>* getIdentifier();
    339             static ClassIdentifier<T>* getIdentifier(const std::string& name);
    340 
    341             bool initialiseObject(T* object, const std::string& className, bool bRootClass);
    342 
    343             void updateConfigValues(bool updateChildren = true) const;
    344 
    345         private:
    346             static void initialiseIdentifier();
    347             ClassIdentifier(const ClassIdentifier<T>& identifier) {}    // don't copy
    348             ClassIdentifier()
    349             {
    350                 SuperFunctionInitialization<0, T>::initialize(this);
    351             }
    352             ~ClassIdentifier()
    353             {
    354                 SuperFunctionDestruction<0, T>::destroy(this);
    355             }
    356 
    357             static ClassIdentifier<T>* classIdentifier_s;
    358     };
    359 
    360     template <class T>
    361     ClassIdentifier<T>* ClassIdentifier<T>::classIdentifier_s = 0;
    362 
    363     /**
    364         @brief Returns the only instance of this class.
    365         @return The unique Identifier
    366     */
    367     template <class T>
    368     inline ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()
    369     {
    370         // check if the Identifier already exists
    371         if (!ClassIdentifier<T>::classIdentifier_s)
    372             ClassIdentifier<T>::initialiseIdentifier();
    373 
    374         return ClassIdentifier<T>::classIdentifier_s;
    375     }
    376 
    377     /**
    378         @brief Does the same as getIdentifier() but sets the name if this wasn't done yet.
    379         @param name The name of this Identifier
    380         @return The Identifier
    381     */
    382     template <class T>
    383     inline ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier(const std::string& name)
    384     {
    385         ClassIdentifier<T>* identifier = ClassIdentifier<T>::getIdentifier();
    386         identifier->setName(name);
    387         return identifier;
    388     }
    389 
    390     /**
    391         @brief Assigns the static field for the identifier singleton.
    392     */
    393     template <class T>
    394     void ClassIdentifier<T>::initialiseIdentifier()
    395     {
    396         // Get the name of the class
    397         std::string name = typeid(T).name();
    398 
    399         // create a new identifier anyway. Will be deleted in Identifier::getIdentifier if not used.
    400         ClassIdentifier<T>* proposal = new ClassIdentifier<T>();
    401 
    402         // Get the entry from the map
    403         ClassIdentifier<T>::classIdentifier_s = (ClassIdentifier<T>*)Identifier::getIdentifierSingleton(name, proposal);
    404 
    405         if (ClassIdentifier<T>::classIdentifier_s == proposal)
    406         {
    407             orxout(verbose, context::identifier) << "Requested Identifier for " << name << " was not yet existing and got created." << endl;
    408         }
    409         else
    410         {
    411             orxout(verbose, context::identifier) << "Requested Identifier for " << name << " was already existing and got assigned." << endl;
    412         }
    413     }
    414 
    415     /**
    416         @brief Adds an object of the given type to the ObjectList.
    417         @param object The object to add
    418         @param className The name of the class T
    419         @param bRootClass True if this is a root class (i.e. it inherits directly from OrxonoxClass)
    420     */
    421     template <class T>
    422     bool ClassIdentifier<T>::initialiseObject(T* object, const std::string& className, bool bRootClass)
    423     {
    424         if (bRootClass)
    425             orxout(verbose, context::object_list) << "Register Root-Object: " << className << endl;
    426         else
    427             orxout(verbose, context::object_list) << "Register Object: " << className << endl;
    428 
    429         object->identifier_ = this;
    430         if (Identifier::isCreatingHierarchy())
    431         {
    432             if (bRootClass && !object->parents_)
    433                 object->parents_ = new std::set<const Identifier*>();
    434 
    435             if (object->parents_)
    436             {
    437                 this->initializeClassHierarchy(object->parents_, bRootClass);
    438                 object->parents_->insert(object->parents_->end(), this);
    439             }
    440 
    441             object->setConfigValues();
    442             return true;
    443         }
    444         else
    445         {
    446             orxout(verbose, context::object_list) << "Added object to " << this->getName() << "-list." << endl;
    447             object->metaList_->add(this->objects_, this->objects_->add(new ObjectListElement<T>(object)));
    448 
    449             // Add pointer of type T to the map in the OrxonoxClass instance that enables "dynamic_casts"
    450             object->objectPointers_.push_back(std::make_pair(this->getClassID(), static_cast<void*>(object)));
    451             return false;
    452         }
    453     }
    454 
    455     /**
    456         @brief Updates the config-values of all existing objects of this class by calling their setConfigValues() function.
    457     */
    458     template <class T>
    459     void ClassIdentifier<T>::updateConfigValues(bool updateChildren) const
    460     {
    461         if (!this->hasConfigValues())
    462             return;
    463 
    464         for (ObjectListIterator<T> it = ObjectList<T>::begin(); it; ++it)
    465             it->setConfigValues();
    466 
    467         if (updateChildren)
    468             for (std::set<const Identifier*>::const_iterator it = this->getChildrenBegin(); it != this->getChildrenEnd(); ++it)
    469                 (*it)->updateConfigValues(false);
    470     }
    471 
    472 
    473     // ###############################
    474     // ###      orxonox_cast       ###
    475     // ###############################
    476     /**
    477     @brief
    478         Casts on object of type OrxonoxClass to any derived type that is
    479         registered in the class hierarchy.
    480     @return
    481         Returns NULL if the cast is not possible
    482     @note
    483         In case of NULL return (and using MSVC), a dynamic_cast might still be possible if
    484         a class forgot to register its objects.
    485         Also note that the function is implemented differently for GCC/MSVC.
    486     */
    487     template <class T, class U>
    488     ORX_FORCEINLINE T orxonox_cast(U* source)
    489     {
    490 #ifdef ORXONOX_COMPILER_MSVC
    491         typedef Loki::TypeTraits<typename Loki::TypeTraits<T>::PointeeType>::NonConstType ClassType;
    492         if (source != NULL)
    493             return source->template getDerivedPointer<ClassType>(ClassIdentifier<ClassType>::getIdentifier()->getClassID());
    494         else
    495             return NULL;
    496 #else
    497         return dynamic_cast<T>(source);
    498 #endif
    499     }
    500124}
    501125
    502 #endif /* _Identifier_H__ */
     126#endif /* _IdentifierManager_H__ */
Note: See TracChangeset for help on using the changeset viewer.