L4Re - L4 Runtime Environment
unique_ptr
1 // vi:set ft=cpp: -*- Mode: C++ -*-
2 #pragma once
3 
4 #include "type_traits"
5 
6 namespace cxx
7 {
8 
9 template< typename T >
10 struct default_delete
11 {
12  default_delete() {}
13 
14  template< typename U >
15  default_delete(default_delete<U> const &) {}
16 
17  void operator () (T *p) const
18  { delete p; }
19 };
20 
21 template< typename T >
22 struct default_delete<T[]>
23 {
24  default_delete() {}
25 
26  void operator () (T *p)
27  { delete [] p; }
28 };
29 
30 template< typename T, typename C >
31 struct unique_ptr_index_op {};
32 
33 template< typename T, typename C >
34 struct unique_ptr_index_op<T[], C>
35 {
36  typedef T &reference;
37  reference operator [] (int idx) const
38  { return static_cast<C const *>(this)->get()[idx]; }
39 };
40 
41 template< typename T, typename T_Del = default_delete<T> >
42 class unique_ptr : public unique_ptr_index_op<T, unique_ptr<T, T_Del> >
43 {
44 private:
45  struct _unspec;
46  typedef _unspec* _unspec_ptr_type;
47 
48 public:
49  typedef typename cxx::remove_extent<T>::type element_type;
50  typedef element_type *pointer;
51  typedef element_type &reference;
52  typedef T_Del deleter_type;
53 
54  unique_ptr() : _ptr(pointer()) {}
55 
56  explicit unique_ptr(pointer p) : _ptr(p) {}
57 
58  unique_ptr(unique_ptr &&o) : _ptr(o.release()) {}
59 
60  ~unique_ptr() { reset(); }
61 
62  unique_ptr &operator = (unique_ptr &&o)
63  {
64  reset(o.release());
65  return *this;
66  }
67 
68  unique_ptr &operator = (_unspec_ptr_type)
69  {
70  reset();
71  return *this;
72  }
73 
74  element_type &operator * () const { return *get(); }
75  pointer operator -> () const { return get(); }
76 
77  pointer get() const { return _ptr; }
78 
79  operator _unspec_ptr_type () const
80  { return reinterpret_cast<_unspec_ptr_type>(get()); }
81 
82  pointer release()
83  {
84  pointer r = _ptr;
85  _ptr = 0;
86  return r;
87  }
88 
89  void reset(pointer p = pointer())
90  {
91  if (p != get())
92  {
93  deleter_type()(get());
94  _ptr = p;
95  }
96  }
97 
98  unique_ptr(unique_ptr const &) = delete;
99  unique_ptr &operator = (unique_ptr const &) = delete;
100 
101 private:
102  pointer _ptr;
103 };
104 
105 template< typename T >
106 unique_ptr<T>
107 make_unique_ptr(T *p)
108 { return unique_ptr<T>(p); }
109 
110 template< typename T >
111 typename cxx::enable_if<cxx::is_array<T>::value, unique_ptr<T>>::type
112 make_unique(unsigned long size)
113 { return cxx::unique_ptr<T>(new typename cxx::remove_extent<T>::type[size]()); }
114 
115 template< typename T, typename... Args >
116 typename cxx::enable_if<!cxx::is_array<T>::value, unique_ptr<T>>::type
117 make_unique(Args &&... args)
118 { return cxx::unique_ptr<T>(new T(cxx::forward<Args>(args)...)); }
119 
120 }
Our C++ library.
Definition: arith:22