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;
|
delete ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T* get()
|
inline T* get() const
|
||||||
{
|
{
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue