~ubuntu-branches/debian/sid/boost1.49/sid

« back to all changes in this revision

Viewing changes to boost/interprocess/smart_ptr/weak_ptr.hpp

  • Committer: Package Import Robot
  • Author(s): Steve M. Robbins
  • Date: 2012-02-26 00:31:44 UTC
  • Revision ID: package-import@ubuntu.com-20120226003144-eaytp12cbf6ubpms
Tags: upstream-1.49.0
ImportĀ upstreamĀ versionĀ 1.49.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//////////////////////////////////////////////////////////////////////////////
 
2
//
 
3
// This file is the adaptation for Interprocess of boost/weak_ptr.hpp
 
4
//
 
5
// (C) Copyright Peter Dimov 2001, 2002, 2003
 
6
// (C) Copyright Ion Gaztanaga 2006-2011.
 
7
// Distributed under the Boost Software License, Version 1.0.
 
8
// (See accompanying file LICENSE_1_0.txt or copy at
 
9
// http://www.boost.org/LICENSE_1_0.txt)
 
10
//
 
11
// See http://www.boost.org/libs/interprocess for documentation.
 
12
//
 
13
//////////////////////////////////////////////////////////////////////////////
 
14
 
 
15
#ifndef BOOST_INTERPROCESS_WEAK_PTR_HPP_INCLUDED
 
16
#define BOOST_INTERPROCESS_WEAK_PTR_HPP_INCLUDED
 
17
 
 
18
#include <boost/interprocess/detail/config_begin.hpp>
 
19
#include <boost/interprocess/detail/workaround.hpp>
 
20
 
 
21
#include <boost/interprocess/smart_ptr/shared_ptr.hpp>
 
22
#include <boost/detail/no_exceptions_support.hpp>
 
23
#include <boost/interprocess/allocators/allocator.hpp>
 
24
#include <boost/interprocess/smart_ptr/deleter.hpp>
 
25
#include <boost/intrusive/pointer_traits.hpp>
 
26
 
 
27
//!\file
 
28
//!Describes the smart pointer weak_ptr.
 
