TIVI-1924: Initial commit of IVI settings daemon.
[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
84       pointer
85       release()
86       {
87         pointer const old = p_;
88         p_ = nullptr;
89
90         return old;
91       }
92
93       void
94       reset(pointer p = pointer())
95       {
96         smart_ptr<T> tmp(p);
97         swap(tmp);
98       }
99
100       void swap(smart_ptr& other) { std::swap(p_, other.p_); }
101
102       pointer get() const { return p_; }
103
104       explicit operator bool() const { return p_ != nullptr; }
105
106       typename std::add_lvalue_reference<T>::type
107       operator*() const
108       {
109         /**
110          * @todo Throw exception if @c p_ @c == @c nullptr.
111          */
112         return *p_;
113       }
114
115       pointer operator->() const { return p_; }
116
117     private:
118
119       /**
120        * @name Prevent copying
121        */
122       //@{
123       smart_ptr(smart_ptr const &) = delete;
124       smart_ptr & operator=(smart_ptr const &) = delete;
125       //@}
126
127     private:
128
129       /// Pointer to the object being managed.
130       T * p_;
131
132     };
133
134     template<typename T1, typename T2>
135     bool
136     operator==(smart_ptr<T1> const & x, smart_ptr<T2> const & y)
137     {
138       return x.get() == y.get();
139     }
140
141     template<typename T1, typename T2>
142     bool
143     operator!=(smart_ptr<T1> const & x, smart_ptr<T2> const & y)
144     {
145       return x.get() != y.get();
146     }
147
148     template<typename T1, typename T2>
149     bool
150     operator<(smart_ptr<T1> const & x, smart_ptr<T2> const & y)
151     {
152       typedef typename
153         std::common_type<typename smart_ptr<T1>::pointer,
154                          typename smart_ptr<T2>::pointer>::type type;
155
156       return std::less<type>()(x.get(), y.get());
157     }
158
159
160     template<typename T1, typename T2>
161     bool operator<=(smart_ptr<T1> const & x, smart_ptr<T2> const & y)
162     {
163       return !(y < x);
164     }
165
166     template<typename T1, typename T2>
167     bool
168     operator>(smart_ptr<T1> const & x, smart_ptr<T2> const & y)
169     {
170       return (y < x);
171     }
172
173     template<typename T1, typename T2>
174     bool
175     operator>=(smart_ptr<T1> const & x, smart_ptr<T2> const & y)
176     {
177       return !(x < y);
178     }
179
180     template<typename T>
181     bool
182     operator==(smart_ptr<T> const & x, std::nullptr_t) noexcept
183     {
184       return !x;
185     }
186
187     template<typename T>
188     bool
189     operator==(std::nullptr_t, smart_ptr<T> const & x) noexcept
190     {
191       return !x;
192     }
193
194     template<typename T>
195     bool
196     operator!=(smart_ptr<T> const & x, std::nullptr_t) noexcept
197     {
198       return static_cast<bool>(x);
199     }
200
201     template<typename T>
202     bool
203     operator!=(std::nullptr_t, smart_ptr<T> const & x) noexcept
204     {
205       return static_cast<bool>(x);
206     }
207
208     template<typename T>
209     bool
210     operator<(smart_ptr<T> const & x, std::nullptr_t)
211     {
212       return std::less<typename smart_ptr<T>::pointer>()(x.get(), nullptr);
213     }
214
215     template<typename T>
216     bool
217     operator<(std::nullptr_t, smart_ptr<T> const & y)
218     {
219       return std::less<typename smart_ptr<T>::pointer>()(nullptr, y.get());
220     }
221
222     template<typename T>
223     bool
224     operator<=(smart_ptr<T> const & x, std::nullptr_t)
225     {
226       return nullptr < x;
227     }
228
229     template<typename T>
230     bool
231     operator<=(std::nullptr_t, smart_ptr<T> const & y)
232     {
233       return y < nullptr;
234     }
235
236     template<typename T>
237     bool
238     operator>(smart_ptr<T> const & x, std::nullptr_t)
239     {
240       return !(nullptr < x);
241     }
242
243     template<typename T>
244     bool
245     operator>(std::nullptr_t, smart_ptr<T> const & y)
246     {
247       return !(y < nullptr);
248     }
249
250     template<typename T>
251     bool
252     operator>=(smart_ptr<T> const & x, std::nullptr_t)
253     {
254       return !(x < nullptr);
255     }
256
257     template<typename T>
258     bool
259     operator>=(std::nullptr_t, smart_ptr<T> const & y)
260     {
261       return !(nullptr < y);
262     }
263
264   }
265 }
266
267 namespace std
268 {
269   template<typename T>
270   void
271   swap(ivi::settings::smart_ptr<T> & lhs,
272        ivi::settings::smart_ptr<T> & rhs)
273   {
274     lhs.swap(rhs);
275   }
276
277   template<typename T>
278   struct hash<ivi::settings::smart_ptr<T>>
279   {
280     typedef ivi::settings::smart_ptr<T> argument_type;
281     typedef std::size_t                 result_type;
282
283     hash();
284
285     result_type
286       operator()(argument_type const & p) const
287     {
288       typedef typename argument_type::pointer key_type;
289
290       return hash<key_type>(p.get());
291     }
292   };
293 }
294
295 #endif /* IVI_SETTINGS_SMART_PTR_HPP */
296
297
298 // Local Variables:
299 // mode:c++
300 // c-basic-offset:2
301 // indent-tabs-mode: nil
302 // End: