1 /*------------------------------------------------------------------------------
2 Name: ReferenceHolder.h
3 Project: xmlBlaster.org
4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
5 Comment: Entry Holder to use with stl containers as containers of references
6 Version: $Id: ReferenceHolder.h 13505 2005-07-20 16:22:14Z ruff $
7 ------------------------------------------------------------------------------*/
8
9 #ifndef _UTIL_REFERENCEHOLDER_H
10 #define _UTIL_REFERENCEHOLDER_H
11
12 #include <util/XmlBCfg.h>
13 //
14
15 namespace org { namespace xmlBlaster { namespace util {
16
17 /**
18 * Normally stl containers store values, i.e. if you pass an entry to a container, the entry is first
19 * copied and then put into the container. When you retrieve the entry it is copied again. In cases you
20 * want to allocate the objects outside the container and store the references of such objects in the
21 * container (i.e. the container is not the owner of the object), you could use pointers. The drawback of
22 * using pointers however is that you loose the comparison operator. This class allows you to store the
23 * objects as references and at the same time maintains the correct comparison between entries in the
24 * container.
25 * @author <a href="mailto:laghi@swissinfo.org">Michele Laghi</a>
26 */
27
28 template <class T> class Dll_Export ReferenceHolder
29 {
30 private:
31 T* element_;
32
33 void init() const
34 {
35 if (!element_) return;
36 // if (!element_->isShareable()) {
37 // element_ = new T(*element_);
38 // throw an exception here since the class could have virtual methods.
39 // }
40 element_->addReference();
41 }
42
43
44 public:
45
46 ReferenceHolder(T* el)
47 {
48 element_ = el;
49 init();
50 }
51
52 ReferenceHolder(T& el) : element_(&el)
53 {
54 init();
55 }
56
57 ReferenceHolder(const ReferenceHolder& refHolder)
58 : element_(refHolder.element_)
59 {
60 init();
61 }
62
63 ReferenceHolder& operator =(const ReferenceHolder& refHolder)
64 {
65 if (element_ != refHolder.element_) {
66 if (element_) element_->removeReference();
67 element_ = refHolder.element_;
68 init();
69 }
70 return *this;
71 }
72
73
74 ~ReferenceHolder()
75 {
76 if (element_) element_->removeReference();
77 }
78
79
80 T& operator *() const
81 {
82 return *element_;
83 }
84
85 T* operator->() const
86 {
87 return element_;
88 }
89
90 T* getElement() const
91 {
92 return element_;
93 }
94
95 bool isNull() const
96 {
97 return element_ == 0;
98 }
99
100 bool operator ==(const ReferenceHolder<T> other) const
101 {
102 return *element_ == *other.element_;
103 }
104
105 bool operator <(const ReferenceHolder<T> other) const
106 {
107 return *element_ < *other.element_;
108 }
109
110 /*
111 bool operator >(const ReferenceHolder<T> other) const
112 {
113 return !(this->operator<(other)) && !(this->operator==(other));
114 }
115 */
116
117 bool operator >(const ReferenceHolder<T> other) const
118 {
119 return !(*element_ < *other.element_) && !(*element_ == *other.element_);
120 }
121
122 // friend bool operator== (const ReferenceHolder<T>& lhs, const ReferenceHolder<T>& rhs);
123
124 // friend bool operator< (const ReferenceHolder<T>& lhs, const ReferenceHolder<T>& rhs);
125
126 };
127
128 /*
129 template <class T>
130 inline bool operator== (const ReferenceHolder<T>& lhs, const ReferenceHolder<T>& rhs)
131 {
132 return *lhs.element_ == *rhs.element_;
133 }
134
135 template <class T>
136 inline bool operator< (const ReferenceHolder<T>& lhs, const ReferenceHolder<T>& rhs)
137 {
138 return *lhs.element_ < *rhs.element_;
139 }
140 */
141
142 }}} // namespace
143
144 #endif
syntax highlighted by Code2HTML, v. 0.9.1