src/sysc/packages/boost/shared_ptr.hpp

Go to the documentation of this file.
00001 #ifndef BOOST_SHARED_PTR_HPP_INCLUDED
00002 #define BOOST_SHARED_PTR_HPP_INCLUDED
00003 
00004 //
00005 //  shared_ptr.hpp
00006 //
00007 //  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
00008 //  Copyright (c) 2001, 2002 Peter Dimov
00009 //
00010 //  Permission to copy, use, modify, sell and distribute this software
00011 //  is granted provided this copyright notice appears in all copies.
00012 //  This software is provided "as is" without express or implied
00013 //  warranty, and with no claim as to its suitability for any purpose.
00014 //
00015 //  See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
00016 //
00017 
00018 #include <sysc/packages/boost/config.hpp>   // for broken compiler workarounds
00019 
00020 #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
00021 #include <sysc/packages/boost/detail/shared_ptr_nmt.hpp>
00022 #else
00023 
00024 #include <sysc/packages/boost/assert.hpp>
00025 #include <sysc/packages/boost/checked_delete.hpp>
00026 #include <sysc/packages/boost/throw_exception.hpp>
00027 #include <sysc/packages/boost/detail/shared_count.hpp>
00028 
00029 #include <memory>             // for std::auto_ptr
00030 #include <algorithm>          // for std::swap
00031 #include <functional>         // for std::less
00032 #include <typeinfo>           // for std::bad_cast
00033 
00034 #ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash
00035 # pragma warning(push)
00036 # pragma warning(disable:4284) // odd return type for operator->
00037 #endif
00038 
00039 namespace boost
00040 {
00041 
00042 namespace detail
00043 {
00044 
00045 struct static_cast_tag {};
00046 struct dynamic_cast_tag {};
00047 struct polymorphic_cast_tag {};
00048 
00049 template<typename T> struct shared_ptr_traits
00050 {
00051     typedef T & reference;
00052 };
00053 
00054 template<> struct shared_ptr_traits<void>
00055 {
00056     typedef void reference;
00057 };
00058 
00059 #if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
00060 
00061 template<> struct shared_ptr_traits<void const>
00062 {
00063     typedef void reference;
00064 };
00065 
00066 #endif
00067 
00068 } // namespace detail
00069 
00070 
00071 //
00072 //  shared_ptr
00073 //
00074 //  An enhanced relative of scoped_ptr with reference counted copy semantics.
00075 //  The object pointed to is deleted when the last shared_ptr pointing to it
00076 //  is destroyed or reset.
00077 //
00078 
00079 template<typename T> class weak_ptr;
00080 template<typename T> class intrusive_ptr;
00081 
00082 template<typename T> class shared_ptr
00083 {
00084 private:
00085 
00086     // Borland 5.5.1 specific workarounds
00087 //  typedef checked_deleter<T> deleter;
00088     typedef shared_ptr<T> this_type;
00089 
00090 public:
00091 
00092     typedef T element_type;
00093     typedef T value_type;
00094 
00095     shared_ptr(): px(0), pn()
00096     {
00097     }
00098 
00099     template<typename Y>
00100     explicit shared_ptr(Y * p): px(p), pn(p, checked_deleter<Y>(), p) // Y must be complete
00101     {
00102     }
00103 
00104     //
00105     // Requirements: D's copy constructor must not throw
00106     //
00107     // shared_ptr will release p by calling d(p)
00108     //
00109 
00110     template<typename Y, typename D> shared_ptr(Y * p, D d): px(p), pn(p, d)
00111     {
00112     }
00113 
00114 //  generated copy constructor, assignment, destructor are fine
00115 
00116     template<typename Y>
00117     explicit shared_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn) // may throw
00118     {
00119     }
00120 
00121     template<typename Y>
00122     shared_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
00123     {
00124     }
00125 
00126     template<typename Y>
00127     shared_ptr(intrusive_ptr<Y> const & r): px(r.get()), pn(r.get()) // never throws
00128     {
00129     }
00130 
00131     template<typename Y>
00132     shared_ptr(shared_ptr<Y> const & r, detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn)
00133     {
00134     }
00135 
00136     template<typename Y>
00137     shared_ptr(shared_ptr<Y> const & r, detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
00138     {
00139         if (px == 0) // need to allocate new counter -- the cast failed
00140         {
00141             pn = detail::shared_count();
00142         }
00143     }
00144 
00145     template<typename Y>
00146     shared_ptr(shared_ptr<Y> const & r, detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn)
00147     {
00148         if (px == 0)
00149         {
00150             boost::throw_exception(std::bad_cast());
00151         }
00152     }
00153 
00154 #ifndef BOOST_NO_AUTO_PTR
00155 
00156     template<typename Y>
00157     explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn(r)
00158     {
00159     }
00160 
00161 #endif
00162 
00163 #if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
00164 
00165     template<typename Y>
00166     shared_ptr & operator=(shared_ptr<Y> const & r) // never throws
00167     {
00168         px = r.px;
00169         pn = r.pn; // shared_count::op= doesn't throw
00170         return *this;
00171     }
00172 
00173 #endif
00174 
00175 #ifndef BOOST_NO_AUTO_PTR
00176 
00177     template<typename Y>
00178     shared_ptr & operator=(std::auto_ptr<Y> & r)
00179     {
00180         this_type(r).swap(*this);
00181         return *this;
00182     }
00183 
00184 #endif
00185 
00186     void reset()
00187     {
00188         this_type().swap(*this);
00189     }
00190 
00191     template<typename Y> void reset(Y * p) // Y must be complete
00192     {
00193         BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors
00194         this_type(p).swap(*this);
00195     }
00196 
00197     template<typename Y, typename D> void reset(Y * p, D d)
00198     {
00199         this_type(p, d).swap(*this);
00200     }
00201 
00202     typename detail::shared_ptr_traits<T>::reference operator* () const // never throws
00203     {
00204         BOOST_ASSERT(px != 0);
00205         return *px;
00206     }
00207 
00208     T * operator-> () const // never throws
00209     {
00210         BOOST_ASSERT(px != 0);
00211         return px;
00212     }
00213     
00214     T * get() const // never throws
00215     {
00216         return px;
00217     }
00218 
00219     // implicit conversion to "bool"
00220 
00221     typedef T * (this_type::*unspecified_bool_type)() const;
00222 
00223     operator unspecified_bool_type() const // never throws
00224     {
00225         return px == 0? 0: &this_type::get;
00226     }
00227 
00228     bool operator! () const // never throws
00229     {
00230         return px == 0;
00231     }
00232 
00233     bool unique() const // never throws
00234     {
00235         return pn.unique();
00236     }
00237 
00238     long use_count() const // never throws
00239     {
00240         return pn.use_count();
00241     }
00242 
00243     void swap(shared_ptr<T> & other) // never throws
00244     {
00245         std::swap(px, other.px);
00246         pn.swap(other.pn);
00247     }
00248 
00249 // Tasteless as this may seem, making all members public allows member templates
00250 // to work in the absence of member template friends. (Matthew Langston)
00251 
00252 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
00253 
00254 private:
00255 
00256     template<typename Y> friend class shared_ptr;
00257     template<typename Y> friend class weak_ptr;
00258 
00259 
00260 #endif
00261 
00262     T * px;                     // contained pointer
00263     detail::shared_count pn;    // reference counter
00264 
00265 };  // shared_ptr
00266 
00267 template<typename T, typename U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b)
00268 {
00269     return a.get() == b.get();
00270 }
00271 
00272 template<typename T, typename U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b)
00273 {
00274     return a.get() != b.get();
00275 }
00276 
00277 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
00278 
00279 // Resolve the ambiguity between our op!= and the one in rel_ops
00280 
00281 template<typename T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b)
00282 {
00283     return a.get() != b.get();
00284 }
00285 
00286 #endif
00287 
00288 template<typename T> inline bool operator<(shared_ptr<T> const & a, shared_ptr<T> const & b)
00289 {
00290     return std::less<T*>()(a.get(), b.get());
00291 }
00292 
00293 template<typename T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
00294 {
00295     a.swap(b);
00296 }
00297 
00298 template<typename T, typename U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r)
00299 {
00300     return shared_ptr<T>(r, detail::static_cast_tag());
00301 }
00302 
00303 template<typename T, typename U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r)
00304 {
00305     return shared_ptr<T>(r, detail::dynamic_cast_tag());
00306 }
00307 
00308 template<typename T, typename U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r)
00309 {
00310     return shared_ptr<T>(r, detail::polymorphic_cast_tag());
00311 }
00312 
00313 template<typename T, typename U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r)
00314 {
00315     BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get());
00316     return shared_static_cast<T>(r);
00317 }
00318 
00319 // get_pointer() enables boost::mem_fn to recognize shared_ptr
00320 
00321 template<typename T> inline T * get_pointer(shared_ptr<T> const & p)
00322 {
00323     return p.get();
00324 }
00325 
00326 // shared_from_this() creates a shared_ptr from a raw pointer (usually 'this')
00327 
00328 namespace detail
00329 {
00330 
00331 inline void sp_assert_counted_base(boost::counted_base const *)
00332 {
00333 }
00334 
00335 template<class T> inline T * sp_remove_const(T const * p)
00336 {
00337     return const_cast<T *>(p);
00338 }
00339 
00340 } // namespace detail
00341 
00342 template<class T> shared_ptr<T> shared_from_this(T * p)
00343 {
00344     detail::sp_assert_counted_base(p);
00345     return shared_ptr<T>(detail::sp_remove_const(p));
00346 }
00347 
00348 } // namespace boost
00349 
00350 #ifdef BOOST_MSVC
00351 # pragma warning(pop)
00352 #endif    
00353 
00354 #endif  // #if defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
00355 
00356 #endif  // #ifndef BOOST_SHARED_PTR_HPP_INCLUDED

Generated on Wed Apr 25 13:53:28 2007 for SystemC by  doxygen 1.5.1