fix shared_ptr and shared_array implementation. add pointer_cast facility.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@716 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
aramis_acg 2010-05-10 10:18:54 +00:00
parent aba91ce95d
commit 1928dc7df7
5 changed files with 214 additions and 72 deletions

View File

@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,45 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2005.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_POINTER_CAST_HPP
#define BOOST_POINTER_CAST_HPP
namespace boost {
//static_pointer_cast overload for raw pointers
template<class T, class U>
inline T* static_pointer_cast(U *ptr)
{
return static_cast<T*>(ptr);
}
//dynamic_pointer_cast overload for raw pointers
template<class T, class U>
inline T* dynamic_pointer_cast(U *ptr)
{
return dynamic_cast<T*>(ptr);
}
//const_pointer_cast overload for raw pointers
template<class T, class U>
inline T* const_pointer_cast(U *ptr)
{
return const_cast<T*>(ptr);
}
//reinterpret_pointer_cast overload for raw pointers
template<class T, class U>
inline T* reinterpret_pointer_cast(U *ptr)
{
return reinterpret_cast<T*>(ptr);
}
} // namespace boost
#endif //BOOST_POINTER_CAST_HPP

View File

@ -31,7 +31,7 @@ public:
delete ptr; delete ptr;
} }
inline T* get() inline T* get() const
{ {
return ptr; return ptr;
} }

View File

