Mercurial > hg > sv-dependency-builds
comparison osx/include/kj/common.h @ 49:3ab5a40c4e3b
Add Capnp and KJ builds for OSX
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Tue, 25 Oct 2016 14:48:23 +0100 |
parents | |
children | 0994c39f1e94 |
comparison
equal
deleted
inserted
replaced
48:9530b331f8c1 | 49:3ab5a40c4e3b |
---|---|
1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors | |
2 // Licensed under the MIT License: | |
3 // | |
4 // Permission is hereby granted, free of charge, to any person obtaining a copy | |
5 // of this software and associated documentation files (the "Software"), to deal | |
6 // in the Software without restriction, including without limitation the rights | |
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
8 // copies of the Software, and to permit persons to whom the Software is | |
9 // furnished to do so, subject to the following conditions: | |
10 // | |
11 // The above copyright notice and this permission notice shall be included in | |
12 // all copies or substantial portions of the Software. | |
13 // | |
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
20 // THE SOFTWARE. | |
21 | |
22 // Header that should be #included by everyone. | |
23 // | |
24 // This defines very simple utilities that are widely applicable. | |
25 | |
26 #ifndef KJ_COMMON_H_ | |
27 #define KJ_COMMON_H_ | |
28 | |
29 #if defined(__GNUC__) && !KJ_HEADER_WARNINGS | |
30 #pragma GCC system_header | |
31 #endif | |
32 | |
33 #ifndef KJ_NO_COMPILER_CHECK | |
34 #if __cplusplus < 201103L && !__CDT_PARSER__ && !_MSC_VER | |
35 #error "This code requires C++11. Either your compiler does not support it or it is not enabled." | |
36 #ifdef __GNUC__ | |
37 // Compiler claims compatibility with GCC, so presumably supports -std. | |
38 #error "Pass -std=c++11 on the compiler command line to enable C++11." | |
39 #endif | |
40 #endif | |
41 | |
42 #ifdef __GNUC__ | |
43 #if __clang__ | |
44 #if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2) | |
45 #warning "This library requires at least Clang 3.2." | |
46 #elif defined(__apple_build_version__) && __apple_build_version__ <= 4250028 | |
47 #warning "This library requires at least Clang 3.2. XCode 4.6's Clang, which claims to be "\ | |
48 "version 4.2 (wat?), is actually built from some random SVN revision between 3.1 "\ | |
49 "and 3.2. Unfortunately, it is insufficient for compiling this library. You can "\ | |
50 "download the real Clang 3.2 (or newer) from the Clang web site. Step-by-step "\ | |
51 "instructions can be found in Cap'n Proto's documentation: "\ | |
52 "http://kentonv.github.io/capnproto/install.html#clang_32_on_mac_osx" | |
53 #elif __cplusplus >= 201103L && !__has_include(<initializer_list>) | |
54 #warning "Your compiler supports C++11 but your C++ standard library does not. If your "\ | |
55 "system has libc++ installed (as should be the case on e.g. Mac OSX), try adding "\ | |
56 "-stdlib=libc++ to your CXXFLAGS." | |
57 #endif | |
58 #else | |
59 #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) | |
60 #warning "This library requires at least GCC 4.7." | |
61 #endif | |
62 #endif | |
63 #elif defined(_MSC_VER) | |
64 #if _MSC_VER < 1900 | |
65 #error "You need Visual Studio 2015 or better to compile this code." | |
66 #elif !CAPNP_LITE | |
67 // TODO(cleanup): This is KJ, but we're talking about Cap'n Proto. | |
68 #error "As of this writing, Cap'n Proto only supports Visual C++ in 'lite mode'; please #define CAPNP_LITE" | |
69 #endif | |
70 #else | |
71 #warning "I don't recognize your compiler. As of this writing, Clang and GCC are the only "\ | |
72 "known compilers with enough C++11 support for this library. "\ | |
73 "#define KJ_NO_COMPILER_CHECK to make this warning go away." | |
74 #endif | |
75 #endif | |
76 | |
77 #include <stddef.h> | |
78 #include <initializer_list> | |
79 | |
80 #if __linux__ && __cplusplus > 201200L | |
81 // Hack around stdlib bug with C++14 that exists on some Linux systems. | |
82 // Apparently in this mode the C library decides not to define gets() but the C++ library still | |
83 // tries to import it into the std namespace. This bug has been fixed at the source but is still | |
84 // widely present in the wild e.g. on Ubuntu 14.04. | |
85 #undef _GLIBCXX_HAVE_GETS | |
86 #endif | |
87 | |
88 #if defined(_MSC_VER) | |
89 #include <intrin.h> // __popcnt | |
90 #endif | |
91 | |
92 // ======================================================================================= | |
93 | |
94 namespace kj { | |
95 | |
96 typedef unsigned int uint; | |
97 typedef unsigned char byte; | |
98 | |
99 // ======================================================================================= | |
100 // Common macros, especially for common yet compiler-specific features. | |
101 | |
102 // Detect whether RTTI and exceptions are enabled, assuming they are unless we have specific | |
103 // evidence to the contrary. Clients can always define KJ_NO_RTTI or KJ_NO_EXCEPTIONS explicitly | |
104 // to override these checks. | |
105 #ifdef __GNUC__ | |
106 #if !defined(KJ_NO_RTTI) && !__GXX_RTTI | |
107 #define KJ_NO_RTTI 1 | |
108 #endif | |
109 #if !defined(KJ_NO_EXCEPTIONS) && !__EXCEPTIONS | |
110 #define KJ_NO_EXCEPTIONS 1 | |
111 #endif | |
112 #elif defined(_MSC_VER) | |
113 #if !defined(KJ_NO_RTTI) && !defined(_CPPRTTI) | |
114 #define KJ_NO_RTTI 1 | |
115 #endif | |
116 #if !defined(KJ_NO_EXCEPTIONS) && !defined(_CPPUNWIND) | |
117 #define KJ_NO_EXCEPTIONS 1 | |
118 #endif | |
119 #endif | |
120 | |
121 #if !defined(KJ_DEBUG) && !defined(KJ_NDEBUG) | |
122 // Heuristically decide whether to enable debug mode. If DEBUG or NDEBUG is defined, use that. | |
123 // Otherwise, fall back to checking whether optimization is enabled. | |
124 #if defined(DEBUG) || defined(_DEBUG) | |
125 #define KJ_DEBUG | |
126 #elif defined(NDEBUG) | |
127 #define KJ_NDEBUG | |
128 #elif __OPTIMIZE__ | |
129 #define KJ_NDEBUG | |
130 #else | |
131 #define KJ_DEBUG | |
132 #endif | |
133 #endif | |
134 | |
135 #define KJ_DISALLOW_COPY(classname) \ | |
136 classname(const classname&) = delete; \ | |
137 classname& operator=(const classname&) = delete | |
138 // Deletes the implicit copy constructor and assignment operator. | |
139 | |
140 #ifdef __GNUC__ | |
141 #define KJ_LIKELY(condition) __builtin_expect(condition, true) | |
142 #define KJ_UNLIKELY(condition) __builtin_expect(condition, false) | |
143 // Branch prediction macros. Evaluates to the condition given, but also tells the compiler that we | |
144 // expect the condition to be true/false enough of the time that it's worth hard-coding branch | |
145 // prediction. | |
146 #else | |
147 #define KJ_LIKELY(condition) (condition) | |
148 #define KJ_UNLIKELY(condition) (condition) | |
149 #endif | |
150 | |
151 #if defined(KJ_DEBUG) || __NO_INLINE__ | |
152 #define KJ_ALWAYS_INLINE(prototype) inline prototype | |
153 // Don't force inline in debug mode. | |
154 #else | |
155 #if defined(_MSC_VER) | |
156 #define KJ_ALWAYS_INLINE(prototype) __forceinline prototype | |
157 #else | |
158 #define KJ_ALWAYS_INLINE(prototype) inline prototype __attribute__((always_inline)) | |
159 #endif | |
160 // Force a function to always be inlined. Apply only to the prototype, not to the definition. | |
161 #endif | |
162 | |
163 #if defined(_MSC_VER) | |
164 #define KJ_NOINLINE __declspec(noinline) | |
165 #else | |
166 #define KJ_NOINLINE __attribute__((noinline)) | |
167 #endif | |
168 | |
169 #if defined(_MSC_VER) | |
170 #define KJ_NORETURN(prototype) __declspec(noreturn) prototype | |
171 #define KJ_UNUSED | |
172 #define KJ_WARN_UNUSED_RESULT | |
173 // TODO(msvc): KJ_WARN_UNUSED_RESULT can use _Check_return_ on MSVC, but it's a prefix, so | |
174 // wrapping the whole prototype is needed. http://msdn.microsoft.com/en-us/library/jj159529.aspx | |
175 // Similarly, KJ_UNUSED could use __pragma(warning(suppress:...)), but again that's a prefix. | |
176 #else | |
177 #define KJ_NORETURN(prototype) prototype __attribute__((noreturn)) | |
178 #define KJ_UNUSED __attribute__((unused)) | |
179 #define KJ_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) | |
180 #endif | |
181 | |
182 #if __clang__ | |
183 #define KJ_UNUSED_MEMBER __attribute__((unused)) | |
184 // Inhibits "unused" warning for member variables. Only Clang produces such a warning, while GCC | |
185 // complains if the attribute is set on members. | |
186 #else | |
187 #define KJ_UNUSED_MEMBER | |
188 #endif | |
189 | |
190 #if __clang__ | |
191 #define KJ_DEPRECATED(reason) \ | |
192 __attribute__((deprecated(reason))) | |
193 #define KJ_UNAVAILABLE(reason) \ | |
194 __attribute__((unavailable(reason))) | |
195 #elif __GNUC__ | |
196 #define KJ_DEPRECATED(reason) \ | |
197 __attribute__((deprecated)) | |
198 #define KJ_UNAVAILABLE(reason) | |
199 #else | |
200 #define KJ_DEPRECATED(reason) | |
201 #define KJ_UNAVAILABLE(reason) | |
202 // TODO(msvc): Again, here, MSVC prefers a prefix, __declspec(deprecated). | |
203 #endif | |
204 | |
205 namespace _ { // private | |
206 | |
207 KJ_NORETURN(void inlineRequireFailure( | |
208 const char* file, int line, const char* expectation, const char* macroArgs, | |
209 const char* message = nullptr)); | |
210 | |
211 KJ_NORETURN(void unreachable()); | |
212 | |
213 } // namespace _ (private) | |
214 | |
215 #ifdef KJ_DEBUG | |
216 #if _MSC_VER | |
217 #define KJ_IREQUIRE(condition, ...) \ | |
218 if (KJ_LIKELY(condition)); else ::kj::_::inlineRequireFailure( \ | |
219 __FILE__, __LINE__, #condition, "" #__VA_ARGS__, __VA_ARGS__) | |
220 // Version of KJ_DREQUIRE() which is safe to use in headers that are #included by users. Used to | |
221 // check preconditions inside inline methods. KJ_IREQUIRE is particularly useful in that | |
222 // it will be enabled depending on whether the application is compiled in debug mode rather than | |
223 // whether libkj is. | |
224 #else | |
225 #define KJ_IREQUIRE(condition, ...) \ | |
226 if (KJ_LIKELY(condition)); else ::kj::_::inlineRequireFailure( \ | |
227 __FILE__, __LINE__, #condition, #__VA_ARGS__, ##__VA_ARGS__) | |
228 // Version of KJ_DREQUIRE() which is safe to use in headers that are #included by users. Used to | |
229 // check preconditions inside inline methods. KJ_IREQUIRE is particularly useful in that | |
230 // it will be enabled depending on whether the application is compiled in debug mode rather than | |
231 // whether libkj is. | |
232 #endif | |
233 #else | |
234 #define KJ_IREQUIRE(condition, ...) | |
235 #endif | |
236 | |
237 #define KJ_IASSERT KJ_IREQUIRE | |
238 | |
239 #define KJ_UNREACHABLE ::kj::_::unreachable(); | |
240 // Put this on code paths that cannot be reached to suppress compiler warnings about missing | |
241 // returns. | |
242 | |
243 #if __clang__ | |
244 #define KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT | |
245 #else | |
246 #define KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT KJ_UNREACHABLE | |
247 #endif | |
248 | |
249 // #define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) | |
250 // | |
251 // Allocate an array, preferably on the stack, unless it is too big. On GCC this will use | |
252 // variable-sized arrays. For other compilers we could just use a fixed-size array. `minStack` | |
253 // is the stack array size to use if variable-width arrays are not supported. `maxStack` is the | |
254 // maximum stack array size if variable-width arrays *are* supported. | |
255 #if __GNUC__ && !__clang__ | |
256 #define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) \ | |
257 size_t name##_size = (size); \ | |
258 bool name##_isOnStack = name##_size <= (maxStack); \ | |
259 type name##_stack[name##_isOnStack ? size : 0]; \ | |
260 ::kj::Array<type> name##_heap = name##_isOnStack ? \ | |
261 nullptr : kj::heapArray<type>(name##_size); \ | |
262 ::kj::ArrayPtr<type> name = name##_isOnStack ? \ | |
263 kj::arrayPtr(name##_stack, name##_size) : name##_heap | |
264 #else | |
265 #define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) \ | |
266 size_t name##_size = (size); \ | |
267 bool name##_isOnStack = name##_size <= (minStack); \ | |
268 type name##_stack[minStack]; \ | |
269 ::kj::Array<type> name##_heap = name##_isOnStack ? \ | |
270 nullptr : kj::heapArray<type>(name##_size); \ | |
271 ::kj::ArrayPtr<type> name = name##_isOnStack ? \ | |
272 kj::arrayPtr(name##_stack, name##_size) : name##_heap | |
273 #endif | |
274 | |
275 #define KJ_CONCAT_(x, y) x##y | |
276 #define KJ_CONCAT(x, y) KJ_CONCAT_(x, y) | |
277 #define KJ_UNIQUE_NAME(prefix) KJ_CONCAT(prefix, __LINE__) | |
278 // Create a unique identifier name. We use concatenate __LINE__ rather than __COUNTER__ so that | |
279 // the name can be used multiple times in the same macro. | |
280 | |
281 #if _MSC_VER | |
282 | |
283 #define KJ_CONSTEXPR(...) __VA_ARGS__ | |
284 // Use in cases where MSVC barfs on constexpr. A replacement keyword (e.g. "const") can be | |
285 // provided, or just leave blank to remove the keyword entirely. | |
286 // | |
287 // TODO(msvc): Remove this hack once MSVC fully supports constexpr. | |
288 | |
289 #ifndef __restrict__ | |
290 #define __restrict__ __restrict | |
291 // TODO(msvc): Would it be better to define a KJ_RESTRICT macro? | |
292 #endif | |
293 | |
294 #pragma warning(disable: 4521 4522) | |
295 // This warning complains when there are two copy constructors, one for a const reference and | |
296 // one for a non-const reference. It is often quite necessary to do this in wrapper templates, | |
297 // therefore this warning is dumb and we disable it. | |
298 | |
299 #pragma warning(disable: 4458) | |
300 // Warns when a parameter name shadows a class member. Unfortunately my code does this a lot, | |
301 // since I don't use a special name format for members. | |
302 | |
303 #else // _MSC_VER | |
304 #define KJ_CONSTEXPR(...) constexpr | |
305 #endif | |
306 | |
307 // ======================================================================================= | |
308 // Template metaprogramming helpers. | |
309 | |
310 template <typename T> struct NoInfer_ { typedef T Type; }; | |
311 template <typename T> using NoInfer = typename NoInfer_<T>::Type; | |
312 // Use NoInfer<T>::Type in place of T for a template function parameter to prevent inference of | |
313 // the type based on the parameter value. | |
314 | |
315 template <typename T> struct RemoveConst_ { typedef T Type; }; | |
316 template <typename T> struct RemoveConst_<const T> { typedef T Type; }; | |
317 template <typename T> using RemoveConst = typename RemoveConst_<T>::Type; | |
318 | |
319 template <typename> struct IsLvalueReference_ { static constexpr bool value = false; }; | |
320 template <typename T> struct IsLvalueReference_<T&> { static constexpr bool value = true; }; | |
321 template <typename T> | |
322 inline constexpr bool isLvalueReference() { return IsLvalueReference_<T>::value; } | |
323 | |
324 template <typename T> struct Decay_ { typedef T Type; }; | |
325 template <typename T> struct Decay_<T&> { typedef typename Decay_<T>::Type Type; }; | |
326 template <typename T> struct Decay_<T&&> { typedef typename Decay_<T>::Type Type; }; | |
327 template <typename T> struct Decay_<T[]> { typedef typename Decay_<T*>::Type Type; }; | |
328 template <typename T> struct Decay_<const T[]> { typedef typename Decay_<const T*>::Type Type; }; | |
329 template <typename T, size_t s> struct Decay_<T[s]> { typedef typename Decay_<T*>::Type Type; }; | |
330 template <typename T, size_t s> struct Decay_<const T[s]> { typedef typename Decay_<const T*>::Type Type; }; | |
331 template <typename T> struct Decay_<const T> { typedef typename Decay_<T>::Type Type; }; | |
332 template <typename T> struct Decay_<volatile T> { typedef typename Decay_<T>::Type Type; }; | |
333 template <typename T> using Decay = typename Decay_<T>::Type; | |
334 | |
335 template <bool b> struct EnableIf_; | |
336 template <> struct EnableIf_<true> { typedef void Type; }; | |
337 template <bool b> using EnableIf = typename EnableIf_<b>::Type; | |
338 // Use like: | |
339 // | |
340 // template <typename T, typename = EnableIf<isValid<T>()> | |
341 // void func(T&& t); | |
342 | |
343 template <typename...> struct VoidSfinae_ { using Type = void; }; | |
344 template <typename... Ts> using VoidSfinae = typename VoidSfinae_<Ts...>::Type; | |
345 // Note: VoidSfinae is std::void_t from C++17. | |
346 | |
347 template <typename T> | |
348 T instance() noexcept; | |
349 // Like std::declval, but doesn't transform T into an rvalue reference. If you want that, specify | |
350 // instance<T&&>(). | |
351 | |
352 struct DisallowConstCopy { | |
353 // Inherit from this, or declare a member variable of this type, to prevent the class from being | |
354 // copyable from a const reference -- instead, it will only be copyable from non-const references. | |
355 // This is useful for enforcing transitive constness of contained pointers. | |
356 // | |
357 // For example, say you have a type T which contains a pointer. T has non-const methods which | |
358 // modify the value at that pointer, but T's const methods are designed to allow reading only. | |
359 // Unfortunately, if T has a regular copy constructor, someone can simply make a copy of T and | |
360 // then use it to modify the pointed-to value. However, if T inherits DisallowConstCopy, then | |
361 // callers will only be able to copy non-const instances of T. Ideally, there is some | |
362 // parallel type ImmutableT which is like a version of T that only has const methods, and can | |
363 // be copied from a const T. | |
364 // | |
365 // Note that due to C++ rules about implicit copy constructors and assignment operators, any | |
366 // type that contains or inherits from a type that disallows const copies will also automatically | |
367 // disallow const copies. Hey, cool, that's exactly what we want. | |
368 | |
369 DisallowConstCopy() = default; | |
370 DisallowConstCopy(DisallowConstCopy&) = default; | |
371 DisallowConstCopy(DisallowConstCopy&&) = default; | |
372 DisallowConstCopy& operator=(DisallowConstCopy&) = default; | |
373 DisallowConstCopy& operator=(DisallowConstCopy&&) = default; | |
374 }; | |
375 | |
376 template <typename T> | |
377 struct DisallowConstCopyIfNotConst: public DisallowConstCopy { | |
378 // Inherit from this when implementing a template that contains a pointer to T and which should | |
379 // enforce transitive constness. If T is a const type, this has no effect. Otherwise, it is | |
380 // an alias for DisallowConstCopy. | |
381 }; | |
382 | |
383 template <typename T> | |
384 struct DisallowConstCopyIfNotConst<const T> {}; | |
385 | |
386 template <typename T> struct IsConst_ { static constexpr bool value = false; }; | |
387 template <typename T> struct IsConst_<const T> { static constexpr bool value = true; }; | |
388 template <typename T> constexpr bool isConst() { return IsConst_<T>::value; } | |
389 | |
390 template <typename T> struct EnableIfNotConst_ { typedef T Type; }; | |
391 template <typename T> struct EnableIfNotConst_<const T>; | |
392 template <typename T> using EnableIfNotConst = typename EnableIfNotConst_<T>::Type; | |
393 | |
394 template <typename T> struct EnableIfConst_; | |
395 template <typename T> struct EnableIfConst_<const T> { typedef T Type; }; | |
396 template <typename T> using EnableIfConst = typename EnableIfConst_<T>::Type; | |
397 | |
398 template <typename T> struct RemoveConstOrDisable_ { struct Type; }; | |
399 template <typename T> struct RemoveConstOrDisable_<const T> { typedef T Type; }; | |
400 template <typename T> using RemoveConstOrDisable = typename RemoveConstOrDisable_<T>::Type; | |
401 | |
402 template <typename T> struct IsReference_ { static constexpr bool value = false; }; | |
403 template <typename T> struct IsReference_<T&> { static constexpr bool value = true; }; | |
404 template <typename T> constexpr bool isReference() { return IsReference_<T>::value; } | |
405 | |
406 template <typename From, typename To> | |
407 struct PropagateConst_ { typedef To Type; }; | |
408 template <typename From, typename To> | |
409 struct PropagateConst_<const From, To> { typedef const To Type; }; | |
410 template <typename From, typename To> | |
411 using PropagateConst = typename PropagateConst_<From, To>::Type; | |
412 | |
413 namespace _ { // private | |
414 | |
415 template <typename T> | |
416 T refIfLvalue(T&&); | |
417 | |
418 } // namespace _ (private) | |
419 | |
420 #define KJ_DECLTYPE_REF(exp) decltype(::kj::_::refIfLvalue(exp)) | |
421 // Like decltype(exp), but if exp is an lvalue, produces a reference type. | |
422 // | |
423 // int i; | |
424 // decltype(i) i1(i); // i1 has type int. | |
425 // KJ_DECLTYPE_REF(i + 1) i2(i + 1); // i2 has type int. | |
426 // KJ_DECLTYPE_REF(i) i3(i); // i3 has type int&. | |
427 // KJ_DECLTYPE_REF(kj::mv(i)) i4(kj::mv(i)); // i4 has type int. | |
428 | |
429 template <typename T> | |
430 struct CanConvert_ { | |
431 static int sfinae(T); | |
432 static bool sfinae(...); | |
433 }; | |
434 | |
435 template <typename T, typename U> | |
436 constexpr bool canConvert() { | |
437 return sizeof(CanConvert_<U>::sfinae(instance<T>())) == sizeof(int); | |
438 } | |
439 | |
440 #if __clang__ | |
441 template <typename T> | |
442 constexpr bool canMemcpy() { | |
443 // Returns true if T can be copied using memcpy instead of using the copy constructor or | |
444 // assignment operator. | |
445 | |
446 // Clang unhelpfully defines __has_trivial_{copy,assign}(T) to be true if the copy constructor / | |
447 // assign operator are deleted, on the basis that a strict reading of the definition of "trivial" | |
448 // according to the standard says that deleted functions are in fact trivial. Meanwhile Clang | |
449 // provides these admittedly-better intrinsics, but GCC does not. | |
450 return __is_trivially_constructible(T, const T&) && __is_trivially_assignable(T, const T&); | |
451 } | |
452 #else | |
453 template <typename T> | |
454 constexpr bool canMemcpy() { | |
455 // Returns true if T can be copied using memcpy instead of using the copy constructor or | |
456 // assignment operator. | |
457 | |
458 // GCC defines these to mean what we want them to mean. | |
459 return __has_trivial_copy(T) && __has_trivial_assign(T); | |
460 } | |
461 #endif | |
462 | |
463 // ======================================================================================= | |
464 // Equivalents to std::move() and std::forward(), since these are very commonly needed and the | |
465 // std header <utility> pulls in lots of other stuff. | |
466 // | |
467 // We use abbreviated names mv and fwd because these helpers (especially mv) are so commonly used | |
468 // that the cost of typing more letters outweighs the cost of being slightly harder to understand | |
469 // when first encountered. | |
470 | |
471 template<typename T> constexpr T&& mv(T& t) noexcept { return static_cast<T&&>(t); } | |
472 template<typename T> constexpr T&& fwd(NoInfer<T>& t) noexcept { return static_cast<T&&>(t); } | |
473 | |
474 template<typename T> constexpr T cp(T& t) noexcept { return t; } | |
475 template<typename T> constexpr T cp(const T& t) noexcept { return t; } | |
476 // Useful to force a copy, particularly to pass into a function that expects T&&. | |
477 | |
478 template <typename T, typename U, bool takeT> struct MinType_; | |
479 template <typename T, typename U> struct MinType_<T, U, true> { typedef T Type; }; | |
480 template <typename T, typename U> struct MinType_<T, U, false> { typedef U Type; }; | |
481 | |
482 template <typename T, typename U> | |
483 using MinType = typename MinType_<T, U, sizeof(T) <= sizeof(U)>::Type; | |
484 // Resolves to the smaller of the two input types. | |
485 | |
486 template <typename T, typename U> | |
487 inline constexpr auto min(T&& a, U&& b) -> MinType<Decay<T>, Decay<U>> { | |
488 return a < b ? MinType<Decay<T>, Decay<U>>(a) : MinType<Decay<T>, Decay<U>>(b); | |
489 } | |
490 | |
491 template <typename T, typename U, bool takeT> struct MaxType_; | |
492 template <typename T, typename U> struct MaxType_<T, U, true> { typedef T Type; }; | |
493 template <typename T, typename U> struct MaxType_<T, U, false> { typedef U Type; }; | |
494 | |
495 template <typename T, typename U> | |
496 using MaxType = typename MaxType_<T, U, sizeof(T) >= sizeof(U)>::Type; | |
497 // Resolves to the larger of the two input types. | |
498 | |
499 template <typename T, typename U> | |
500 inline constexpr auto max(T&& a, U&& b) -> MaxType<Decay<T>, Decay<U>> { | |
501 return a > b ? MaxType<Decay<T>, Decay<U>>(a) : MaxType<Decay<T>, Decay<U>>(b); | |
502 } | |
503 | |
504 template <typename T, size_t s> | |
505 inline constexpr size_t size(T (&arr)[s]) { return s; } | |
506 template <typename T> | |
507 inline constexpr size_t size(T&& arr) { return arr.size(); } | |
508 // Returns the size of the parameter, whether the parameter is a regular C array or a container | |
509 // with a `.size()` method. | |
510 | |
511 class MaxValue_ { | |
512 private: | |
513 template <typename T> | |
514 inline constexpr T maxSigned() const { | |
515 return (1ull << (sizeof(T) * 8 - 1)) - 1; | |
516 } | |
517 template <typename T> | |
518 inline constexpr T maxUnsigned() const { | |
519 return ~static_cast<T>(0u); | |
520 } | |
521 | |
522 public: | |
523 #define _kJ_HANDLE_TYPE(T) \ | |
524 inline constexpr operator signed T() const { return MaxValue_::maxSigned < signed T>(); } \ | |
525 inline constexpr operator unsigned T() const { return MaxValue_::maxUnsigned<unsigned T>(); } | |
526 _kJ_HANDLE_TYPE(char) | |
527 _kJ_HANDLE_TYPE(short) | |
528 _kJ_HANDLE_TYPE(int) | |
529 _kJ_HANDLE_TYPE(long) | |
530 _kJ_HANDLE_TYPE(long long) | |
531 #undef _kJ_HANDLE_TYPE | |
532 | |
533 inline constexpr operator char() const { | |
534 // `char` is different from both `signed char` and `unsigned char`, and may be signed or | |
535 // unsigned on different platforms. Ugh. | |
536 return char(-1) < 0 ? MaxValue_::maxSigned<char>() | |
537 : MaxValue_::maxUnsigned<char>(); | |
538 } | |
539 }; | |
540 | |
541 class MinValue_ { | |
542 private: | |
543 template <typename T> | |
544 inline constexpr T minSigned() const { | |
545 return 1ull << (sizeof(T) * 8 - 1); | |
546 } | |
547 template <typename T> | |
548 inline constexpr T minUnsigned() const { | |
549 return 0u; | |
550 } | |
551 | |
552 public: | |
553 #define _kJ_HANDLE_TYPE(T) \ | |
554 inline constexpr operator signed T() const { return MinValue_::minSigned < signed T>(); } \ | |
555 inline constexpr operator unsigned T() const { return MinValue_::minUnsigned<unsigned T>(); } | |
556 _kJ_HANDLE_TYPE(char) | |
557 _kJ_HANDLE_TYPE(short) | |
558 _kJ_HANDLE_TYPE(int) | |
559 _kJ_HANDLE_TYPE(long) | |
560 _kJ_HANDLE_TYPE(long long) | |
561 #undef _kJ_HANDLE_TYPE | |
562 | |
563 inline constexpr operator char() const { | |
564 // `char` is different from both `signed char` and `unsigned char`, and may be signed or | |
565 // unsigned on different platforms. Ugh. | |
566 return char(-1) < 0 ? MinValue_::minSigned<char>() | |
567 : MinValue_::minUnsigned<char>(); | |
568 } | |
569 }; | |
570 | |
571 static KJ_CONSTEXPR(const) MaxValue_ maxValue = MaxValue_(); | |
572 // A special constant which, when cast to an integer type, takes on the maximum possible value of | |
573 // that type. This is useful to use as e.g. a parameter to a function because it will be robust | |
574 // in the face of changes to the parameter's type. | |
575 // | |
576 // `char` is not supported, but `signed char` and `unsigned char` are. | |
577 | |
578 static KJ_CONSTEXPR(const) MinValue_ minValue = MinValue_(); | |
579 // A special constant which, when cast to an integer type, takes on the minimum possible value | |
580 // of that type. This is useful to use as e.g. a parameter to a function because it will be robust | |
581 // in the face of changes to the parameter's type. | |
582 // | |
583 // `char` is not supported, but `signed char` and `unsigned char` are. | |
584 | |
585 #if __GNUC__ | |
586 inline constexpr float inf() { return __builtin_huge_valf(); } | |
587 inline constexpr float nan() { return __builtin_nanf(""); } | |
588 | |
589 #elif _MSC_VER | |
590 | |
591 // Do what MSVC math.h does | |
592 #pragma warning(push) | |
593 #pragma warning(disable: 4756) // "overflow in constant arithmetic" | |
594 inline constexpr float inf() { return (float)(1e300 * 1e300); } | |
595 #pragma warning(pop) | |
596 | |
597 float nan(); | |
598 // Unfortunatley, inf() * 0.0f produces a NaN with the sign bit set, whereas our preferred | |
599 // canonical NaN should not have the sign bit set. std::numeric_limits<float>::quiet_NaN() | |
600 // returns the correct NaN, but we don't want to #include that here. So, we give up and make | |
601 // this out-of-line on MSVC. | |
602 // | |
603 // TODO(msvc): Can we do better? | |
604 | |
605 #else | |
606 #error "Not sure how to support your compiler." | |
607 #endif | |
608 | |
609 inline constexpr bool isNaN(float f) { return f != f; } | |
610 inline constexpr bool isNaN(double f) { return f != f; } | |
611 | |
612 inline int popCount(unsigned int x) { | |
613 #if defined(_MSC_VER) | |
614 return __popcnt(x); | |
615 // Note: __popcnt returns unsigned int, but the value is clearly guaranteed to fit into an int | |
616 #else | |
617 return __builtin_popcount(x); | |
618 #endif | |
619 } | |
620 | |
621 // ======================================================================================= | |
622 // Useful fake containers | |
623 | |
624 template <typename T> | |
625 class Range { | |
626 public: | |
627 inline constexpr Range(const T& begin, const T& end): begin_(begin), end_(end) {} | |
628 | |
629 class Iterator { | |
630 public: | |
631 Iterator() = default; | |
632 inline Iterator(const T& value): value(value) {} | |
633 | |
634 inline const T& operator* () const { return value; } | |
635 inline const T& operator[](size_t index) const { return value + index; } | |
636 inline Iterator& operator++() { ++value; return *this; } | |
637 inline Iterator operator++(int) { return Iterator(value++); } | |
638 inline Iterator& operator--() { --value; return *this; } | |
639 inline Iterator operator--(int) { return Iterator(value--); } | |
640 inline Iterator& operator+=(ptrdiff_t amount) { value += amount; return *this; } | |
641 inline Iterator& operator-=(ptrdiff_t amount) { value -= amount; return *this; } | |
642 inline Iterator operator+ (ptrdiff_t amount) const { return Iterator(value + amount); } | |
643 inline Iterator operator- (ptrdiff_t amount) const { return Iterator(value - amount); } | |
644 inline ptrdiff_t operator- (const Iterator& other) const { return value - other.value; } | |
645 | |
646 inline bool operator==(const Iterator& other) const { return value == other.value; } | |
647 inline bool operator!=(const Iterator& other) const { return value != other.value; } | |
648 inline bool operator<=(const Iterator& other) const { return value <= other.value; } | |
649 inline bool operator>=(const Iterator& other) const { return value >= other.value; } | |
650 inline bool operator< (const Iterator& other) const { return value < other.value; } | |
651 inline bool operator> (const Iterator& other) const { return value > other.value; } | |
652 | |
653 private: | |
654 T value; | |
655 }; | |
656 | |
657 inline Iterator begin() const { return Iterator(begin_); } | |
658 inline Iterator end() const { return Iterator(end_); } | |
659 | |
660 inline auto size() const -> decltype(instance<T>() - instance<T>()) { return end_ - begin_; } | |
661 | |
662 private: | |
663 T begin_; | |
664 T end_; | |
665 }; | |
666 | |
667 template <typename T> | |
668 inline constexpr Range<Decay<T>> range(T begin, T end) { return Range<Decay<T>>(begin, end); } | |
669 // Returns a fake iterable container containing all values of T from `begin` (inclusive) to `end` | |
670 // (exclusive). Example: | |
671 // | |
672 // // Prints 1, 2, 3, 4, 5, 6, 7, 8, 9. | |
673 // for (int i: kj::range(1, 10)) { print(i); } | |
674 | |
675 template <typename T> | |
676 inline constexpr Range<size_t> indices(T&& container) { | |
677 // Shortcut for iterating over the indices of a container: | |
678 // | |
679 // for (size_t i: kj::indices(myArray)) { handle(myArray[i]); } | |
680 | |
681 return range<size_t>(0, kj::size(container)); | |
682 } | |
683 | |
684 template <typename T> | |
685 class Repeat { | |
686 public: | |
687 inline constexpr Repeat(const T& value, size_t count): value(value), count(count) {} | |
688 | |
689 class Iterator { | |
690 public: | |
691 Iterator() = default; | |
692 inline Iterator(const T& value, size_t index): value(value), index(index) {} | |
693 | |
694 inline const T& operator* () const { return value; } | |
695 inline const T& operator[](ptrdiff_t index) const { return value; } | |
696 inline Iterator& operator++() { ++index; return *this; } | |
697 inline Iterator operator++(int) { return Iterator(value, index++); } | |
698 inline Iterator& operator--() { --index; return *this; } | |
699 inline Iterator operator--(int) { return Iterator(value, index--); } | |
700 inline Iterator& operator+=(ptrdiff_t amount) { index += amount; return *this; } | |
701 inline Iterator& operator-=(ptrdiff_t amount) { index -= amount; return *this; } | |
702 inline Iterator operator+ (ptrdiff_t amount) const { return Iterator(value, index + amount); } | |
703 inline Iterator operator- (ptrdiff_t amount) const { return Iterator(value, index - amount); } | |
704 inline ptrdiff_t operator- (const Iterator& other) const { return index - other.index; } | |
705 | |
706 inline bool operator==(const Iterator& other) const { return index == other.index; } | |
707 inline bool operator!=(const Iterator& other) const { return index != other.index; } | |
708 inline bool operator<=(const Iterator& other) const { return index <= other.index; } | |
709 inline bool operator>=(const Iterator& other) const { return index >= other.index; } | |
710 inline bool operator< (const Iterator& other) const { return index < other.index; } | |
711 inline bool operator> (const Iterator& other) const { return index > other.index; } | |
712 | |
713 private: | |
714 T value; | |
715 size_t index; | |
716 }; | |
717 | |
718 inline Iterator begin() const { return Iterator(value, 0); } | |
719 inline Iterator end() const { return Iterator(value, count); } | |
720 | |
721 inline size_t size() const { return count; } | |
722 | |
723 private: | |
724 T value; | |
725 size_t count; | |
726 }; | |
727 | |
728 template <typename T> | |
729 inline constexpr Repeat<Decay<T>> repeat(T&& value, size_t count) { | |
730 // Returns a fake iterable which contains `count` repeats of `value`. Useful for e.g. creating | |
731 // a bunch of spaces: `kj::repeat(' ', indent * 2)` | |
732 | |
733 return Repeat<Decay<T>>(value, count); | |
734 } | |
735 | |
736 // ======================================================================================= | |
737 // Manually invoking constructors and destructors | |
738 // | |
739 // ctor(x, ...) and dtor(x) invoke x's constructor or destructor, respectively. | |
740 | |
741 // We want placement new, but we don't want to #include <new>. operator new cannot be defined in | |
742 // a namespace, and defining it globally conflicts with the definition in <new>. So we have to | |
743 // define a dummy type and an operator new that uses it. | |
744 | |
745 namespace _ { // private | |
746 struct PlacementNew {}; | |
747 } // namespace _ (private) | |
748 } // namespace kj | |
749 | |
750 inline void* operator new(size_t, kj::_::PlacementNew, void* __p) noexcept { | |
751 return __p; | |
752 } | |
753 | |
754 inline void operator delete(void*, kj::_::PlacementNew, void* __p) noexcept {} | |
755 | |
756 namespace kj { | |
757 | |
758 template <typename T, typename... Params> | |
759 inline void ctor(T& location, Params&&... params) { | |
760 new (_::PlacementNew(), &location) T(kj::fwd<Params>(params)...); | |
761 } | |
762 | |
763 template <typename T> | |
764 inline void dtor(T& location) { | |
765 location.~T(); | |
766 } | |
767 | |
768 // ======================================================================================= | |
769 // Maybe | |
770 // | |
771 // Use in cases where you want to indicate that a value may be null. Using Maybe<T&> instead of T* | |
772 // forces the caller to handle the null case in order to satisfy the compiler, thus reliably | |
773 // preventing null pointer dereferences at runtime. | |
774 // | |
775 // Maybe<T> can be implicitly constructed from T and from nullptr. Additionally, it can be | |
776 // implicitly constructed from T*, in which case the pointer is checked for nullness at runtime. | |
777 // To read the value of a Maybe<T>, do: | |
778 // | |
779 // KJ_IF_MAYBE(value, someFuncReturningMaybe()) { | |
780 // doSomething(*value); | |
781 // } else { | |
782 // maybeWasNull(); | |
783 // } | |
784 // | |
785 // KJ_IF_MAYBE's first parameter is a variable name which will be defined within the following | |
786 // block. The variable will behave like a (guaranteed non-null) pointer to the Maybe's value, | |
787 // though it may or may not actually be a pointer. | |
788 // | |
789 // Note that Maybe<T&> actually just wraps a pointer, whereas Maybe<T> wraps a T and a boolean | |
790 // indicating nullness. | |
791 | |
792 template <typename T> | |
793 class Maybe; | |
794 | |
795 namespace _ { // private | |
796 | |
797 #if _MSC_VER | |
798 // TODO(msvc): MSVC barfs on noexcept(instance<T&>().~T()) where T = kj::Exception and | |
799 // kj::_::Void. It and every other factorization I've tried produces: | |
800 // error C2325: 'kj::Blah' unexpected type to the right of '.~': expected 'void' | |
801 #define MSVC_NOEXCEPT_DTOR_WORKAROUND(T) __is_nothrow_destructible(T) | |
802 #else | |
803 #define MSVC_NOEXCEPT_DTOR_WORKAROUND(T) noexcept(instance<T&>().~T()) | |
804 #endif | |
805 | |
806 template <typename T> | |
807 class NullableValue { | |
808 // Class whose interface behaves much like T*, but actually contains an instance of T and a | |
809 // boolean flag indicating nullness. | |
810 | |
811 public: | |
812 inline NullableValue(NullableValue&& other) noexcept(noexcept(T(instance<T&&>()))) | |
813 : isSet(other.isSet) { | |
814 if (isSet) { | |
815 ctor(value, kj::mv(other.value)); | |
816 } | |
817 } | |
818 inline NullableValue(const NullableValue& other) | |
819 : isSet(other.isSet) { | |
820 if (isSet) { | |
821 ctor(value, other.value); | |
822 } | |
823 } | |
824 inline NullableValue(NullableValue& other) | |
825 : isSet(other.isSet) { | |
826 if (isSet) { | |
827 ctor(value, other.value); | |
828 } | |
829 } | |
830 inline ~NullableValue() noexcept(MSVC_NOEXCEPT_DTOR_WORKAROUND(T)) { | |
831 if (isSet) { | |
832 dtor(value); | |
833 } | |
834 } | |
835 | |
836 inline T& operator*() & { return value; } | |
837 inline const T& operator*() const & { return value; } | |
838 inline T&& operator*() && { return kj::mv(value); } | |
839 inline const T&& operator*() const && { return kj::mv(value); } | |
840 inline T* operator->() { return &value; } | |
841 inline const T* operator->() const { return &value; } | |
842 inline operator T*() { return isSet ? &value : nullptr; } | |
843 inline operator const T*() const { return isSet ? &value : nullptr; } | |
844 | |
845 template <typename... Params> | |
846 inline T& emplace(Params&&... params) { | |
847 if (isSet) { | |
848 isSet = false; | |
849 dtor(value); | |
850 } | |
851 ctor(value, kj::fwd<Params>(params)...); | |
852 isSet = true; | |
853 return value; | |
854 } | |
855 | |
856 private: // internal interface used by friends only | |
857 inline NullableValue() noexcept: isSet(false) {} | |
858 inline NullableValue(T&& t) noexcept(noexcept(T(instance<T&&>()))) | |
859 : isSet(true) { | |
860 ctor(value, kj::mv(t)); | |
861 } | |
862 inline NullableValue(T& t) | |
863 : isSet(true) { | |
864 ctor(value, t); | |
865 } | |
866 inline NullableValue(const T& t) | |
867 : isSet(true) { | |
868 ctor(value, t); | |
869 } | |
870 inline NullableValue(const T* t) | |
871 : isSet(t != nullptr) { | |
872 if (isSet) ctor(value, *t); | |
873 } | |
874 template <typename U> | |
875 inline NullableValue(NullableValue<U>&& other) noexcept(noexcept(T(instance<U&&>()))) | |
876 : isSet(other.isSet) { | |
877 if (isSet) { | |
878 ctor(value, kj::mv(other.value)); | |
879 } | |
880 } | |
881 template <typename U> | |
882 inline NullableValue(const NullableValue<U>& other) | |
883 : isSet(other.isSet) { | |
884 if (isSet) { | |
885 ctor(value, other.value); | |
886 } | |
887 } | |
888 template <typename U> | |
889 inline NullableValue(const NullableValue<U&>& other) | |
890 : isSet(other.isSet) { | |
891 if (isSet) { | |
892 ctor(value, *other.ptr); | |
893 } | |
894 } | |
895 inline NullableValue(decltype(nullptr)): isSet(false) {} | |
896 | |
897 inline NullableValue& operator=(NullableValue&& other) { | |
898 if (&other != this) { | |
899 // Careful about throwing destructors/constructors here. | |
900 if (isSet) { | |
901 isSet = false; | |
902 dtor(value); | |
903 } | |
904 if (other.isSet) { | |
905 ctor(value, kj::mv(other.value)); | |
906 isSet = true; | |
907 } | |
908 } | |
909 return *this; | |
910 } | |
911 | |
912 inline NullableValue& operator=(NullableValue& other) { | |
913 if (&other != this) { | |
914 // Careful about throwing destructors/constructors here. | |
915 if (isSet) { | |
916 isSet = false; | |
917 dtor(value); | |
918 } | |
919 if (other.isSet) { | |
920 ctor(value, other.value); | |
921 isSet = true; | |
922 } | |
923 } | |
924 return *this; | |
925 } | |
926 | |
927 inline NullableValue& operator=(const NullableValue& other) { | |
928 if (&other != this) { | |
929 // Careful about throwing destructors/constructors here. | |
930 if (isSet) { | |
931 isSet = false; | |
932 dtor(value); | |
933 } | |
934 if (other.isSet) { | |
935 ctor(value, other.value); | |
936 isSet = true; | |
937 } | |
938 } | |
939 return *this; | |
940 } | |
941 | |
942 inline bool operator==(decltype(nullptr)) const { return !isSet; } | |
943 inline bool operator!=(decltype(nullptr)) const { return isSet; } | |
944 | |
945 private: | |
946 bool isSet; | |
947 | |
948 #if _MSC_VER | |
949 #pragma warning(push) | |
950 #pragma warning(disable: 4624) | |
951 // Warns that the anonymous union has a deleted destructor when T is non-trivial. This warning | |
952 // seems broken. | |
953 #endif | |
954 | |
955 union { | |
956 T value; | |
957 }; | |
958 | |
959 #if _MSC_VER | |
960 #pragma warning(pop) | |
961 #endif | |
962 | |
963 friend class kj::Maybe<T>; | |
964 template <typename U> | |
965 friend NullableValue<U>&& readMaybe(Maybe<U>&& maybe); | |
966 }; | |
967 | |
968 template <typename T> | |
969 inline NullableValue<T>&& readMaybe(Maybe<T>&& maybe) { return kj::mv(maybe.ptr); } | |
970 template <typename T> | |
971 inline T* readMaybe(Maybe<T>& maybe) { return maybe.ptr; } | |
972 template <typename T> | |
973 inline const T* readMaybe(const Maybe<T>& maybe) { return maybe.ptr; } | |
974 template <typename T> | |
975 inline T* readMaybe(Maybe<T&>&& maybe) { return maybe.ptr; } | |
976 template <typename T> | |
977 inline T* readMaybe(const Maybe<T&>& maybe) { return maybe.ptr; } | |
978 | |
979 template <typename T> | |
980 inline T* readMaybe(T* ptr) { return ptr; } | |
981 // Allow KJ_IF_MAYBE to work on regular pointers. | |
982 | |
983 } // namespace _ (private) | |
984 | |
985 #define KJ_IF_MAYBE(name, exp) if (auto name = ::kj::_::readMaybe(exp)) | |
986 | |
987 template <typename T> | |
988 class Maybe { | |
989 // A T, or nullptr. | |
990 | |
991 // IF YOU CHANGE THIS CLASS: Note that there is a specialization of it in memory.h. | |
992 | |
993 public: | |
994 Maybe(): ptr(nullptr) {} | |
995 Maybe(T&& t) noexcept(noexcept(T(instance<T&&>()))): ptr(kj::mv(t)) {} | |
996 Maybe(T& t): ptr(t) {} | |
997 Maybe(const T& t): ptr(t) {} | |
998 Maybe(const T* t) noexcept: ptr(t) {} | |
999 Maybe(Maybe&& other) noexcept(noexcept(T(instance<T&&>()))): ptr(kj::mv(other.ptr)) {} | |
1000 Maybe(const Maybe& other): ptr(other.ptr) {} | |
1001 Maybe(Maybe& other): ptr(other.ptr) {} | |
1002 | |
1003 template <typename U> | |
1004 Maybe(Maybe<U>&& other) noexcept(noexcept(T(instance<U&&>()))) { | |
1005 KJ_IF_MAYBE(val, kj::mv(other)) { | |
1006 ptr = *val; | |
1007 } | |
1008 } | |
1009 template <typename U> | |
1010 Maybe(const Maybe<U>& other) { | |
1011 KJ_IF_MAYBE(val, other) { | |
1012 ptr = *val; | |
1013 } | |
1014 } | |
1015 | |
1016 Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {} | |
1017 | |
1018 template <typename... Params> | |
1019 inline T& emplace(Params&&... params) { | |
1020 // Replace this Maybe's content with a new value constructed by passing the given parametrs to | |
1021 // T's constructor. This can be used to initialize a Maybe without copying or even moving a T. | |
1022 // Returns a reference to the newly-constructed value. | |
1023 | |
1024 return ptr.emplace(kj::fwd<Params>(params)...); | |
1025 } | |
1026 | |
1027 inline Maybe& operator=(Maybe&& other) { ptr = kj::mv(other.ptr); return *this; } | |
1028 inline Maybe& operator=(Maybe& other) { ptr = other.ptr; return *this; } | |
1029 inline Maybe& operator=(const Maybe& other) { ptr = other.ptr; return *this; } | |
1030 | |
1031 inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } | |
1032 inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } | |
1033 | |
1034 T& orDefault(T& defaultValue) { | |
1035 if (ptr == nullptr) { | |
1036 return defaultValue; | |
1037 } else { | |
1038 return *ptr; | |
1039 } | |
1040 } | |
1041 const T& orDefault(const T& defaultValue) const { | |
1042 if (ptr == nullptr) { | |
1043 return defaultValue; | |
1044 } else { | |
1045 return *ptr; | |
1046 } | |
1047 } | |
1048 | |
1049 template <typename Func> | |
1050 auto map(Func&& f) & -> Maybe<decltype(f(instance<T&>()))> { | |
1051 if (ptr == nullptr) { | |
1052 return nullptr; | |
1053 } else { | |
1054 return f(*ptr); | |
1055 } | |
1056 } | |
1057 | |
1058 template <typename Func> | |
1059 auto map(Func&& f) const & -> Maybe<decltype(f(instance<const T&>()))> { | |
1060 if (ptr == nullptr) { | |
1061 return nullptr; | |
1062 } else { | |
1063 return f(*ptr); | |
1064 } | |
1065 } | |
1066 | |
1067 template <typename Func> | |
1068 auto map(Func&& f) && -> Maybe<decltype(f(instance<T&&>()))> { | |
1069 if (ptr == nullptr) { | |
1070 return nullptr; | |
1071 } else { | |
1072 return f(kj::mv(*ptr)); | |
1073 } | |
1074 } | |
1075 | |
1076 template <typename Func> | |
1077 auto map(Func&& f) const && -> Maybe<decltype(f(instance<const T&&>()))> { | |
1078 if (ptr == nullptr) { | |
1079 return nullptr; | |
1080 } else { | |
1081 return f(kj::mv(*ptr)); | |
1082 } | |
1083 } | |
1084 | |
1085 private: | |
1086 _::NullableValue<T> ptr; | |
1087 | |
1088 template <typename U> | |
1089 friend class Maybe; | |
1090 template <typename U> | |
1091 friend _::NullableValue<U>&& _::readMaybe(Maybe<U>&& maybe); | |
1092 template <typename U> | |
1093 friend U* _::readMaybe(Maybe<U>& maybe); | |
1094 template <typename U> | |
1095 friend const U* _::readMaybe(const Maybe<U>& maybe); | |
1096 }; | |
1097 | |
1098 template <typename T> | |
1099 class Maybe<T&>: public DisallowConstCopyIfNotConst<T> { | |
1100 public: | |
1101 Maybe() noexcept: ptr(nullptr) {} | |
1102 Maybe(T& t) noexcept: ptr(&t) {} | |
1103 Maybe(T* t) noexcept: ptr(t) {} | |
1104 | |
1105 template <typename U> | |
1106 inline Maybe(Maybe<U&>& other) noexcept: ptr(other.ptr) {} | |
1107 template <typename U> | |
1108 inline Maybe(const Maybe<const U&>& other) noexcept: ptr(other.ptr) {} | |
1109 inline Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {} | |
1110 | |
1111 inline Maybe& operator=(T& other) noexcept { ptr = &other; return *this; } | |
1112 inline Maybe& operator=(T* other) noexcept { ptr = other; return *this; } | |
1113 template <typename U> | |
1114 inline Maybe& operator=(Maybe<U&>& other) noexcept { ptr = other.ptr; return *this; } | |
1115 template <typename U> | |
1116 inline Maybe& operator=(const Maybe<const U&>& other) noexcept { ptr = other.ptr; return *this; } | |
1117 | |
1118 inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } | |
1119 inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } | |
1120 | |
1121 T& orDefault(T& defaultValue) { | |
1122 if (ptr == nullptr) { | |
1123 return defaultValue; | |
1124 } else { | |
1125 return *ptr; | |
1126 } | |
1127 } | |
1128 const T& orDefault(const T& defaultValue) const { | |
1129 if (ptr == nullptr) { | |
1130 return defaultValue; | |
1131 } else { | |
1132 return *ptr; | |
1133 } | |
1134 } | |
1135 | |
1136 template <typename Func> | |
1137 auto map(Func&& f) -> Maybe<decltype(f(instance<T&>()))> { | |
1138 if (ptr == nullptr) { | |
1139 return nullptr; | |
1140 } else { | |
1141 return f(*ptr); | |
1142 } | |
1143 } | |
1144 | |
1145 private: | |
1146 T* ptr; | |
1147 | |
1148 template <typename U> | |
1149 friend class Maybe; | |
1150 template <typename U> | |
1151 friend U* _::readMaybe(Maybe<U&>&& maybe); | |
1152 template <typename U> | |
1153 friend U* _::readMaybe(const Maybe<U&>& maybe); | |
1154 }; | |
1155 | |
1156 // ======================================================================================= | |
1157 // ArrayPtr | |
1158 // | |
1159 // So common that we put it in common.h rather than array.h. | |
1160 | |
1161 template <typename T> | |
1162 class ArrayPtr: public DisallowConstCopyIfNotConst<T> { | |
1163 // A pointer to an array. Includes a size. Like any pointer, it doesn't own the target data, | |
1164 // and passing by value only copies the pointer, not the target. | |
1165 | |
1166 public: | |
1167 inline constexpr ArrayPtr(): ptr(nullptr), size_(0) {} | |
1168 inline constexpr ArrayPtr(decltype(nullptr)): ptr(nullptr), size_(0) {} | |
1169 inline constexpr ArrayPtr(T* ptr, size_t size): ptr(ptr), size_(size) {} | |
1170 inline constexpr ArrayPtr(T* begin, T* end): ptr(begin), size_(end - begin) {} | |
1171 inline KJ_CONSTEXPR() ArrayPtr(::std::initializer_list<RemoveConstOrDisable<T>> init) | |
1172 : ptr(init.begin()), size_(init.size()) {} | |
1173 | |
1174 template <size_t size> | |
1175 inline constexpr ArrayPtr(T (&native)[size]): ptr(native), size_(size) {} | |
1176 // Construct an ArrayPtr from a native C-style array. | |
1177 | |
1178 inline operator ArrayPtr<const T>() const { | |
1179 return ArrayPtr<const T>(ptr, size_); | |
1180 } | |
1181 inline ArrayPtr<const T> asConst() const { | |
1182 return ArrayPtr<const T>(ptr, size_); | |
1183 } | |
1184 | |
1185 inline size_t size() const { return size_; } | |
1186 inline const T& operator[](size_t index) const { | |
1187 KJ_IREQUIRE(index < size_, "Out-of-bounds ArrayPtr access."); | |
1188 return ptr[index]; | |
1189 } | |
1190 inline T& operator[](size_t index) { | |
1191 KJ_IREQUIRE(index < size_, "Out-of-bounds ArrayPtr access."); | |
1192 return ptr[index]; | |
1193 } | |
1194 | |
1195 inline T* begin() { return ptr; } | |
1196 inline T* end() { return ptr + size_; } | |
1197 inline T& front() { return *ptr; } | |
1198 inline T& back() { return *(ptr + size_ - 1); } | |
1199 inline const T* begin() const { return ptr; } | |
1200 inline const T* end() const { return ptr + size_; } | |
1201 inline const T& front() const { return *ptr; } | |
1202 inline const T& back() const { return *(ptr + size_ - 1); } | |
1203 | |
1204 inline ArrayPtr<const T> slice(size_t start, size_t end) const { | |
1205 KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds ArrayPtr::slice()."); | |
1206 return ArrayPtr<const T>(ptr + start, end - start); | |
1207 } | |
1208 inline ArrayPtr slice(size_t start, size_t end) { | |
1209 KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds ArrayPtr::slice()."); | |
1210 return ArrayPtr(ptr + start, end - start); | |
1211 } | |
1212 | |
1213 inline ArrayPtr<PropagateConst<T, byte>> asBytes() const { | |
1214 // Reinterpret the array as a byte array. This is explicitly legal under C++ aliasing | |
1215 // rules. | |
1216 return { reinterpret_cast<PropagateConst<T, byte>*>(ptr), size_ * sizeof(T) }; | |
1217 } | |
1218 inline ArrayPtr<PropagateConst<T, char>> asChars() const { | |
1219 // Reinterpret the array as a char array. This is explicitly legal under C++ aliasing | |
1220 // rules. | |
1221 return { reinterpret_cast<PropagateConst<T, char>*>(ptr), size_ * sizeof(T) }; | |
1222 } | |
1223 | |
1224 inline bool operator==(decltype(nullptr)) const { return size_ == 0; } | |
1225 inline bool operator!=(decltype(nullptr)) const { return size_ != 0; } | |
1226 | |
1227 inline bool operator==(const ArrayPtr& other) const { | |
1228 if (size_ != other.size_) return false; | |
1229 for (size_t i = 0; i < size_; i++) { | |
1230 if (ptr[i] != other[i]) return false; | |
1231 } | |
1232 return true; | |
1233 } | |
1234 inline bool operator!=(const ArrayPtr& other) const { return !(*this == other); } | |
1235 | |
1236 private: | |
1237 T* ptr; | |
1238 size_t size_; | |
1239 }; | |
1240 | |
1241 template <typename T> | |
1242 inline constexpr ArrayPtr<T> arrayPtr(T* ptr, size_t size) { | |
1243 // Use this function to construct ArrayPtrs without writing out the type name. | |
1244 return ArrayPtr<T>(ptr, size); | |
1245 } | |
1246 | |
1247 template <typename T> | |
1248 inline constexpr ArrayPtr<T> arrayPtr(T* begin, T* end) { | |
1249 // Use this function to construct ArrayPtrs without writing out the type name. | |
1250 return ArrayPtr<T>(begin, end); | |
1251 } | |
1252 | |
1253 // ======================================================================================= | |
1254 // Casts | |
1255 | |
1256 template <typename To, typename From> | |
1257 To implicitCast(From&& from) { | |
1258 // `implicitCast<T>(value)` casts `value` to type `T` only if the conversion is implicit. Useful | |
1259 // for e.g. resolving ambiguous overloads without sacrificing type-safety. | |
1260 return kj::fwd<From>(from); | |
1261 } | |
1262 | |
1263 template <typename To, typename From> | |
1264 Maybe<To&> dynamicDowncastIfAvailable(From& from) { | |
1265 // If RTTI is disabled, always returns nullptr. Otherwise, works like dynamic_cast. Useful | |
1266 // in situations where dynamic_cast could allow an optimization, but isn't strictly necessary | |
1267 // for correctness. It is highly recommended that you try to arrange all your dynamic_casts | |
1268 // this way, as a dynamic_cast that is necessary for correctness implies a flaw in the interface | |
1269 // design. | |
1270 | |
1271 // Force a compile error if To is not a subtype of From. Cross-casting is rare; if it is needed | |
1272 // we should have a separate cast function like dynamicCrosscastIfAvailable(). | |
1273 if (false) { | |
1274 kj::implicitCast<From*>(kj::implicitCast<To*>(nullptr)); | |
1275 } | |
1276 | |
1277 #if KJ_NO_RTTI | |
1278 return nullptr; | |
1279 #else | |
1280 return dynamic_cast<To*>(&from); | |
1281 #endif | |
1282 } | |
1283 | |
1284 template <typename To, typename From> | |
1285 To& downcast(From& from) { | |
1286 // Down-cast a value to a sub-type, asserting that the cast is valid. In opt mode this is a | |
1287 // static_cast, but in debug mode (when RTTI is enabled) a dynamic_cast will be used to verify | |
1288 // that the value really has the requested type. | |
1289 | |
1290 // Force a compile error if To is not a subtype of From. | |
1291 if (false) { | |
1292 kj::implicitCast<From*>(kj::implicitCast<To*>(nullptr)); | |
1293 } | |
1294 | |
1295 #if !KJ_NO_RTTI | |
1296 KJ_IREQUIRE(dynamic_cast<To*>(&from) != nullptr, "Value cannot be downcast() to requested type."); | |
1297 #endif | |
1298 | |
1299 return static_cast<To&>(from); | |
1300 } | |
1301 | |
1302 // ======================================================================================= | |
1303 // Defer | |
1304 | |
1305 namespace _ { // private | |
1306 | |
1307 template <typename Func> | |
1308 class Deferred { | |
1309 public: | |
1310 inline Deferred(Func&& func): func(kj::fwd<Func>(func)), canceled(false) {} | |
1311 inline ~Deferred() noexcept(false) { if (!canceled) func(); } | |
1312 KJ_DISALLOW_COPY(Deferred); | |
1313 | |
1314 // This move constructor is usually optimized away by the compiler. | |
1315 inline Deferred(Deferred&& other): func(kj::mv(other.func)), canceled(false) { | |
1316 other.canceled = true; | |
1317 } | |
1318 private: | |
1319 Func func; | |
1320 bool canceled; | |
1321 }; | |
1322 | |
1323 } // namespace _ (private) | |
1324 | |
1325 template <typename Func> | |
1326 _::Deferred<Func> defer(Func&& func) { | |
1327 // Returns an object which will invoke the given functor in its destructor. The object is not | |
1328 // copyable but is movable with the semantics you'd expect. Since the return type is private, | |
1329 // you need to assign to an `auto` variable. | |
1330 // | |
1331 // The KJ_DEFER macro provides slightly more convenient syntax for the common case where you | |
1332 // want some code to run at current scope exit. | |
1333 | |
1334 return _::Deferred<Func>(kj::fwd<Func>(func)); | |
1335 } | |
1336 | |
1337 #define KJ_DEFER(code) auto KJ_UNIQUE_NAME(_kjDefer) = ::kj::defer([&](){code;}) | |
1338 // Run the given code when the function exits, whether by return or exception. | |
1339 | |
1340 } // namespace kj | |
1341 | |
1342 #endif // KJ_COMMON_H_ |