Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / interprocess / smart_ptr / intrusive_ptr.hpp
1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // This file is the adaptation for Interprocess of boost/intrusive_ptr.hpp
4 //
5 // (C) Copyright Peter Dimov 2001, 2002
6 // (C) Copyright Ion Gaztanaga 2006-2012. Distributed under the Boost
7 // Software License, Version 1.0. (See accompanying file
8 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 // See http://www.boost.org/libs/interprocess for documentation.
11 //
12 //////////////////////////////////////////////////////////////////////////////
13
14 #ifndef BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED
15 #define BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED
16
17 #if defined(_MSC_VER)
18 #  pragma once
19 #endif
20
21 //!\file
22 //!Describes an intrusive ownership pointer.
23
24 #include <boost/interprocess/detail/config_begin.hpp>
25 #include <boost/interprocess/detail/workaround.hpp>
26
27 #include <boost/assert.hpp>
28 #include <boost/interprocess/detail/utilities.hpp>
29 #include <boost/intrusive/pointer_traits.hpp>
30
31 #include <functional>           // for std::less
32 #include <iosfwd>               // for std::basic_ostream
33
34
35 namespace boost {
36 namespace interprocess {
37
38 //!The intrusive_ptr class template stores a pointer to an object
39 //!with an embedded reference count. intrusive_ptr is parameterized on
40 //!T (the type of the object pointed to) and VoidPointer(a void pointer type
41 //!that defines the type of pointer that intrusive_ptr will store).
42 //!intrusive_ptr<T, void *> defines a class with a T* member whereas
43 //!intrusive_ptr<T, offset_ptr<void> > defines a class with a offset_ptr<T> member.
44 //!Relies on unqualified calls to:
45 //!
46 //!  void intrusive_ptr_add_ref(T * p);
47 //!  void intrusive_ptr_release(T * p);
48 //!
49 //!  with (p != 0)
50 //!
51 //!The object is responsible for destroying itself.
52 template<class T, class VoidPointer>
53 class intrusive_ptr
54 {
55    public:
56    //!Provides the type of the internal stored pointer.
57    typedef typename boost::intrusive::
58       pointer_traits<VoidPointer>::template
59          rebind_pointer<T>::type                pointer;
60    //!Provides the type of the stored pointer.
61    typedef T element_type;
62
63    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
64    private:
65    typedef VoidPointer VP;
66    typedef intrusive_ptr this_type;
67    typedef pointer this_type::*unspecified_bool_type;
68    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
69
70    public:
71    //!Constructor. Initializes internal pointer to 0.
72    //!Does not throw
73    intrusive_ptr(): m_ptr(0)
74    {}
75
76    //!Constructor. Copies pointer and if "p" is not zero and
77    //!"add_ref" is true calls intrusive_ptr_add_ref(to_raw_pointer(p)).
78    //!Does not throw
79    intrusive_ptr(const pointer &p, bool add_ref = true): m_ptr(p)
80    {
81       if(m_ptr != 0 && add_ref) intrusive_ptr_add_ref(ipcdetail::to_raw_pointer(m_ptr));
82    }
83
84    //!Copy constructor. Copies the internal pointer and if "p" is not
85    //!zero calls intrusive_ptr_add_ref(to_raw_pointer(p)). Does not throw
86    intrusive_ptr(intrusive_ptr const & rhs)
87       :  m_ptr(rhs.m_ptr)
88    {
89       if(m_ptr != 0) intrusive_ptr_add_ref(ipcdetail::to_raw_pointer(m_ptr));
90    }
91
92    //!Constructor from related. Copies the internal pointer and if "p" is not
93    //!zero calls intrusive_ptr_add_ref(to_raw_pointer(p)). Does not throw
94    template<class U> intrusive_ptr
95       (intrusive_ptr<U, VP> const & rhs)
96       :  m_ptr(rhs.get())
97    {
98       if(m_ptr != 0) intrusive_ptr_add_ref(ipcdetail::to_raw_pointer(m_ptr));
99    }
100
101    //!Destructor. If internal pointer is not 0, calls
102    //!intrusive_ptr_release(to_raw_pointer(m_ptr)). Does not throw
103    ~intrusive_ptr()
104    {
105       if(m_ptr != 0) intrusive_ptr_release(ipcdetail::to_raw_pointer(m_ptr));
106    }
107
108    //!Assignment operator. Equivalent to intrusive_ptr(r).swap(*this).
109    //!Does not throw
110    intrusive_ptr & operator=(intrusive_ptr const & rhs)
111    {
112       this_type(rhs).swap(*this);
113       return *this;
114    }
115
116    //!Assignment from related. Equivalent to intrusive_ptr(r).swap(*this).
117    //!Does not throw
118    template<class U> intrusive_ptr & operator=
119       (intrusive_ptr<U, VP> const & rhs)
120    {
121       this_type(rhs).swap(*this);
122       return *this;
123    }
124
125    //!Assignment from pointer. Equivalent to intrusive_ptr(r).swap(*this).
126    //!Does not throw
127    intrusive_ptr & operator=(pointer rhs)
128    {
129       this_type(rhs).swap(*this);
130       return *this;
131    }
132
133    //!Returns a reference to the internal pointer.
134    //!Does not throw
135    pointer &get()
136    {  return m_ptr;  }
137
138    //!Returns a reference to the internal pointer.
139    //!Does not throw
140    const pointer &get() const
141    {  return m_ptr;  }
142
143    //!Returns *get().
144    //!Does not throw
145    T & operator*() const
146    {  return *m_ptr; }
147
148    //!Returns *get().
149    //!Does not throw
150    const pointer &operator->() const
151    {  return m_ptr;  }
152
153    //!Returns get().
154    //!Does not throw
155    pointer &operator->()
156    {  return m_ptr;  }
157
158    //!Conversion to boolean.
159    //!Does not throw
160    operator unspecified_bool_type () const
161    {  return m_ptr == 0? 0: &this_type::m_ptr;  }
162
163    //!Not operator.
164    //!Does not throw
165    bool operator! () const
166    {  return m_ptr == 0;   }
167
168    //!Exchanges the contents of the two smart pointers.
169    //!Does not throw
170    void swap(intrusive_ptr & rhs)
171    {  ipcdetail::do_swap(m_ptr, rhs.m_ptr);  }
172
173    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
174    private:
175    pointer m_ptr;
176    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
177 };
178
179 //!Returns a.get() == b.get().
180 //!Does not throw
181 template<class T, class U, class VP> inline
182 bool operator==(intrusive_ptr<T, VP> const & a,
183                 intrusive_ptr<U, VP> const & b)
184 {  return a.get() == b.get(); }
185
186 //!Returns a.get() != b.get().
187 //!Does not throw
188 template<class T, class U, class VP> inline
189 bool operator!=(intrusive_ptr<T, VP> const & a,
190                 intrusive_ptr<U, VP> const & b)
191 {  return a.get() != b.get(); }
192
193 //!Returns a.get() == b.
194 //!Does not throw
195 template<class T, class VP> inline
196 bool operator==(intrusive_ptr<T, VP> const & a,
197                        const typename intrusive_ptr<T, VP>::pointer &b)
198 {  return a.get() == b; }
199
200 //!Returns a.get() != b.
201 //!Does not throw
202 template<class T, class VP> inline
203 bool operator!=(intrusive_ptr<T, VP> const & a,
204                 const typename intrusive_ptr<T, VP>::pointer &b)
205 {  return a.get() != b; }
206
207 //!Returns a == b.get().
208 //!Does not throw
209 template<class T, class VP> inline
210 bool operator==(const typename intrusive_ptr<T, VP>::pointer &a,
211                 intrusive_ptr<T, VP> const & b)
212 {  return a == b.get(); }
213
214 //!Returns a != b.get().
215 //!Does not throw
216 template<class T, class VP> inline
217 bool operator!=(const typename intrusive_ptr<T, VP>::pointer &a,
218                        intrusive_ptr<T, VP> const & b)
219 {  return a != b.get(); }
220
221 //!Returns a.get() < b.get().
222 //!Does not throw
223 template<class T, class VP> inline
224 bool operator<(intrusive_ptr<T, VP> const & a,
225                intrusive_ptr<T, VP> const & b)
226 {
227    return std::less<typename intrusive_ptr<T, VP>::pointer>()
228       (a.get(), b.get());
229 }
230
231 //!Exchanges the contents of the two intrusive_ptrs.
232 //!Does not throw
233 template<class T, class VP> inline
234 void swap(intrusive_ptr<T, VP> & lhs,
235           intrusive_ptr<T, VP> & rhs)
236 {  lhs.swap(rhs); }
237
238 // operator<<
239 template<class E, class T, class Y, class VP>
240 inline std::basic_ostream<E, T> & operator<<
241    (std::basic_ostream<E, T> & os, intrusive_ptr<Y, VP> const & p)
242 {  os << p.get(); return os;  }
243
244 //!Returns p.get().
245 //!Does not throw
246 template<class T, class VP>
247 inline typename boost::interprocess::intrusive_ptr<T, VP>::pointer
248    to_raw_pointer(intrusive_ptr<T, VP> p)
249 {  return p.get();   }
250
251 /*Emulates static cast operator. Does not throw*/
252 /*
253 template<class T, class U, class VP>
254 inline boost::interprocess::intrusive_ptr<T, VP> static_pointer_cast
255    (boost::interprocess::intrusive_ptr<U, VP> const & p)
256 {  return do_static_cast<U>(p.get());  }
257 */
258 /*Emulates const cast operator. Does not throw*/
259 /*
260 template<class T, class U, class VP>
261 inline boost::interprocess::intrusive_ptr<T, VP> const_pointer_cast
262    (boost::interprocess::intrusive_ptr<U, VP> const & p)
263 {  return do_const_cast<U>(p.get());   }
264 */
265
266 /*Emulates dynamic cast operator. Does not throw*/
267 /*
268 template<class T, class U, class VP>
269 inline boost::interprocess::intrusive_ptr<T, VP> dynamic_pointer_cast
270    (boost::interprocess::intrusive_ptr<U, VP> const & p)
271 {  return do_dynamic_cast<U>(p.get()); }
272 */
273
274 /*Emulates reinterpret cast operator. Does not throw*/
275 /*
276 template<class T, class U, class VP>
277 inline boost::interprocess::intrusive_ptr<T, VP>reinterpret_pointer_cast
278    (boost::interprocess::intrusive_ptr<U, VP> const & p)
279 {  return do_reinterpret_cast<U>(p.get());   }
280 */
281
282 } // namespace interprocess
283
284 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
285
286 #if defined(_MSC_VER) && (_MSC_VER < 1400)
287 //!Returns p.get().
288 //!Does not throw
289 template<class T, class VP>
290 inline T *to_raw_pointer(boost::interprocess::intrusive_ptr<T, VP> p)
291 {  return p.get();   }
292 #endif
293
294 #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
295
296 } // namespace boost
297
298 #include <boost/interprocess/detail/config_end.hpp>
299
300 #endif  // #ifndef BOOST_INTERPROCESS_INTRUSIVE_PTR_HPP_INCLUDED