123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- // smartptr.h - originally written and placed in the public domain by Wei Dai
- /// \file smartptr.h
- /// \brief Classes for automatic resource management
- #ifndef CRYPTOPP_SMARTPTR_H
- #define CRYPTOPP_SMARTPTR_H
- #include "config.h"
- #include "stdcpp.h"
- NAMESPACE_BEGIN(CryptoPP)
- /// \brief Manages resources for a single object
- /// \tparam T class or type
- /// \details \p simple_ptr is used frequently in the library to manage resources and
- /// ensure cleanup under the RAII pattern (Resource Acquisition Is Initialization).
- template <class T> class simple_ptr
- {
- public:
- simple_ptr(T *p = NULLPTR) : m_p(p) {}
- ~simple_ptr()
- {
- delete m_p;
- m_p = NULLPTR;
- }
- T *m_p;
- };
- /// \brief Pointer that overloads operator ->
- /// \tparam T class or type
- /// \details member_ptr is used frequently in the library to avoid the issues related to
- /// std::auto_ptr in C++11 (deprecated) and std::unique_ptr in C++03 (non-existent).
- /// \bug <a href="http://github.com/weidai11/cryptopp/issues/48">Issue 48: "Use of auto_ptr
- /// causes dirty compile under C++11"</a>
- template <class T> class member_ptr
- {
- public:
- explicit member_ptr(T *p = NULLPTR) : m_p(p) {}
- ~member_ptr();
- const T& operator*() const { return *m_p; }
- T& operator*() { return *m_p; }
- const T* operator->() const { return m_p; }
- T* operator->() { return m_p; }
- const T* get() const { return m_p; }
- T* get() { return m_p; }
- T* release()
- {
- T *old_p = m_p;
- m_p = NULLPTR;
- return old_p;
- }
- void reset(T *p = NULLPTR);
- protected:
- member_ptr(const member_ptr<T>& rhs); // copy not allowed
- void operator=(const member_ptr<T>& rhs); // assignment not allowed
- T *m_p;
- };
- template <class T> member_ptr<T>::~member_ptr() {delete m_p;}
- template <class T> void member_ptr<T>::reset(T *p) {delete m_p; m_p = p;}
- // ********************************************************
- /// \brief Value pointer
- /// \tparam T class or type
- template<class T> class value_ptr : public member_ptr<T>
- {
- public:
- value_ptr(const T &obj) : member_ptr<T>(new T(obj)) {}
- value_ptr(T *p = NULLPTR) : member_ptr<T>(p) {}
- value_ptr(const value_ptr<T>& rhs)
- : member_ptr<T>(rhs.m_p ? new T(*rhs.m_p) : NULLPTR) {}
- value_ptr<T>& operator=(const value_ptr<T>& rhs);
- bool operator==(const value_ptr<T>& rhs)
- {
- return (!this->m_p && !rhs.m_p) || (this->m_p && rhs.m_p && *this->m_p == *rhs.m_p);
- }
- };
- template <class T> value_ptr<T>& value_ptr<T>::operator=(const value_ptr<T>& rhs)
- {
- T *old_p = this->m_p;
- this->m_p = rhs.m_p ? new T(*rhs.m_p) : NULLPTR;
- delete old_p;
- return *this;
- }
- // ********************************************************
- /// \brief A pointer which can be copied and cloned
- /// \tparam T class or type
- /// \details \p T should adhere to the \p Clonable interface
- template<class T> class clonable_ptr : public member_ptr<T>
- {
- public:
- clonable_ptr(const T &obj) : member_ptr<T>(obj.Clone()) {}
- clonable_ptr(T *p = NULLPTR) : member_ptr<T>(p) {}
- clonable_ptr(const clonable_ptr<T>& rhs)
- : member_ptr<T>(rhs.m_p ? rhs.m_p->Clone() : NULLPTR) {}
- clonable_ptr<T>& operator=(const clonable_ptr<T>& rhs);
- };
- template <class T> clonable_ptr<T>& clonable_ptr<T>::operator=(const clonable_ptr<T>& rhs)
- {
- T *old_p = this->m_p;
- this->m_p = rhs.m_p ? rhs.m_p->Clone() : NULLPTR;
- delete old_p;
- return *this;
- }
- // ********************************************************
- /// \brief Reference counted pointer
- /// \tparam T class or type
- /// \details users should declare \p m_referenceCount as <tt>std::atomic<unsigned></tt>
- /// (or similar) under C++ 11
- template<class T> class counted_ptr
- {
- public:
- explicit counted_ptr(T *p = NULLPTR);
- counted_ptr(const T &r) : m_p(0) {attach(r);}
- counted_ptr(const counted_ptr<T>& rhs);
- ~counted_ptr();
- const T& operator*() const { return *m_p; }
- T& operator*() { return *m_p; }
- const T* operator->() const { return m_p; }
- T* operator->() { return get(); }
- const T* get() const { return m_p; }
- T* get();
- void attach(const T &p);
- counted_ptr<T> & operator=(const counted_ptr<T>& rhs);
- private:
- T *m_p;
- };
- template <class T> counted_ptr<T>::counted_ptr(T *p)
- : m_p(p)
- {
- if (m_p)
- m_p->m_referenceCount = 1;
- }
- template <class T> counted_ptr<T>::counted_ptr(const counted_ptr<T>& rhs)
- : m_p(rhs.m_p)
- {
- if (m_p)
- m_p->m_referenceCount++;
- }
- template <class T> counted_ptr<T>::~counted_ptr()
- {
- if (m_p && --m_p->m_referenceCount == 0)
- delete m_p;
- }
- template <class T> void counted_ptr<T>::attach(const T &r)
- {
- if (m_p && --m_p->m_referenceCount == 0)
- delete m_p;
- if (r.m_referenceCount == 0)
- {
- m_p = r.clone();
- m_p->m_referenceCount = 1;
- }
- else
- {
- m_p = const_cast<T *>(&r);
- m_p->m_referenceCount++;
- }
- }
- template <class T> T* counted_ptr<T>::get()
- {
- if (m_p && m_p->m_referenceCount > 1)
- {
- T *temp = m_p->clone();
- m_p->m_referenceCount--;
- m_p = temp;
- m_p->m_referenceCount = 1;
- }
- return m_p;
- }
- template <class T> counted_ptr<T> & counted_ptr<T>::operator=(const counted_ptr<T>& rhs)
- {
- if (m_p != rhs.m_p)
- {
- if (m_p && --m_p->m_referenceCount == 0)
- delete m_p;
- m_p = rhs.m_p;
- if (m_p)
- m_p->m_referenceCount++;
- }
- return *this;
- }
- // ********************************************************
- /// \brief Manages resources for an array of objects
- /// \tparam T class or type
- template <class T> class vector_member_ptrs
- {
- public:
- /// Construct an array of \p T
- /// \param size the size of the array, in elements
- /// \details If \p T is a Plain Old Dataype (POD), then the array is uninitialized.
- vector_member_ptrs(size_t size=0)
- : m_size(size), m_ptr(new member_ptr<T>[size]) {}
- ~vector_member_ptrs()
- {delete [] this->m_ptr;}
- member_ptr<T>& operator[](size_t index)
- {CRYPTOPP_ASSERT(index<this->m_size); return this->m_ptr[index];}
- const member_ptr<T>& operator[](size_t index) const
- {CRYPTOPP_ASSERT(index<this->m_size); return this->m_ptr[index];}
- size_t size() const {return this->m_size;}
- void resize(size_t newSize)
- {
- member_ptr<T> *newPtr = new member_ptr<T>[newSize];
- for (size_t i=0; i<this->m_size && i<newSize; i++)
- newPtr[i].reset(this->m_ptr[i].release());
- delete [] this->m_ptr;
- this->m_size = newSize;
- this->m_ptr = newPtr;
- }
- private:
- vector_member_ptrs(const vector_member_ptrs<T> &c); // copy not allowed
- void operator=(const vector_member_ptrs<T> &x); // assignment not allowed
- size_t m_size;
- member_ptr<T> *m_ptr;
- };
- NAMESPACE_END
- #endif
|