#ifndef CRYPTOPP_SMARTPTR_H #define CRYPTOPP_SMARTPTR_H #include "config.h" #include "stdcpp.h" #include "trap.h" NAMESPACE_BEGIN(CryptoPP) #if 0 // This must be kept in sync with stdcpp.h because is included based on the same logic. #if ((__cplusplus >= 201103L) || (_MSC_VER >= 1600)) && !defined(__clang__) # include template using auto_ptr = std::unique_ptr; #elif defined(__clang__) # if (__has_include()) # include using std::auto_ptr; # endif #elif (__cplusplus < 201103L) # include using std::auto_ptr; #else # include template using auto_ptr = std::unique_ptr; #endif #endif // 0 template class simple_ptr { public: simple_ptr(T *p = NULL) : m_p(p) {} ~simple_ptr(); public: T *m_p; private: simple_ptr(const simple_ptr& rhs); // copy not allowed void operator=(const simple_ptr& rhs); // assignment not allowed }; #if GCC_OPTIMIZE_AWARE # pragma GCC optimize push_options # pragma GCC optimize ("-O0") #endif // set m_p to NULL so double destruction (which might occur in Singleton) will be harmless template simple_ptr::~simple_ptr() { delete m_p; m_p = NULL; } #if GCC_OPTIMIZE_AWARE # pragma GCC optimize pop_options #endif template class member_ptr { public: explicit member_ptr(T *p = NULL) : 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 = 0; return old_p; } void reset(T *p = 0); protected: T *m_p; private: member_ptr(const member_ptr& rhs); // copy not allowed void operator=(const member_ptr& rhs); // assignment not allowed }; template member_ptr::~member_ptr() {delete m_p;} template void member_ptr::reset(T *p) {delete m_p; m_p = p;} // ******************************************************** template class value_ptr : public member_ptr { public: value_ptr(const T &obj) : member_ptr(new T(obj)) {} value_ptr(T *p = NULL) : member_ptr(p) {} value_ptr(const value_ptr& rhs) : member_ptr(rhs.m_p ? new T(*rhs.m_p) : NULL) {} value_ptr& operator=(const value_ptr& rhs); bool operator==(const value_ptr& rhs) { return (!this->m_p && !rhs.m_p) || (this->m_p && rhs.m_p && *this->m_p == *rhs.m_p); } }; template value_ptr& value_ptr::operator=(const value_ptr& rhs) { if(this != &rhs) { T *old_p = this->m_p; this->m_p = rhs.m_p ? new T(*rhs.m_p) : NULL; delete old_p; } return *this; } // ******************************************************** template class clonable_ptr : public member_ptr { public: clonable_ptr(const T &obj) : member_ptr(obj.Clone()) {} clonable_ptr(T *p = NULL) : member_ptr(p) {} clonable_ptr(const clonable_ptr& rhs) : member_ptr(rhs.m_p ? rhs.m_p->Clone() : NULL) {} clonable_ptr& operator=(const clonable_ptr& rhs); }; template clonable_ptr& clonable_ptr::operator=(const clonable_ptr& rhs) { if(this != &rhs) { T *old_p = this->m_p; this->m_p = rhs.m_p ? rhs.m_p->Clone() : NULL; delete old_p; } return *this; } // ******************************************************** template class counted_ptr { public: explicit counted_ptr(T *p = 0); counted_ptr(const T &r) : m_p(0) {attach(r);} counted_ptr(const counted_ptr& 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 & operator=(const counted_ptr& rhs); protected: T *m_p; }; template counted_ptr::counted_ptr(T *p) : m_p(p) { if (m_p) m_p->m_referenceCount = 1; } template counted_ptr::counted_ptr(const counted_ptr& rhs) : m_p(rhs.m_p) { if (m_p) m_p->m_referenceCount++; } template counted_ptr::~counted_ptr() { if (m_p && --m_p->m_referenceCount == 0) delete m_p; } template void counted_ptr::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(&r); m_p->m_referenceCount++; } } template T* counted_ptr::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 counted_ptr & counted_ptr::operator=(const counted_ptr& rhs) { if(this == &rhs) { return *this; } 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; } // ******************************************************** template class vector_member_ptrs { public: vector_member_ptrs(size_t size=0) : m_size(size), m_ptr(new member_ptr[size]) {} ~vector_member_ptrs() {delete [] this->m_ptr;} member_ptr& operator[](size_t index) {CRYPTOPP_ASSERT(indexm_size); return this->m_ptr[index];} const member_ptr& operator[](size_t index) const {CRYPTOPP_ASSERT(indexm_size); return this->m_ptr[index];} size_t size() const {return this->m_size;} void resize(size_t newSize) { member_ptr *newPtr = new member_ptr[newSize]; for (size_t i=0; im_size && im_ptr[i].release()); delete [] this->m_ptr; this->m_size = newSize; this->m_ptr = newPtr; } private: vector_member_ptrs(const vector_member_ptrs &c); // copy not allowed void operator=(const vector_member_ptrs &x); // assignment not allowed size_t m_size; member_ptr *m_ptr; }; NAMESPACE_END #endif