[devel_3.0_main] Change included header files in unique_ptr.hpp
[platform/framework/native/appfw.git] / inc / unique_ptr.hpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // unique_ptr.hpp header file
3 //
4 // Copyright 2009 Howard Hinnant, Ion Gaztañaga.
5 // Distributed under the Boost Software License, Version 1.0. (See
6 // accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 // See http://www.boost.org/libs/foreach for documentation
9
10 // This is a C++03 emulation of std::unique_ptr placed in namespace boost.
11 // Reference http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2800.pdf
12 //   for the latest unique_ptr specification, and
13 //   reference http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html
14 //   for any pending issues against this specification.
15
16 #ifndef _BOOST_UNIQUE_PTR_HPP_
17 #define _BOOST_UNIQUE_PTR_HPP_
18
19 #include <boost/utility/enable_if.hpp>
20 #include <boost/static_assert.hpp>
21 #include <boost/mpl/if.hpp>
22 #include <boost/type_traits/is_reference.hpp>
23 #include <boost/type_traits/is_empty.hpp>
24 #include <boost/type_traits/remove_reference.hpp>
25 #include <boost/type_traits/is_array.hpp>
26 #include <boost/type_traits/is_pointer.hpp>
27
28 namespace boost
29 {
30
31 namespace detail_unique_ptr
32 {
33
34 typedef char one;
35 struct two {one _[2];};
36
37 // An is_convertible<From, To> that considers From an rvalue (consistent with C++0X).
38 //   This is a simplified version neglecting the types function, array, void and abstract types
39 //   I had to make a special case out of is_convertible<T,T> to make move-only
40 //   types happy.
41
42 namespace is_conv_imp
43 {
44 template <class T> one test1(const T&);
45 template <class T> two test1(...);
46 template <class T> one test2(T);
47 template <class T> two test2(...);
48 template <class T> T source();
49 }
50
51 template <class T1, class T2>
52 struct is_convertible
53 {
54     static const bool value = sizeof(is_conv_imp::test1<T2>(is_conv_imp::source<T1>())) == 1;
55 };
56
57 template <class T>
58 struct is_convertible<T, T>
59 {
60     static const bool value = sizeof(is_conv_imp::test2<T>(is_conv_imp::source<T>())) == 1;
61 };
62
63 template <class T>
64 class rv
65 {
66     T& r_;
67
68 public:
69     explicit rv(T& r) : r_(r) {}
70     T* operator->() {return &r_;}
71     T& operator*() {return r_;}
72 };
73
74 template <class T>
75 struct identity
76 {
77     typedef T type;
78 };
79
80 }  // detail_unique_ptr
81
82 template <class T>
83 inline
84 typename enable_if_c
85 <
86     !detail_unique_ptr::is_convertible<T, detail_unique_ptr::rv<T> >::value,
87     T&
88 >::type
89 move(T& t)
90 {
91     return t;
92 }
93
94 template <class T>
95 inline
96 typename enable_if_c
97 <
98     !detail_unique_ptr::is_convertible<T, detail_unique_ptr::rv<T> >::value,
99     const T&
100 >::type
101 move(const T& t)
102 {
103     return t;
104 }
105
106 template <class T>
107 inline
108 typename enable_if_c
109 <
110     detail_unique_ptr::is_convertible<T, detail_unique_ptr::rv<T> >::value,
111     T
112 >::type
113 move(T& t)
114 {
115     return T(detail_unique_ptr::rv<T>(t));
116 }
117
118 template <class T>
119 inline
120 typename enable_if_c
121 <
122     is_reference<T>::value,
123     T
124 >::type
125 forward(typename detail_unique_ptr::identity<T>::type t)
126 {
127     return t;
128 }
129
130 template <class T>
131 inline
132 typename enable_if_c
133 <
134     !is_reference<T>::value,
135     T
136 >::type
137 forward(typename detail_unique_ptr::identity<T>::type& t)
138 {
139     return boost::move(t);
140 }
141
142 template <class T>
143 inline
144 typename enable_if_c
145 <
146     !is_reference<T>::value,
147     T
148 >::type
149 forward(const typename detail_unique_ptr::identity<T>::type& t)
150 {
151     return boost::move(const_cast<T&>(t));
152 }
153
154 namespace detail_unique_ptr {
155
156 // A move-aware but stripped-down compressed_pair which only optimizes storage for T2
157 template <class T1, class T2, bool = is_empty<T2>::value>
158 class unique_ptr_storage
159 {
160     T1 t1_;
161     T2 t2_;
162
163     typedef typename add_reference<T2>::type T2_reference;
164     typedef typename add_reference<const T2>::type T2_const_reference;
165
166     unique_ptr_storage(const unique_ptr_storage&);
167     unique_ptr_storage& operator=(const unique_ptr_storage&);
168 public:
169     operator rv<unique_ptr_storage>() {return rv<unique_ptr_storage>(*this);}
170
171     unique_ptr_storage() : t1_(), t2_() {}
172
173     explicit unique_ptr_storage(T1 t1)
174         : t1_(boost::move(t1)), t2_() {}
175
176     unique_ptr_storage(T1 t1, T2 t2)
177         : t1_(boost::move(t1)), t2_(boost::forward<T2>(t2)) {}
178
179           T1& first()       {return t1_;}
180     const T1& first() const {return t1_;}
181
182           T2_reference second()       {return t2_;}
183     T2_const_reference second() const {return t2_;}
184 };
185
186 template <class T1, class T2>
187 class unique_ptr_storage<T1, T2, true>
188     : private T2
189 {
190     T1 t1_;
191     typedef T2 t2_;
192
193     unique_ptr_storage(const unique_ptr_storage&);
194     unique_ptr_storage& operator=(const unique_ptr_storage&);
195 public:
196     operator rv<unique_ptr_storage>() {return rv<unique_ptr_storage>(*this);}
197
198     unique_ptr_storage() : t1_() {}
199
200     explicit unique_ptr_storage(T1 t1)
201         : t1_(boost::move(t1)) {}
202
203     unique_ptr_storage(T1 t1, T2 t2)
204         : t2_(boost::move(t2)), t1_(boost::move(t1)) {}
205
206           T1& first()       {return t1_;}
207     const T1& first() const {return t1_;}
208
209           T2& second()       {return *this;}
210     const T2& second() const {return *this;}
211 };
212
213 template <class T1, class T2, bool b>
214 inline
215 void
216 swap(unique_ptr_storage<T1, T2, b>& x, unique_ptr_storage<T1, T2, b>& y)
217 {
218     using std::swap;
219     swap(x.first(), y.first());
220     swap(x.second(), y.second());
221 }
222
223 }  // detail_unique_ptr
224
225 template <class T>
226 struct default_delete
227 {
228     default_delete() {}
229     template <class U>
230         default_delete(const default_delete<U>&,
231             typename enable_if_c<detail_unique_ptr::is_convertible<U*, T*>::value>::type* = 0)
232         {}
233
234     void operator()(T* ptr) const
235     {
236         BOOST_STATIC_ASSERT(sizeof(T) > 0);
237         delete ptr;
238     }
239 };
240
241 template <class T>
242 struct default_delete<T[]>
243 {
244     void operator()(T* ptr) const
245     {
246         BOOST_STATIC_ASSERT(sizeof(T) > 0);
247         delete [] ptr;
248     }
249
250 private:
251
252     template <class U> void operator()(U*) const;
253 };
254
255 namespace detail_unique_ptr
256 {
257
258 namespace pointer_type_imp
259 {
260
261 template <class U> static two test(...);
262 template <class U> static one test(typename U::pointer* = 0);
263
264 }  // pointer_type_imp
265
266 template <class T>
267 struct has_pointer_type
268 {
269     static const bool value = sizeof(pointer_type_imp::test<T>(0)) == 1;
270 };
271
272 namespace pointer_type_imp
273 {
274
275 template <class T, class D, bool = has_pointer_type<D>::value>
276 struct pointer_type
277 {
278     typedef typename D::pointer type;
279 };
280
281 template <class T, class D>
282 struct pointer_type<T, D, false>
283 {
284     typedef T* type;
285 };
286
287 }  // pointer_type_imp
288
289 template <class T, class D>
290 struct pointer_type
291 {
292     typedef typename pointer_type_imp::pointer_type<T,
293         typename boost::remove_reference<D>::type>::type type;
294 };
295
296 }  // detail_unique_ptr
297
298 template <class T, class D = default_delete<T> >
299 class unique_ptr
300 {
301 public:
302     typedef T element_type;
303     typedef D deleter_type;
304     typedef typename detail_unique_ptr::pointer_type<element_type, deleter_type>::type pointer;
305
306 private:
307     detail_unique_ptr::unique_ptr_storage<pointer, deleter_type> ptr_;
308
309     typedef typename add_reference<deleter_type>::type deleter_reference;
310     typedef typename add_reference<const deleter_type>::type deleter_const_reference;
311
312     struct nat {int for_bool_;};
313
314     unique_ptr(unique_ptr&);
315     unique_ptr& operator=(unique_ptr&);
316
317 public:
318     operator detail_unique_ptr::rv<unique_ptr>() {return detail_unique_ptr::rv<unique_ptr>(*this);}
319     unique_ptr(detail_unique_ptr::rv<unique_ptr> r) : ptr_(r->release(), boost::forward<deleter_type>(r->get_deleter())) {}
320     unique_ptr& operator=(detail_unique_ptr::rv<unique_ptr> r)
321     {
322         reset(r->release());
323         ptr_.second() = boost::move(r->get_deleter());
324         return *this;
325     }
326
327     unique_ptr()
328         {
329             BOOST_STATIC_ASSERT(!is_reference<deleter_type>::value);
330             BOOST_STATIC_ASSERT(!is_pointer<deleter_type>::value);
331         }
332
333     explicit unique_ptr(pointer p)
334         : ptr_(p)
335         {
336             BOOST_STATIC_ASSERT(!is_reference<deleter_type>::value);
337             BOOST_STATIC_ASSERT(!is_pointer<deleter_type>::value);
338         }
339
340     unique_ptr(pointer p, typename mpl::if_<is_reference<D>,
341                           volatile typename remove_reference<D>::type&, D>::type d)
342         : ptr_(boost::move(p), boost::forward<D>(const_cast<typename add_reference<D>::type>(d))) {}
343
344     template <class U, class E>
345         unique_ptr(unique_ptr<U, E> u,
346             typename enable_if_c
347                 <
348                 !boost::is_array<U>::value &&
349                 detail_unique_ptr::is_convertible<typename unique_ptr<U>::pointer, pointer>::value &&
350                 detail_unique_ptr::is_convertible<E, deleter_type>::value &&
351                 (
352                     !is_reference<deleter_type>::value ||
353                      is_same<deleter_type, E>::value
354                 )
355                 >::type* = 0)
356             : ptr_(u.release(), boost::forward<D>(boost::forward<E>(u.get_deleter()))) {}
357
358     ~unique_ptr() {reset();}
359
360     unique_ptr& operator=(int nat::*)
361     {
362         reset();
363         return *this;
364     }
365
366     template <class U, class E>
367         unique_ptr&
368         operator=(unique_ptr<U, E> u)
369         {
370             reset(u.release());
371             ptr_.second() = boost::move(u.get_deleter());
372             return *this;
373         }
374
375     typename add_reference<T>::type operator*() const {return *get();}
376     pointer operator->() const {return get();}
377     pointer get() const {return ptr_.first();}
378     deleter_reference       get_deleter()       {return ptr_.second();}
379     deleter_const_reference get_deleter() const {return ptr_.second();}
380     operator int nat::*() const {return get() ? &nat::for_bool_ : 0;}
381
382     void reset(pointer p = pointer())
383     {
384         pointer t = get();
385         if (t != pointer())
386             get_deleter()(t);
387         ptr_.first() = p;
388     }
389
390     pointer release()
391     {
392         pointer tmp = get();
393         ptr_.first() = pointer();
394         return tmp;
395     }
396
397     void swap(unique_ptr& u) {detail_unique_ptr::swap(ptr_, u.ptr_);}
398 };
399
400 template <class T, class D>
401 class unique_ptr<T[], D>
402 {
403 public:
404     typedef T element_type;
405     typedef D deleter_type;
406     typedef typename detail_unique_ptr::pointer_type<element_type, deleter_type>::type pointer;
407
408 private:
409     detail_unique_ptr::unique_ptr_storage<pointer, deleter_type> ptr_;
410
411     typedef typename add_reference<deleter_type>::type deleter_reference;
412     typedef typename add_reference<const deleter_type>::type deleter_const_reference;
413
414     struct nat {int for_bool_;};
415
416     unique_ptr(unique_ptr&);
417     unique_ptr& operator=(unique_ptr&);
418
419 public:
420     operator detail_unique_ptr::rv<unique_ptr>() {return detail_unique_ptr::rv<unique_ptr>(*this);}
421     unique_ptr(detail_unique_ptr::rv<unique_ptr> r) : ptr_(r->release(), boost::forward<deleter_type>(r->get_deleter())) {}
422     unique_ptr& operator=(detail_unique_ptr::rv<unique_ptr> r)
423     {
424         reset(r->release());
425         ptr_.second() = boost::move(r->get_deleter());
426         return *this;
427     }
428
429     unique_ptr()
430         {
431             BOOST_STATIC_ASSERT(!is_reference<deleter_type>::value);
432             BOOST_STATIC_ASSERT(!is_pointer<deleter_type>::value);
433         }
434
435     explicit unique_ptr(pointer p)
436         : ptr_(p)
437         {
438             BOOST_STATIC_ASSERT(!is_reference<deleter_type>::value);
439             BOOST_STATIC_ASSERT(!is_pointer<deleter_type>::value);
440         }
441
442     unique_ptr(pointer p, typename mpl::if_<is_reference<D>,
443                           volatile typename remove_reference<D>::type&, D>::type d)
444         : ptr_(boost::move(p), boost::forward<D>(const_cast<typename add_reference<D>::type>(d))) {}
445
446     ~unique_ptr() {reset();}
447
448     T& operator[](size_t i) const {return get()[i];}
449     pointer get() const {return ptr_.first();}
450     deleter_reference       get_deleter()       {return ptr_.second();}
451     deleter_const_reference get_deleter() const {return ptr_.second();}
452     operator int nat::*() const {return get() ? &nat::for_bool_ : 0;}
453
454     void reset(pointer p = pointer())
455     {
456         pointer t = get();
457         if (t != pointer())
458             get_deleter()(t);
459         ptr_.first() = p;
460     }
461
462     pointer release()
463     {
464         pointer tmp = get();
465         ptr_.first() = pointer();
466         return tmp;
467     }
468
469     void swap(unique_ptr& u) {detail_unique_ptr::swap(ptr_, u.ptr_);}
470 private:
471     template <class U>
472         explicit unique_ptr(U,
473             typename enable_if_c<detail_unique_ptr::is_convertible<U, pointer>::value>::type* = 0);
474
475     template <class U>
476         unique_ptr(U, typename mpl::if_<is_reference<D>,
477                           volatile typename remove_reference<D>::type&, D>::type,
478                           typename enable_if_c<detail_unique_ptr::is_convertible<U, pointer>::value>::type* = 0);
479 };
480
481 template<class T, class D>
482 inline
483 void
484 swap(unique_ptr<T, D>& x, unique_ptr<T, D>& y)
485 {
486     x.swap(y);
487 }
488
489 template<class T1, class D1, class T2, class D2>
490 inline
491 bool
492 operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
493 {
494     return x.get() == y.get();
495 }
496
497 template<class T1, class D1, class T2, class D2>
498 inline
499 bool
500 operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
501 {
502     return !(x == y);
503 }
504
505 template<class T1, class D1, class T2, class D2> 
506 inline
507 bool
508 operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
509 {
510     return x.get() < y.get();
511 }
512
513 template<class T1, class D1, class T2, class D2> 
514 inline
515 bool
516 operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
517 {
518     return !(y < x);
519 }
520
521 template<class T1, class D1, class T2, class D2> 
522 inline
523 bool
524 operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
525 {
526     return y < x;
527 }
528
529 template<class T1, class D1, class T2, class D2> 
530 inline
531 bool
532 operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y)
533 {
534     return !(x < y);
535 }
536
537 }  // boost
538
539 #endif  // _BOOST_UNIQUE_PTR_HPP_