29
 
 
30
namespace boost{
 
31
namespace interprocess{
 
32
 
 
33
//!The weak_ptr class template stores a "weak reference" to an object
 
34
//!that's already managed by a shared_ptr. To access the object, a weak_ptr 
 
35
//!can be converted to a shared_ptr using  the shared_ptr constructor or the
 
36
//!member function  lock. When the last shared_ptr to the object goes away
 
37
//!and the object is deleted, the attempt to obtain a shared_ptr from the
 
38
//!weak_ptr instances that refer to the deleted object will fail: the constructor
 
39
//!will throw an exception of type bad_weak_ptr, and weak_ptr::lock will
 
40
//!return an empty shared_ptr.
 
41
//!
 
42
//!Every weak_ptr meets the CopyConstructible and Assignable requirements
 
43
//!of the C++ Standard Library, and so can be used in standard library containers.
 
44
//!Comparison operators are supplied so that weak_ptr works with the standard
 
45
//!library's associative containers.
 
46
//!
 
47
//!weak_ptr operations never throw exceptions.
 
48
//!
 
49
//!The class template is parameterized on T, the type of the object pointed to.
 
50
template<class T, class A, class D>
 
51
class weak_ptr
 
52
{
 
53
   /// @cond
 
54
   private:
 
55
   // Borland 5.5.1 specific workarounds
 
56
   typedef weak_ptr<T, A, D> this_type;
 
57
   typedef typename boost::intrusive::
 
58
      pointer_traits<typename A::pointer>::template
 
59
         rebind_pointer<T>::type                         pointer;
 
60
   typedef typename ipcdetail::add_reference
 
61
                     <T>::type            reference;
 
62
   typedef typename ipcdetail::add_reference
 
63
                     <T>::type            const_reference;
 
64
   /// @endcond
 
65
 
 
66
   public:
 
67
   typedef T element_type;
 
68
   typedef T value_type;
 
69
 
 
70
   //!Effects: Constructs an empty weak_ptr.
 
71
   //!Postconditions: use_count() == 0.
 
72
   weak_ptr()
 
73
   : m_pn() // never throws
 
74
   {}
 
75
   //  generated copy constructor, assignment, destructor are fine
 
76
   //
 
77
   //  The "obvious" converting constructor implementation:
 
78
   //
 
79
   //  template<class Y>
 
80
   //  weak_ptr(weak_ptr<Y> const & r): m_px(r.m_px), m_pn(r.m_pn) // never throws
 
81
   //  {
 
82
   //  }
 
83
   //
 
84
   //  has a serious problem.
 
85
   //
 
86
   //  r.m_px may already have been invalidated. The m_px(r.m_px)
 
87
   //  conversion may require access to *r.m_px (virtual inheritance).
 
88
   //
 
89
   //  It is not possible to avoid spurious access violations since
 
90
   //  in multithreaded programs r.m_px may be invalidated at any point.
 
91
 
 
92
   //!Effects: If r is empty, constructs an empty weak_ptr; otherwise,
 
93
   //!constructs a weak_ptr that shares ownership with r as if by storing a
 
94
   //!copy of the pointer stored in r.
 
95
   //!
 
96
   //!Postconditions: use_count() == r.use_count().
 
97
   //!
 
98
   //!Throws: nothing.
 
99
   template<class Y>
 
100
   weak_ptr(weak_ptr<Y, A, D> const & r)
 
101
      : m_pn(r.m_pn) // never throws
 
102
   {  
 
103
      //Construct a temporary shared_ptr so that nobody
 
104
      //can destroy the value while constructing this
 
105
      const shared_ptr<T, A, D> &ref = r.lock();
 
106
      m_pn.set_pointer(ref.get()); 
 
107
   }
 
108
 
 
109
   //!Effects: If r is empty, constructs an empty weak_ptr; otherwise,
 
110
   //!constructs a weak_ptr that shares ownership with r as if by storing a
 
111
   //!copy of the pointer stored in r.
 
112
   //!
 
113
   //!Postconditions: use_count() == r.use_count().
 
114
   //!
 
115
   //!Throws: nothing.
 
116
   template<class Y>
 
117
   weak_ptr(shared_ptr<Y, A, D> const & r)
 
118
      : m_pn(r.m_pn) // never throws
 
119
   {}
 
120
 
 
121
   //!Effects: Equivalent to weak_ptr(r).swap(*this).
 
122
   //!
 
123
   //!Throws: nothing.
 
124
   //!
 
125
   //!Notes: The implementation is free to meet the effects (and the
 
126
   //!implied guarantees) via different means, without creating a temporary.
 
127
   template<class Y>
 
128
   weak_ptr & operator=(weak_ptr<Y, A, D> const & r) // never throws
 
129
   {  
 
130
      //Construct a temporary shared_ptr so that nobody
 
131
      //can destroy the value while constructing this
 
132
      const shared_ptr<T, A, D> &ref = r.lock();
 
133
      m_pn = r.m_pn;
 
134
      m_pn.set_pointer(ref.get());
 
135
      return *this;
 
136
   }
 
137
 
 
138
   //!Effects: Equivalent to weak_ptr(r).swap(*this).
 
139
   //!
 
140
   //!Throws: nothing.
 
141
   //!
 
142
   //!Notes: The implementation is free to meet the effects (and the
 
143
   //!implied guarantees) via different means, without creating a temporary.
 
144
   template<class Y>
 
145
   weak_ptr & operator=(shared_ptr<Y, A, D> const & r) // never throws
 
146
   {  m_pn = r.m_pn;  return *this;  }
 
147
 
 
148
   //!Returns: expired()? shared_ptr<T>(): shared_ptr<T>(*this).
 
149
   //!
 
150
   //!Throws: nothing.
 
151
   shared_ptr<T, A, D> lock() const // never throws
 
152
   {
 
153
      // optimization: avoid throw overhead
 
154
      if(expired()){
 
155
         return shared_ptr<element_type, A, D>();
 
156
      }
 
157
      BOOST_TRY{
 
158
         return shared_ptr<element_type, A, D>(*this);
 
159
      }
 
160
      BOOST_CATCH(bad_weak_ptr const &){
 
161
         // Q: how can we get here?
 
162
         // A: another thread may have invalidated r after the use_count test above.
 
163
         return shared_ptr<element_type, A, D>();
 
164
      }
 
165
      BOOST_CATCH_END
 
166
   }
 
167
 
 
168
   //!Returns: 0 if *this is empty; otherwise, the number of shared_ptr objects
 
169
   //!that share ownership with *this.
 
170
   //!
 
171
   //!Throws: nothing.
 
172
   //!
 
173
   //!Notes: use_count() is not necessarily efficient. Use only for debugging and
 
174
   //!testing purposes, not for production code.
 
175
   long use_count() const // never throws
 
176
   {  return m_pn.use_count();  }
 
177
    
 
178
   //!Returns: Returns: use_count() == 0.
 
179
   //!
 
180
   //!Throws: nothing.
 
181
   //!
 
182
   //!Notes: expired() may be faster than use_count().
 
183
   bool expired() const // never throws
 
184
   {  return m_pn.use_count() == 0;   }
 
185
 
 
186
   //!Effects: Equivalent to:
 
187
   //!weak_ptr().swap(*this).
 
188
   void reset() // never throws in 1.30+
 
189
   {  this_type().swap(*this);   }
 
190
 
 
191
   //!Effects: Exchanges the contents of the two
 
192
   //!smart pointers.
 
193
   //!
 
194
   //!Throws: nothing.
 
195
   void swap(this_type & other) // never throws
 
196
   {  ipcdetail::do_swap(m_pn, other.m_pn);   }
 
197
 
 
198
   /// @cond
 
199
   template<class T2, class A2, class D2> 
 
200
   bool _internal_less(weak_ptr<T2, A2, D2> const & rhs) const
 
201
   {  return m_pn < rhs.m_pn;  }
 
202
   
 
203
   template<class Y>
 
204
   void _internal_assign(const ipcdetail::shared_count<Y, A, D> & pn2)
 
205
   {
 
206
 
 
207
      m_pn = pn2;
 
208
   }
 
209
 
 
210
   private:
 
211
 
 
212
   template<class T2, class A2, class D2> friend class shared_ptr;
 
213
   template<class T2, class A2, class D2> friend class weak_ptr;
 
214
 
 
215
   ipcdetail::weak_count<T, A, D> m_pn;      // reference counter
 
216
   /// @endcond
 
217
};  // weak_ptr
 
218
 
 
219
template<class T, class A, class D, class U, class A2, class D2> inline 
 
220
bool operator<(weak_ptr<T, A, D> const & a, weak_ptr<U, A2, D2> const & b)
 
221
{  return a._internal_less(b);   }
 
222
 
 
223
template<class T, class A, class D> inline
 
224
void swap(weak_ptr<T, A, D> & a, weak_ptr<T, A, D> & b)
 
225
{  a.swap(b);  }
 
226
 
 
227
//!Returns the type of a weak pointer
 
228
//!of type T with the allocator boost::interprocess::allocator allocator
 
229
//!and boost::interprocess::deleter deleter
 
230
//!that can be constructed in the given managed segment type.
 
231
template<class T, class ManagedMemory>
 
232
struct managed_weak_ptr
 
233
{
 
234
   typedef weak_ptr
 
235
   < T
 
236
   , typename ManagedMemory::template allocator<void>::type
 
237
   , typename ManagedMemory::template deleter<T>::type
 
238
   > type;
 
239
};
 
240
 
 
241
//!Returns an instance of a weak pointer constructed
 
242
//!with the default allocator and deleter from a pointer
 
243
//!of type T that has been allocated in the passed managed segment
 
244
template<class T, class ManagedMemory>
 
245
inline typename managed_weak_ptr<T, ManagedMemory>::type
 
246
   make_managed_weak_ptr(T *constructed_object, ManagedMemory &managed_memory)
 
247
{
 
248
   return typename managed_weak_ptr<T, ManagedMemory>::type
 
249
   ( constructed_object
 
250
   , managed_memory.template get_allocator<void>()
 
251
   , managed_memory.template get_deleter<T>()
 
252
   );
 
253
}
 
254
 
 
255
} // namespace interprocess
 
256
} // namespace boost
 
257
 
 
258
#include <boost/interprocess/detail/config_end.hpp>
 
259
 
 
260
#endif  // #ifndef BOOST_INTERPROCESS_WEAK_PTR_HPP_INCLUDED