Added missing return value in assignment operator.
[profile/ivi/settings-daemon.git] / include / settingsd / smart_ptr.hpp
1 /**
2  * @file smart_ptr.hpp
3  *
4  * @brief C++11 style smart pointer for use by settings plug-ins.
5  *
6  * @author Ossama Othman @<ossama.othman@@intel.com@>
7  *
8  * @copyright @par
9  * Copyright 2013 Intel Corporation All Rights Reserved.
10  * @par
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation;
14  * version 2.1 of the License.
15  * @par
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Lesser General Public License for more details.
20  * @par
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this library; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
24  * Boston, MA  02110-1301  USA
25  */
26
27 #ifndef IVI_SETTINGS_SMART_PTR_HPP
28 #define IVI_SETTINGS_SMART_PTR_HPP
29
30 #include <cstddef>
31 #include <utility>
32 #include <functional>
33
34
35 namespace ivi
36 {
37   namespace settings
38   {
39     /**
40      * @typename smart_ptr
41      *
42      * @brief C++11 style smart pointer for use by settings plug-ins.
43      *
44      * This typename exposes a C++11-style smart pointer interface to
45      * allow RAII based handling of resources provided by third party
46      * libraries, such as Glib.  Core functionality is implemented in
47      * traits that this typename template leverages.
48      */
49     template<typename T>
50     class smart_ptr
51     {
52     public:
53       typedef T *       pointer;
54       typedef T         element_type;
55       typedef traits<T> traits_type;
56
57       constexpr smart_ptr() : p_(nullptr) {}
58
59       constexpr smart_ptr(std::nullptr_t) : p_(nullptr) {}
60
61       explicit smart_ptr(pointer p) : p_(p) {}
62
63       smart_ptr(smart_ptr&& u) : p_(u.p_) { u.p_ = nullptr; }
64
65       ~smart_ptr() { traits_type::release(p_); }
66
67       smart_ptr &
68       operator=(smart_ptr && r)
69       {
70         if (this != &r) {
71           smart_ptr<T> tmp(r);
72           swap(tmp);
73         }
74
75         return *this;
76       }
77
78       smart_ptr &
79       operator=(std::nullptr_t)
80       {
81         reset(nullptr);
82
83         return *this;
84       }
85
86       pointer
87       release()
88       {
89         pointer const old = p_;
90         p_ = nullptr;
91
92         return old;
93       }
94
95       void
96       reset(pointer p = pointer())
97       {
98         smart_ptr<T> tmp(p);
99         swap(tmp);
100       }
101
102       void swap(smart_ptr& other) { std::swap(p_, other.p_); }
103
104       pointer get() const { return p_; }
105
106       explicit operator bool() const { return p_ != nullptr; }
107
108       typename std::add_lvalue_reference<T>::type
109       operator*() const
110       {
111         /**
112          * @todo Throw exception if @c p_ @c == @c nullptr.
113          */
114         return *p_;
115       }
116
117       pointer operator->() const { return p_; }
118
119     private:
120
121       /**
122        * @name Prevent copying
123        */
124       //@{
125       smart_ptr(smart_ptr const &) = delete;
126       smart_ptr & operator=(smart_ptr const &) = delete;
127       //@}
128
129     private:
130
131       /// Pointer to the object being managed.
132       T * p_;
133
134     };
135
136     template<typename T1, typename T2>
137     bool
138     operator==(smart_ptr<T1> const & x, smart_ptr<T2> const & y)
139     {
140       return x.get() == y.get();
141     }
142
143     template<typename T1, typename T2>
144     bool
145     operator!=(smart_ptr<T1> const & x, smart_ptr<T2> const & y)
146     {
147       return x.get() != y.get();
148     }
149
150     template<typename T1, typename T2>
151     bool
152     operator<(smart_ptr<T1> const & x, smart_ptr<T2> const & y)
153     {
154       typedef typename
155         std::common_type<typename smart_ptr<T1>::pointer,
156                          typename smart_ptr<T2>::pointer>::type type;
157
158       return std::less<type>()(x.get(), y.get());
159     }
160
161
162     template<typename T1, typename T2>
163     bool operator<=(smart_ptr<T1> const & x, smart_ptr<T2> const & y)
164     {
165       return !(y < x);
166     }
167
168     template<typename T1, typename T2>
169     bool
170     operator>(smart_ptr<T1> const & x, smart_ptr<T2> const & y)
171     {
172       return (y < x);
173     }
174
175     template<typename T1, typename T2>
176     bool
177     operator>=(smart_ptr<T1> const & x, smart_ptr<T2> const & y)
178     {
179       return !(x < y);
180     }
181
182     template<typename T>
183     bool
184     operator==(smart_ptr<T> const & x, std::nullptr_t) noexcept
185     {
186       return !x;
187     }
188
189     template<typename T>
190     bool
191     operator==(std::nullptr_t, smart_ptr<T> const & x) noexcept
192     {
193       return !x;
194     }
195
196     template<typename T>
197     bool
198     operator!=(smart_ptr<T> const & x, std::nullptr_t) noexcept
199     {
200       return static_cast<bool>(x);
201     }
202
203     template<typename T>
204     bool
205     operator!=(std::nullptr_t, smart_ptr<T> const & x) noexcept
206     {
207       return static_cast<bool>(x);
208     }
209
210     template<typename T>
211     bool
212     operator<(smart_ptr<T> const & x, std::nullptr_t)
213     {
214       return std::less<typename smart_ptr<T>::pointer>()(x.get(), nullptr);
215     }
216
217     template<typename T>
218     bool
219     operator<(std::nullptr_t, smart_ptr<T> const & y)
220     {
221       return std::less<typename smart_ptr<T>::pointer>()(nullptr, y.get());
222     }
223
224     template<typename T>
225     bool
226     operator<=(smart_ptr<T> const & x, std::nullptr_t)
227     {
228       return nullptr < x;
229     }
230
231     template<typename T>
232     bool
233     operator<=(std::nullptr_t, smart_ptr<T> const & y)
234     {
235       return y < nullptr;
236     }
237
238     template<typename T>
239     bool
240     operator>(smart_ptr<T> const & x, std::nullptr_t)
241     {
242       return !(nullptr < x);
243     }
244
245     template<typename T>
246     bool
247     operator>(std::nullptr_t, smart_ptr<T> const & y)
248     {
249       return !(y < nullptr);
250     }
251
252     template<typename T>
253     bool
254     operator>=(smart_ptr<T> const & x, std::nullptr_t)
255     {
256       return !(x < nullptr);
257     }
258
259     template<typename T>
260     bool
261     operator>=(std::nullptr_t, smart_ptr<T> const & y)
262     {
263       return !(nullptr < y);
264     }
265
266   }
267 }
268
269 namespace std
270 {
271   template<typename T>
272   void
273   swap(ivi::settings::smart_ptr<T> & lhs,
274        ivi::settings::smart_ptr<T> & rhs)
275   {
276     lhs.swap(rhs);
277   }
278
279   template<typename T>
280   struct hash<ivi::settings::smart_ptr<T>>
281   {
282     typedef ivi::settings::smart_ptr<T> argument_type;
283     typedef std::size_t                 result_type;
284
285     hash();
286
287     result_type
288       operator()(argument_type const & p) const
289     {
290       typedef typename argument_type::pointer key_type;
291
292       return hash<key_type>(p.get());
293     }
294   };
295 }
296
297 #endif /* IVI_SETTINGS_SMART_PTR_HPP */
298
299
300 // Local Variables:
301 // mode:c++
302 // c-basic-offset:2
303 // indent-tabs-mode: nil
304 // End: