Bugfix: avoid sub-cent change (lost in fees) whenever possible
[bitcoin.git] / cryptopp / smartptr.h
blob6b4040e9996015e06e1575f72825952bfc376261
1 #ifndef CRYPTOPP_SMARTPTR_H
2 #define CRYPTOPP_SMARTPTR_H
4 #include "config.h"
5 #include <algorithm>
7 NAMESPACE_BEGIN(CryptoPP)
9 template <class T> class simple_ptr
11 public:
12 simple_ptr() : m_p(NULL) {}
13 ~simple_ptr() {delete m_p;}
14 T *m_p;
17 template <class T> class member_ptr
19 public:
20 explicit member_ptr(T *p = NULL) : m_p(p) {}
22 ~member_ptr();
24 const T& operator*() const { return *m_p; }
25 T& operator*() { return *m_p; }
27 const T* operator->() const { return m_p; }
28 T* operator->() { return m_p; }
30 const T* get() const { return m_p; }
31 T* get() { return m_p; }
33 T* release()
35 T *old_p = m_p;
36 m_p = 0;
37 return old_p;
40 void reset(T *p = 0);
42 protected:
43 member_ptr(const member_ptr<T>& rhs); // copy not allowed
44 void operator=(const member_ptr<T>& rhs); // assignment not allowed
46 T *m_p;
49 template <class T> member_ptr<T>::~member_ptr() {delete m_p;}
50 template <class T> void member_ptr<T>::reset(T *p) {delete m_p; m_p = p;}
52 // ********************************************************
54 template<class T> class value_ptr : public member_ptr<T>
56 public:
57 value_ptr(const T &obj) : member_ptr<T>(new T(obj)) {}
58 value_ptr(T *p = NULL) : member_ptr<T>(p) {}
59 value_ptr(const value_ptr<T>& rhs)
60 : member_ptr<T>(rhs.m_p ? new T(*rhs.m_p) : NULL) {}
62 value_ptr<T>& operator=(const value_ptr<T>& rhs);
63 bool operator==(const value_ptr<T>& rhs)
65 return (!this->m_p && !rhs.m_p) || (this->m_p && rhs.m_p && *this->m_p == *rhs.m_p);
69 template <class T> value_ptr<T>& value_ptr<T>::operator=(const value_ptr<T>& rhs)
71 T *old_p = this->m_p;
72 this->m_p = rhs.m_p ? new T(*rhs.m_p) : NULL;
73 delete old_p;
74 return *this;
77 // ********************************************************
79 template<class T> class clonable_ptr : public member_ptr<T>
81 public:
82 clonable_ptr(const T &obj) : member_ptr<T>(obj.Clone()) {}
83 clonable_ptr(T *p = NULL) : member_ptr<T>(p) {}
84 clonable_ptr(const clonable_ptr<T>& rhs)
85 : member_ptr<T>(rhs.m_p ? rhs.m_p->Clone() : NULL) {}
87 clonable_ptr<T>& operator=(const clonable_ptr<T>& rhs);
90 template <class T> clonable_ptr<T>& clonable_ptr<T>::operator=(const clonable_ptr<T>& rhs)
92 T *old_p = this->m_p;
93 this->m_p = rhs.m_p ? rhs.m_p->Clone() : NULL;
94 delete old_p;
95 return *this;
98 // ********************************************************
100 template<class T> class counted_ptr
102 public:
103 explicit counted_ptr(T *p = 0);
104 counted_ptr(const T &r) : m_p(0) {attach(r);}
105 counted_ptr(const counted_ptr<T>& rhs);
107 ~counted_ptr();
109 const T& operator*() const { return *m_p; }
110 T& operator*() { return *m_p; }
112 const T* operator->() const { return m_p; }
113 T* operator->() { return get(); }
115 const T* get() const { return m_p; }
116 T* get();
118 void attach(const T &p);
120 counted_ptr<T> & operator=(const counted_ptr<T>& rhs);
122 private:
123 T *m_p;
126 template <class T> counted_ptr<T>::counted_ptr(T *p)
127 : m_p(p)
129 if (m_p)
130 m_p->m_referenceCount = 1;
133 template <class T> counted_ptr<T>::counted_ptr(const counted_ptr<T>& rhs)
134 : m_p(rhs.m_p)
136 if (m_p)
137 m_p->m_referenceCount++;
140 template <class T> counted_ptr<T>::~counted_ptr()
142 if (m_p && --m_p->m_referenceCount == 0)
143 delete m_p;
146 template <class T> void counted_ptr<T>::attach(const T &r)
148 if (m_p && --m_p->m_referenceCount == 0)
149 delete m_p;
150 if (r.m_referenceCount == 0)
152 m_p = r.clone();
153 m_p->m_referenceCount = 1;
155 else
157 m_p = const_cast<T *>(&r);
158 m_p->m_referenceCount++;
162 template <class T> T* counted_ptr<T>::get()
164 if (m_p && m_p->m_referenceCount > 1)
166 T *temp = m_p->clone();
167 m_p->m_referenceCount--;
168 m_p = temp;
169 m_p->m_referenceCount = 1;
171 return m_p;
174 template <class T> counted_ptr<T> & counted_ptr<T>::operator=(const counted_ptr<T>& rhs)
176 if (m_p != rhs.m_p)
178 if (m_p && --m_p->m_referenceCount == 0)
179 delete m_p;
180 m_p = rhs.m_p;
181 if (m_p)
182 m_p->m_referenceCount++;
184 return *this;
187 // ********************************************************
189 template <class T> class vector_member_ptrs
191 public:
192 vector_member_ptrs(size_t size=0)
193 : m_size(size), m_ptr(new member_ptr<T>[size]) {}
194 ~vector_member_ptrs()
195 {delete [] this->m_ptr;}
197 member_ptr<T>& operator[](size_t index)
198 {assert(index<this->m_size); return this->m_ptr[index];}
199 const member_ptr<T>& operator[](size_t index) const
200 {assert(index<this->m_size); return this->m_ptr[index];}
202 size_t size() const {return this->m_size;}
203 void resize(size_t newSize)
205 member_ptr<T> *newPtr = new member_ptr<T>[newSize];
206 for (size_t i=0; i<this->m_size && i<newSize; i++)
207 newPtr[i].reset(this->m_ptr[i].release());
208 delete [] this->m_ptr;
209 this->m_size = newSize;
210 this->m_ptr = newPtr;
213 private:
214 vector_member_ptrs(const vector_member_ptrs<T> &c); // copy not allowed
215 void operator=(const vector_member_ptrs<T> &x); // assignment not allowed
217 size_t m_size;
218 member_ptr<T> *m_ptr;
221 NAMESPACE_END
223 #endif