summaryrefslogtreecommitdiff
path: root/libs/intrusive/test/smart_ptr.hpp
blob: 28004305acf5fb8e4331a6839502e5a6e08f5136 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/intrusive for documentation.
//
//////////////////////////////////////////////////////////////////////////////

#ifndef BOOST_INTRUSIVE_SMART_PTR_HPP
#define BOOST_INTRUSIVE_SMART_PTR_HPP

#include <boost/iterator.hpp>
#include <boost/intrusive/pointer_plus_bits.hpp>
#include <boost/intrusive/pointer_traits.hpp>

#if (defined _MSC_VER)
#  pragma once
#endif

namespace boost{
namespace intrusive{

namespace detail {

struct static_cast_tag {};
struct const_cast_tag {};
struct dynamic_cast_tag {};
struct reinterpret_cast_tag {};

}  //namespace detail {

//Empty class
struct empty_type{};

template<class T>
struct random_it
: public boost::iterator<std::random_access_iterator_tag,
                         T, std::ptrdiff_t, T*, T&>
{
   typedef const T*           const_pointer;
   typedef const T&           const_reference;
};

template<> struct random_it<void>
{
   typedef const void *       const_pointer;
   typedef empty_type&        reference;
   typedef const empty_type&  const_reference;
   typedef empty_type         difference_type;
   typedef empty_type         iterator_category;
};

template<> struct random_it<const void>
{
   typedef const void *       const_pointer;
   typedef const empty_type & reference;
   typedef const empty_type & const_reference;
   typedef empty_type         difference_type;
   typedef empty_type         iterator_category;
};

template<> struct random_it<volatile void>
{
   typedef const volatile void * const_pointer;
   typedef empty_type&           reference;
   typedef const empty_type&     const_reference;
   typedef empty_type            difference_type;
   typedef empty_type            iterator_category;
};

template<> struct random_it<const volatile void>
{
   typedef const volatile void *    const_pointer;
   typedef const empty_type &       reference;
   typedef const empty_type &       const_reference;
   typedef empty_type               difference_type;
   typedef empty_type               iterator_category;
};

}  //namespace intrusive {
}  //namespace boost {


namespace boost {
namespace intrusive {

template <class PointedType>
class smart_ptr
{
   typedef random_it<PointedType> random_it_t;
   typedef smart_ptr<PointedType>                           self_t;
   typedef typename random_it_t::const_pointer              const_pointer_t;
   typedef typename random_it_t::const_reference            const_reference_t;

   void unspecified_bool_type_func() const {}
   typedef void (self_t::*unspecified_bool_type)() const;

   public:
   typedef PointedType *                           pointer;
   typedef typename random_it_t::reference         reference;
   typedef PointedType                             value_type;
   typedef typename random_it_t::difference_type   difference_type;
   typedef typename random_it_t::iterator_category iterator_category;

   PointedType *m_ptr;

   public:   //Public Functions

   smart_ptr()
      :  m_ptr(0)
   {}

   //!Constructor from other smart_ptr
   smart_ptr(const smart_ptr& ptr)
      :  m_ptr(ptr.m_ptr)
   {}

   static smart_ptr pointer_to(reference r)
   {  smart_ptr p; p.m_ptr = &r; return p;  }

   //!Constructor from other smart_ptr. If pointers of pointee types are
   //!convertible, offset_ptrs will be convertibles. Never throws.
   template<class T2>
   smart_ptr(const smart_ptr<T2> &ptr)
      :  m_ptr(ptr.m_ptr)
   {}

   //!Pointer-like -> operator. It can return 0 pointer. Never throws.
   pointer operator->() const
   {  return m_ptr; }

   //!Dereferencing operator, if it is a null smart_ptr behavior
   //!   is undefined. Never throws.
   reference operator* () const
   {  return *m_ptr;   }

   //!Indexing operator. Never throws.
   reference operator[](std::ptrdiff_t idx) const
   {  return m_ptr[idx];  }

   //!Assignment from other smart_ptr. Never throws.
   smart_ptr& operator= (const smart_ptr & pt)
   {  m_ptr = pt.m_ptr;  return *this;  }

   //!Assignment from related smart_ptr. If pointers of pointee types
   //!   are assignable, offset_ptrs will be assignable. Never throws.
   template <class T2>
   smart_ptr& operator= (const smart_ptr<T2> & pt)
   {  m_ptr = pt.m_ptr;  return *this;  }

   //!smart_ptr + std::ptrdiff_t. Never throws.
   smart_ptr operator+ (std::ptrdiff_t offset) const
   {  smart_ptr s; s.m_ptr = m_ptr + offset; return s;   }

   //!smart_ptr - std::ptrdiff_t. Never throws.
   smart_ptr operator- (std::ptrdiff_t offset) const
   {  smart_ptr s; s.m_ptr = m_ptr - offset; return s;   }

   //!smart_ptr += std::ptrdiff_t. Never throws.
   smart_ptr &operator+= (std::ptrdiff_t offset)
   {  m_ptr += offset;   return *this;  }

   //!smart_ptr -= std::ptrdiff_t. Never throws.
   smart_ptr &operator-= (std::ptrdiff_t offset)
   {  m_ptr -= offset;  return *this;  }

