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

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

Issue 1330503006: Add skstd::unique_ptr and use it. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Formatting. Created 5 years, 3 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/SkTLogic.h ('k') | include/private/SkUniquePtr.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 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 9
10 #ifndef SkTemplates_DEFINED 10 #ifndef SkTemplates_DEFINED
11 #define SkTemplates_DEFINED 11 #define SkTemplates_DEFINED
12 12
13 #include "../private/SkTLogic.h"
14 #include "SkMath.h" 13 #include "SkMath.h"
14 #include "SkTLogic.h"
15 #include "SkTypes.h" 15 #include "SkTypes.h"
16 #include "SkUniquePtr.h"
17 #include "SkUtility.h"
16 #include <limits.h> 18 #include <limits.h>
17 #include <new> 19 #include <new>
18 20
19 /** \file SkTemplates.h 21 /** \file SkTemplates.h
20 22
21 This file contains light-weight template classes for type-safe and exception -safe 23 This file contains light-weight template classes for type-safe and exception -safe
22 resource management. 24 resource management.
23 */ 25 */
24 26
25 /** 27 /**
26 * Marks a local variable as known to be unused (to avoid warnings). 28 * Marks a local variable as known to be unused (to avoid warnings).
27 * Note that this does *not* prevent the local variable from being optimized aw ay. 29 * Note that this does *not* prevent the local variable from being optimized aw ay.
28 */ 30 */
29 template<typename T> inline void sk_ignore_unused_variable(const T&) { } 31 template<typename T> inline void sk_ignore_unused_variable(const T&) { }
30 32
31 namespace skstd {
32
33 template <typename T> inline remove_reference_t<T>&& move(T&& t) {
34 return static_cast<remove_reference_t<T>&&>(t);
35 }
36
37 template <typename T> inline T&& forward(remove_reference_t<T>& t) /*noexcept*/ {
38 return static_cast<T&&>(t);
39 }
40 template <typename T> inline T&& forward(remove_reference_t<T>&& t) /*noexcept*/ {
41 static_assert(!is_lvalue_reference<T>::value,
42 "Forwarding an rvalue reference as an lvalue reference is not allowed.");
43 return static_cast<T&&>(t);
44 }
45
46 template <typename T> add_rvalue_reference_t<T> declval();
47
48 } // namespace skstd
49
50 /** 33 /**
51 * Returns a pointer to a D which comes immediately after S[count]. 34 * Returns a pointer to a D which comes immediately after S[count].
52 */ 35 */
53 template <typename D, typename S> static D* SkTAfter(S* ptr, size_t count = 1) { 36 template <typename D, typename S> static D* SkTAfter(S* ptr, size_t count = 1) {
54 return reinterpret_cast<D*>(ptr + count); 37 return reinterpret_cast<D*>(ptr + count);
55 } 38 }
56 39
57 /** 40 /**
58 * Returns a pointer to a D which comes byteOffset bytes after S. 41 * Returns a pointer to a D which comes byteOffset bytes after S.
59 */ 42 */
60 template <typename D, typename S> static D* SkTAddOffset(S* ptr, size_t byteOffs et) { 43 template <typename D, typename S> static D* SkTAddOffset(S* ptr, size_t byteOffs et) {
61 // The intermediate char* has the same cv-ness as D as this produces better error messages. 44 // The intermediate char* has the same cv-ness as D as this produces better error messages.
62 // This relies on the fact that reinterpret_cast can add constness, but cann ot remove it. 45 // This relies on the fact that reinterpret_cast can add constness, but cann ot remove it.
63 return reinterpret_cast<D*>(reinterpret_cast<sknonstd::same_cv_t<char, D>*>( ptr) + byteOffset); 46 return reinterpret_cast<D*>(reinterpret_cast<sknonstd::same_cv_t<char, D>*>( ptr) + byteOffset);
64 } 47 }
65 48
49 template <typename R, typename T, R (*P)(T*)> struct SkFunctionWrapper {
50 R operator()(T* t) { return P(t); }
51 };
52
66 /** \class SkAutoTCallVProc 53 /** \class SkAutoTCallVProc
67 54
68 Call a function when this goes out of scope. The template uses two 55 Call a function when this goes out of scope. The template uses two
69 parameters, the object, and a function that is to be called in the destructo r. 56 parameters, the object, and a function that is to be called in the destructo r.
70 If detach() is called, the object reference is set to null. If the object 57 If detach() is called, the object reference is set to null. If the object
71 reference is null when the destructor is called, we do not call the 58 reference is null when the destructor is called, we do not call the
72 function. 59 function.
73 */ 60 */
74 template <typename T, void (*P)(T*)> class SkAutoTCallVProc : SkNoncopyable { 61 template <typename T, void (*P)(T*)> class SkAutoTCallVProc
62 : public skstd::unique_ptr<T, SkFunctionWrapper<void, T, P>> {
75 public: 63 public:
76 SkAutoTCallVProc(T* obj): fObj(obj) {} 64 SkAutoTCallVProc(T* obj): skstd::unique_ptr<T, SkFunctionWrapper<void, T, P> >(obj) {}
77 ~SkAutoTCallVProc() { if (fObj) P(fObj); }
78 65
79 operator T*() const { return fObj; } 66 operator T*() const { return this->get(); }
80 T* operator->() const { SkASSERT(fObj); return fObj; } 67 T* detach() { return this->release(); }
81
82 T* detach() { T* obj = fObj; fObj = NULL; return obj; }
83 void reset(T* obj = NULL) {
84 if (fObj != obj) {
85 if (fObj) {
86 P(fObj);
87 }
88 fObj = obj;
89 }
90 }
91 private:
92 T* fObj;
93 }; 68 };
94 69
95 /** \class SkAutoTCallIProc 70 /** \class SkAutoTCallIProc
96 71
97 Call a function when this goes out of scope. The template uses two 72 Call a function when this goes out of scope. The template uses two
98 parameters, the object, and a function that is to be called in the destructor. 73 parameters, the object, and a function that is to be called in the destructor.
99 If detach() is called, the object reference is set to null. If the object 74 If detach() is called, the object reference is set to null. If the object
100 reference is null when the destructor is called, we do not call the 75 reference is null when the destructor is called, we do not call the
101 function. 76 function.
102 */ 77 */
103 template <typename T, int (*P)(T*)> class SkAutoTCallIProc : SkNoncopyable { 78 template <typename T, int (*P)(T*)> class SkAutoTCallIProc
79 : public skstd::unique_ptr<T, SkFunctionWrapper<int, T, P>> {
104 public: 80 public:
105 SkAutoTCallIProc(T* obj): fObj(obj) {} 81 SkAutoTCallIProc(T* obj): skstd::unique_ptr<T, SkFunctionWrapper<int, T, P>> (obj) {}
106 ~SkAutoTCallIProc() { if (fObj) P(fObj); }
107 82
108 operator T*() const { return fObj; } 83 operator T*() const { return this->get(); }
109 T* operator->() const { SkASSERT(fObj); return fObj; } 84 T* detach() { return this->release(); }
110
111 T* detach() { T* obj = fObj; fObj = NULL; return obj; }
112 private:
113 T* fObj;
114 }; 85 };
115 86
116 /** \class SkAutoTDelete 87 /** \class SkAutoTDelete
117 An SkAutoTDelete<T> is like a T*, except that the destructor of SkAutoTDelete< T> 88 An SkAutoTDelete<T> is like a T*, except that the destructor of SkAutoTDelete< T>
118 automatically deletes the pointer it holds (if any). That is, SkAutoTDelete<T > 89 automatically deletes the pointer it holds (if any). That is, SkAutoTDelete<T >
119 owns the T object that it points to. Like a T*, an SkAutoTDelete<T> may hold 90 owns the T object that it points to. Like a T*, an SkAutoTDelete<T> may hold
120 either NULL or a pointer to a T object. Also like T*, SkAutoTDelete<T> is 91 either NULL or a pointer to a T object. Also like T*, SkAutoTDelete<T> is
121 thread-compatible, and once you dereference it, you get the threadsafety 92 thread-compatible, and once you dereference it, you get the threadsafety
122 guarantees of T. 93 guarantees of T.
123 94
124 The size of a SkAutoTDelete is small: sizeof(SkAutoTDelete<T>) == sizeof(T*) 95 The size of a SkAutoTDelete is small: sizeof(SkAutoTDelete<T>) == sizeof(T*)
125 */ 96 */
126 template <typename T> class SkAutoTDelete : SkNoncopyable { 97 template <typename T> class SkAutoTDelete : public skstd::unique_ptr<T> {
127 public: 98 public:
128 SkAutoTDelete(T* obj = NULL) : fObj(obj) {} 99 SkAutoTDelete(T* obj = NULL) : skstd::unique_ptr<T>(obj) {}
129 ~SkAutoTDelete() { delete fObj; }
130 100
131 T* get() const { return fObj; } 101 operator T*() const { return this->get(); }
132 operator T*() const { return fObj; } 102 void free() { this->reset(nullptr); }
133 T& operator*() const { SkASSERT(fObj); return *fObj; } 103 T* detach() { return this->release(); }
134 T* operator->() const { SkASSERT(fObj); return fObj; }
135
136 void reset(T* obj) {
137 if (fObj != obj) {
138 delete fObj;
139 fObj = obj;
140 }
141 }
142
143 /**
144 * Delete the owned object, setting the internal pointer to NULL.
145 */
146 void free() {
147 delete fObj;
148 fObj = NULL;
149 }
150
151 /**
152 * Transfer ownership of the object to the caller, setting the internal
153 * pointer to NULL. Note that this differs from get(), which also returns
154 * the pointer, but it does not transfer ownership.
155 */
156 T* detach() {
157 T* obj = fObj;
158 fObj = NULL;
159 return obj;
160 }
161
162 void swap(SkAutoTDelete* that) {
163 SkTSwap(fObj, that->fObj);
164 }
165
166 private:
167 T* fObj;
168 }; 104 };
169 105
170 // Calls ~T() in the destructor. 106 template <typename T> class SkAutoTDeleteArray : public skstd::unique_ptr<T[]> {
171 template <typename T> class SkAutoTDestroy : SkNoncopyable {
172 public: 107 public:
173 SkAutoTDestroy(T* obj = NULL) : fObj(obj) {} 108 SkAutoTDeleteArray(T array[]) : skstd::unique_ptr<T[]>(array) {}
174 ~SkAutoTDestroy() {
175 if (fObj) {
176 fObj->~T();
177 }
178 }
179 109
180 T* get() const { return fObj; } 110 void free() { this->reset(nullptr); }
181 T& operator*() const { SkASSERT(fObj); return *fObj; } 111 T* detach() { return this->release(); }
182 T* operator->() const { SkASSERT(fObj); return fObj; }
183
184 private:
185 T* fObj;
186 };
187
188 template <typename T> class SkAutoTDeleteArray : SkNoncopyable {
189 public:
190 SkAutoTDeleteArray(T array[]) : fArray(array) {}
191 ~SkAutoTDeleteArray() { delete[] fArray; }
192
193 T* get() const { return fArray; }
194 void free() {
195 delete[] fArray;
196 fArray = NULL;
197 }
198 T* detach() { T* array = fArray; fArray = NULL; return array; }
199
200 void reset(T array[]) {
201 if (fArray != array) {
202 delete[] fArray;
203 fArray = array;
204 }
205 }
206
207 private:
208 T* fArray;
209 }; 112 };
210 113
211 /** Allocate an array of T elements, and free the array in the destructor 114 /** Allocate an array of T elements, and free the array in the destructor
212 */ 115 */
213 template <typename T> class SkAutoTArray : SkNoncopyable { 116 template <typename T> class SkAutoTArray : SkNoncopyable {
214 public: 117 public:
215 SkAutoTArray() { 118 SkAutoTArray() {
216 fArray = NULL; 119 fArray = NULL;
217 SkDEBUGCODE(fCount = 0;) 120 SkDEBUGCODE(fCount = 0;)
218 } 121 }
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 * Returns void* because this object does not initialize the 442 * Returns void* because this object does not initialize the
540 * memory. Use placement new for types that require a cons. 443 * memory. Use placement new for types that require a cons.
541 */ 444 */
542 void* get() { return fStorage.get(); } 445 void* get() { return fStorage.get(); }
543 const void* get() const { return fStorage.get(); } 446 const void* get() const { return fStorage.get(); }
544 private: 447 private:
545 SkAlignedSStorage<sizeof(T)*N> fStorage; 448 SkAlignedSStorage<sizeof(T)*N> fStorage;
546 }; 449 };
547 450
548 #endif 451 #endif
OLDNEW
« no previous file with comments | « include/private/SkTLogic.h ('k') | include/private/SkUniquePtr.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698