@ -7,27 +7,18 @@
// ------------------------------ // ------------------------------
// Internal stub // Internal stub
namespace boost { namespace boost {
namespace detail { namespace array_detail {
class controller { class controller {
public: public:
controller() controller()
: cnt(0) : cnt(1)
{}
template <typename T>
controller(T* ptr)
: cnt(ptr?1:0)
{} {}
public: public:
template <typename T> template <typename T>
controller* decref(T* pt) { controller* decref(T* pt) {
if (!pt) {
return NULL;
}
if (--cnt <= 0) { if (--cnt <= 0) {
delete this; delete this;
delete[] pt; delete[] pt;
@ -94,39 +85,61 @@ public:
// provide a default constructor // provide a default constructor
shared_array() shared_array()
: ptr() : ptr()
, ctr(new detail::controller()) , ctr(NULL)
{ {
} }
// construction from an existing object of type T // construction from an existing object of type T
explicit shared_array(T* _ptr) explicit shared_array(T* ptr)
: ptr(_ptr) : ptr(ptr)
, ctr(new detail::controller(ptr)) , ctr(ptr ? new array_detail::controller() : NULL)
{
}
shared_array(const shared_array& r)
: ptr(r.ptr)
, ctr(r.ctr ? r.ctr->incref() : NULL)
{ {
} }
template <typename Y> template <typename Y>
shared_array(const shared_array<Y>& o,typename detail::is_convertible<T,Y>::result = detail::empty()) shared_array(const shared_array<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty())
: ptr(o.ptr) : ptr(r.ptr)
, ctr(o.ctr->incref()) , ctr(r.ctr ? r.ctr->incref() : NULL)
{ {
} }
shared_array& operator= (const shared_array& r) {
if(r == *this) {
return *this;
}
ctr->decref(ptr);
ctr = r.ctr->incref();
ptr = r.ptr;
return *this;
}
// automatic destruction of the wrapped object when all // automatic destruction of the wrapped object when all
// references are freed. // references are freed.
~shared_array() { ~shared_array() {
ctr = ctr->decref(ptr); if (ctr) {
ctr = ctr->decref(ptr);
}
}
shared_array& operator=(const shared_array& r) {
if (this == &r) {
return *this;
}
if (ctr) {
ctr->decref(ptr);
}
ptr = r.ptr;
ctr = ptr?r.ctr->incref():NULL;
return *this;
}
template <typename Y>
shared_array& operator=(const shared_array<Y>& r) {
if (this == &r) {
return *this;
}
if (ctr) {
ctr->decref(ptr);
}
ptr = r.ptr;
ctr = ptr?r.ctr->incref():NULL;
return *this;
} }
// pointer access // pointer access
@ -134,12 +147,20 @@ public:
return ptr; return ptr;
} }
inline T* operator-> () { inline T* operator-> () const {
return ptr; return ptr;
} }
// standard semantics // standard semantics
inline T* get() { inline T* get() {
return ptr;
}
T& operator[] (std::ptrdiff_t index) const {
return ptr[index];
}
inline const T* get() const {
return ptr; return ptr;
} }
@ -156,11 +177,11 @@ public:
} }
inline void reset (T* t = 0) { inline void reset (T* t = 0) {
ctr = ctr->decref(ptr); if (ctr) {
ptr = t; ctr->decref(ptr);
if(ptr) {
ctr = new detail::controller(ptr);
} }
ptr = t;
ctr = ptr?new array_detail::controller():NULL;
} }
void swap(shared_array & b) { void swap(shared_array & b) {
@ -168,13 +189,14 @@ public:
std::swap(ctr, b.ctr); std::swap(ctr, b.ctr);
} }
private: private:
// encapsulated object pointer // encapsulated object pointer
T* ptr; T* ptr;
// control block // control block
detail::controller* ctr; array_detail::controller* ctr;
}; };
template<class T> template<class T>

View File

@ -9,25 +9,16 @@
namespace boost { namespace boost {
namespace detail { namespace detail {
class controller { class controller {
public: public:
controller() controller()
: cnt(0) : cnt(1)
{}
template <typename T>
controller(T* ptr)
: cnt(ptr?1:0)
{} {}
public: public:
template <typename T> template <typename T>
controller* decref(T* pt) { controller* decref(T* pt) {
if (!pt) {
return NULL;
}
if (--cnt <= 0) { if (--cnt <= 0) {
delete this; delete this;
delete pt; delete pt;
@ -81,6 +72,10 @@ class shared_ptr
{ {
template <typename TT> friend class shared_ptr; template <typename TT> friend class shared_ptr;
template<class TT, class U> friend shared_ptr<TT> static_pointer_cast (shared_ptr<U> ptr);
template<class TT, class U> friend shared_ptr<TT> dynamic_pointer_cast (shared_ptr<U> ptr);
template<class TT, class U> friend shared_ptr<TT> const_pointer_cast (shared_ptr<U> ptr);
template<class TT> friend bool operator== (const shared_ptr<TT>& a, const shared_ptr<TT>& b); template<class TT> friend bool operator== (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
template<class TT> friend bool operator!= (const shared_ptr<TT>& a, const shared_ptr<TT>& b); template<class TT> friend bool operator!= (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
template<class TT> friend bool operator< (const shared_ptr<TT>& a, const shared_ptr<TT>& b); template<class TT> friend bool operator< (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
@ -94,38 +89,61 @@ public:
// provide a default constructor // provide a default constructor
shared_ptr() shared_ptr()
: ptr() : ptr()
, ctr(new detail::controller()) , ctr(NULL)
{ {
} }
// construction from an existing object of type T // construction from an existing object of type T
explicit shared_ptr(T* _ptr) explicit shared_ptr(T* ptr)
: ptr(_ptr) : ptr(ptr)
, ctr(new detail::controller(ptr)) , ctr(ptr ? new detail::controller() : NULL)
{
}
shared_ptr(const shared_ptr& r)
: ptr(r.ptr)
, ctr(r.ctr ? r.ctr->incref() : NULL)
{ {
} }
template <typename Y> template <typename Y>
shared_ptr(const shared_ptr<Y>& o,typename detail::is_convertible<T,Y>::result = detail::empty()) shared_ptr(const shared_ptr<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty())
: ptr(o.ptr) : ptr(r.ptr)
, ctr(o.ctr->incref()) , ctr(r.ctr ? r.ctr->incref() : NULL)
{ {
} }
shared_ptr& operator= (const shared_ptr& r) {
if(r == *this) {
return *this;
}
ctr->decref(ptr);
ctr = r.ctr->incref();
ptr = r.ptr;
return *this;
}
// automatic destruction of the wrapped object when all // automatic destruction of the wrapped object when all
// references are freed. // references are freed.
~shared_ptr() { ~shared_ptr() {
ctr = ctr->decref(ptr); if (ctr) {
ctr = ctr->decref(ptr);
}
}
shared_ptr& operator=(const shared_ptr& r) {
if (this == &r) {
return *this;
}
if (ctr) {
ctr->decref(ptr);
}
ptr = r.ptr;
ctr = ptr?r.ctr->incref():NULL;
return *this;
}
template <typename Y>
shared_ptr& operator=(const shared_ptr<Y>& r) {
if (this == &r) {
return *this;
}
if (ctr) {
ctr->decref(ptr);
}
ptr = r.ptr;
ctr = ptr?r.ctr->incref():NULL;
return *this;
} }
// pointer access // pointer access
@ -133,12 +151,16 @@ public:
return ptr; return ptr;
} }
inline T* operator-> () { inline T* operator-> () const {
return ptr; return ptr;
} }
// standard semantics // standard semantics
inline T* get() { inline T* get() {
return ptr;
}
inline const T* get() const {
return ptr; return ptr;
} }
@ -155,11 +177,11 @@ public:
} }
inline void reset (T* t = 0) { inline void reset (T* t = 0) {
ctr = ctr->decref(ptr); if (ctr) {
ptr = t; ctr->decref(ptr);
if(ptr) {
ctr = new detail::controller(ptr);
} }
ptr = t;
ctr = ptr?new detail::controller():NULL;
} }
void swap(shared_ptr & b) { void swap(shared_ptr & b) {
@ -167,6 +189,16 @@ public:
std::swap(ctr, b.ctr); std::swap(ctr, b.ctr);
} }
private:
// for use by the various xxx_pointer_cast helper templates
explicit shared_ptr(T* ptr, detail::controller* ctr)
: ptr(ptr)
, ctr(ctr->incref())
{
}
private: private:
// encapsulated object pointer // encapsulated object pointer
@ -197,6 +229,26 @@ bool operator< (const shared_ptr<T>& a, const shared_ptr<T>& b) {
} }
template<class T, class U>
inline shared_ptr<T> static_pointer_cast( shared_ptr<U> ptr)
{
return shared_ptr<T>(static_cast<T*>(ptr.ptr),ptr.ctr);
}
template<class T, class U>
inline shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> ptr)
{
return shared_ptr<T>(dynamic_cast<T*>(ptr.ptr),ptr.ctr);
}
template<class T, class U>
inline shared_ptr<T> const_pointer_cast( shared_ptr<U> ptr)
{
return shared_ptr<T>(const_cast<T*>(ptr.ptr),ptr.ctr);
}
} // end of namespace boost } // end of namespace boost
#else #else