epoc32/include/stdapis/boost/weak_ptr.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:27:01 +0100
branchSymbian2
changeset 3 e1b950c65cb4
permissions -rw-r--r--
Attempt to represent the S^2->S^3 header reorganisation as a series of "hg rename" operations
     1 #ifndef BOOST_WEAK_PTR_HPP_INCLUDED
     2 #define BOOST_WEAK_PTR_HPP_INCLUDED
     3 
     4 //
     5 //  weak_ptr.hpp
     6 //
     7 //  Copyright (c) 2001, 2002, 2003 Peter Dimov
     8 //
     9 // Distributed under the Boost Software License, Version 1.0. (See
    10 // accompanying file LICENSE_1_0.txt or copy at
    11 // http://www.boost.org/LICENSE_1_0.txt)
    12 //
    13 //  See http://www.boost.org/libs/smart_ptr/weak_ptr.htm for documentation.
    14 //
    15 
    16 #include <memory> // boost.TR1 include order fix
    17 #include <boost/detail/shared_count.hpp>
    18 #include <boost/shared_ptr.hpp>
    19 
    20 #ifdef BOOST_MSVC  // moved here to work around VC++ compiler crash
    21 # pragma warning(push)
    22 # pragma warning(disable:4284) // odd return type for operator->
    23 #endif
    24 
    25 namespace boost
    26 {
    27 
    28 template<class T> class weak_ptr
    29 {
    30 private:
    31 
    32     // Borland 5.5.1 specific workarounds
    33     typedef weak_ptr<T> this_type;
    34 
    35 public:
    36 
    37     typedef T element_type;
    38 
    39     weak_ptr(): px(0), pn() // never throws in 1.30+
    40     {
    41     }
    42 
    43 //  generated copy constructor, assignment, destructor are fine
    44 
    45 
    46 //
    47 //  The "obvious" converting constructor implementation:
    48 //
    49 //  template<class Y>
    50 //  weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
    51 //  {
    52 //  }
    53 //
    54 //  has a serious problem.
    55 //
    56 //  r.px may already have been invalidated. The px(r.px)
    57 //  conversion may require access to *r.px (virtual inheritance).
    58 //
    59 //  It is not possible to avoid spurious access violations since
    60 //  in multithreaded programs r.px may be invalidated at any point.
    61 //
    62 
    63     template<class Y>
    64     weak_ptr(weak_ptr<Y> const & r): pn(r.pn) // never throws
    65     {
    66         px = r.lock().get();
    67     }
    68 
    69     template<class Y>
    70     weak_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
    71     {
    72     }
    73 
    74 #if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
    75 
    76     template<class Y>
    77     weak_ptr & operator=(weak_ptr<Y> const & r) // never throws
    78     {
    79         px = r.lock().get();
    80         pn = r.pn;
    81         return *this;
    82     }
    83 
    84     template<class Y>
    85     weak_ptr & operator=(shared_ptr<Y> const & r) // never throws
    86     {
    87         px = r.px;
    88         pn = r.pn;
    89         return *this;
    90     }
    91 
    92 #endif
    93 
    94     shared_ptr<T> lock() const // never throws
    95     {
    96 #if defined(BOOST_HAS_THREADS)
    97 
    98         // optimization: avoid throw overhead
    99         if(expired())
   100         {
   101             return shared_ptr<element_type>();
   102         }
   103 
   104         try
   105         {
   106             return shared_ptr<element_type>(*this);
   107         }
   108         catch(bad_weak_ptr const &)
   109         {
   110             // Q: how can we get here?
   111             // A: another thread may have invalidated r after the use_count test above.
   112             return shared_ptr<element_type>();
   113         }
   114 
   115 #else
   116 
   117         // optimization: avoid try/catch overhead when single threaded
   118         return expired()? shared_ptr<element_type>(): shared_ptr<element_type>(*this);
   119 
   120 #endif
   121     }
   122 
   123     long use_count() const // never throws
   124     {
   125         return pn.use_count();
   126     }
   127 
   128     bool expired() const // never throws
   129     {
   130         return pn.use_count() == 0;
   131     }
   132 
   133     void reset() // never throws in 1.30+
   134     {
   135         this_type().swap(*this);
   136     }
   137 
   138     void swap(this_type & other) // never throws
   139     {
   140         std::swap(px, other.px);
   141         pn.swap(other.pn);
   142     }
   143 
   144     void _internal_assign(T * px2, boost::detail::shared_count const & pn2)
   145     {
   146         px = px2;
   147         pn = pn2;
   148     }
   149 
   150     template<class Y> bool _internal_less(weak_ptr<Y> const & rhs) const
   151     {
   152         return pn < rhs.pn;
   153     }
   154 
   155 // Tasteless as this may seem, making all members public allows member templates
   156 // to work in the absence of member template friends. (Matthew Langston)
   157 
   158 #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
   159 
   160 private:
   161 
   162     template<class Y> friend class weak_ptr;
   163     template<class Y> friend class shared_ptr;
   164 
   165 #endif
   166 
   167     T * px;                       // contained pointer
   168     boost::detail::weak_count pn; // reference counter
   169 
   170 };  // weak_ptr
   171 
   172 template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b)
   173 {
   174     return a._internal_less(b);
   175 }
   176 
   177 template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b)
   178 {
   179     a.swap(b);
   180 }
   181 
   182 // deprecated, provided for backward compatibility
   183 template<class T> shared_ptr<T> make_shared(weak_ptr<T> const & r)
   184 {
   185     return r.lock();
   186 }
   187 
   188 } // namespace boost
   189 
   190 #ifdef BOOST_MSVC
   191 # pragma warning(pop)
   192 #endif    
   193 
   194 #endif  // #ifndef BOOST_WEAK_PTR_HPP_INCLUDED