Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(329)

Side by Side Diff: include/private/SkUniquePtr.h

Issue 1561683002: Start using <type_traits> and <utility> (C++11). (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #ifndef SkUniquePtr_DEFINED 8 #ifndef SkUniquePtr_DEFINED
9 #define SkUniquePtr_DEFINED 9 #define SkUniquePtr_DEFINED
10 10
11 #include "SkTLogic.h" 11 #include "SkTLogic.h"
12 #include "SkUtility.h" 12 #include <utility>
13 13
14 namespace skstd { 14 namespace skstd {
15 15
16 template <typename T> struct default_delete { 16 template <typename T> struct default_delete {
17 /*constexpr*/ default_delete() /*noexcept*/ = default; 17 /*constexpr*/ default_delete() /*noexcept*/ = default;
18 18
19 template <typename U, typename = enable_if_t<is_convertible<U*, T*>::value>> 19 template <typename U, typename = enable_if_t<is_convertible<U*, T*>::value>>
20 default_delete(const default_delete<U>&) /*noexcept*/ {} 20 default_delete(const default_delete<U>&) /*noexcept*/ {}
21 21
22 void operator()(T* obj) const { 22 void operator()(T* obj) const {
(...skipping 21 matching lines...) Expand all
44 public: 44 public:
45 using pointer = typename pointer_type_detector::type; 45 using pointer = typename pointer_type_detector::type;
46 using element_type = T; 46 using element_type = T;
47 using deleter_type = D; 47 using deleter_type = D;
48 48
49 private: 49 private:
50 template <typename B, bool = is_empty<B>::value /*&& !is_final<B>::value*/> 50 template <typename B, bool = is_empty<B>::value /*&& !is_final<B>::value*/>
51 struct compressed_base : private B { 51 struct compressed_base : private B {
52 /*constexpr*/ compressed_base() : B() {} 52 /*constexpr*/ compressed_base() : B() {}
53 /*constexpr*/ compressed_base(const B& b) : B(b) {} 53 /*constexpr*/ compressed_base(const B& b) : B(b) {}
54 /*constexpr*/ compressed_base(const B&& b) : B(move(b)) {} 54 /*constexpr*/ compressed_base(const B&& b) : B(std::move(b)) {}
55 /*constexpr*/ B& get() /*noexcept*/ { return *this; } 55 /*constexpr*/ B& get() /*noexcept*/ { return *this; }
56 /*constexpr*/ B const& get() const /*noexcept*/ { return *this; } 56 /*constexpr*/ B const& get() const /*noexcept*/ { return *this; }
57 void swap(compressed_base&) /*noexcept*/ { } 57 void swap(compressed_base&) /*noexcept*/ { }
58 }; 58 };
59 59
60 template <typename B> struct compressed_base<B, false> { 60 template <typename B> struct compressed_base<B, false> {
61 B fb; 61 B fb;
62 /*constexpr*/ compressed_base() : B() {} 62 /*constexpr*/ compressed_base() : B() {}
63 /*constexpr*/ compressed_base(const B& b) : fb(b) {} 63 /*constexpr*/ compressed_base(const B& b) : fb(b) {}
64 /*constexpr*/ compressed_base(const B&& b) : fb(move(b)) {} 64 /*constexpr*/ compressed_base(const B&& b) : fb(std::move(b)) {}
65 /*constexpr*/ B& get() /*noexcept*/ { return fb; } 65 /*constexpr*/ B& get() /*noexcept*/ { return fb; }
66 /*constexpr*/ B const& get() const /*noexcept*/ { return fb; } 66 /*constexpr*/ B const& get() const /*noexcept*/ { return fb; }
67 void swap(compressed_base& that) /*noexcept*/ { SkTSwap(fb, that.fB); } 67 void swap(compressed_base& that) /*noexcept*/ { SkTSwap(fb, that.fB); }
68 }; 68 };
69 69
70 struct compressed_data : private compressed_base<deleter_type> { 70 struct compressed_data : private compressed_base<deleter_type> {
71 pointer fPtr; 71 pointer fPtr;
72 /*constexpr*/ compressed_data() : compressed_base<deleter_type>(), fPtr( ) {} 72 /*constexpr*/ compressed_data() : compressed_base<deleter_type>(), fPtr( ) {}
73 /*constexpr*/ compressed_data(const pointer& ptr, const deleter_type& d) 73 /*constexpr*/ compressed_data(const pointer& ptr, const deleter_type& d)
74 : compressed_base<deleter_type>(d), fPtr(ptr) {} 74 : compressed_base<deleter_type>(d), fPtr(ptr) {}
75 template <typename U1, typename U2, typename = enable_if_t< 75 template <typename U1, typename U2, typename = enable_if_t<
76 is_convertible<U1, pointer>::value && is_convertible<U2, deleter_typ e>::value 76 is_convertible<U1, pointer>::value && is_convertible<U2, deleter_typ e>::value
77 >> /*constexpr*/ compressed_data(U1&& ptr, U2&& d) 77 >> /*constexpr*/ compressed_data(U1&& ptr, U2&& d)
78 : compressed_base<deleter_type>(skstd::forward<U2>(d)), fPtr(skstd:: forward<U1>(ptr)) {} 78 : compressed_base<deleter_type>(std::forward<U2>(d)), fPtr(std::forw ard<U1>(ptr)) {}
79 /*constexpr*/ pointer& getPointer() /*noexcept*/ { return fPtr; } 79 /*constexpr*/ pointer& getPointer() /*noexcept*/ { return fPtr; }
80 /*constexpr*/ pointer const& getPointer() const /*noexcept*/ { return fP tr; } 80 /*constexpr*/ pointer const& getPointer() const /*noexcept*/ { return fP tr; }
81 /*constexpr*/ deleter_type& getDeleter() /*noexcept*/ { 81 /*constexpr*/ deleter_type& getDeleter() /*noexcept*/ {
82 return compressed_base<deleter_type>::get(); 82 return compressed_base<deleter_type>::get();
83 } 83 }
84 /*constexpr*/ deleter_type const& getDeleter() const /*noexcept*/ { 84 /*constexpr*/ deleter_type const& getDeleter() const /*noexcept*/ {
85 return compressed_base<deleter_type>::get(); 85 return compressed_base<deleter_type>::get();
86 } 86 }
87 void swap(compressed_data& that) /*noexcept*/ { 87 void swap(compressed_data& that) /*noexcept*/ {
88 compressed_base<deleter_type>::swap(static_cast<compressed_base<dele ter_type>>(that)); 88 compressed_base<deleter_type>::swap(static_cast<compressed_base<dele ter_type>>(that));
89 SkTSwap(fPtr, that.fPtr); 89 SkTSwap(fPtr, that.fPtr);
90 } 90 }
91 }; 91 };
92 compressed_data data; 92 compressed_data data;
93 93
94 public: 94 public:
95 /*constexpr*/ unique_ptr() /*noexcept*/ : data() { 95 /*constexpr*/ unique_ptr() /*noexcept*/ : data() {
96 static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr func tion pointer!"); 96 static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr func tion pointer!");
97 } 97 }
98 98
99 /*constexpr*/ unique_ptr(skstd::nullptr_t) /*noexcept*/ : unique_ptr() { } 99 /*constexpr*/ unique_ptr(std::nullptr_t) /*noexcept*/ : unique_ptr() { }
bungeman-skia 2016/01/05 18:54:43 std::nullptr_t is provided by <cstddef>
bungeman-skia 2016/01/05 18:59:41 Done.
100 100
101 explicit unique_ptr(pointer ptr) /*noexcept*/ : data(ptr, deleter_type()) { 101 explicit unique_ptr(pointer ptr) /*noexcept*/ : data(ptr, deleter_type()) {
102 static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr func tion pointer!"); 102 static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr func tion pointer!");
103 } 103 }
104 104
105 unique_ptr(pointer ptr, 105 unique_ptr(pointer ptr,
106 conditional_t<is_reference<deleter_type>::value, deleter_type,con st deleter_type&> d) 106 conditional_t<is_reference<deleter_type>::value, deleter_type,con st deleter_type&> d)
107 /*noexcept*/ : data(ptr, d) 107 /*noexcept*/ : data(ptr, d)
108 {} 108 {}
109 109
110 unique_ptr(pointer ptr, remove_reference_t<deleter_type>&& d) /*noexcept*/ 110 unique_ptr(pointer ptr, remove_reference_t<deleter_type>&& d) /*noexcept*/
111 : data(move(ptr), move(d)) 111 : data(std::move(ptr), std::move(d))
112 { 112 {
113 static_assert(!is_reference<deleter_type>::value, 113 static_assert(!is_reference<deleter_type>::value,
114 "Binding an rvalue reference deleter as an lvalue reference deleter is not allowed."); 114 "Binding an rvalue reference deleter as an lvalue reference deleter is not allowed.");
115 } 115 }
116 116
117 117
118 unique_ptr(unique_ptr&& that) /*noexcept*/ 118 unique_ptr(unique_ptr&& that) /*noexcept*/
119 : data(that.release(), forward<deleter_type>(that.get_deleter())) 119 : data(that.release(), std::forward<deleter_type>(that.get_deleter()))
120 {} 120 {}
121 121
122 template <typename U, typename ThatD, typename = enable_if_t< 122 template <typename U, typename ThatD, typename = enable_if_t<
123 is_convertible<typename unique_ptr<U, ThatD>::pointer, pointer>::value & & 123 is_convertible<typename unique_ptr<U, ThatD>::pointer, pointer>::value & &
124 !is_array<U>::value && 124 !is_array<U>::value &&
125 conditional_t<is_reference<D>::value, is_same<ThatD, D>, is_convertible< ThatD, D>>::value>> 125 conditional_t<is_reference<D>::value, is_same<ThatD, D>, is_convertible< ThatD, D>>::value>>
126 unique_ptr(unique_ptr<U, ThatD>&& that) /*noexcept*/ 126 unique_ptr(unique_ptr<U, ThatD>&& that) /*noexcept*/
127 : data(that.release(), forward<ThatD>(that.get_deleter())) 127 : data(that.release(), std::forward<ThatD>(that.get_deleter()))
128 {} 128 {}
129 129
130 ~unique_ptr() /*noexcept*/ { 130 ~unique_ptr() /*noexcept*/ {
131 pointer& ptr = data.getPointer(); 131 pointer& ptr = data.getPointer();
132 if (ptr != nullptr) { 132 if (ptr != nullptr) {
133 get_deleter()(ptr); 133 get_deleter()(ptr);
134 } 134 }
135 ptr = pointer(); 135 ptr = pointer();
136 } 136 }
137 137
138 unique_ptr& operator=(unique_ptr&& that) /*noexcept*/ { 138 unique_ptr& operator=(unique_ptr&& that) /*noexcept*/ {
139 reset(that.release()); 139 reset(that.release());
140 get_deleter() = forward<deleter_type>(that.get_deleter()); 140 get_deleter() = std::forward<deleter_type>(that.get_deleter());
141 return *this; 141 return *this;
142 } 142 }
143 143
144 template <typename U, typename ThatD> enable_if_t< 144 template <typename U, typename ThatD> enable_if_t<
145 is_convertible<typename unique_ptr<U, ThatD>::pointer, pointer>::value & & 145 is_convertible<typename unique_ptr<U, ThatD>::pointer, pointer>::value & &
146 !is_array<U>::value, 146 !is_array<U>::value,
147 unique_ptr&> operator=(unique_ptr<U, ThatD>&& that) /*noexcept*/ { 147 unique_ptr&> operator=(unique_ptr<U, ThatD>&& that) /*noexcept*/ {
148 reset(that.release()); 148 reset(that.release());
149 get_deleter() = forward<ThatD>(that.get_deleter()); 149 get_deleter() = std::forward<ThatD>(that.get_deleter());
150 return *this; 150 return *this;
151 } 151 }
152 152
153 unique_ptr& operator=(skstd::nullptr_t) /*noexcept*/ { 153 unique_ptr& operator=(std::nullptr_t) /*noexcept*/ {
154 reset(); 154 reset();
155 return *this; 155 return *this;
156 } 156 }
157 157
158 add_lvalue_reference_t<element_type> operator*() const { 158 add_lvalue_reference_t<element_type> operator*() const {
159 SkASSERT(get() != pointer()); 159 SkASSERT(get() != pointer());
160 return *get(); 160 return *get();
161 } 161 }
162 162
163 pointer operator->() const /*noexcept*/ { 163 pointer operator->() const /*noexcept*/ {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 public: 214 public:
215 using pointer = typename pointer_type_detector::type; 215 using pointer = typename pointer_type_detector::type;
216 using element_type = T; 216 using element_type = T;
217 using deleter_type = D; 217 using deleter_type = D;
218 218
219 private: 219 private:
220 template <typename B, bool = is_empty<B>::value /*&& !is_final<B>::value*/> 220 template <typename B, bool = is_empty<B>::value /*&& !is_final<B>::value*/>
221 struct compressed_base : private B { 221 struct compressed_base : private B {
222 /*constexpr*/ compressed_base() : B() {} 222 /*constexpr*/ compressed_base() : B() {}
223 /*constexpr*/ compressed_base(const B& b) : B(b) {} 223 /*constexpr*/ compressed_base(const B& b) : B(b) {}
224 /*constexpr*/ compressed_base(const B&& b) : B(move(b)) {} 224 /*constexpr*/ compressed_base(const B&& b) : B(std::move(b)) {}
225 /*constexpr*/ B& get() /*noexcept*/ { return *this; } 225 /*constexpr*/ B& get() /*noexcept*/ { return *this; }
226 /*constexpr*/ B const& get() const /*noexcept*/ { return *this; } 226 /*constexpr*/ B const& get() const /*noexcept*/ { return *this; }
227 void swap(compressed_base&) /*noexcept*/ { } 227 void swap(compressed_base&) /*noexcept*/ { }
228 }; 228 };
229 229
230 template <typename B> struct compressed_base<B, false> { 230 template <typename B> struct compressed_base<B, false> {
231 B fb; 231 B fb;
232 /*constexpr*/ compressed_base() : B() {} 232 /*constexpr*/ compressed_base() : B() {}
233 /*constexpr*/ compressed_base(const B& b) : fb(b) {} 233 /*constexpr*/ compressed_base(const B& b) : fb(b) {}
234 /*constexpr*/ compressed_base(const B&& b) : fb(move(b)) {} 234 /*constexpr*/ compressed_base(const B&& b) : fb(std::move(b)) {}
235 /*constexpr*/ B& get() /*noexcept*/ { return fb; } 235 /*constexpr*/ B& get() /*noexcept*/ { return fb; }
236 /*constexpr*/ B const& get() const /*noexcept*/ { return fb; } 236 /*constexpr*/ B const& get() const /*noexcept*/ { return fb; }
237 void swap(compressed_base& that) /*noexcept*/ { SkTSwap(fb, that.fB); } 237 void swap(compressed_base& that) /*noexcept*/ { SkTSwap(fb, that.fB); }
238 }; 238 };
239 239
240 struct compressed_data : private compressed_base<deleter_type> { 240 struct compressed_data : private compressed_base<deleter_type> {
241 pointer fPtr; 241 pointer fPtr;
242 /*constexpr*/ compressed_data() : compressed_base<deleter_type>(), fPtr( ) {} 242 /*constexpr*/ compressed_data() : compressed_base<deleter_type>(), fPtr( ) {}
243 /*constexpr*/ compressed_data(const pointer& ptr, const deleter_type& d) 243 /*constexpr*/ compressed_data(const pointer& ptr, const deleter_type& d)
244 : compressed_base<deleter_type>(d), fPtr(ptr) {} 244 : compressed_base<deleter_type>(d), fPtr(ptr) {}
245 template <typename U1, typename U2, typename = enable_if_t< 245 template <typename U1, typename U2, typename = enable_if_t<
246 is_convertible<U1, pointer>::value && is_convertible<U2, deleter_typ e>::value 246 is_convertible<U1, pointer>::value && is_convertible<U2, deleter_typ e>::value
247 >> /*constexpr*/ compressed_data(U1&& ptr, U2&& d) 247 >> /*constexpr*/ compressed_data(U1&& ptr, U2&& d)
248 : compressed_base<deleter_type>(skstd::forward<U2>(d)), fPtr(skstd:: forward<U1>(ptr)) {} 248 : compressed_base<deleter_type>(std::forward<U2>(d)), fPtr(std::forw ard<U1>(ptr)) {}
249 /*constexpr*/ pointer& getPointer() /*noexcept*/ { return fPtr; } 249 /*constexpr*/ pointer& getPointer() /*noexcept*/ { return fPtr; }
250 /*constexpr*/ pointer const& getPointer() const /*noexcept*/ { return fP tr; } 250 /*constexpr*/ pointer const& getPointer() const /*noexcept*/ { return fP tr; }
251 /*constexpr*/ deleter_type& getDeleter() /*noexcept*/ { 251 /*constexpr*/ deleter_type& getDeleter() /*noexcept*/ {
252 return compressed_base<deleter_type>::get(); 252 return compressed_base<deleter_type>::get();
253 } 253 }
254 /*constexpr*/ deleter_type const& getDeleter() const /*noexcept*/ { 254 /*constexpr*/ deleter_type const& getDeleter() const /*noexcept*/ {
255 return compressed_base<deleter_type>::get(); 255 return compressed_base<deleter_type>::get();
256 } 256 }
257 void swap(compressed_data& that) /*noexcept*/ { 257 void swap(compressed_data& that) /*noexcept*/ {
258 compressed_base<deleter_type>::swap(static_cast<compressed_base<dele ter_type>>(that)); 258 compressed_base<deleter_type>::swap(static_cast<compressed_base<dele ter_type>>(that));
259 SkTSwap(fPtr, that.fPtr); 259 SkTSwap(fPtr, that.fPtr);
260 } 260 }
261 }; 261 };
262 compressed_data data; 262 compressed_data data;
263 263
264 public: 264 public:
265 /*constexpr*/ unique_ptr() /*noexcept*/ : data() { 265 /*constexpr*/ unique_ptr() /*noexcept*/ : data() {
266 static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr func tion pointer!"); 266 static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr func tion pointer!");
267 } 267 }
268 268
269 /*constexpr*/ unique_ptr(skstd::nullptr_t) /*noexcept*/ : unique_ptr() { } 269 /*constexpr*/ unique_ptr(std::nullptr_t) /*noexcept*/ : unique_ptr() { }
270 270
271 explicit unique_ptr(pointer ptr) /*noexcept*/ : data(ptr, deleter_type()) { 271 explicit unique_ptr(pointer ptr) /*noexcept*/ : data(ptr, deleter_type()) {
272 static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr func tion pointer!"); 272 static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr func tion pointer!");
273 } 273 }
274 274
275 unique_ptr(pointer ptr, 275 unique_ptr(pointer ptr,
276 conditional_t<is_reference<deleter_type>::value, deleter_type,con st deleter_type&> d) 276 conditional_t<is_reference<deleter_type>::value, deleter_type,con st deleter_type&> d)
277 /*noexcept*/ : data(ptr, d) 277 /*noexcept*/ : data(ptr, d)
278 {} 278 {}
279 279
280 unique_ptr(pointer ptr, remove_reference_t<deleter_type>&& d) /*noexcept*/ 280 unique_ptr(pointer ptr, remove_reference_t<deleter_type>&& d) /*noexcept*/
281 : data(move(ptr), move(d)) 281 : data(std::move(ptr), std::move(d))
282 { 282 {
283 static_assert(!is_reference<deleter_type>::value, 283 static_assert(!is_reference<deleter_type>::value,
284 "Binding an rvalue reference deleter as an lvalue reference deleter is not allowed."); 284 "Binding an rvalue reference deleter as an lvalue reference deleter is not allowed.");
285 } 285 }
286 286
287 unique_ptr(unique_ptr&& that) /*noexcept*/ 287 unique_ptr(unique_ptr&& that) /*noexcept*/
288 : data(that.release(), forward<deleter_type>(that.get_deleter())) 288 : data(that.release(), std::forward<deleter_type>(that.get_deleter()))
289 {} 289 {}
290 290
291 ~unique_ptr() { 291 ~unique_ptr() {
292 pointer& ptr = data.getPointer(); 292 pointer& ptr = data.getPointer();
293 if (ptr != nullptr) { 293 if (ptr != nullptr) {
294 get_deleter()(ptr); 294 get_deleter()(ptr);
295 } 295 }
296 ptr = pointer(); 296 ptr = pointer();
297 } 297 }
298 298
299 unique_ptr& operator=(unique_ptr&& that) /*noexcept*/ { 299 unique_ptr& operator=(unique_ptr&& that) /*noexcept*/ {
300 reset(that.release()); 300 reset(that.release());
301 get_deleter() = forward<deleter_type>(that.get_deleter()); 301 get_deleter() = std::forward<deleter_type>(that.get_deleter());
302 return *this; 302 return *this;
303 } 303 }
304 304
305 unique_ptr& operator=(skstd::nullptr_t) /*noexcept*/ { 305 unique_ptr& operator=(std::nullptr_t) /*noexcept*/ {
306 reset(); 306 reset();
307 return *this; 307 return *this;
308 } 308 }
309 309
310 add_lvalue_reference_t<element_type> operator[](size_t i) const { 310 add_lvalue_reference_t<element_type> operator[](size_t i) const {
311 SkASSERT(get() != pointer()); 311 SkASSERT(get() != pointer());
312 return get()[i]; 312 return get()[i];
313 } 313 }
314 314
315 pointer get() const /*noexcept*/ { 315 pointer get() const /*noexcept*/ {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 inline void swap(unique_ptr<T, D>& a, unique_ptr<T, D>& b) /*noexcept*/ { 356 inline void swap(unique_ptr<T, D>& a, unique_ptr<T, D>& b) /*noexcept*/ {
357 a.swap(b); 357 a.swap(b);
358 } 358 }
359 359
360 template <typename T, typename D, typename U, typename ThatD> 360 template <typename T, typename D, typename U, typename ThatD>
361 inline bool operator==(const unique_ptr<T, D>& a, const unique_ptr<U, ThatD>& b) { 361 inline bool operator==(const unique_ptr<T, D>& a, const unique_ptr<U, ThatD>& b) {
362 return a.get() == b.get(); 362 return a.get() == b.get();
363 } 363 }
364 364
365 template <typename T, typename D> 365 template <typename T, typename D>
366 inline bool operator==(const unique_ptr<T, D>& a, skstd::nullptr_t) /*noexcept*/ { 366 inline bool operator==(const unique_ptr<T, D>& a, std::nullptr_t) /*noexcept*/ {
367 //return !a; 367 //return !a;
368 return !a.is_attached(); 368 return !a.is_attached();
369 } 369 }
370 370
371 template <typename T, typename D> 371 template <typename T, typename D>
372 inline bool operator==(skstd::nullptr_t, const unique_ptr<T, D>& b) /*noexcept*/ { 372 inline bool operator==(std::nullptr_t, const unique_ptr<T, D>& b) /*noexcept*/ {
373 //return !b; 373 //return !b;
374 return !b.is_attached(); 374 return !b.is_attached();
375 } 375 }
376 376
377 template <typename T, typename D, typename U, typename ThatD> 377 template <typename T, typename D, typename U, typename ThatD>
378 inline bool operator!=(const unique_ptr<T, D>& a, const unique_ptr<U, ThatD>& b) { 378 inline bool operator!=(const unique_ptr<T, D>& a, const unique_ptr<U, ThatD>& b) {
379 return a.get() != b.get(); 379 return a.get() != b.get();
380 } 380 }
381 381
382 template <typename T, typename D> 382 template <typename T, typename D>
383 inline bool operator!=(const unique_ptr<T, D>& a, skstd::nullptr_t) /*noexcept*/ { 383 inline bool operator!=(const unique_ptr<T, D>& a, std::nullptr_t) /*noexcept*/ {
384 //return (bool)a; 384 //return (bool)a;
385 return a.is_attached(); 385 return a.is_attached();
386 } 386 }
387 387
388 template <typename T, typename D> 388 template <typename T, typename D>
389 inline bool operator!=(skstd::nullptr_t, const unique_ptr<T, D>& b) /*noexcept*/ { 389 inline bool operator!=(std::nullptr_t, const unique_ptr<T, D>& b) /*noexcept*/ {
390 //return (bool)b; 390 //return (bool)b;
391 return b.is_attached(); 391 return b.is_attached();
392 } 392 }
393 393
394 } // namespace skstd 394 } // namespace skstd
395 395
396 #endif 396 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698