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-9d2fd5bffc1fpull/1/head
parent
aba91ce95d
commit
1928dc7df7
|
@ -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.
|
|
@ -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
|
|
@ -31,7 +31,7 @@ public:
|
|||
delete ptr;
|
||||
}
|
||||
|
||||
inline T* get()
|
||||
inline T* get() const
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
|
|
@ -7,27 +7,18 @@
|
|||
// ------------------------------
|
||||
// Internal stub
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
namespace array_detail {
|
||||
class controller {
|
||||
|
||||
public:
|
||||
|
||||
controller()
|
||||
: cnt(0)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
controller(T* ptr)
|
||||
: cnt(ptr?1:0)
|
||||
: cnt(1)
|
||||
{}
|
||||
|
||||
public:
|
||||
|
||||
template <typename T>
|
||||
controller* decref(T* pt) {
|
||||
if (!pt) {
|
||||
return NULL;
|
||||
}
|
||||
if (--cnt <= 0) {
|
||||
delete this;
|
||||
delete[] pt;
|
||||
|
@ -94,39 +85,61 @@ public:
|
|||
// provide a default constructor
|
||||
shared_array()
|
||||
: ptr()
|
||||
, ctr(new detail::controller())
|
||||
, ctr(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
// construction from an existing object of type T
|
||||
explicit shared_array(T* _ptr)
|
||||
: ptr(_ptr)
|
||||
, ctr(new detail::controller(ptr))
|
||||
explicit shared_array(T* ptr)
|
||||
: ptr(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>
|
||||
shared_array(const shared_array<Y>& o,typename detail::is_convertible<T,Y>::result = detail::empty())
|
||||
: ptr(o.ptr)
|
||||
, ctr(o.ctr->incref())
|
||||
shared_array(const shared_array<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty())
|
||||
: ptr(r.ptr)
|
||||
, 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
|
||||
// references are freed.
|
||||
~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
|
||||
|
@ -134,12 +147,20 @@ public:
|
|||
return ptr;
|
||||
}
|
||||
|
||||
inline T* operator-> () {
|
||||
inline T* operator-> () const {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -156,11 +177,11 @@ public:
|
|||
}
|
||||
|
||||
inline void reset (T* t = 0) {
|
||||
ctr = ctr->decref(ptr);
|
||||
ptr = t;
|
||||
if(ptr) {
|
||||
ctr = new detail::controller(ptr);
|
||||
if (ctr) {
|
||||
ctr->decref(ptr);
|
||||
}
|
||||
ptr = t;
|
||||
ctr = ptr?new array_detail::controller():NULL;
|
||||
}
|
||||
|
||||
void swap(shared_array & b) {
|
||||
|
@ -168,13 +189,14 @@ public:
|
|||
std::swap(ctr, b.ctr);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// encapsulated object pointer
|
||||
T* ptr;
|
||||
|
||||
// control block
|
||||
detail::controller* ctr;
|
||||
array_detail::controller* ctr;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
|
|
|
@ -9,25 +9,16 @@
|
|||
namespace boost {
|
||||
namespace detail {
|
||||
class controller {
|
||||
|
||||
public:
|
||||
|
||||
controller()
|
||||
: cnt(0)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
controller(T* ptr)
|
||||
: cnt(ptr?1:0)
|
||||
: cnt(1)
|
||||
{}
|
||||
|
||||
public:
|
||||
|
||||
template <typename T>
|
||||
controller* decref(T* pt) {
|
||||
if (!pt) {
|
||||
return NULL;
|
||||
}
|
||||
if (--cnt <= 0) {
|
||||
delete this;
|
||||
delete pt;
|
||||
|
@ -81,6 +72,10 @@ 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);
|
||||
|
@ -94,38 +89,61 @@ public:
|
|||
// provide a default constructor
|
||||
shared_ptr()
|
||||
: ptr()
|
||||
, ctr(new detail::controller())
|
||||
, ctr(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
// construction from an existing object of type T
|
||||
explicit shared_ptr(T* _ptr)
|
||||
: ptr(_ptr)
|
||||
, ctr(new detail::controller(ptr))
|
||||
explicit shared_ptr(T* ptr)
|
||||
: ptr(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>
|
||||
shared_ptr(const shared_ptr<Y>& o,typename detail::is_convertible<T,Y>::result = detail::empty())
|
||||
: ptr(o.ptr)
|
||||
, ctr(o.ctr->incref())
|
||||
shared_ptr(const shared_ptr<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty())
|
||||
: ptr(r.ptr)
|
||||
, 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
|
||||
// references are freed.
|
||||
~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
|
||||
|
@ -133,12 +151,16 @@ public:
|
|||
return ptr;
|
||||
}
|
||||
|
||||
inline T* operator-> () {
|
||||
inline T* operator-> () const {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
// standard semantics
|
||||
inline T* get() {
|
||||
inline T* get() {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
inline const T* get() const {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
@ -155,11 +177,11 @@ public:
|
|||
}
|
||||
|
||||
inline void reset (T* t = 0) {
|
||||
ctr = ctr->decref(ptr);
|
||||
ptr = t;
|
||||
if(ptr) {
|
||||
ctr = new detail::controller(ptr);
|
||||
if (ctr) {
|
||||
ctr->decref(ptr);
|
||||
}
|
||||
ptr = t;
|
||||
ctr = ptr?new detail::controller():NULL;
|
||||
}
|
||||
|
||||
void swap(shared_ptr & b) {
|
||||
|
@ -167,6 +189,16 @@ public:
|
|||
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:
|
||||
|
||||
// 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
|
||||
|
||||
#else
|
||||
|
|
Loading…
Reference in New Issue