OLD | NEW |
| (Empty) |
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef PlatformSTL_h | |
6 #define PlatformSTL_h | |
7 | |
8 #include <memory> | |
9 | |
10 #define PLATFORM_EXPORT | |
11 #ifndef CHECK | |
12 #define CHECK(condition) ((void) 0) | |
13 #endif | |
14 #define DCHECK(condition) ((void) 0) | |
15 #define NOTREACHED() | |
16 #define DCHECK_EQ(i, j) DCHECK(i == j) | |
17 #define DCHECK_GE(i, j) DCHECK(i >= j) | |
18 #define DCHECK_LT(i, j) DCHECK(i < j) | |
19 #define DCHECK_GT(i, j) DCHECK(i > j) | |
20 template <typename T> | |
21 inline void USE(T) { } | |
22 | |
23 #define DEFINE_STATIC_LOCAL(type, name, arguments) \ | |
24 static type name; | |
25 | |
26 #if defined(__APPLE__) && !defined(_LIBCPP_VERSION) | |
27 | |
28 namespace std { | |
29 | |
30 template <typename T1, typename T2> | |
31 struct is_convertible { | |
32 private: | |
33 struct True_ { | |
34 char x[2]; | |
35 }; | |
36 struct False_ { | |
37 }; | |
38 | |
39 static True_ helper(T2 const &); | |
40 static False_ helper(...); | |
41 | |
42 public: | |
43 static bool const value = ( | |
44 sizeof(True_) == sizeof(is_convertible::helper(T1())) | |
45 ); | |
46 }; | |
47 | |
48 template <bool, class T = void> | |
49 struct enable_if { | |
50 }; | |
51 | |
52 template <class T> | |
53 struct enable_if<true, T> { | |
54 typedef T type; | |
55 }; | |
56 | |
57 template<class T> | |
58 struct remove_extent { | |
59 typedef T type; | |
60 }; | |
61 | |
62 template<class T> | |
63 struct remove_extent<T[]> { | |
64 typedef T type; | |
65 }; | |
66 | |
67 template<class T, std::size_t N> | |
68 struct remove_extent<T[N]> { | |
69 typedef T type; | |
70 }; | |
71 | |
72 typedef decltype(nullptr) nullptr_t; | |
73 | |
74 template<class T, T v> | |
75 struct integral_constant { | |
76 static constexpr T value = v; | |
77 typedef T value_type; | |
78 typedef integral_constant type; | |
79 constexpr operator value_type() const noexcept { return value; } | |
80 constexpr value_type operator()() const noexcept { return value; } | |
81 }; | |
82 | |
83 typedef integral_constant<bool, true> true_type; | |
84 typedef integral_constant<bool, false> false_type; | |
85 | |
86 template<class T> | |
87 struct is_array : false_type {}; | |
88 | |
89 template<class T> | |
90 struct is_array<T[]> : true_type {}; | |
91 | |
92 template<class T, std::size_t N> | |
93 struct is_array<T[N]> : true_type {}; | |
94 | |
95 template <typename T> | |
96 struct OwnedPtrDeleter { | |
97 static void deletePtr(T* ptr) | |
98 { | |
99 static_assert(sizeof(T) > 0, "type must be complete"); | |
100 delete ptr; | |
101 } | |
102 }; | |
103 | |
104 template <typename T> | |
105 struct OwnedPtrDeleter<T[]> { | |
106 static void deletePtr(T* ptr) | |
107 { | |
108 static_assert(sizeof(T) > 0, "type must be complete"); | |
109 delete[] ptr; | |
110 } | |
111 }; | |
112 | |
113 template <class T, int n> | |
114 struct OwnedPtrDeleter<T[n]> { | |
115 static_assert(sizeof(T) < 0, "do not use array with size as type"); | |
116 }; | |
117 | |
118 template <typename T> class unique_ptr { | |
119 public: | |
120 typedef typename remove_extent<T>::type ValueType; | |
121 typedef ValueType* PtrType; | |
122 | |
123 unique_ptr() : m_ptr(nullptr) {} | |
124 unique_ptr(std::nullptr_t) : m_ptr(nullptr) {} | |
125 unique_ptr(const unique_ptr&); | |
126 unique_ptr(unique_ptr&&); | |
127 template <typename U, typename = typename enable_if<is_convertible<U*, T*>::
value>::type> unique_ptr(unique_ptr<U>&&); | |
128 | |
129 ~unique_ptr() | |
130 { | |
131 OwnedPtrDeleter<T>::deletePtr(m_ptr); | |
132 m_ptr = nullptr; | |
133 } | |
134 | |
135 PtrType get() const { return m_ptr; } | |
136 | |
137 void reset(PtrType = nullptr); | |
138 PtrType release() | |
139 { | |
140 return this->internalRelease(); | |
141 } | |
142 | |
143 ValueType& operator*() const { DCHECK(m_ptr); return *m_ptr; } | |
144 PtrType operator->() const { DCHECK(m_ptr); return m_ptr; } | |
145 | |
146 ValueType& operator[](std::ptrdiff_t i) const; | |
147 | |
148 bool operator!() const { return !m_ptr; } | |
149 explicit operator bool() const { return m_ptr; } | |
150 | |
151 unique_ptr& operator=(std::nullptr_t) { reset(); return *this; } | |
152 | |
153 unique_ptr& operator=(const unique_ptr&); | |
154 unique_ptr& operator=(unique_ptr&&); | |
155 template <typename U> unique_ptr& operator=(unique_ptr<U>&&); | |
156 | |
157 void swap(unique_ptr& o) { std::swap(m_ptr, o.m_ptr); } | |
158 | |
159 static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } | |
160 | |
161 explicit unique_ptr(PtrType ptr) : m_ptr(ptr) {} // NOLINT | |
162 | |
163 private: | |
164 PtrType internalRelease() const | |
165 { | |
166 PtrType ptr = m_ptr; | |
167 m_ptr = nullptr; | |
168 return ptr; | |
169 } | |
170 | |
171 // We should never have two unique_ptrs for the same underlying object | |
172 // (otherwise we'll get double-destruction), so these equality operators | |
173 // should never be needed. | |
174 template <typename U> bool operator==(const unique_ptr<U>&) const | |
175 { | |
176 static_assert(!sizeof(U*), "unique_ptrs should never be equal"); | |
177 return false; | |
178 } | |
179 template <typename U> bool operator!=(const unique_ptr<U>&) const | |
180 { | |
181 static_assert(!sizeof(U*), "unique_ptrs should never be equal"); | |
182 return false; | |
183 } | |
184 | |
185 mutable PtrType m_ptr; | |
186 }; | |
187 | |
188 | |
189 template <typename T> inline void unique_ptr<T>::reset(PtrType ptr) | |
190 { | |
191 PtrType p = m_ptr; | |
192 m_ptr = ptr; | |
193 DCHECK(!p || m_ptr != p); | |
194 OwnedPtrDeleter<T>::deletePtr(p); | |
195 } | |
196 | |
197 template <typename T> inline typename unique_ptr<T>::ValueType& unique_ptr<T>::o
perator[](std::ptrdiff_t i) const | |
198 { | |
199 static_assert(is_array<T>::value, "elements access is possible for arrays on
ly"); | |
200 DCHECK(m_ptr); | |
201 DCHECK_GE(i, 0); | |
202 return m_ptr[i]; | |
203 } | |
204 | |
205 template <typename T> inline unique_ptr<T>::unique_ptr(const unique_ptr<T>& o)
// NOLINT | |
206 : m_ptr(o.internalRelease()) | |
207 { | |
208 } | |
209 | |
210 template <typename T> inline unique_ptr<T>::unique_ptr(unique_ptr<T>&& o) // NO
LINT | |
211 : m_ptr(o.internalRelease()) | |
212 { | |
213 } | |
214 | |
215 template <typename T> | |
216 template <typename U, typename> inline unique_ptr<T>::unique_ptr(unique_ptr<U>&&
o) | |
217 : m_ptr(o.release()) | |
218 { | |
219 static_assert(!is_array<T>::value, "pointers to array must never be converte
d"); | |
220 } | |
221 | |
222 template <typename T> inline unique_ptr<T>& unique_ptr<T>::operator=(const uniqu
e_ptr<T>& o) | |
223 { | |
224 reset(o.internalRelease()); | |
225 return *this; | |
226 } | |
227 | |
228 template <typename T> inline unique_ptr<T>& unique_ptr<T>::operator=(unique_ptr<
T>&& o) | |
229 { | |
230 reset(o.internalRelease()); | |
231 return *this; | |
232 } | |
233 | |
234 template <typename T> | |
235 template <typename U> inline unique_ptr<T>& unique_ptr<T>::operator=(unique_ptr<
U>&& o) | |
236 { | |
237 static_assert(!is_array<T>::value, "pointers to array must never be converte
d"); | |
238 PtrType ptr = m_ptr; | |
239 m_ptr = o.release(); | |
240 DCHECK(!ptr || m_ptr != ptr); | |
241 OwnedPtrDeleter<T>::deletePtr(ptr); | |
242 | |
243 return *this; | |
244 } | |
245 | |
246 template <typename T> inline void swap(unique_ptr<T>& a, unique_ptr<T>& b) | |
247 { | |
248 a.swap(b); | |
249 } | |
250 | |
251 template <typename T, typename U> inline bool operator==(const unique_ptr<T>& a,
U* b) | |
252 { | |
253 return a.get() == b; | |
254 } | |
255 | |
256 template <typename T, typename U> inline bool operator==(T* a, const unique_ptr<
U>& b) | |
257 { | |
258 return a == b.get(); | |
259 } | |
260 | |
261 template <typename T, typename U> inline bool operator!=(const unique_ptr<T>& a,
U* b) | |
262 { | |
263 return a.get() != b; | |
264 } | |
265 | |
266 template <typename T, typename U> inline bool operator!=(T* a, const unique_ptr<
U>& b) | |
267 { | |
268 return a != b.get(); | |
269 } | |
270 | |
271 template <typename T> inline typename unique_ptr<T>::PtrType getPtr(const unique
_ptr<T>& p) | |
272 { | |
273 return p.get(); | |
274 } | |
275 | |
276 template <typename T> | |
277 unique_ptr<T> move(unique_ptr<T>& ptr) | |
278 { | |
279 return unique_ptr<T>(ptr.release()); | |
280 } | |
281 | |
282 } | |
283 | |
284 #endif // defined(__APPLE__) && !defined(_LIBCPP_VERSION) | |
285 | |
286 template <typename T> | |
287 std::unique_ptr<T> wrapUnique(T* ptr) | |
288 { | |
289 return std::unique_ptr<T>(ptr); | |
290 } | |
291 | |
292 // emulate snprintf() on windows, _snprintf() doesn't zero-terminate the buffer | |
293 // on overflow... | |
294 // VS 2015 added a standard conform snprintf | |
295 #if defined(_WIN32) && defined( _MSC_VER ) && (_MSC_VER < 1900) | |
296 #include <stdarg.h> | |
297 namespace std { | |
298 | |
299 inline static int snprintf(char *buffer, size_t n, const char *format, ...) | |
300 { | |
301 va_list argp; | |
302 va_start(argp, format); | |
303 int ret = _vscprintf(format, argp); | |
304 vsnprintf_s(buffer, n, _TRUNCATE, format, argp); | |
305 va_end(argp); | |
306 return ret; | |
307 } | |
308 } // namespace std | |
309 #endif // (_WIN32) && defined( _MSC_VER ) && (_MSC_VER < 1900) | |
310 | |
311 #ifdef __sun | |
312 namespace std { | |
313 using ::snprintf; | |
314 } // namespace std | |
315 #endif // __sun | |
316 | |
317 #endif // PlatformSTL_h | |
OLD | NEW |