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

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: Fix skstd::unique_ptr::compressed_pair. 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
« no previous file with comments | « include/private/SkTemplates.h ('k') | include/private/SkUtility.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <cstddef>
13 #include <utility>
13 14
14 namespace skstd { 15 namespace skstd {
15 16
16 template <typename T> struct default_delete { 17 template <typename T> struct default_delete {
17 /*constexpr*/ default_delete() /*noexcept*/ = default; 18 /*constexpr*/ default_delete() /*noexcept*/ = default;
18 19
19 template <typename U, typename = enable_if_t<is_convertible<U*, T*>::value>> 20 template <typename U, typename = enable_if_t<is_convertible<U*, T*>::value>>
20 default_delete(const default_delete<U>&) /*noexcept*/ {} 21 default_delete(const default_delete<U>&) /*noexcept*/ {}
21 22
22 void operator()(T* obj) const { 23 void operator()(T* obj) const {
(...skipping 21 matching lines...) Expand all
44 public: 45 public:
45 using pointer = typename pointer_type_detector::type; 46 using pointer = typename pointer_type_detector::type;
46 using element_type = T; 47 using element_type = T;
47 using deleter_type = D; 48 using deleter_type = D;
48 49
49 private: 50 private:
50 template <typename B, bool = is_empty<B>::value /*&& !is_final<B>::value*/> 51 template <typename B, bool = is_empty<B>::value /*&& !is_final<B>::value*/>
51 struct compressed_base : private B { 52 struct compressed_base : private B {
52 /*constexpr*/ compressed_base() : B() {} 53 /*constexpr*/ compressed_base() : B() {}
53 /*constexpr*/ compressed_base(const B& b) : B(b) {} 54 /*constexpr*/ compressed_base(const B& b) : B(b) {}
54 /*constexpr*/ compressed_base(const B&& b) : B(move(b)) {} 55 /*constexpr*/ compressed_base(B&& b) : B(std::move(b)) {}
55 /*constexpr*/ B& get() /*noexcept*/ { return *this; } 56 /*constexpr*/ B& get() /*noexcept*/ { return *this; }
56 /*constexpr*/ B const& get() const /*noexcept*/ { return *this; } 57 /*constexpr*/ B const& get() const /*noexcept*/ { return *this; }
57 void swap(compressed_base&) /*noexcept*/ { } 58 void swap(compressed_base&) /*noexcept*/ { }
58 }; 59 };
59 60
60 template <typename B> struct compressed_base<B, false> { 61 template <typename B> struct compressed_base<B, false> {
61 B fb; 62 B fb;
62 /*constexpr*/ compressed_base() : B() {} 63 /*constexpr*/ compressed_base() : B() {}
63 /*constexpr*/ compressed_base(const B& b) : fb(b) {} 64 /*constexpr*/ compressed_base(const B& b) : fb(b) {}
64 /*constexpr*/ compressed_base(const B&& b) : fb(move(b)) {} 65 /*constexpr*/ compressed_base(B&& b) : fb(std::move(b)) {}
65 /*constexpr*/ B& get() /*noexcept*/ { return fb; } 66 /*constexpr*/ B& get() /*noexcept*/ { return fb; }
66 /*constexpr*/ B const& get() const /*noexcept*/ { return fb; } 67 /*constexpr*/ B const& get() const /*noexcept*/ { return fb; }
67 void swap(compressed_base& that) /*noexcept*/ { SkTSwap(fb, that.fB); } 68 void swap(compressed_base& that) /*noexcept*/ { SkTSwap(fb, that.fB); }
68 }; 69 };
69 70
70 struct compressed_data : private compressed_base<deleter_type> { 71 struct compressed_data : private compressed_base<deleter_type> {
71 pointer fPtr; 72 pointer fPtr;
72 /*constexpr*/ compressed_data() : compressed_base<deleter_type>(), fPtr( ) {} 73 /*constexpr*/ compressed_data() : compressed_base<deleter_type>(), fPtr( ) {}
73 /*constexpr*/ compressed_data(const pointer& ptr, const deleter_type& d) 74 /*constexpr*/ compressed_data(const pointer& ptr, const deleter_type& d)
74 : compressed_base<deleter_type>(d), fPtr(ptr) {} 75 : compressed_base<deleter_type>(d), fPtr(ptr) {}
75 template <typename U1, typename U2, typename = enable_if_t< 76 template <typename U1, typename U2, typename = enable_if_t<
76 is_convertible<U1, pointer>::value && is_convertible<U2, deleter_typ e>::value 77 is_convertible<U1, pointer>::value && is_convertible<U2, deleter_typ e>::value
77 >> /*constexpr*/ compressed_data(U1&& ptr, U2&& d) 78 >> /*constexpr*/ compressed_data(U1&& ptr, U2&& d)
78 : compressed_base<deleter_type>(skstd::forward<U2>(d)), fPtr(skstd:: forward<U1>(ptr)) {} 79 : compressed_base<deleter_type>(std::forward<U2>(d)), fPtr(std::forw ard<U1>(ptr)) {}
79 /*constexpr*/ pointer& getPointer() /*noexcept*/ { return fPtr; } 80 /*constexpr*/ pointer& getPointer() /*noexcept*/ { return fPtr; }
80 /*constexpr*/ pointer const& getPointer() const /*noexcept*/ { return fP tr; } 81 /*constexpr*/ pointer const& getPointer() const /*noexcept*/ { return fP tr; }
81 /*constexpr*/ deleter_type& getDeleter() /*noexcept*/ { 82 /*constexpr*/ deleter_type& getDeleter() /*noexcept*/ {
82 return compressed_base<deleter_type>::get(); 83 return compressed_base<deleter_type>::get();
83 } 84 }
84 /*constexpr*/ deleter_type const& getDeleter() const /*noexcept*/ { 85 /*constexpr*/ deleter_type const& getDeleter() const /*noexcept*/ {
85 return compressed_base<deleter_type>::get(); 86 return compressed_base<deleter_type>::get();
86 } 87 }
87 void swap(compressed_data& that) /*noexcept*/ { 88 void swap(compressed_data& that) /*noexcept*/ {
88 compressed_base<deleter_type>::swap(static_cast<compressed_base<dele ter_type>>(that)); 89 compressed_base<deleter_type>::swap(static_cast<compressed_base<dele ter_type>>(that));
89 SkTSwap(fPtr, that.fPtr); 90 SkTSwap(fPtr, that.fPtr);
90 } 91 }
91 }; 92 };
92 compressed_data data; 93 compressed_data data;
93 94
94 public: 95 public:
95 /*constexpr*/ unique_ptr() /*noexcept*/ : data() { 96 /*constexpr*/ unique_ptr() /*noexcept*/ : data() {
96 static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr func tion pointer!"); 97 static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr func tion pointer!");
97 } 98 }
98 99
99 /*constexpr*/ unique_ptr(skstd::nullptr_t) /*noexcept*/ : unique_ptr() { } 100 /*constexpr*/ unique_ptr(std::nullptr_t) /*noexcept*/ : unique_ptr() { }
100 101
101 explicit unique_ptr(pointer ptr) /*noexcept*/ : data(ptr, deleter_type()) { 102 explicit unique_ptr(pointer ptr) /*noexcept*/ : data(ptr, deleter_type()) {
102 static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr func tion pointer!"); 103 static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr func tion pointer!");
103 } 104 }
104 105
105 unique_ptr(pointer ptr, 106 unique_ptr(pointer ptr,
106 conditional_t<is_reference<deleter_type>::value, deleter_type,con st deleter_type&> d) 107 conditional_t<is_reference<deleter_type>::value, deleter_type,con st deleter_type&> d)
107 /*noexcept*/ : data(ptr, d) 108 /*noexcept*/ : data(ptr, d)
108 {} 109 {}
109 110
110 unique_ptr(pointer ptr, remove_reference_t<deleter_type>&& d) /*noexcept*/ 111 unique_ptr(pointer ptr, remove_reference_t<deleter_type>&& d) /*noexcept*/
111 : data(move(ptr), move(d)) 112 : data(std::move(ptr), std::move(d))
112 { 113 {
113 static_assert(!is_reference<deleter_type>::value, 114 static_assert(!is_reference<deleter_type>::value,
114 "Binding an rvalue reference deleter as an lvalue reference deleter is not allowed."); 115 "Binding an rvalue reference deleter as an lvalue reference deleter is not allowed.");
115 } 116 }
116 117
117 118
118 unique_ptr(unique_ptr&& that) /*noexcept*/ 119 unique_ptr(unique_ptr&& that) /*noexcept*/
119 : data(that.release(), forward<deleter_type>(that.get_deleter())) 120 : data(that.release(), std::forward<deleter_type>(that.get_deleter()))
120 {} 121 {}
121 122
122 template <typename U, typename ThatD, typename = enable_if_t< 123 template <typename U, typename ThatD, typename = enable_if_t<
123 is_convertible<typename unique_ptr<U, ThatD>::pointer, pointer>::value & & 124 is_convertible<typename unique_ptr<U, ThatD>::pointer, pointer>::value & &
124 !is_array<U>::value && 125 !is_array<U>::value &&
125 conditional_t<is_reference<D>::value, is_same<ThatD, D>, is_convertible< ThatD, D>>::value>> 126 conditional_t<is_reference<D>::value, is_same<ThatD, D>, is_convertible< ThatD, D>>::value>>
126 unique_ptr(unique_ptr<U, ThatD>&& that) /*noexcept*/ 127 unique_ptr(unique_ptr<U, ThatD>&& that) /*noexcept*/
127 : data(that.release(), forward<ThatD>(that.get_deleter())) 128 : data(that.release(), std::forward<ThatD>(that.get_deleter()))
128 {} 129 {}
129 130
130 ~unique_ptr() /*noexcept*/ { 131 ~unique_ptr() /*noexcept*/ {
131 pointer& ptr = data.getPointer(); 132 pointer& ptr = data.getPointer();
132 if (ptr != nullptr) { 133 if (ptr != nullptr) {
133 get_deleter()(ptr); 134 get_deleter()(ptr);
134 } 135 }
135 ptr = pointer(); 136 ptr = pointer();
136 } 137 }
137 138
138 unique_ptr& operator=(unique_ptr&& that) /*noexcept*/ { 139 unique_ptr& operator=(unique_ptr&& that) /*noexcept*/ {
139 reset(that.release()); 140 reset(that.release());
140 get_deleter() = forward<deleter_type>(that.get_deleter()); 141 get_deleter() = std::forward<deleter_type>(that.get_deleter());
141 return *this; 142 return *this;
142 } 143 }
143 144
144 template <typename U, typename ThatD> enable_if_t< 145 template <typename U, typename ThatD> enable_if_t<
145 is_convertible<typename unique_ptr<U, ThatD>::pointer, pointer>::value & & 146 is_convertible<typename unique_ptr<U, ThatD>::pointer, pointer>::value & &
146 !is_array<U>::value, 147 !is_array<U>::value,
147 unique_ptr&> operator=(unique_ptr<U, ThatD>&& that) /*noexcept*/ { 148 unique_ptr&> operator=(unique_ptr<U, ThatD>&& that) /*noexcept*/ {
148 reset(that.release()); 149 reset(that.release());
149 get_deleter() = forward<ThatD>(that.get_deleter()); 150 get_deleter() = std::forward<ThatD>(that.get_deleter());
150 return *this; 151 return *this;
151 } 152 }
152 153
153 unique_ptr& operator=(skstd::nullptr_t) /*noexcept*/ { 154 unique_ptr& operator=(std::nullptr_t) /*noexcept*/ {
154 reset(); 155 reset();
155 return *this; 156 return *this;
156 } 157 }
157 158
158 add_lvalue_reference_t<element_type> operator*() const { 159 add_lvalue_reference_t<element_type> operator*() const {
159 SkASSERT(get() != pointer()); 160 SkASSERT(get() != pointer());
160 return *get(); 161 return *get();
161 } 162 }
162 163
163 pointer operator->() const /*noexcept*/ { 164 pointer operator->() const /*noexcept*/ {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 public: 215 public:
215 using pointer = typename pointer_type_detector::type; 216 using pointer = typename pointer_type_detector::type;
216 using element_type = T; 217 using element_type = T;
217 using deleter_type = D; 218 using deleter_type = D;
218 219
219 private: 220 private:
220 template <typename B, bool = is_empty<B>::value /*&& !is_final<B>::value*/> 221 template <typename B, bool = is_empty<B>::value /*&& !is_final<B>::value*/>
221 struct compressed_base : private B { 222 struct compressed_base : private B {
222 /*constexpr*/ compressed_base() : B() {} 223 /*constexpr*/ compressed_base() : B() {}
223 /*constexpr*/ compressed_base(const B& b) : B(b) {} 224 /*constexpr*/ compressed_base(const B& b) : B(b) {}
224 /*constexpr*/ compressed_base(const B&& b) : B(move(b)) {} 225 /*constexpr*/ compressed_base(B&& b) : B(std::move(b)) {}
225 /*constexpr*/ B& get() /*noexcept*/ { return *this; } 226 /*constexpr*/ B& get() /*noexcept*/ { return *this; }
226 /*constexpr*/ B const& get() const /*noexcept*/ { return *this; } 227 /*constexpr*/ B const& get() const /*noexcept*/ { return *this; }
227 void swap(compressed_base&) /*noexcept*/ { } 228 void swap(compressed_base&) /*noexcept*/ { }
228 }; 229 };
229 230
230 template <typename B> struct compressed_base<B, false> { 231 template <typename B> struct compressed_base<B, false> {
231 B fb; 232 B fb;
232 /*constexpr*/ compressed_base() : B() {} 233 /*constexpr*/ compressed_base() : B() {}
233 /*constexpr*/ compressed_base(const B& b) : fb(b) {} 234 /*constexpr*/ compressed_base(const B& b) : fb(b) {}
234 /*constexpr*/ compressed_base(const B&& b) : fb(move(b)) {} 235 /*constexpr*/ compressed_base(B&& b) : fb(std::move(b)) {}
235 /*constexpr*/ B& get() /*noexcept*/ { return fb; } 236 /*constexpr*/ B& get() /*noexcept*/ { return fb; }
236 /*constexpr*/ B const& get() const /*noexcept*/ { return fb; } 237 /*constexpr*/ B const& get() const /*noexcept*/ { return fb; }
237 void swap(compressed_base& that) /*noexcept*/ { SkTSwap(fb, that.fB); } 238 void swap(compressed_base& that) /*noexcept*/ { SkTSwap(fb, that.fB); }
238 }; 239 };
239 240
240 struct compressed_data : private compressed_base<deleter_type> { 241 struct compressed_data : private compressed_base<deleter_type> {
241 pointer fPtr; 242 pointer fPtr;
242 /*constexpr*/ compressed_data() : compressed_base<deleter_type>(), fPtr( ) {} 243 /*constexpr*/ compressed_data() : compressed_base<deleter_type>(), fPtr( ) {}
243 /*constexpr*/ compressed_data(const pointer& ptr, const deleter_type& d) 244 /*constexpr*/ compressed_data(const pointer& ptr, const deleter_type& d)
244 : compressed_base<deleter_type>(d), fPtr(ptr) {} 245 : compressed_base<deleter_type>(d), fPtr(ptr) {}
245 template <typename U1, typename U2, typename = enable_if_t< 246 template <typename U1, typename U2, typename = enable_if_t<
246 is_convertible<U1, pointer>::value && is_convertible<U2, deleter_typ e>::value 247 is_convertible<U1, pointer>::value && is_convertible<U2, deleter_typ e>::value
247 >> /*constexpr*/ compressed_data(U1&& ptr, U2&& d) 248 >> /*constexpr*/ compressed_data(U1&& ptr, U2&& d)
248 : compressed_base<deleter_type>(skstd::forward<U2>(d)), fPtr(skstd:: forward<U1>(ptr)) {} 249 : compressed_base<deleter_type>(std::forward<U2>(d)), fPtr(std::forw ard<U1>(ptr)) {}
249 /*constexpr*/ pointer& getPointer() /*noexcept*/ { return fPtr; } 250 /*constexpr*/ pointer& getPointer() /*noexcept*/ { return fPtr; }
250 /*constexpr*/ pointer const& getPointer() const /*noexcept*/ { return fP tr; } 251 /*constexpr*/ pointer const& getPointer() const /*noexcept*/ { return fP tr; }
251 /*constexpr*/ deleter_type& getDeleter() /*noexcept*/ { 252 /*constexpr*/ deleter_type& getDeleter() /*noexcept*/ {
252 return compressed_base<deleter_type>::get(); 253 return compressed_base<deleter_type>::get();
253 } 254 }
254 /*constexpr*/ deleter_type const& getDeleter() const /*noexcept*/ { 255 /*constexpr*/ deleter_type const& getDeleter() const /*noexcept*/ {
255 return compressed_base<deleter_type>::get(); 256 return compressed_base<deleter_type>::get();
256 } 257 }
257 void swap(compressed_data& that) /*noexcept*/ { 258 void swap(compressed_data& that) /*noexcept*/ {
258 compressed_base<deleter_type>::swap(static_cast<compressed_base<dele ter_type>>(that)); 259 compressed_base<deleter_type>::swap(static_cast<compressed_base<dele ter_type>>(that));
259 SkTSwap(fPtr, that.fPtr); 260 SkTSwap(fPtr, that.fPtr);
260 } 261 }
261 }; 262 };
262 compressed_data data; 263 compressed_data data;
263 264
264 public: 265 public:
265 /*constexpr*/ unique_ptr() /*noexcept*/ : data() { 266 /*constexpr*/ unique_ptr() /*noexcept*/ : data() {
266 static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr func tion pointer!"); 267 static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr func tion pointer!");
267 } 268 }
268 269
269 /*constexpr*/ unique_ptr(skstd::nullptr_t) /*noexcept*/ : unique_ptr() { } 270 /*constexpr*/ unique_ptr(std::nullptr_t) /*noexcept*/ : unique_ptr() { }
270 271
271 explicit unique_ptr(pointer ptr) /*noexcept*/ : data(ptr, deleter_type()) { 272 explicit unique_ptr(pointer ptr) /*noexcept*/ : data(ptr, deleter_type()) {
272 static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr func tion pointer!"); 273 static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr func tion pointer!");
273 } 274 }
274 275
275 unique_ptr(pointer ptr, 276 unique_ptr(pointer ptr,
276 conditional_t<is_reference<deleter_type>::value, deleter_type,con st deleter_type&> d) 277 conditional_t<is_reference<deleter_type>::value, deleter_type,con st deleter_type&> d)
277 /*noexcept*/ : data(ptr, d) 278 /*noexcept*/ : data(ptr, d)
278 {} 279 {}
279 280
280 unique_ptr(pointer ptr, remove_reference_t<deleter_type>&& d) /*noexcept*/ 281 unique_ptr(pointer ptr, remove_reference_t<deleter_type>&& d) /*noexcept*/
281 : data(move(ptr), move(d)) 282 : data(std::move(ptr), std::move(d))
282 { 283 {
283 static_assert(!is_reference<deleter_type>::value, 284 static_assert(!is_reference<deleter_type>::value,
284 "Binding an rvalue reference deleter as an lvalue reference deleter is not allowed."); 285 "Binding an rvalue reference deleter as an lvalue reference deleter is not allowed.");
285 } 286 }
286 287
287 unique_ptr(unique_ptr&& that) /*noexcept*/ 288 unique_ptr(unique_ptr&& that) /*noexcept*/
288 : data(that.release(), forward<deleter_type>(that.get_deleter())) 289 : data(that.release(), std::forward<deleter_type>(that.get_deleter()))
289 {} 290 {}
290 291
291 ~unique_ptr() { 292 ~unique_ptr() {
292 pointer& ptr = data.getPointer(); 293 pointer& ptr = data.getPointer();
293 if (ptr != nullptr) { 294 if (ptr != nullptr) {
294 get_deleter()(ptr); 295 get_deleter()(ptr);
295 } 296 }
296 ptr = pointer(); 297 ptr = pointer();
297 } 298 }
298 299
299 unique_ptr& operator=(unique_ptr&& that) /*noexcept*/ { 300 unique_ptr& operator=(unique_ptr&& that) /*noexcept*/ {
300 reset(that.release()); 301 reset(that.release());
301 get_deleter() = forward<deleter_type>(that.get_deleter()); 302 get_deleter() = std::forward<deleter_type>(that.get_deleter());
302 return *this; 303 return *this;
303 } 304 }
304 305
305 unique_ptr& operator=(skstd::nullptr_t) /*noexcept*/ { 306 unique_ptr& operator=(std::nullptr_t) /*noexcept*/ {
306 reset(); 307 reset();
307 return *this; 308 return *this;
308 } 309 }
309 310
310 add_lvalue_reference_t<element_type> operator[](size_t i) const { 311 add_lvalue_reference_t<element_type> operator[](size_t i) const {
311 SkASSERT(get() != pointer()); 312 SkASSERT(get() != pointer());
312 return get()[i]; 313 return get()[i];
313 } 314 }
314 315
315 pointer get() const /*noexcept*/ { 316 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*/ { 357 inline void swap(unique_ptr<T, D>& a, unique_ptr<T, D>& b) /*noexcept*/ {
357 a.swap(b); 358 a.swap(b);
358 } 359 }
359 360
360 template <typename T, typename D, typename U, typename ThatD> 361 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) { 362 inline bool operator==(const unique_ptr<T, D>& a, const unique_ptr<U, ThatD>& b) {
362 return a.get() == b.get(); 363 return a.get() == b.get();
363 } 364 }
364 365
365 template <typename T, typename D> 366 template <typename T, typename D>
366 inline bool operator==(const unique_ptr<T, D>& a, skstd::nullptr_t) /*noexcept*/ { 367 inline bool operator==(const unique_ptr<T, D>& a, std::nullptr_t) /*noexcept*/ {
367 //return !a; 368 //return !a;
368 return !a.is_attached(); 369 return !a.is_attached();
369 } 370 }
370 371
371 template <typename T, typename D> 372 template <typename T, typename D>
372 inline bool operator==(skstd::nullptr_t, const unique_ptr<T, D>& b) /*noexcept*/ { 373 inline bool operator==(std::nullptr_t, const unique_ptr<T, D>& b) /*noexcept*/ {
373 //return !b; 374 //return !b;
374 return !b.is_attached(); 375 return !b.is_attached();
375 } 376 }
376 377
377 template <typename T, typename D, typename U, typename ThatD> 378 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) { 379 inline bool operator!=(const unique_ptr<T, D>& a, const unique_ptr<U, ThatD>& b) {
379 return a.get() != b.get(); 380 return a.get() != b.get();
380 } 381 }
381 382
382 template <typename T, typename D> 383 template <typename T, typename D>
383 inline bool operator!=(const unique_ptr<T, D>& a, skstd::nullptr_t) /*noexcept*/ { 384 inline bool operator!=(const unique_ptr<T, D>& a, std::nullptr_t) /*noexcept*/ {
384 //return (bool)a; 385 //return (bool)a;
385 return a.is_attached(); 386 return a.is_attached();
386 } 387 }
387 388
388 template <typename T, typename D> 389 template <typename T, typename D>
389 inline bool operator!=(skstd::nullptr_t, const unique_ptr<T, D>& b) /*noexcept*/ { 390 inline bool operator!=(std::nullptr_t, const unique_ptr<T, D>& b) /*noexcept*/ {
390 //return (bool)b; 391 //return (bool)b;
391 return b.is_attached(); 392 return b.is_attached();
392 } 393 }
393 394
394 } // namespace skstd 395 } // namespace skstd
395 396
396 #endif 397 #endif
OLDNEW
« no previous file with comments | « include/private/SkTemplates.h ('k') | include/private/SkUtility.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698