source: src/Patterns/Registry_impl.hpp@ e2e035e

Last change on this file since e2e035e was 296839, checked in by Frederik Heber <heber@…>, 15 years ago

BUGFIX: Registry<T>::cleanup() - first erase from list, then delete instance.

  • if we just delete all instances, then free the list. We ran into problems when instances had an unregisterInstance() call in their destructor for this effectively invalidated the current iterator.
  • Library version is now 7:2:0, API version is 1.1.2.
  • Property mode set to 100644
File size: 5.1 KB
Line 
1/*
2 * Registry_impl.hpp
3 *
4 * Created on: Jul 28, 2010
5 * Author: heber
6 */
7
8#ifndef REGISTRY_IMPL_HPP_
9#define REGISTRY_IMPL_HPP_
10
11// include config.h
12#ifdef HAVE_CONFIG_H
13#include <config.h>
14#endif
15
16#include "MemDebug.hpp"
17
18#include "Registry.hpp"
19#include "Singleton_impl.hpp"
20
21#include "Assert.hpp"
22#include <iostream>
23
24/** Constructor for class Registry.
25 */
26template <class T> Registry<T>::Registry()
27{}
28
29/** Destructor for class Registry.
30 */
31template <class T> Registry<T>::~Registry()
32{}
33
34/** Returns pointer to an instance named by \a name.
35 * \param name name of instance
36 * \return pointer to instance
37 */
38template <class T> T* Registry<T>::getByName(const std::string name) const
39{
40 typename std::map<const std::string,T*>::const_iterator iter;
41 iter = InstanceMap.find(name);
42 ASSERT(iter!=InstanceMap.end(),"Query for an instance "+name+" not stored in registry");
43 return (iter!=InstanceMap.end()) ? iter->second : NULL;
44}
45
46/** States whether instance is present or not.
47 * \note This is needed as Registry<T>::getByName() ASSERT()s that instance is in std::map.
48 * \param name name of instance
49 * \return true - present, false - instance absent
50 */
51template <class T>bool Registry<T>::isPresentByName(const std::string name) const
52{
53 typename std::map<const std::string,T*>::const_iterator iter;
54 iter = InstanceMap.find(name);
55 return iter!=InstanceMap.end();
56}
57
58/** Registers an instance with the Registry.
59 * \param *instance pointer to T.
60 */
61template <class T>void Registry<T>::registerInstance(T* instance){
62 std::pair<typename std::map<const std::string,T*>::iterator,bool> ret;
63 //std::cout << "Trying to register instance of type " << typeid(T).name() << " with name " << instance->getName() << "." << std::endl;
64 ret = InstanceMap.insert(typename std::pair<const std::string,T*>(instance->getName(),instance));
65 ASSERT(ret.second,"Two instances with the same name "+instance->getName()+" added to registry");
66}
67
68/** Unregisters an instance.
69 * \param *instance pointer to instance.
70 */
71template <class T>void Registry<T>::unregisterInstance(T* instance){
72 //std::cout << "Unregistering instance of type " << typeid(T).name() << " with name " << instance->getName() << "." << std::endl;
73 InstanceMap.erase(instance->getName());
74}
75
76/** Removes every instance from the registry.
77 */
78template <class T>void Registry<T>::cleanup()
79{
80 typename std::map<const std::string,T*>::iterator iter = InstanceMap.begin();
81 for(;!InstanceMap.empty();iter=InstanceMap.begin()) {
82 //std::cerr << "Removing instance "+iter->first+" from registry" << std::endl;
83 T* instance = iter->second;
84 InstanceMap.erase(iter);
85 delete instance;
86 }
87 InstanceMap.clear();
88}
89
90
91/** Returns an iterator pointing to the start of the std::map of instance's.
92 * \return begin iterator
93 */
94template <class T>
95typename std::map<const std::string,T*>::iterator Registry<T>::getBeginIter()
96{
97 return InstanceMap.begin();
98}
99
100/** Returns an iterator pointing to the end of the std::map of instance's.
101 * \return end iterator
102 */
103template <class T>
104typename std::map<const std::string,T*>::iterator Registry<T>::getEndIter()
105{
106 return InstanceMap.end();
107}
108
109/** Returns a const iterator pointing to the start of the std::map of instance's.
110 * \return constant begin iterator
111 */
112template <class T>
113typename std::map<const std::string,T*>::const_iterator Registry<T>::getBeginIter() const
114{
115 return InstanceMap.begin();
116}
117
118/** Returns a const iterator pointing to the end of the std::map of instance's.
119 * \return constant end iterator
120 */
121template <class T>
122typename std::map<const std::string,T*>::const_iterator Registry<T>::getEndIter() const
123{
124 return InstanceMap.end();
125}
126
127/** Prints the contents of the Registry \a &m to \a &ost.
128 * \param &ost output stream
129 * \param &m reference to Registry
130 * \return reference to the above out stream for concatenation
131 */
132template <class T>
133std::ostream& operator<<(std::ostream& ost, const Registry<T>& m)
134{
135 ost << "Registry contains:" << std::endl;
136 for (typename std::map<const std::string,T*>::const_iterator iter = m.getBeginIter(); iter != m.getEndIter(); ++iter) {
137 ost << "\t" << iter->first << " with pointer " << iter->second << std::endl;
138 }
139 return ost;
140};
141
142/**
143 * This define allows simple instantiation of the necessary registryfunctions
144 * at a chosen place.
145 */
146#define CONSTRUCT_REGISTRY(InstanceType) \
147 template InstanceType* Registry<InstanceType>::getByName(const std::string) const; \
148 template bool Registry<InstanceType>::isPresentByName(const std::string) const; \
149 template void Registry<InstanceType>::registerInstance(InstanceType*); \
150 template void Registry<InstanceType>::unregisterInstance(InstanceType*); \
151 template std::map<const std::string,InstanceType*>::iterator Registry<InstanceType>::getBeginIter(); \
152 template std::map<const std::string,InstanceType*>::const_iterator Registry<InstanceType>::getBeginIter() const; \
153 template std::map<const std::string,InstanceType*>::iterator Registry<InstanceType>::getEndIter(); \
154 template std::map<const std::string,InstanceType*>::const_iterator Registry<InstanceType>::getEndIter() const;
155
156
157#endif /* REGISTRY_IMPL_HPP_ */
Note: See TracBrowser for help on using the repository browser.