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