   //!++smart_ptr. Never throws.
   smart_ptr& operator++ (void)
   {  ++m_ptr;   return *this;  }

   //!smart_ptr++. Never throws.
   smart_ptr operator++ (int)
   {  smart_ptr temp(*this); ++*this; return temp; }

   //!--smart_ptr. Never throws.
   smart_ptr& operator-- (void)
   {  --m_ptr;   return *this;  }

   //!smart_ptr--. Never throws.
   smart_ptr operator-- (int)
   {  smart_ptr temp(*this); --*this; return temp; }

   //!safe bool conversion operator. Never throws.
   operator unspecified_bool_type() const
   {  return m_ptr? &self_t::unspecified_bool_type_func : 0;   }

   //!Not operator. Not needed in theory, but improves portability.
   //!Never throws.
   bool operator! () const
   {  return m_ptr == 0;   }
};

//!smart_ptr<T1> == smart_ptr<T2>. Never throws.
template<class T1, class T2>
inline bool operator== (const smart_ptr<T1> &pt1,
                        const smart_ptr<T2> &pt2)
{  return pt1.operator->() == pt2.operator->();  }

//!smart_ptr<T1> != smart_ptr<T2>. Never throws.
template<class T1, class T2>
inline bool operator!= (const smart_ptr<T1> &pt1,
                        const smart_ptr<T2> &pt2)
{  return pt1.operator->() != pt2.operator->();  }

//!smart_ptr<T1> < smart_ptr<T2>. Never throws.
template<class T1, class T2>
inline bool operator< (const smart_ptr<T1> &pt1,
                       const smart_ptr<T2> &pt2)
{  return pt1.operator->() < pt2.operator->();  }

//!smart_ptr<T1> <= smart_ptr<T2>. Never throws.
template<class T1, class T2>
inline bool operator<= (const smart_ptr<T1> &pt1,
                        const smart_ptr<T2> &pt2)
{  return pt1.operator->() <= pt2.operator->();  }

//!smart_ptr<T1> > smart_ptr<T2>. Never throws.
template<class T1, class T2>
inline bool operator> (const smart_ptr<T1> &pt1,
                       const smart_ptr<T2> &pt2)
{  return pt1.operator->() > pt2.operator->();  }

//!smart_ptr<T1> >= smart_ptr<T2>. Never throws.
template<class T1, class T2>
inline bool operator>= (const smart_ptr<T1> &pt1,
                        const smart_ptr<T2> &pt2)
{  return pt1.operator->() >= pt2.operator->();  }

//!operator<<
template<class E, class T, class Y>
inline std::basic_ostream<E, T> & operator<<
   (std::basic_ostream<E, T> & os, smart_ptr<Y> const & p)
{  return os << p.operator->();   }

//!operator>>
template<class E, class T, class Y>
inline std::basic_istream<E, T> & operator>>
   (std::basic_istream<E, T> & os, smart_ptr<Y> & p)
{  Y * tmp; return os >> tmp; p = tmp;   }

//!std::ptrdiff_t + smart_ptr
template<class T>
inline smart_ptr<T> operator+(std::ptrdiff_t diff, const smart_ptr<T>& right)
{  return right + diff;  }

//!smart_ptr - smart_ptr
template<class T, class T2>
inline std::ptrdiff_t operator- (const smart_ptr<T> &pt, const smart_ptr<T2> &pt2)
{  return pt.operator->()- pt2.operator->();   }

//!swap specialization
template<class T>
inline void swap (smart_ptr<T> &pt,
                  smart_ptr<T> &pt2)
{
   typename smart_ptr<T>::value_type *ptr = pt.operator->();
   pt = pt2;
   pt2 = ptr;
}

}  //namespace intrusive {
}  //namespace boost {

namespace boost{

//This is to support embedding a bit in the pointer
//for intrusive containers, saving space
namespace intrusive {

template<std::size_t Alignment>
struct max_pointer_plus_bits<smart_ptr<void>, Alignment>
{
   static const std::size_t value = max_pointer_plus_bits<void*, Alignment>::value;
};

template<class T, std::size_t NumBits>
struct pointer_plus_bits<smart_ptr<T>, NumBits>
{
   typedef smart_ptr<T>         pointer;

   static pointer get_pointer(const pointer &n)
   {
      return  pointer_traits<pointer>::pointer_to
         (*pointer_plus_bits<T*, NumBits>::get_pointer(n.operator->()));
   }

   static void set_pointer(pointer &n, pointer p)
   {
      T *raw_n = n.operator->();
      pointer_plus_bits<T*, NumBits>::set_pointer(raw_n, p.operator->());
      n = pointer_traits<pointer>::pointer_to(*raw_n);
   }

   static std::size_t get_bits(const pointer &n)
   {  return pointer_plus_bits<T*, NumBits>::get_bits(n.operator->());  }

   static void set_bits(pointer &n, std::size_t c)
   {
      T *raw_n = n.operator->();
      pointer_plus_bits<T*, NumBits>::set_bits(raw_n, c);
      n = pointer_traits<pointer>::pointer_to(*raw_n);
   }
};

}  //namespace intrusive
}  //namespace boost{

#endif //#ifndef BOOST_INTRUSIVE_SMART_PTR_HPP