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