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