From 1928dc7df75a2417975056e83a2e7170026cac87 Mon Sep 17 00:00:00 2001 From: aramis_acg Date: Mon, 10 May 2010 10:18:54 +0000 Subject: [PATCH] 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 --- code/BoostWorkaround/boost/LICENSE_1_0.txt | 23 ++++ code/BoostWorkaround/boost/pointer_cast.hpp | 45 ++++++++ code/BoostWorkaround/boost/scoped_ptr.hpp | 2 +- code/BoostWorkaround/boost/shared_array.hpp | 96 ++++++++++------ code/BoostWorkaround/boost/shared_ptr.hpp | 120 ++++++++++++++------ 5 files changed, 214 insertions(+), 72 deletions(-) create mode 100644 code/BoostWorkaround/boost/LICENSE_1_0.txt create mode 100644 code/BoostWorkaround/boost/pointer_cast.hpp diff --git a/code/BoostWorkaround/boost/LICENSE_1_0.txt b/code/BoostWorkaround/boost/LICENSE_1_0.txt new file mode 100644 index 000000000..30aac2cf4 --- /dev/null +++ b/code/BoostWorkaround/boost/LICENSE_1_0.txt @@ -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. \ No newline at end of file diff --git a/code/BoostWorkaround/boost/pointer_cast.hpp b/code/BoostWorkaround/boost/pointer_cast.hpp new file mode 100644 index 000000000..1083f599e --- /dev/null +++ b/code/BoostWorkaround/boost/pointer_cast.hpp @@ -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 +inline T* static_pointer_cast(U *ptr) +{ + return static_cast(ptr); +} + +//dynamic_pointer_cast overload for raw pointers +template +inline T* dynamic_pointer_cast(U *ptr) +{ + return dynamic_cast(ptr); +} + +//const_pointer_cast overload for raw pointers +template +inline T* const_pointer_cast(U *ptr) +{ + return const_cast(ptr); +} + +//reinterpret_pointer_cast overload for raw pointers +template +inline T* reinterpret_pointer_cast(U *ptr) +{ + return reinterpret_cast(ptr); +} + +} // namespace boost + +#endif //BOOST_POINTER_CAST_HPP diff --git a/code/BoostWorkaround/boost/scoped_ptr.hpp b/code/BoostWorkaround/boost/scoped_ptr.hpp index 8f4bde3fc..615db640d 100644 --- a/code/BoostWorkaround/boost/scoped_ptr.hpp +++ b/code/BoostWorkaround/boost/scoped_ptr.hpp @@ -31,7 +31,7 @@ public: delete ptr; } - inline T* get() + inline T* get() const { return ptr; } diff --git a/code/BoostWorkaround/boost/shared_array.hpp b/code/BoostWorkaround/boost/shared_array.hpp index eb6501565..47bb4cf6f 100644 --- a/code/BoostWorkaround/boost/shared_array.hpp +++ b/code/BoostWorkaround/boost/shared_array.hpp @@ -7,27 +7,18 @@ // ------------------------------ // Internal stub namespace boost { - namespace detail { + namespace array_detail { class controller { - public: controller() - : cnt(0) - {} - - template - controller(T* ptr) - : cnt(ptr?1:0) + : cnt(1) {} public: template 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 - shared_array(const shared_array& o,typename detail::is_convertible::result = detail::empty()) - : ptr(o.ptr) - , ctr(o.ctr->incref()) + shared_array(const shared_array& r,typename detail::is_convertible::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 + 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; } // 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 diff --git a/code/BoostWorkaround/boost/shared_ptr.hpp b/code/BoostWorkaround/boost/shared_ptr.hpp index 6069ca101..daf5a1b68 100644 --- a/code/BoostWorkaround/boost/shared_ptr.hpp +++ b/code/BoostWorkaround/boost/shared_ptr.hpp @@ -9,25 +9,16 @@ namespace boost { namespace detail { class controller { - public: controller() - : cnt(0) - {} - - template - controller(T* ptr) - : cnt(ptr?1:0) + : cnt(1) {} public: template controller* decref(T* pt) { - if (!pt) { - return NULL; - } if (--cnt <= 0) { delete this; delete pt; @@ -81,6 +72,10 @@ class shared_ptr { template friend class shared_ptr; + template friend shared_ptr static_pointer_cast (shared_ptr ptr); + template friend shared_ptr dynamic_pointer_cast (shared_ptr ptr); + template friend shared_ptr const_pointer_cast (shared_ptr ptr); + template friend bool operator== (const shared_ptr& a, const shared_ptr& b); template friend bool operator!= (const shared_ptr& a, const shared_ptr& b); template friend bool operator< (const shared_ptr& a, const shared_ptr& 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 - shared_ptr(const shared_ptr& o,typename detail::is_convertible::result = detail::empty()) - : ptr(o.ptr) - , ctr(o.ctr->incref()) + shared_ptr(const shared_ptr& r,typename detail::is_convertible::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 + 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; } // 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& a, const shared_ptr& b) { } +template +inline shared_ptr static_pointer_cast( shared_ptr ptr) +{ + return shared_ptr(static_cast(ptr.ptr),ptr.ctr); +} + +template +inline shared_ptr dynamic_pointer_cast( shared_ptr ptr) +{ + return shared_ptr(dynamic_cast(ptr.ptr),ptr.ctr); +} + +template +inline shared_ptr const_pointer_cast( shared_ptr ptr) +{ + return shared_ptr(const_cast(ptr.ptr),ptr.ctr); +} + + + } // end of namespace boost #else