Mercurial > repos > rliterman > csp2
comparison CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/include/kj/common.h @ 69:33d812a61356
planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author | jpayne |
---|---|
date | Tue, 18 Mar 2025 17:55:14 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
67:0e9998148a16 | 69:33d812a61356 |
---|---|
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 #pragma once | |
27 | |
28 #if defined(__GNUC__) || defined(__clang__) | |
29 #define KJ_BEGIN_SYSTEM_HEADER _Pragma("GCC system_header") | |
30 #elif defined(_MSC_VER) | |
31 #define KJ_BEGIN_SYSTEM_HEADER __pragma(warning(push, 0)) | |
32 #define KJ_END_SYSTEM_HEADER __pragma(warning(pop)) | |
33 #endif | |
34 | |
35 #ifndef KJ_BEGIN_SYSTEM_HEADER | |
36 #define KJ_BEGIN_SYSTEM_HEADER | |
37 #endif | |
38 | |
39 #ifndef KJ_END_SYSTEM_HEADER | |
40 #define KJ_END_SYSTEM_HEADER | |
41 #endif | |
42 | |
43 #if !defined(KJ_HEADER_WARNINGS) || !KJ_HEADER_WARNINGS | |
44 #define KJ_BEGIN_HEADER KJ_BEGIN_SYSTEM_HEADER | |
45 #define KJ_END_HEADER KJ_END_SYSTEM_HEADER | |
46 #else | |
47 #define KJ_BEGIN_HEADER | |
48 #define KJ_END_HEADER | |
49 #endif | |
50 | |
51 #ifdef __has_cpp_attribute | |
52 #define KJ_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) | |
53 #else | |
54 #define KJ_HAS_CPP_ATTRIBUTE(x) 0 | |
55 #endif | |
56 | |
57 #ifdef __has_feature | |
58 #define KJ_HAS_COMPILER_FEATURE(x) __has_feature(x) | |
59 #else | |
60 #define KJ_HAS_COMPILER_FEATURE(x) 0 | |
61 #endif | |
62 | |
63 #if defined(_MSVC_LANG) && !defined(__clang__) | |
64 #define KJ_CPP_STD _MSVC_LANG | |
65 #else | |
66 #define KJ_CPP_STD __cplusplus | |
67 #endif | |
68 | |
69 KJ_BEGIN_HEADER | |
70 | |
71 #ifndef KJ_NO_COMPILER_CHECK | |
72 // Technically, __cplusplus should be 201402L for C++14, but GCC 4.9 -- which is supported -- still | |
73 // had it defined to 201300L even with -std=c++14. | |
74 #if KJ_CPP_STD < 201300L && !__CDT_PARSER__ | |
75 #error "This code requires C++14. Either your compiler does not support it or it is not enabled." | |
76 #ifdef __GNUC__ | |
77 // Compiler claims compatibility with GCC, so presumably supports -std. | |
78 #error "Pass -std=c++14 on the compiler command line to enable C++14." | |
79 #endif | |
80 #endif | |
81 | |
82 #ifdef __GNUC__ | |
83 #if __clang__ | |
84 #if __clang_major__ < 5 | |
85 #warning "This library requires at least Clang 5.0." | |
86 #elif KJ_CPP_STD >= 201402L && !__has_include(<initializer_list>) | |
87 #warning "Your compiler supports C++14 but your C++ standard library does not. If your "\ | |
88 "system has libc++ installed (as should be the case on e.g. Mac OSX), try adding "\ | |
89 "-stdlib=libc++ to your CXXFLAGS." | |
90 #endif | |
91 #else | |
92 #if __GNUC__ < 5 | |
93 #warning "This library requires at least GCC 5.0." | |
94 #endif | |
95 #endif | |
96 #elif defined(_MSC_VER) | |
97 #if _MSC_VER < 1910 && !defined(__clang__) | |
98 #error "You need Visual Studio 2017 or better to compile this code." | |
99 #endif | |
100 #else | |
101 #warning "I don't recognize your compiler. As of this writing, Clang, GCC, and Visual Studio "\ | |
102 "are the only known compilers with enough C++14 support for this library. "\ | |
103 "#define KJ_NO_COMPILER_CHECK to make this warning go away." | |
104 #endif | |
105 #endif | |
106 | |
107 #include <stddef.h> | |
108 #include <cstring> | |
109 #include <initializer_list> | |
110 #include <string.h> | |
111 | |
112 #if __linux__ && KJ_CPP_STD > 201200L | |
113 // Hack around stdlib bug with C++14 that exists on some Linux systems. | |
114 // Apparently in this mode the C library decides not to define gets() but the C++ library still | |
115 // tries to import it into the std namespace. This bug has been fixed at the source but is still | |
116 // widely present in the wild e.g. on Ubuntu 14.04. | |
117 #undef _GLIBCXX_HAVE_GETS | |
118 #endif | |
119 | |
120 #if _WIN32 | |
121 // Windows likes to define macros for min() and max(). We just can't deal with this. | |
122 // If windows.h was included already, undef these. | |
123 #undef min | |
124 #undef max | |
125 // If windows.h was not included yet, define the macro that prevents min() and max() from being | |
126 // defined. | |
127 #ifndef NOMINMAX | |
128 #define NOMINMAX 1 | |
129 #endif | |
130 #endif | |
131 | |
132 #if defined(_MSC_VER) | |
133 #include <intrin.h> // __popcnt | |
134 #endif | |
135 | |
136 // ======================================================================================= | |
137 | |
138 namespace kj { | |
139 | |
140 typedef unsigned int uint; | |
141 typedef unsigned char byte; | |
142 | |
143 // ======================================================================================= | |
144 // Common macros, especially for common yet compiler-specific features. | |
145 | |
146 // Detect whether RTTI and exceptions are enabled, assuming they are unless we have specific | |
147 // evidence to the contrary. Clients can always define KJ_NO_RTTI or KJ_NO_EXCEPTIONS explicitly | |
148 // to override these checks. | |
149 | |
150 // TODO: Ideally we'd use __cpp_exceptions/__cpp_rtti not being defined as the first pass since | |
151 // that is the standard compliant way. However, it's unclear how to use those macros (or any | |
152 // others) to distinguish between the compiler supporting feature detection and the feature being | |
153 // disabled vs the compiler not supporting feature detection at all. | |
154 #if defined(__has_feature) | |
155 #if !defined(KJ_NO_RTTI) && !__has_feature(cxx_rtti) | |
156 #define KJ_NO_RTTI 1 | |
157 #endif | |
158 #if !defined(KJ_NO_EXCEPTIONS) && !__has_feature(cxx_exceptions) | |
159 #define KJ_NO_EXCEPTIONS 1 | |
160 #endif | |
161 #elif defined(__GNUC__) | |
162 #if !defined(KJ_NO_RTTI) && !__GXX_RTTI | |
163 #define KJ_NO_RTTI 1 | |
164 #endif | |
165 #if !defined(KJ_NO_EXCEPTIONS) && !__EXCEPTIONS | |
166 #define KJ_NO_EXCEPTIONS 1 | |
167 #endif | |
168 #elif defined(_MSC_VER) | |
169 #if !defined(KJ_NO_RTTI) && !defined(_CPPRTTI) | |
170 #define KJ_NO_RTTI 1 | |
171 #endif | |
172 #if !defined(KJ_NO_EXCEPTIONS) && !defined(_CPPUNWIND) | |
173 #define KJ_NO_EXCEPTIONS 1 | |
174 #endif | |
175 #endif | |
176 | |
177 #if !defined(KJ_DEBUG) && !defined(KJ_NDEBUG) | |
178 // Heuristically decide whether to enable debug mode. If DEBUG or NDEBUG is defined, use that. | |
179 // Otherwise, fall back to checking whether optimization is enabled. | |
180 #if defined(DEBUG) || defined(_DEBUG) | |
181 #define KJ_DEBUG | |
182 #elif defined(NDEBUG) | |
183 #define KJ_NDEBUG | |
184 #elif __OPTIMIZE__ | |
185 #define KJ_NDEBUG | |
186 #else | |
187 #define KJ_DEBUG | |
188 #endif | |
189 #endif | |
190 | |
191 #define KJ_DISALLOW_COPY(classname) \ | |
192 classname(const classname&) = delete; \ | |
193 classname& operator=(const classname&) = delete | |
194 // Deletes the implicit copy constructor and assignment operator. This inhibits the compiler from | |
195 // generating the implicit move constructor and assignment operator for this class, but allows the | |
196 // code author to supply them, if they make sense to implement. | |
197 // | |
198 // This macro should not be your first choice. Instead, prefer using KJ_DISALLOW_COPY_AND_MOVE, and only use | |
199 // this macro when you have determined that you must implement move semantics for your type. | |
200 | |
201 #define KJ_DISALLOW_COPY_AND_MOVE(classname) \ | |
202 classname(const classname&) = delete; \ | |
203 classname& operator=(const classname&) = delete; \ | |
204 classname(classname&&) = delete; \ | |
205 classname& operator=(classname&&) = delete | |
206 // Deletes the implicit copy and move constructors and assignment operators. This is useful in cases | |
207 // where the code author wants to provide an additional compile-time guard against subsequent | |
208 // maintainers casually adding move operations. This is particularly useful when implementing RAII | |
209 // classes that are intended to be completely immobile. | |
210 | |
211 #ifdef __GNUC__ | |
212 #define KJ_LIKELY(condition) __builtin_expect(condition, true) | |
213 #define KJ_UNLIKELY(condition) __builtin_expect(condition, false) | |
214 // Branch prediction macros. Evaluates to the condition given, but also tells the compiler that we | |
215 // expect the condition to be true/false enough of the time that it's worth hard-coding branch | |
216 // prediction. | |
217 #else | |
218 #define KJ_LIKELY(condition) (condition) | |
219 #define KJ_UNLIKELY(condition) (condition) | |
220 #endif | |
221 | |
222 #if defined(KJ_DEBUG) || __NO_INLINE__ | |
223 #define KJ_ALWAYS_INLINE(...) inline __VA_ARGS__ | |
224 // Don't force inline in debug mode. | |
225 #else | |
226 #if defined(_MSC_VER) && !defined(__clang__) | |
227 #define KJ_ALWAYS_INLINE(...) __forceinline __VA_ARGS__ | |
228 #else | |
229 #define KJ_ALWAYS_INLINE(...) inline __VA_ARGS__ __attribute__((always_inline)) | |
230 #endif | |
231 // Force a function to always be inlined. Apply only to the prototype, not to the definition. | |
232 #endif | |
233 | |
234 #if defined(_MSC_VER) && !defined(__clang__) | |
235 #define KJ_NOINLINE __declspec(noinline) | |
236 #else | |
237 #define KJ_NOINLINE __attribute__((noinline)) | |
238 #endif | |
239 | |
240 #if defined(_MSC_VER) && !__clang__ | |
241 #define KJ_NORETURN(prototype) __declspec(noreturn) prototype | |
242 #define KJ_UNUSED | |
243 #define KJ_WARN_UNUSED_RESULT | |
244 // TODO(msvc): KJ_WARN_UNUSED_RESULT can use _Check_return_ on MSVC, but it's a prefix, so | |
245 // wrapping the whole prototype is needed. http://msdn.microsoft.com/en-us/library/jj159529.aspx | |
246 // Similarly, KJ_UNUSED could use __pragma(warning(suppress:...)), but again that's a prefix. | |
247 #else | |
248 #define KJ_NORETURN(prototype) prototype __attribute__((noreturn)) | |
249 #define KJ_UNUSED __attribute__((unused)) | |
250 #define KJ_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) | |
251 #endif | |
252 | |
253 #if KJ_HAS_CPP_ATTRIBUTE(clang::lifetimebound) | |
254 // If this is generating too many false-positives, the user is responsible for disabling the | |
255 // problematic warning at the compiler switch level or by suppressing the place where the | |
256 // false-positive is reported through compiler-specific pragmas if available. | |
257 #define KJ_LIFETIMEBOUND [[clang::lifetimebound]] | |
258 #else | |
259 #define KJ_LIFETIMEBOUND | |
260 #endif | |
261 // Annotation that indicates the returned value is referencing a resource owned by this type (e.g. | |
262 // cStr() on a std::string). Unfortunately this lifetime can only be superficial currently & cannot | |
263 // track further. For example, there's no way to get `array.asPtr().slice(5, 6))` to warn if the | |
264 // last slice exceeds the lifetime of `array`. That's because in the general case `ArrayPtr::slice` | |
265 // can't have the lifetime bound annotation since it's not wrong to do something like: | |
266 // ArrayPtr<char> doSomething(ArrayPtr<char> foo) { | |
267 // ... | |
268 // return foo.slice(5, 6); | |
269 // } | |
270 // If `ArrayPtr::slice` had a lifetime bound then the compiler would warn about this perfectly | |
271 // legitimate method. Really there needs to be 2 more annotations. One to inherit the lifetime bound | |
272 // and another to inherit the lifetime bound from a parameter (which really could be the same thing | |
273 // by allowing a syntax like `[[clang::lifetimebound(*this)]]`. | |
274 // https://clang.llvm.org/docs/AttributeReference.html#lifetimebound | |
275 | |
276 #if __clang__ | |
277 #define KJ_UNUSED_MEMBER __attribute__((unused)) | |
278 // Inhibits "unused" warning for member variables. Only Clang produces such a warning, while GCC | |
279 // complains if the attribute is set on members. | |
280 #else | |
281 #define KJ_UNUSED_MEMBER | |
282 #endif | |
283 | |
284 #if KJ_CPP_STD > 201703L || (__clang__ && __clang_major__ >= 9 && KJ_CPP_STD >= 201103L) | |
285 // Technically this was only added to C++20 but Clang allows it for >= C++11 and spelunking the | |
286 // attributes manual indicates it first came in with Clang 9. | |
287 #define KJ_NO_UNIQUE_ADDRESS [[no_unique_address]] | |
288 #else | |
289 #define KJ_NO_UNIQUE_ADDRESS | |
290 #endif | |
291 | |
292 #if KJ_HAS_COMPILER_FEATURE(thread_sanitizer) || defined(__SANITIZE_THREAD__) | |
293 #define KJ_DISABLE_TSAN __attribute__((no_sanitize("thread"), noinline)) | |
294 #else | |
295 #define KJ_DISABLE_TSAN | |
296 #endif | |
297 | |
298 #if __clang__ | |
299 #define KJ_DEPRECATED(reason) \ | |
300 __attribute__((deprecated(reason))) | |
301 #define KJ_UNAVAILABLE(reason) \ | |
302 __attribute__((unavailable(reason))) | |
303 #elif __GNUC__ | |
304 #define KJ_DEPRECATED(reason) \ | |
305 __attribute__((deprecated)) | |
306 #define KJ_UNAVAILABLE(reason) = delete | |
307 // If the `unavailable` attribute is not supproted, just mark the method deleted, which at least | |
308 // makes it a compile-time error to try to call it. Note that on Clang, marking a method deleted | |
309 // *and* unavailable unfortunately defeats the purpose of the unavailable annotation, as the | |
310 // generic "deleted" error is reported instead. | |
311 #else | |
312 #define KJ_DEPRECATED(reason) | |
313 #define KJ_UNAVAILABLE(reason) = delete | |
314 // TODO(msvc): Again, here, MSVC prefers a prefix, __declspec(deprecated). | |
315 #endif | |
316 | |
317 #if KJ_TESTING_KJ // defined in KJ's own unit tests; others should not define this | |
318 #undef KJ_DEPRECATED | |
319 #define KJ_DEPRECATED(reason) | |
320 #endif | |
321 | |
322 namespace _ { // private | |
323 | |
324 KJ_NORETURN(void inlineRequireFailure( | |
325 const char* file, int line, const char* expectation, const char* macroArgs, | |
326 const char* message = nullptr)); | |
327 | |
328 KJ_NORETURN(void unreachable()); | |
329 | |
330 } // namespace _ (private) | |
331 | |
332 #if _MSC_VER && !defined(__clang__) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL) | |
333 #define KJ_MSVC_TRADITIONAL_CPP 1 | |
334 #endif | |
335 | |
336 #ifdef KJ_DEBUG | |
337 #if KJ_MSVC_TRADITIONAL_CPP | |
338 #define KJ_IREQUIRE(condition, ...) \ | |
339 if (KJ_LIKELY(condition)); else ::kj::_::inlineRequireFailure( \ | |
340 __FILE__, __LINE__, #condition, "" #__VA_ARGS__, __VA_ARGS__) | |
341 // Version of KJ_DREQUIRE() which is safe to use in headers that are #included by users. Used to | |
342 // check preconditions inside inline methods. KJ_IREQUIRE is particularly useful in that | |
343 // it will be enabled depending on whether the application is compiled in debug mode rather than | |
344 // whether libkj is. | |
345 #else | |
346 #define KJ_IREQUIRE(condition, ...) \ | |
347 if (KJ_LIKELY(condition)); else ::kj::_::inlineRequireFailure( \ | |
348 __FILE__, __LINE__, #condition, #__VA_ARGS__, ##__VA_ARGS__) | |
349 // Version of KJ_DREQUIRE() which is safe to use in headers that are #included by users. Used to | |
350 // check preconditions inside inline methods. KJ_IREQUIRE is particularly useful in that | |
351 // it will be enabled depending on whether the application is compiled in debug mode rather than | |
352 // whether libkj is. | |
353 #endif | |
354 #else | |
355 #define KJ_IREQUIRE(condition, ...) | |
356 #endif | |
357 | |
358 #define KJ_IASSERT KJ_IREQUIRE | |
359 | |
360 #define KJ_UNREACHABLE ::kj::_::unreachable(); | |
361 // Put this on code paths that cannot be reached to suppress compiler warnings about missing | |
362 // returns. | |
363 | |
364 #if __clang__ | |
365 #define KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT | |
366 #else | |
367 #define KJ_CLANG_KNOWS_THIS_IS_UNREACHABLE_BUT_GCC_DOESNT KJ_UNREACHABLE | |
368 #endif | |
369 | |
370 #if __clang__ | |
371 #define KJ_KNOWN_UNREACHABLE(code) \ | |
372 do { \ | |
373 _Pragma("clang diagnostic push") \ | |
374 _Pragma("clang diagnostic ignored \"-Wunreachable-code\"") \ | |
375 code; \ | |
376 _Pragma("clang diagnostic pop") \ | |
377 } while (false) | |
378 // Suppress "unreachable code" warnings on intentionally unreachable code. | |
379 #else | |
380 // TODO(someday): Add support for non-clang compilers. | |
381 #define KJ_KNOWN_UNREACHABLE(code) do {code;} while(false) | |
382 #endif | |
383 | |
384 #if KJ_HAS_CPP_ATTRIBUTE(fallthrough) | |
385 #define KJ_FALLTHROUGH [[fallthrough]] | |
386 #else | |
387 #define KJ_FALLTHROUGH | |
388 #endif | |
389 | |
390 // #define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) | |
391 // | |
392 // Allocate an array, preferably on the stack, unless it is too big. On GCC this will use | |
393 // variable-sized arrays. For other compilers we could just use a fixed-size array. `minStack` | |
394 // is the stack array size to use if variable-width arrays are not supported. `maxStack` is the | |
395 // maximum stack array size if variable-width arrays *are* supported. | |
396 #if __GNUC__ && !__clang__ | |
397 #define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) \ | |
398 size_t name##_size = (size); \ | |
399 bool name##_isOnStack = name##_size <= (maxStack); \ | |
400 type name##_stack[kj::max(1, name##_isOnStack ? name##_size : 0)]; \ | |
401 ::kj::Array<type> name##_heap = name##_isOnStack ? \ | |
402 nullptr : kj::heapArray<type>(name##_size); \ | |
403 ::kj::ArrayPtr<type> name = name##_isOnStack ? \ | |
404 kj::arrayPtr(name##_stack, name##_size) : name##_heap | |
405 #else | |
406 #define KJ_STACK_ARRAY(type, name, size, minStack, maxStack) \ | |
407 size_t name##_size = (size); \ | |
408 bool name##_isOnStack = name##_size <= (minStack); \ | |
409 type name##_stack[minStack]; \ | |
410 ::kj::Array<type> name##_heap = name##_isOnStack ? \ | |
411 nullptr : kj::heapArray<type>(name##_size); \ | |
412 ::kj::ArrayPtr<type> name = name##_isOnStack ? \ | |
413 kj::arrayPtr(name##_stack, name##_size) : name##_heap | |
414 #endif | |
415 | |
416 #define KJ_CONCAT_(x, y) x##y | |
417 #define KJ_CONCAT(x, y) KJ_CONCAT_(x, y) | |
418 #define KJ_UNIQUE_NAME(prefix) KJ_CONCAT(prefix, __LINE__) | |
419 // Create a unique identifier name. We use concatenate __LINE__ rather than __COUNTER__ so that | |
420 // the name can be used multiple times in the same macro. | |
421 | |
422 #if _MSC_VER && !defined(__clang__) | |
423 | |
424 #define KJ_CONSTEXPR(...) __VA_ARGS__ | |
425 // Use in cases where MSVC barfs on constexpr. A replacement keyword (e.g. "const") can be | |
426 // provided, or just leave blank to remove the keyword entirely. | |
427 // | |
428 // TODO(msvc): Remove this hack once MSVC fully supports constexpr. | |
429 | |
430 #ifndef __restrict__ | |
431 #define __restrict__ __restrict | |
432 // TODO(msvc): Would it be better to define a KJ_RESTRICT macro? | |
433 #endif | |
434 | |
435 #pragma warning(disable: 4521 4522) | |
436 // This warning complains when there are two copy constructors, one for a const reference and | |
437 // one for a non-const reference. It is often quite necessary to do this in wrapper templates, | |
438 // therefore this warning is dumb and we disable it. | |
439 | |
440 #pragma warning(disable: 4458) | |
441 // Warns when a parameter name shadows a class member. Unfortunately my code does this a lot, | |
442 // since I don't use a special name format for members. | |
443 | |
444 #else // _MSC_VER | |
445 #define KJ_CONSTEXPR(...) constexpr | |
446 #endif | |
447 | |
448 // ======================================================================================= | |
449 // Template metaprogramming helpers. | |
450 | |
451 #define KJ_HAS_TRIVIAL_CONSTRUCTOR __is_trivially_constructible | |
452 #if __GNUC__ && !__clang__ | |
453 #define KJ_HAS_NOTHROW_CONSTRUCTOR __has_nothrow_constructor | |
454 #define KJ_HAS_TRIVIAL_DESTRUCTOR __has_trivial_destructor | |
455 #else | |
456 #define KJ_HAS_NOTHROW_CONSTRUCTOR __is_nothrow_constructible | |
457 #define KJ_HAS_TRIVIAL_DESTRUCTOR __is_trivially_destructible | |
458 #endif | |
459 | |
460 template <typename T> struct NoInfer_ { typedef T Type; }; | |
461 template <typename T> using NoInfer = typename NoInfer_<T>::Type; | |
462 // Use NoInfer<T>::Type in place of T for a template function parameter to prevent inference of | |
463 // the type based on the parameter value. | |
464 | |
465 template <typename T> struct RemoveConst_ { typedef T Type; }; | |
466 template <typename T> struct RemoveConst_<const T> { typedef T Type; }; | |
467 template <typename T> using RemoveConst = typename RemoveConst_<T>::Type; | |
468 | |
469 template <typename> struct IsLvalueReference_ { static constexpr bool value = false; }; | |
470 template <typename T> struct IsLvalueReference_<T&> { static constexpr bool value = true; }; | |
471 template <typename T> | |
472 inline constexpr bool isLvalueReference() { return IsLvalueReference_<T>::value; } | |
473 | |
474 template <typename T> struct Decay_ { typedef T Type; }; | |
475 template <typename T> struct Decay_<T&> { typedef typename Decay_<T>::Type Type; }; | |
476 template <typename T> struct Decay_<T&&> { typedef typename Decay_<T>::Type Type; }; | |
477 template <typename T> struct Decay_<T[]> { typedef typename Decay_<T*>::Type Type; }; | |
478 template <typename T> struct Decay_<const T[]> { typedef typename Decay_<const T*>::Type Type; }; | |
479 template <typename T, size_t s> struct Decay_<T[s]> { typedef typename Decay_<T*>::Type Type; }; | |
480 template <typename T, size_t s> struct Decay_<const T[s]> { typedef typename Decay_<const T*>::Type Type; }; | |
481 template <typename T> struct Decay_<const T> { typedef typename Decay_<T>::Type Type; }; | |
482 template <typename T> struct Decay_<volatile T> { typedef typename Decay_<T>::Type Type; }; | |
483 template <typename T> using Decay = typename Decay_<T>::Type; | |
484 | |
485 template <bool b> struct EnableIf_; | |
486 template <> struct EnableIf_<true> { typedef void Type; }; | |
487 template <bool b> using EnableIf = typename EnableIf_<b>::Type; | |
488 // Use like: | |
489 // | |
490 // template <typename T, typename = EnableIf<isValid<T>()>> | |
491 // void func(T&& t); | |
492 | |
493 template <typename...> struct VoidSfinae_ { using Type = void; }; | |
494 template <typename... Ts> using VoidSfinae = typename VoidSfinae_<Ts...>::Type; | |
495 // Note: VoidSfinae is std::void_t from C++17. | |
496 | |
497 template <typename T> | |
498 T instance() noexcept; | |
499 // Like std::declval, but doesn't transform T into an rvalue reference. If you want that, specify | |
500 // instance<T&&>(). | |
501 | |
502 struct DisallowConstCopy { | |
503 // Inherit from this, or declare a member variable of this type, to prevent the class from being | |
504 // copyable from a const reference -- instead, it will only be copyable from non-const references. | |
505 // This is useful for enforcing transitive constness of contained pointers. | |
506 // | |
507 // For example, say you have a type T which contains a pointer. T has non-const methods which | |
508 // modify the value at that pointer, but T's const methods are designed to allow reading only. | |
509 // Unfortunately, if T has a regular copy constructor, someone can simply make a copy of T and | |
510 // then use it to modify the pointed-to value. However, if T inherits DisallowConstCopy, then | |
511 // callers will only be able to copy non-const instances of T. Ideally, there is some | |
512 // parallel type ImmutableT which is like a version of T that only has const methods, and can | |
513 // be copied from a const T. | |
514 // | |
515 // Note that due to C++ rules about implicit copy constructors and assignment operators, any | |
516 // type that contains or inherits from a type that disallows const copies will also automatically | |
517 // disallow const copies. Hey, cool, that's exactly what we want. | |
518 | |
519 #if CAPNP_DEBUG_TYPES | |
520 // Alas! Declaring a defaulted non-const copy constructor tickles a bug which causes GCC and | |
521 // Clang to disagree on ABI, using different calling conventions to pass this type, leading to | |
522 // immediate segfaults. See: | |
523 // https://bugs.llvm.org/show_bug.cgi?id=23764 | |
524 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58074 | |
525 // | |
526 // Because of this, we can't use this technique. We guard it by CAPNP_DEBUG_TYPES so that it | |
527 // still applies to the Cap'n Proto developers during internal testing. | |
528 | |
529 DisallowConstCopy() = default; | |
530 DisallowConstCopy(DisallowConstCopy&) = default; | |
531 DisallowConstCopy(DisallowConstCopy&&) = default; | |
532 DisallowConstCopy& operator=(DisallowConstCopy&) = default; | |
533 DisallowConstCopy& operator=(DisallowConstCopy&&) = default; | |
534 #endif | |
535 }; | |
536 | |
537 #if _MSC_VER && !defined(__clang__) | |
538 | |
539 #define KJ_CPCAP(obj) obj=::kj::cp(obj) | |
540 // TODO(msvc): MSVC refuses to invoke non-const versions of copy constructors in by-value lambda | |
541 // captures. Wrap your captured object in this macro to force the compiler to perform a copy. | |
542 // Example: | |
543 // | |
544 // struct Foo: DisallowConstCopy {}; | |
545 // Foo foo; | |
546 // auto lambda = [KJ_CPCAP(foo)] {}; | |
547 | |
548 #else | |
549 | |
550 #define KJ_CPCAP(obj) obj | |
551 // Clang and gcc both already perform copy capturing correctly with non-const copy constructors. | |
552 | |
553 #endif | |
554 | |
555 template <typename T> | |
556 struct DisallowConstCopyIfNotConst: public DisallowConstCopy { | |
557 // Inherit from this when implementing a template that contains a pointer to T and which should | |
558 // enforce transitive constness. If T is a const type, this has no effect. Otherwise, it is | |
559 // an alias for DisallowConstCopy. | |
560 }; | |
561 | |
562 template <typename T> | |
563 struct DisallowConstCopyIfNotConst<const T> {}; | |
564 | |
565 template <typename T> struct IsConst_ { static constexpr bool value = false; }; | |
566 template <typename T> struct IsConst_<const T> { static constexpr bool value = true; }; | |
567 template <typename T> constexpr bool isConst() { return IsConst_<T>::value; } | |
568 | |
569 template <typename T> struct EnableIfNotConst_ { typedef T Type; }; | |
570 template <typename T> struct EnableIfNotConst_<const T>; | |
571 template <typename T> using EnableIfNotConst = typename EnableIfNotConst_<T>::Type; | |
572 | |
573 template <typename T> struct EnableIfConst_; | |
574 template <typename T> struct EnableIfConst_<const T> { typedef T Type; }; | |
575 template <typename T> using EnableIfConst = typename EnableIfConst_<T>::Type; | |
576 | |
577 template <typename T> struct RemoveConstOrDisable_ { struct Type; }; | |
578 template <typename T> struct RemoveConstOrDisable_<const T> { typedef T Type; }; | |
579 template <typename T> using RemoveConstOrDisable = typename RemoveConstOrDisable_<T>::Type; | |
580 | |
581 template <typename T> struct IsReference_ { static constexpr bool value = false; }; | |
582 template <typename T> struct IsReference_<T&> { static constexpr bool value = true; }; | |
583 template <typename T> constexpr bool isReference() { return IsReference_<T>::value; } | |
584 | |
585 template <typename From, typename To> | |
586 struct PropagateConst_ { typedef To Type; }; | |
587 template <typename From, typename To> | |
588 struct PropagateConst_<const From, To> { typedef const To Type; }; | |
589 template <typename From, typename To> | |
590 using PropagateConst = typename PropagateConst_<From, To>::Type; | |
591 | |
592 namespace _ { // private | |
593 | |
594 template <typename T> | |
595 T refIfLvalue(T&&); | |
596 | |
597 } // namespace _ (private) | |
598 | |
599 #define KJ_DECLTYPE_REF(exp) decltype(::kj::_::refIfLvalue(exp)) | |
600 // Like decltype(exp), but if exp is an lvalue, produces a reference type. | |
601 // | |
602 // int i; | |
603 // decltype(i) i1(i); // i1 has type int. | |
604 // KJ_DECLTYPE_REF(i + 1) i2(i + 1); // i2 has type int. | |
605 // KJ_DECLTYPE_REF(i) i3(i); // i3 has type int&. | |
606 // KJ_DECLTYPE_REF(kj::mv(i)) i4(kj::mv(i)); // i4 has type int. | |
607 | |
608 template <typename T, typename U> struct IsSameType_ { static constexpr bool value = false; }; | |
609 template <typename T> struct IsSameType_<T, T> { static constexpr bool value = true; }; | |
610 template <typename T, typename U> constexpr bool isSameType() { return IsSameType_<T, U>::value; } | |
611 | |
612 template <typename T> constexpr bool isIntegral() { return false; } | |
613 template <> constexpr bool isIntegral<char>() { return true; } | |
614 template <> constexpr bool isIntegral<signed char>() { return true; } | |
615 template <> constexpr bool isIntegral<short>() { return true; } | |
616 template <> constexpr bool isIntegral<int>() { return true; } | |
617 template <> constexpr bool isIntegral<long>() { return true; } | |
618 template <> constexpr bool isIntegral<long long>() { return true; } | |
619 template <> constexpr bool isIntegral<unsigned char>() { return true; } | |
620 template <> constexpr bool isIntegral<unsigned short>() { return true; } | |
621 template <> constexpr bool isIntegral<unsigned int>() { return true; } | |
622 template <> constexpr bool isIntegral<unsigned long>() { return true; } | |
623 template <> constexpr bool isIntegral<unsigned long long>() { return true; } | |
624 | |
625 template <typename T> | |
626 struct CanConvert_ { | |
627 static int sfinae(T); | |
628 static bool sfinae(...); | |
629 }; | |
630 | |
631 template <typename T, typename U> | |
632 constexpr bool canConvert() { | |
633 return sizeof(CanConvert_<U>::sfinae(instance<T>())) == sizeof(int); | |
634 } | |
635 | |
636 #if __GNUC__ && !__clang__ && __GNUC__ < 5 | |
637 template <typename T> | |
638 constexpr bool canMemcpy() { | |
639 // Returns true if T can be copied using memcpy instead of using the copy constructor or | |
640 // assignment operator. | |
641 | |
642 // GCC 4 does not have __is_trivially_constructible and friends, and there doesn't seem to be | |
643 // any reliable alternative. __has_trivial_copy() and __has_trivial_assign() return the right | |
644 // thing at one point but later on they changed such that a deleted copy constructor was | |
645 // considered "trivial" (apparently technically correct, though useless). So, on GCC 4 we give up | |
646 // and assume we can't memcpy() at all, and must explicitly copy-construct everything. | |
647 return false; | |
648 } | |
649 #define KJ_ASSERT_CAN_MEMCPY(T) | |
650 #else | |
651 template <typename T> | |
652 constexpr bool canMemcpy() { | |
653 // Returns true if T can be copied using memcpy instead of using the copy constructor or | |
654 // assignment operator. | |
655 | |
656 return __is_trivially_constructible(T, const T&) && __is_trivially_assignable(T, const T&); | |
657 } | |
658 #define KJ_ASSERT_CAN_MEMCPY(T) \ | |
659 static_assert(kj::canMemcpy<T>(), "this code expects this type to be memcpy()-able"); | |
660 #endif | |
661 | |
662 template <typename T> | |
663 class Badge { | |
664 // A pattern for marking individual methods such that they can only be called from a specific | |
665 // caller class: Make the method public but give it a parameter of type `Badge<Caller>`. Only | |
666 // `Caller` can construct one, so only `Caller` can call the method. | |
667 // | |
668 // // We only allow calls from the class `Bar`. | |
669 // void foo(Badge<Bar>) | |
670 // | |
671 // The call site looks like: | |
672 // | |
673 // foo({}); | |
674 // | |
675 // This pattern also works well for declaring private constructors, but still being able to use | |
676 // them with `kj::heap()`, etc. | |
677 // | |
678 // Idea from: https://awesomekling.github.io/Serenity-C++-patterns-The-Badge/ | |
679 // | |
680 // Note that some forms of this idea make the copy constructor private as well, in order to | |
681 // prohibit `Badge<NotMe>(*(Badge<NotMe>*)nullptr)`. However, that would prevent badges from | |
682 // being passed through forwarding functions like `kj::heap()`, which would ruin one of the main | |
683 // use cases for this pattern in KJ. In any case, dereferencing a null pointer is UB; there are | |
684 // plenty of other ways to get access to private members if you're willing to go UB. For one-off | |
685 // debugging purposes, you might as well use `#define private public` at the top of the file. | |
686 private: | |
687 Badge() {} | |
688 friend T; | |
689 }; | |
690 | |
691 // ======================================================================================= | |
692 // Equivalents to std::move() and std::forward(), since these are very commonly needed and the | |
693 // std header <utility> pulls in lots of other stuff. | |
694 // | |
695 // We use abbreviated names mv and fwd because these helpers (especially mv) are so commonly used | |
696 // that the cost of typing more letters outweighs the cost of being slightly harder to understand | |
697 // when first encountered. | |
698 | |
699 template<typename T> constexpr T&& mv(T& t) noexcept { return static_cast<T&&>(t); } | |
700 template<typename T> constexpr T&& fwd(NoInfer<T>& t) noexcept { return static_cast<T&&>(t); } | |
701 | |
702 template<typename T> constexpr T cp(T& t) noexcept { return t; } | |
703 template<typename T> constexpr T cp(const T& t) noexcept { return t; } | |
704 // Useful to force a copy, particularly to pass into a function that expects T&&. | |
705 | |
706 template <typename T, typename U, bool takeT, bool uOK = true> struct ChooseType_; | |
707 template <typename T, typename U> struct ChooseType_<T, U, true, true> { typedef T Type; }; | |
708 template <typename T, typename U> struct ChooseType_<T, U, true, false> { typedef T Type; }; | |
709 template <typename T, typename U> struct ChooseType_<T, U, false, true> { typedef U Type; }; | |
710 | |
711 template <typename T, typename U> | |
712 using WiderType = typename ChooseType_<T, U, sizeof(T) >= sizeof(U)>::Type; | |
713 | |
714 template <typename T, typename U> | |
715 inline constexpr auto min(T&& a, U&& b) -> WiderType<Decay<T>, Decay<U>> { | |
716 return a < b ? WiderType<Decay<T>, Decay<U>>(a) : WiderType<Decay<T>, Decay<U>>(b); | |
717 } | |
718 | |
719 template <typename T, typename U> | |
720 inline constexpr auto max(T&& a, U&& b) -> WiderType<Decay<T>, Decay<U>> { | |
721 return a > b ? WiderType<Decay<T>, Decay<U>>(a) : WiderType<Decay<T>, Decay<U>>(b); | |
722 } | |
723 | |
724 template <typename T, size_t s> | |
725 inline constexpr size_t size(T (&arr)[s]) { return s; } | |
726 template <typename T> | |
727 inline constexpr size_t size(T&& arr) { return arr.size(); } | |
728 // Returns the size of the parameter, whether the parameter is a regular C array or a container | |
729 // with a `.size()` method. | |
730 | |
731 class MaxValue_ { | |
732 private: | |
733 template <typename T> | |
734 inline constexpr T maxSigned() const { | |
735 return (1ull << (sizeof(T) * 8 - 1)) - 1; | |
736 } | |
737 template <typename T> | |
738 inline constexpr T maxUnsigned() const { | |
739 return ~static_cast<T>(0u); | |
740 } | |
741 | |
742 public: | |
743 #define _kJ_HANDLE_TYPE(T) \ | |
744 inline constexpr operator signed T() const { return MaxValue_::maxSigned < signed T>(); } \ | |
745 inline constexpr operator unsigned T() const { return MaxValue_::maxUnsigned<unsigned T>(); } | |
746 _kJ_HANDLE_TYPE(char) | |
747 _kJ_HANDLE_TYPE(short) | |
748 _kJ_HANDLE_TYPE(int) | |
749 _kJ_HANDLE_TYPE(long) | |
750 _kJ_HANDLE_TYPE(long long) | |
751 #undef _kJ_HANDLE_TYPE | |
752 | |
753 inline constexpr operator char() const { | |
754 // `char` is different from both `signed char` and `unsigned char`, and may be signed or | |
755 // unsigned on different platforms. Ugh. | |
756 return char(-1) < 0 ? MaxValue_::maxSigned<char>() | |
757 : MaxValue_::maxUnsigned<char>(); | |
758 } | |
759 }; | |
760 | |
761 class MinValue_ { | |
762 private: | |
763 template <typename T> | |
764 inline constexpr T minSigned() const { | |
765 return 1ull << (sizeof(T) * 8 - 1); | |
766 } | |
767 template <typename T> | |
768 inline constexpr T minUnsigned() const { | |
769 return 0u; | |
770 } | |
771 | |
772 public: | |
773 #define _kJ_HANDLE_TYPE(T) \ | |
774 inline constexpr operator signed T() const { return MinValue_::minSigned < signed T>(); } \ | |
775 inline constexpr operator unsigned T() const { return MinValue_::minUnsigned<unsigned T>(); } | |
776 _kJ_HANDLE_TYPE(char) | |
777 _kJ_HANDLE_TYPE(short) | |
778 _kJ_HANDLE_TYPE(int) | |
779 _kJ_HANDLE_TYPE(long) | |
780 _kJ_HANDLE_TYPE(long long) | |
781 #undef _kJ_HANDLE_TYPE | |
782 | |
783 inline constexpr operator char() const { | |
784 // `char` is different from both `signed char` and `unsigned char`, and may be signed or | |
785 // unsigned on different platforms. Ugh. | |
786 return char(-1) < 0 ? MinValue_::minSigned<char>() | |
787 : MinValue_::minUnsigned<char>(); | |
788 } | |
789 }; | |
790 | |
791 static KJ_CONSTEXPR(const) MaxValue_ maxValue = MaxValue_(); | |
792 // A special constant which, when cast to an integer type, takes on the maximum possible value of | |
793 // that type. This is useful to use as e.g. a parameter to a function because it will be robust | |
794 // in the face of changes to the parameter's type. | |
795 // | |
796 // `char` is not supported, but `signed char` and `unsigned char` are. | |
797 | |
798 static KJ_CONSTEXPR(const) MinValue_ minValue = MinValue_(); | |
799 // A special constant which, when cast to an integer type, takes on the minimum possible value | |
800 // of that type. This is useful to use as e.g. a parameter to a function because it will be robust | |
801 // in the face of changes to the parameter's type. | |
802 // | |
803 // `char` is not supported, but `signed char` and `unsigned char` are. | |
804 | |
805 template <typename T> | |
806 inline bool operator==(T t, MaxValue_) { return t == Decay<T>(maxValue); } | |
807 template <typename T> | |
808 inline bool operator==(T t, MinValue_) { return t == Decay<T>(minValue); } | |
809 | |
810 template <uint bits> | |
811 inline constexpr unsigned long long maxValueForBits() { | |
812 // Get the maximum integer representable in the given number of bits. | |
813 | |
814 // 1ull << 64 is unfortunately undefined. | |
815 return (bits == 64 ? 0 : (1ull << bits)) - 1; | |
816 } | |
817 | |
818 struct ThrowOverflow { | |
819 // Functor which throws an exception complaining about integer overflow. Usually this is used | |
820 // with the interfaces in units.h, but is defined here because Cap'n Proto wants to avoid | |
821 // including units.h when not using CAPNP_DEBUG_TYPES. | |
822 [[noreturn]] void operator()() const; | |
823 }; | |
824 | |
825 #if __GNUC__ || __clang__ || _MSC_VER | |
826 inline constexpr float inf() { return __builtin_huge_valf(); } | |
827 inline constexpr float nan() { return __builtin_nanf(""); } | |
828 | |
829 #else | |
830 #error "Not sure how to support your compiler." | |
831 #endif | |
832 | |
833 inline constexpr bool isNaN(float f) { return f != f; } | |
834 inline constexpr bool isNaN(double f) { return f != f; } | |
835 | |
836 inline int popCount(unsigned int x) { | |
837 #if defined(_MSC_VER) && !defined(__clang__) | |
838 return __popcnt(x); | |
839 // Note: __popcnt returns unsigned int, but the value is clearly guaranteed to fit into an int | |
840 #else | |
841 return __builtin_popcount(x); | |
842 #endif | |
843 } | |
844 | |
845 // ======================================================================================= | |
846 // Useful fake containers | |
847 | |
848 template <typename T> | |
849 class Range { | |
850 public: | |
851 inline constexpr Range(const T& begin, const T& end): begin_(begin), end_(end) {} | |
852 inline explicit constexpr Range(const T& end): begin_(0), end_(end) {} | |
853 | |
854 class Iterator { | |
855 public: | |
856 Iterator() = default; | |
857 inline Iterator(const T& value): value(value) {} | |
858 | |
859 inline const T& operator* () const { return value; } | |
860 inline const T& operator[](size_t index) const { return value + index; } | |
861 inline Iterator& operator++() { ++value; return *this; } | |
862 inline Iterator operator++(int) { return Iterator(value++); } | |
863 inline Iterator& operator--() { --value; return *this; } | |
864 inline Iterator operator--(int) { return Iterator(value--); } | |
865 inline Iterator& operator+=(ptrdiff_t amount) { value += amount; return *this; } | |
866 inline Iterator& operator-=(ptrdiff_t amount) { value -= amount; return *this; } | |
867 inline Iterator operator+ (ptrdiff_t amount) const { return Iterator(value + amount); } | |
868 inline Iterator operator- (ptrdiff_t amount) const { return Iterator(value - amount); } | |
869 inline ptrdiff_t operator- (const Iterator& other) const { return value - other.value; } | |
870 | |
871 inline bool operator==(const Iterator& other) const { return value == other.value; } | |
872 inline bool operator!=(const Iterator& other) const { return value != other.value; } | |
873 inline bool operator<=(const Iterator& other) const { return value <= other.value; } | |
874 inline bool operator>=(const Iterator& other) const { return value >= other.value; } | |
875 inline bool operator< (const Iterator& other) const { return value < other.value; } | |
876 inline bool operator> (const Iterator& other) const { return value > other.value; } | |
877 | |
878 private: | |
879 T value; | |
880 }; | |
881 | |
882 inline Iterator begin() const { return Iterator(begin_); } | |
883 inline Iterator end() const { return Iterator(end_); } | |
884 | |
885 inline auto size() const -> decltype(instance<T>() - instance<T>()) { return end_ - begin_; } | |
886 | |
887 private: | |
888 T begin_; | |
889 T end_; | |
890 }; | |
891 | |
892 template <typename T, typename U> | |
893 inline constexpr Range<WiderType<Decay<T>, Decay<U>>> range(T begin, U end) { | |
894 return Range<WiderType<Decay<T>, Decay<U>>>(begin, end); | |
895 } | |
896 | |
897 template <typename T> | |
898 inline constexpr Range<Decay<T>> range(T begin, T end) { return Range<Decay<T>>(begin, end); } | |
899 // Returns a fake iterable container containing all values of T from `begin` (inclusive) to `end` | |
900 // (exclusive). Example: | |
901 // | |
902 // // Prints 1, 2, 3, 4, 5, 6, 7, 8, 9. | |
903 // for (int i: kj::range(1, 10)) { print(i); } | |
904 | |
905 template <typename T> | |
906 inline constexpr Range<Decay<T>> zeroTo(T end) { return Range<Decay<T>>(end); } | |
907 // Returns a fake iterable container containing all values of T from zero (inclusive) to `end` | |
908 // (exclusive). Example: | |
909 // | |
910 // // Prints 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. | |
911 // for (int i: kj::zeroTo(10)) { print(i); } | |
912 | |
913 template <typename T> | |
914 inline constexpr Range<size_t> indices(T&& container) { | |
915 // Shortcut for iterating over the indices of a container: | |
916 // | |
917 // for (size_t i: kj::indices(myArray)) { handle(myArray[i]); } | |
918 | |
919 return range<size_t>(0, kj::size(container)); | |
920 } | |
921 | |
922 template <typename T> | |
923 class Repeat { | |
924 public: | |
925 inline constexpr Repeat(const T& value, size_t count): value(value), count(count) {} | |
926 | |
927 class Iterator { | |
928 public: | |
929 Iterator() = default; | |
930 inline Iterator(const T& value, size_t index): value(value), index(index) {} | |
931 | |
932 inline const T& operator* () const { return value; } | |
933 inline const T& operator[](ptrdiff_t index) const { return value; } | |
934 inline Iterator& operator++() { ++index; return *this; } | |
935 inline Iterator operator++(int) { return Iterator(value, index++); } | |
936 inline Iterator& operator--() { --index; return *this; } | |
937 inline Iterator operator--(int) { return Iterator(value, index--); } | |
938 inline Iterator& operator+=(ptrdiff_t amount) { index += amount; return *this; } | |
939 inline Iterator& operator-=(ptrdiff_t amount) { index -= amount; return *this; } | |
940 inline Iterator operator+ (ptrdiff_t amount) const { return Iterator(value, index + amount); } | |
941 inline Iterator operator- (ptrdiff_t amount) const { return Iterator(value, index - amount); } | |
942 inline ptrdiff_t operator- (const Iterator& other) const { return index - other.index; } | |
943 | |
944 inline bool operator==(const Iterator& other) const { return index == other.index; } | |
945 inline bool operator!=(const Iterator& other) const { return index != other.index; } | |
946 inline bool operator<=(const Iterator& other) const { return index <= other.index; } | |
947 inline bool operator>=(const Iterator& other) const { return index >= other.index; } | |
948 inline bool operator< (const Iterator& other) const { return index < other.index; } | |
949 inline bool operator> (const Iterator& other) const { return index > other.index; } | |
950 | |
951 private: | |
952 T value; | |
953 size_t index; | |
954 }; | |
955 | |
956 inline Iterator begin() const { return Iterator(value, 0); } | |
957 inline Iterator end() const { return Iterator(value, count); } | |
958 | |
959 inline size_t size() const { return count; } | |
960 inline const T& operator[](ptrdiff_t) const { return value; } | |
961 | |
962 private: | |
963 T value; | |
964 size_t count; | |
965 }; | |
966 | |
967 template <typename T> | |
968 inline constexpr Repeat<Decay<T>> repeat(T&& value, size_t count) { | |
969 // Returns a fake iterable which contains `count` repeats of `value`. Useful for e.g. creating | |
970 // a bunch of spaces: `kj::repeat(' ', indent * 2)` | |
971 | |
972 return Repeat<Decay<T>>(value, count); | |
973 } | |
974 | |
975 template <typename Inner, class Mapping> | |
976 class MappedIterator: private Mapping { | |
977 // An iterator that wraps some other iterator and maps the values through a mapping function. | |
978 // The type `Mapping` must define a method `map()` which performs this mapping. | |
979 | |
980 public: | |
981 template <typename... Params> | |
982 MappedIterator(Inner inner, Params&&... params) | |
983 : Mapping(kj::fwd<Params>(params)...), inner(inner) {} | |
984 | |
985 inline auto operator->() const { return &Mapping::map(*inner); } | |
986 inline decltype(auto) operator* () const { return Mapping::map(*inner); } | |
987 inline decltype(auto) operator[](size_t index) const { return Mapping::map(inner[index]); } | |
988 inline MappedIterator& operator++() { ++inner; return *this; } | |
989 inline MappedIterator operator++(int) { return MappedIterator(inner++, *this); } | |
990 inline MappedIterator& operator--() { --inner; return *this; } | |
991 inline MappedIterator operator--(int) { return MappedIterator(inner--, *this); } | |
992 inline MappedIterator& operator+=(ptrdiff_t amount) { inner += amount; return *this; } | |
993 inline MappedIterator& operator-=(ptrdiff_t amount) { inner -= amount; return *this; } | |
994 inline MappedIterator operator+ (ptrdiff_t amount) const { | |
995 return MappedIterator(inner + amount, *this); | |
996 } | |
997 inline MappedIterator operator- (ptrdiff_t amount) const { | |
998 return MappedIterator(inner - amount, *this); | |
999 } | |
1000 inline ptrdiff_t operator- (const MappedIterator& other) const { return inner - other.inner; } | |
1001 | |
1002 inline bool operator==(const MappedIterator& other) const { return inner == other.inner; } | |
1003 inline bool operator!=(const MappedIterator& other) const { return inner != other.inner; } | |
1004 inline bool operator<=(const MappedIterator& other) const { return inner <= other.inner; } | |
1005 inline bool operator>=(const MappedIterator& other) const { return inner >= other.inner; } | |
1006 inline bool operator< (const MappedIterator& other) const { return inner < other.inner; } | |
1007 inline bool operator> (const MappedIterator& other) const { return inner > other.inner; } | |
1008 | |
1009 private: | |
1010 Inner inner; | |
1011 }; | |
1012 | |
1013 template <typename Inner, typename Mapping> | |
1014 class MappedIterable: private Mapping { | |
1015 // An iterable that wraps some other iterable and maps the values through a mapping function. | |
1016 // The type `Mapping` must define a method `map()` which performs this mapping. | |
1017 | |
1018 public: | |
1019 template <typename... Params> | |
1020 MappedIterable(Inner inner, Params&&... params) | |
1021 : Mapping(kj::fwd<Params>(params)...), inner(inner) {} | |
1022 | |
1023 typedef Decay<decltype(instance<Inner>().begin())> InnerIterator; | |
1024 typedef MappedIterator<InnerIterator, Mapping> Iterator; | |
1025 typedef Decay<decltype(instance<const Inner>().begin())> InnerConstIterator; | |
1026 typedef MappedIterator<InnerConstIterator, Mapping> ConstIterator; | |
1027 | |
1028 inline Iterator begin() { return { inner.begin(), (Mapping&)*this }; } | |
1029 inline Iterator end() { return { inner.end(), (Mapping&)*this }; } | |
1030 inline ConstIterator begin() const { return { inner.begin(), (const Mapping&)*this }; } | |
1031 inline ConstIterator end() const { return { inner.end(), (const Mapping&)*this }; } | |
1032 | |
1033 private: | |
1034 Inner inner; | |
1035 }; | |
1036 | |
1037 // ======================================================================================= | |
1038 // Manually invoking constructors and destructors | |
1039 // | |
1040 // ctor(x, ...) and dtor(x) invoke x's constructor or destructor, respectively. | |
1041 | |
1042 // We want placement new, but we don't want to #include <new>. operator new cannot be defined in | |
1043 // a namespace, and defining it globally conflicts with the definition in <new>. So we have to | |
1044 // define a dummy type and an operator new that uses it. | |
1045 | |
1046 namespace _ { // private | |
1047 struct PlacementNew {}; | |
1048 } // namespace _ (private) | |
1049 } // namespace kj | |
1050 | |
1051 inline void* operator new(size_t, kj::_::PlacementNew, void* __p) noexcept { | |
1052 return __p; | |
1053 } | |
1054 | |
1055 inline void operator delete(void*, kj::_::PlacementNew, void* __p) noexcept {} | |
1056 | |
1057 namespace kj { | |
1058 | |
1059 template <typename T, typename... Params> | |
1060 inline void ctor(T& location, Params&&... params) { | |
1061 new (_::PlacementNew(), &location) T(kj::fwd<Params>(params)...); | |
1062 } | |
1063 | |
1064 template <typename T> | |
1065 inline void dtor(T& location) { | |
1066 location.~T(); | |
1067 } | |
1068 | |
1069 // ======================================================================================= | |
1070 // Maybe | |
1071 // | |
1072 // Use in cases where you want to indicate that a value may be null. Using Maybe<T&> instead of T* | |
1073 // forces the caller to handle the null case in order to satisfy the compiler, thus reliably | |
1074 // preventing null pointer dereferences at runtime. | |
1075 // | |
1076 // Maybe<T> can be implicitly constructed from T and from nullptr. | |
1077 // To read the value of a Maybe<T>, do: | |
1078 // | |
1079 // KJ_IF_MAYBE(value, someFuncReturningMaybe()) { | |
1080 // doSomething(*value); | |
1081 // } else { | |
1082 // maybeWasNull(); | |
1083 // } | |
1084 // | |
1085 // KJ_IF_MAYBE's first parameter is a variable name which will be defined within the following | |
1086 // block. The variable will behave like a (guaranteed non-null) pointer to the Maybe's value, | |
1087 // though it may or may not actually be a pointer. | |
1088 // | |
1089 // Note that Maybe<T&> actually just wraps a pointer, whereas Maybe<T> wraps a T and a boolean | |
1090 // indicating nullness. | |
1091 | |
1092 template <typename T> | |
1093 class Maybe; | |
1094 | |
1095 namespace _ { // private | |
1096 | |
1097 template <typename T> | |
1098 class NullableValue { | |
1099 // Class whose interface behaves much like T*, but actually contains an instance of T and a | |
1100 // boolean flag indicating nullness. | |
1101 | |
1102 public: | |
1103 inline NullableValue(NullableValue&& other) | |
1104 : isSet(other.isSet) { | |
1105 if (isSet) { | |
1106 ctor(value, kj::mv(other.value)); | |
1107 } | |
1108 } | |
1109 inline NullableValue(const NullableValue& other) | |
1110 : isSet(other.isSet) { | |
1111 if (isSet) { | |
1112 ctor(value, other.value); | |
1113 } | |
1114 } | |
1115 inline NullableValue(NullableValue& other) | |
1116 : isSet(other.isSet) { | |
1117 if (isSet) { | |
1118 ctor(value, other.value); | |
1119 } | |
1120 } | |
1121 inline ~NullableValue() | |
1122 #if _MSC_VER && !defined(__clang__) | |
1123 // TODO(msvc): MSVC has a hard time with noexcept specifier expressions that are more complex | |
1124 // than `true` or `false`. We had a workaround for VS2015, but VS2017 regressed. | |
1125 noexcept(false) | |
1126 #else | |
1127 noexcept(noexcept(instance<T&>().~T())) | |
1128 #endif | |
1129 { | |
1130 if (isSet) { | |
1131 dtor(value); | |
1132 } | |
1133 } | |
1134 | |
1135 inline T& operator*() & { return value; } | |
1136 inline const T& operator*() const & { return value; } | |
1137 inline T&& operator*() && { return kj::mv(value); } | |
1138 inline const T&& operator*() const && { return kj::mv(value); } | |
1139 inline T* operator->() { return &value; } | |
1140 inline const T* operator->() const { return &value; } | |
1141 inline operator T*() { return isSet ? &value : nullptr; } | |
1142 inline operator const T*() const { return isSet ? &value : nullptr; } | |
1143 | |
1144 template <typename... Params> | |
1145 inline T& emplace(Params&&... params) { | |
1146 if (isSet) { | |
1147 isSet = false; | |
1148 dtor(value); | |
1149 } | |
1150 ctor(value, kj::fwd<Params>(params)...); | |
1151 isSet = true; | |
1152 return value; | |
1153 } | |
1154 | |
1155 inline NullableValue(): isSet(false) {} | |
1156 inline NullableValue(T&& t) | |
1157 : isSet(true) { | |
1158 ctor(value, kj::mv(t)); | |
1159 } | |
1160 inline NullableValue(T& t) | |
1161 : isSet(true) { | |
1162 ctor(value, t); | |
1163 } | |
1164 inline NullableValue(const T& t) | |
1165 : isSet(true) { | |
1166 ctor(value, t); | |
1167 } | |
1168 template <typename U> | |
1169 inline NullableValue(NullableValue<U>&& other) | |
1170 : isSet(other.isSet) { | |
1171 if (isSet) { | |
1172 ctor(value, kj::mv(other.value)); | |
1173 } | |
1174 } | |
1175 template <typename U> | |
1176 inline NullableValue(const NullableValue<U>& other) | |
1177 : isSet(other.isSet) { | |
1178 if (isSet) { | |
1179 ctor(value, other.value); | |
1180 } | |
1181 } | |
1182 template <typename U> | |
1183 inline NullableValue(const NullableValue<U&>& other) | |
1184 : isSet(other.isSet) { | |
1185 if (isSet) { | |
1186 ctor(value, *other.ptr); | |
1187 } | |
1188 } | |
1189 inline NullableValue(decltype(nullptr)): isSet(false) {} | |
1190 | |
1191 inline NullableValue& operator=(NullableValue&& other) { | |
1192 if (&other != this) { | |
1193 // Careful about throwing destructors/constructors here. | |
1194 if (isSet) { | |
1195 isSet = false; | |
1196 dtor(value); | |
1197 } | |
1198 if (other.isSet) { | |
1199 ctor(value, kj::mv(other.value)); | |
1200 isSet = true; | |
1201 } | |
1202 } | |
1203 return *this; | |
1204 } | |
1205 | |
1206 inline NullableValue& operator=(NullableValue& other) { | |
1207 if (&other != this) { | |
1208 // Careful about throwing destructors/constructors here. | |
1209 if (isSet) { | |
1210 isSet = false; | |
1211 dtor(value); | |
1212 } | |
1213 if (other.isSet) { | |
1214 ctor(value, other.value); | |
1215 isSet = true; | |
1216 } | |
1217 } | |
1218 return *this; | |
1219 } | |
1220 | |
1221 inline NullableValue& operator=(const NullableValue& other) { | |
1222 if (&other != this) { | |
1223 // Careful about throwing destructors/constructors here. | |
1224 if (isSet) { | |
1225 isSet = false; | |
1226 dtor(value); | |
1227 } | |
1228 if (other.isSet) { | |
1229 ctor(value, other.value); | |
1230 isSet = true; | |
1231 } | |
1232 } | |
1233 return *this; | |
1234 } | |
1235 | |
1236 inline NullableValue& operator=(T&& other) { emplace(kj::mv(other)); return *this; } | |
1237 inline NullableValue& operator=(T& other) { emplace(other); return *this; } | |
1238 inline NullableValue& operator=(const T& other) { emplace(other); return *this; } | |
1239 template <typename U> | |
1240 inline NullableValue& operator=(NullableValue<U>&& other) { | |
1241 if (other.isSet) { | |
1242 emplace(kj::mv(other.value)); | |
1243 } else { | |
1244 *this = nullptr; | |
1245 } | |
1246 return *this; | |
1247 } | |
1248 template <typename U> | |
1249 inline NullableValue& operator=(const NullableValue<U>& other) { | |
1250 if (other.isSet) { | |
1251 emplace(other.value); | |
1252 } else { | |
1253 *this = nullptr; | |
1254 } | |
1255 return *this; | |
1256 } | |
1257 template <typename U> | |
1258 inline NullableValue& operator=(const NullableValue<U&>& other) { | |
1259 if (other.isSet) { | |
1260 emplace(other.value); | |
1261 } else { | |
1262 *this = nullptr; | |
1263 } | |
1264 return *this; | |
1265 } | |
1266 inline NullableValue& operator=(decltype(nullptr)) { | |
1267 if (isSet) { | |
1268 isSet = false; | |
1269 dtor(value); | |
1270 } | |
1271 return *this; | |
1272 } | |
1273 | |
1274 inline bool operator==(decltype(nullptr)) const { return !isSet; } | |
1275 inline bool operator!=(decltype(nullptr)) const { return isSet; } | |
1276 | |
1277 NullableValue(const T* t) = delete; | |
1278 NullableValue& operator=(const T* other) = delete; | |
1279 // We used to permit assigning a Maybe<T> directly from a T*, and the assignment would check for | |
1280 // nullness. This turned out never to be useful, and sometimes to be dangerous. | |
1281 | |
1282 private: | |
1283 bool isSet; | |
1284 | |
1285 #if _MSC_VER && !defined(__clang__) | |
1286 #pragma warning(push) | |
1287 #pragma warning(disable: 4624) | |
1288 // Warns that the anonymous union has a deleted destructor when T is non-trivial. This warning | |
1289 // seems broken. | |
1290 #endif | |
1291 | |
1292 union { | |
1293 T value; | |
1294 }; | |
1295 | |
1296 #if _MSC_VER && !defined(__clang__) | |
1297 #pragma warning(pop) | |
1298 #endif | |
1299 | |
1300 friend class kj::Maybe<T>; | |
1301 template <typename U> | |
1302 friend NullableValue<U>&& readMaybe(Maybe<U>&& maybe); | |
1303 }; | |
1304 | |
1305 template <typename T> | |
1306 inline NullableValue<T>&& readMaybe(Maybe<T>&& maybe) { return kj::mv(maybe.ptr); } | |
1307 template <typename T> | |
1308 inline T* readMaybe(Maybe<T>& maybe) { return maybe.ptr; } | |
1309 template <typename T> | |
1310 inline const T* readMaybe(const Maybe<T>& maybe) { return maybe.ptr; } | |
1311 template <typename T> | |
1312 inline T* readMaybe(Maybe<T&>&& maybe) { return maybe.ptr; } | |
1313 template <typename T> | |
1314 inline T* readMaybe(const Maybe<T&>& maybe) { return maybe.ptr; } | |
1315 | |
1316 template <typename T> | |
1317 inline T* readMaybe(T* ptr) { return ptr; } | |
1318 // Allow KJ_IF_MAYBE to work on regular pointers. | |
1319 | |
1320 } // namespace _ (private) | |
1321 | |
1322 #define KJ_IF_MAYBE(name, exp) if (auto name = ::kj::_::readMaybe(exp)) | |
1323 | |
1324 #if __GNUC__ || __clang__ | |
1325 // These two macros provide a friendly syntax to extract the value of a Maybe or return early. | |
1326 // | |
1327 // Use KJ_UNWRAP_OR_RETURN if you just want to return a simple value when the Maybe is null: | |
1328 // | |
1329 // int foo(Maybe<int> maybe) { | |
1330 // int value = KJ_UNWRAP_OR_RETURN(maybe, -1); | |
1331 // // ... use value ... | |
1332 // } | |
1333 // | |
1334 // For functions returning void, omit the second parameter to KJ_UNWRAP_OR_RETURN: | |
1335 // | |
1336 // void foo(Maybe<int> maybe) { | |
1337 // int value = KJ_UNWRAP_OR_RETURN(maybe); | |
1338 // // ... use value ... | |
1339 // } | |
1340 // | |
1341 // Use KJ_UNWRAP_OR if you want to execute a block with multiple statements. | |
1342 // | |
1343 // int foo(Maybe<int> maybe) { | |
1344 // int value = KJ_UNWRAP_OR(maybe, { | |
1345 // KJ_LOG(ERROR, "problem!!!"); | |
1346 // return -1; | |
1347 // }); | |
1348 // // ... use value ... | |
1349 // } | |
1350 // | |
1351 // The block MUST return at the end or you will get a compiler error | |
1352 // | |
1353 // Unfortunately, these macros seem impossible to express without using GCC's non-standard | |
1354 // "statement expressions" extension. IIFEs don't do the trick here because a lambda cannot | |
1355 // return out of the parent scope. These macros should therefore only be used in projects that | |
1356 // target GCC or GCC-compatible compilers. | |
1357 // | |
1358 // `__GNUC__` is not defined when using LLVM's MSVC-compatible compiler driver `clang-cl` (even | |
1359 // though clang supports the required extension), hence the additional `|| __clang__`. | |
1360 | |
1361 #define KJ_UNWRAP_OR_RETURN(value, ...) \ | |
1362 (*({ \ | |
1363 auto _kj_result = ::kj::_::readMaybe(value); \ | |
1364 if (!_kj_result) { \ | |
1365 return __VA_ARGS__; \ | |
1366 } \ | |
1367 kj::mv(_kj_result); \ | |
1368 })) | |
1369 | |
1370 #define KJ_UNWRAP_OR(value, block) \ | |
1371 (*({ \ | |
1372 auto _kj_result = ::kj::_::readMaybe(value); \ | |
1373 if (!_kj_result) { \ | |
1374 block; \ | |
1375 asm("KJ_UNWRAP_OR_block_is_missing_return_statement\n"); \ | |
1376 } \ | |
1377 kj::mv(_kj_result); \ | |
1378 })) | |
1379 #endif | |
1380 | |
1381 template <typename T> | |
1382 class Maybe { | |
1383 // A T, or nullptr. | |
1384 | |
1385 // IF YOU CHANGE THIS CLASS: Note that there is a specialization of it in memory.h. | |
1386 | |
1387 public: | |
1388 Maybe(): ptr(nullptr) {} | |
1389 Maybe(T&& t): ptr(kj::mv(t)) {} | |
1390 Maybe(T& t): ptr(t) {} | |
1391 Maybe(const T& t): ptr(t) {} | |
1392 Maybe(Maybe&& other): ptr(kj::mv(other.ptr)) { other = nullptr; } | |
1393 Maybe(const Maybe& other): ptr(other.ptr) {} | |
1394 Maybe(Maybe& other): ptr(other.ptr) {} | |
1395 | |
1396 template <typename U> | |
1397 Maybe(Maybe<U>&& other) { | |
1398 KJ_IF_MAYBE(val, kj::mv(other)) { | |
1399 ptr.emplace(kj::mv(*val)); | |
1400 other = nullptr; | |
1401 } | |
1402 } | |
1403 template <typename U> | |
1404 Maybe(Maybe<U&>&& other) { | |
1405 KJ_IF_MAYBE(val, other) { | |
1406 ptr.emplace(*val); | |
1407 other = nullptr; | |
1408 } | |
1409 } | |
1410 template <typename U> | |
1411 Maybe(const Maybe<U>& other) { | |
1412 KJ_IF_MAYBE(val, other) { | |
1413 ptr.emplace(*val); | |
1414 } | |
1415 } | |
1416 | |
1417 Maybe(decltype(nullptr)): ptr(nullptr) {} | |
1418 | |
1419 template <typename... Params> | |
1420 inline T& emplace(Params&&... params) { | |
1421 // Replace this Maybe's content with a new value constructed by passing the given parameters to | |
1422 // T's constructor. This can be used to initialize a Maybe without copying or even moving a T. | |
1423 // Returns a reference to the newly-constructed value. | |
1424 | |
1425 return ptr.emplace(kj::fwd<Params>(params)...); | |
1426 } | |
1427 | |
1428 inline Maybe& operator=(T&& other) { ptr = kj::mv(other); return *this; } | |
1429 inline Maybe& operator=(T& other) { ptr = other; return *this; } | |
1430 inline Maybe& operator=(const T& other) { ptr = other; return *this; } | |
1431 | |
1432 inline Maybe& operator=(Maybe&& other) { ptr = kj::mv(other.ptr); other = nullptr; return *this; } | |
1433 inline Maybe& operator=(Maybe& other) { ptr = other.ptr; return *this; } | |
1434 inline Maybe& operator=(const Maybe& other) { ptr = other.ptr; return *this; } | |
1435 | |
1436 template <typename U> | |
1437 Maybe& operator=(Maybe<U>&& other) { | |
1438 KJ_IF_MAYBE(val, kj::mv(other)) { | |
1439 ptr.emplace(kj::mv(*val)); | |
1440 other = nullptr; | |
1441 } else { | |
1442 ptr = nullptr; | |
1443 } | |
1444 return *this; | |
1445 } | |
1446 template <typename U> | |
1447 Maybe& operator=(const Maybe<U>& other) { | |
1448 KJ_IF_MAYBE(val, other) { | |
1449 ptr.emplace(*val); | |
1450 } else { | |
1451 ptr = nullptr; | |
1452 } | |
1453 return *this; | |
1454 } | |
1455 | |
1456 inline Maybe& operator=(decltype(nullptr)) { ptr = nullptr; return *this; } | |
1457 | |
1458 inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } | |
1459 inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } | |
1460 | |
1461 inline bool operator==(const Maybe<T>& other) const { | |
1462 if (ptr == nullptr) { | |
1463 return other == nullptr; | |
1464 } else { | |
1465 return other.ptr != nullptr && *ptr == *other.ptr; | |
1466 } | |
1467 } | |
1468 inline bool operator!=(const Maybe<T>& other) const { return !(*this == other); } | |
1469 | |
1470 Maybe(const T* t) = delete; | |
1471 Maybe& operator=(const T* other) = delete; | |
1472 // We used to permit assigning a Maybe<T> directly from a T*, and the assignment would check for | |
1473 // nullness. This turned out never to be useful, and sometimes to be dangerous. | |
1474 | |
1475 T& orDefault(T& defaultValue) & { | |
1476 if (ptr == nullptr) { | |
1477 return defaultValue; | |
1478 } else { | |
1479 return *ptr; | |
1480 } | |
1481 } | |
1482 const T& orDefault(const T& defaultValue) const & { | |
1483 if (ptr == nullptr) { | |
1484 return defaultValue; | |
1485 } else { | |
1486 return *ptr; | |
1487 } | |
1488 } | |
1489 T&& orDefault(T&& defaultValue) && { | |
1490 if (ptr == nullptr) { | |
1491 return kj::mv(defaultValue); | |
1492 } else { | |
1493 return kj::mv(*ptr); | |
1494 } | |
1495 } | |
1496 const T&& orDefault(const T&& defaultValue) const && { | |
1497 if (ptr == nullptr) { | |
1498 return kj::mv(defaultValue); | |
1499 } else { | |
1500 return kj::mv(*ptr); | |
1501 } | |
1502 } | |
1503 | |
1504 template <typename F, | |
1505 typename Result = decltype(instance<bool>() ? instance<T&>() : instance<F>()())> | |
1506 Result orDefault(F&& lazyDefaultValue) & { | |
1507 if (ptr == nullptr) { | |
1508 return lazyDefaultValue(); | |
1509 } else { | |
1510 return *ptr; | |
1511 } | |
1512 } | |
1513 | |
1514 template <typename F, | |
1515 typename Result = decltype(instance<bool>() ? instance<const T&>() : instance<F>()())> | |
1516 Result orDefault(F&& lazyDefaultValue) const & { | |
1517 if (ptr == nullptr) { | |
1518 return lazyDefaultValue(); | |
1519 } else { | |
1520 return *ptr; | |
1521 } | |
1522 } | |
1523 | |
1524 template <typename F, | |
1525 typename Result = decltype(instance<bool>() ? instance<T&&>() : instance<F>()())> | |
1526 Result orDefault(F&& lazyDefaultValue) && { | |
1527 if (ptr == nullptr) { | |
1528 return lazyDefaultValue(); | |
1529 } else { | |
1530 return kj::mv(*ptr); | |
1531 } | |
1532 } | |
1533 | |
1534 template <typename F, | |
1535 typename Result = decltype(instance<bool>() ? instance<const T&&>() : instance<F>()())> | |
1536 Result orDefault(F&& lazyDefaultValue) const && { | |
1537 if (ptr == nullptr) { | |
1538 return lazyDefaultValue(); | |
1539 } else { | |
1540 return kj::mv(*ptr); | |
1541 } | |
1542 } | |
1543 | |
1544 template <typename Func> | |
1545 auto map(Func&& f) & -> Maybe<decltype(f(instance<T&>()))> { | |
1546 if (ptr == nullptr) { | |
1547 return nullptr; | |
1548 } else { | |
1549 return f(*ptr); | |
1550 } | |
1551 } | |
1552 | |
1553 template <typename Func> | |
1554 auto map(Func&& f) const & -> Maybe<decltype(f(instance<const T&>()))> { | |
1555 if (ptr == nullptr) { | |
1556 return nullptr; | |
1557 } else { | |
1558 return f(*ptr); | |
1559 } | |
1560 } | |
1561 | |
1562 template <typename Func> | |
1563 auto map(Func&& f) && -> Maybe<decltype(f(instance<T&&>()))> { | |
1564 if (ptr == nullptr) { | |
1565 return nullptr; | |
1566 } else { | |
1567 return f(kj::mv(*ptr)); | |
1568 } | |
1569 } | |
1570 | |
1571 template <typename Func> | |
1572 auto map(Func&& f) const && -> Maybe<decltype(f(instance<const T&&>()))> { | |
1573 if (ptr == nullptr) { | |
1574 return nullptr; | |
1575 } else { | |
1576 return f(kj::mv(*ptr)); | |
1577 } | |
1578 } | |
1579 | |
1580 private: | |
1581 _::NullableValue<T> ptr; | |
1582 | |
1583 template <typename U> | |
1584 friend class Maybe; | |
1585 template <typename U> | |
1586 friend _::NullableValue<U>&& _::readMaybe(Maybe<U>&& maybe); | |
1587 template <typename U> | |
1588 friend U* _::readMaybe(Maybe<U>& maybe); | |
1589 template <typename U> | |
1590 friend const U* _::readMaybe(const Maybe<U>& maybe); | |
1591 }; | |
1592 | |
1593 template <typename T> | |
1594 class Maybe<T&> { | |
1595 public: | |
1596 constexpr Maybe(): ptr(nullptr) {} | |
1597 constexpr Maybe(T& t): ptr(&t) {} | |
1598 constexpr Maybe(T* t): ptr(t) {} | |
1599 | |
1600 inline constexpr Maybe(PropagateConst<T, Maybe>& other): ptr(other.ptr) {} | |
1601 // Allow const copy only if `T` itself is const. Otherwise allow only non-const copy, to | |
1602 // protect transitive constness. Clang is happy for this constructor to be declared `= default` | |
1603 // since, after evaluation of `PropagateConst`, it does end up being a default-able constructor. | |
1604 // But, GCC and MSVC both complain about that, claiming this constructor cannot be declared | |
1605 // default. I don't know who is correct, but whatever, we'll write out an implementation, fine. | |
1606 // | |
1607 // Note that we can't solve this by inheriting DisallowConstCopyIfNotConst<T> because we want | |
1608 // to override the move constructor, and if we override the move constructor then we must define | |
1609 // the copy constructor here. | |
1610 | |
1611 inline constexpr Maybe(Maybe&& other): ptr(other.ptr) { other.ptr = nullptr; } | |
1612 | |
1613 template <typename U> | |
1614 inline constexpr Maybe(Maybe<U&>& other): ptr(other.ptr) {} | |
1615 template <typename U> | |
1616 inline constexpr Maybe(const Maybe<U&>& other): ptr(const_cast<const U*>(other.ptr)) {} | |
1617 template <typename U> | |
1618 inline constexpr Maybe(Maybe<U&>&& other): ptr(other.ptr) { other.ptr = nullptr; } | |
1619 template <typename U> | |
1620 inline constexpr Maybe(const Maybe<U&>&& other) = delete; | |
1621 template <typename U, typename = EnableIf<canConvert<U*, T*>()>> | |
1622 constexpr Maybe(Maybe<U>& other): ptr(other.ptr.operator U*()) {} | |
1623 template <typename U, typename = EnableIf<canConvert<const U*, T*>()>> | |
1624 constexpr Maybe(const Maybe<U>& other): ptr(other.ptr.operator const U*()) {} | |
1625 inline constexpr Maybe(decltype(nullptr)): ptr(nullptr) {} | |
1626 | |
1627 inline Maybe& operator=(T& other) { ptr = &other; return *this; } | |
1628 inline Maybe& operator=(T* other) { ptr = other; return *this; } | |
1629 inline Maybe& operator=(PropagateConst<T, Maybe>& other) { ptr = other.ptr; return *this; } | |
1630 inline Maybe& operator=(Maybe&& other) { ptr = other.ptr; other.ptr = nullptr; return *this; } | |
1631 template <typename U> | |
1632 inline Maybe& operator=(Maybe<U&>& other) { ptr = other.ptr; return *this; } | |
1633 template <typename U> | |
1634 inline Maybe& operator=(const Maybe<const U&>& other) { ptr = other.ptr; return *this; } | |
1635 template <typename U> | |
1636 inline Maybe& operator=(Maybe<U&>&& other) { ptr = other.ptr; other.ptr = nullptr; return *this; } | |
1637 template <typename U> | |
1638 inline Maybe& operator=(const Maybe<U&>&& other) = delete; | |
1639 | |
1640 inline bool operator==(decltype(nullptr)) const { return ptr == nullptr; } | |
1641 inline bool operator!=(decltype(nullptr)) const { return ptr != nullptr; } | |
1642 | |
1643 T& orDefault(T& defaultValue) { | |
1644 if (ptr == nullptr) { | |
1645 return defaultValue; | |
1646 } else { | |
1647 return *ptr; | |
1648 } | |
1649 } | |
1650 const T& orDefault(const T& defaultValue) const { | |
1651 if (ptr == nullptr) { | |
1652 return defaultValue; | |
1653 } else { | |
1654 return *ptr; | |
1655 } | |
1656 } | |
1657 | |
1658 template <typename Func> | |
1659 auto map(Func&& f) -> Maybe<decltype(f(instance<T&>()))> { | |
1660 if (ptr == nullptr) { | |
1661 return nullptr; | |
1662 } else { | |
1663 return f(*ptr); | |
1664 } | |
1665 } | |
1666 | |
1667 template <typename Func> | |
1668 auto map(Func&& f) const -> Maybe<decltype(f(instance<const T&>()))> { | |
1669 if (ptr == nullptr) { | |
1670 return nullptr; | |
1671 } else { | |
1672 const T& ref = *ptr; | |
1673 return f(ref); | |
1674 } | |
1675 } | |
1676 | |
1677 private: | |
1678 T* ptr; | |
1679 | |
1680 template <typename U> | |
1681 friend class Maybe; | |
1682 template <typename U> | |
1683 friend U* _::readMaybe(Maybe<U&>&& maybe); | |
1684 template <typename U> | |
1685 friend U* _::readMaybe(const Maybe<U&>& maybe); | |
1686 }; | |
1687 | |
1688 // ======================================================================================= | |
1689 // ArrayPtr | |
1690 // | |
1691 // So common that we put it in common.h rather than array.h. | |
1692 | |
1693 template <typename T> | |
1694 class Array; | |
1695 | |
1696 template <typename T> | |
1697 class ArrayPtr: public DisallowConstCopyIfNotConst<T> { | |
1698 // A pointer to an array. Includes a size. Like any pointer, it doesn't own the target data, | |
1699 // and passing by value only copies the pointer, not the target. | |
1700 | |
1701 public: | |
1702 inline constexpr ArrayPtr(): ptr(nullptr), size_(0) {} | |
1703 inline constexpr ArrayPtr(decltype(nullptr)): ptr(nullptr), size_(0) {} | |
1704 inline constexpr ArrayPtr(T* ptr KJ_LIFETIMEBOUND, size_t size): ptr(ptr), size_(size) {} | |
1705 inline constexpr ArrayPtr(T* begin KJ_LIFETIMEBOUND, T* end KJ_LIFETIMEBOUND) | |
1706 : ptr(begin), size_(end - begin) {} | |
1707 ArrayPtr<T>& operator=(Array<T>&&) = delete; | |
1708 ArrayPtr<T>& operator=(decltype(nullptr)) { | |
1709 ptr = nullptr; | |
1710 size_ = 0; | |
1711 return *this; | |
1712 } | |
1713 | |
1714 #if __GNUC__ && !__clang__ && __GNUC__ >= 9 | |
1715 // GCC 9 added a warning when we take an initializer_list as a constructor parameter and save a | |
1716 // pointer to its content in a class member. GCC apparently imagines we're going to do something | |
1717 // dumb like this: | |
1718 // ArrayPtr<const int> ptr = { 1, 2, 3 }; | |
1719 // foo(ptr[1]); // undefined behavior! | |
1720 // Any KJ programmer should be able to recognize that this is UB, because an ArrayPtr does not own | |
1721 // its content. That's not what this constructor is for, tohugh. This constructor is meant to allow | |
1722 // code like this: | |
1723 // int foo(ArrayPtr<const int> p); | |
1724 // // ... later ... | |
1725 // foo({1, 2, 3}); | |
1726 // In this case, the initializer_list's backing array, like any temporary, lives until the end of | |
1727 // the statement `foo({1, 2, 3});`. Therefore, it lives at least until the call to foo() has | |
1728 // returned, which is exactly what we care about. This usage is fine! GCC is wrong to warn. | |
1729 // | |
1730 // Amusingly, Clang's implementation has a similar type that they call ArrayRef which apparently | |
1731 // triggers this same GCC warning. My guess is that Clang will not introduce a similar warning | |
1732 // given that it triggers on their own, legitimate code. | |
1733 #pragma GCC diagnostic push | |
1734 #pragma GCC diagnostic ignored "-Winit-list-lifetime" | |
1735 #endif | |
1736 inline KJ_CONSTEXPR() ArrayPtr( | |
1737 ::std::initializer_list<RemoveConstOrDisable<T>> init KJ_LIFETIMEBOUND) | |
1738 : ptr(init.begin()), size_(init.size()) {} | |
1739 #if __GNUC__ && !__clang__ && __GNUC__ >= 9 | |
1740 #pragma GCC diagnostic pop | |
1741 #endif | |
1742 | |
1743 template <size_t size> | |
1744 inline constexpr ArrayPtr(KJ_LIFETIMEBOUND T (&native)[size]): ptr(native), size_(size) { | |
1745 // Construct an ArrayPtr from a native C-style array. | |
1746 // | |
1747 // We disable this constructor for const char arrays because otherwise you would be able to | |
1748 // implicitly convert a character literal to ArrayPtr<const char>, which sounds really great, | |
1749 // except that the NUL terminator would be included, which probably isn't what you intended. | |
1750 // | |
1751 // TODO(someday): Maybe we should support character literals but explicitly chop off the NUL | |
1752 // terminator. This could do the wrong thing if someone tries to construct an | |
1753 // ArrayPtr<const char> from a non-NUL-terminated char array, but evidence suggests that all | |
1754 // real use cases are in fact intending to remove the NUL terminator. It's convenient to be | |
1755 // able to specify ArrayPtr<const char> as a parameter type and be able to accept strings | |
1756 // as input in addition to arrays. Currently, you'll need overloading to support string | |
1757 // literals in this case, but if you overload StringPtr, then you'll find that several | |
1758 // conversions (e.g. from String and from a literal char array) become ambiguous! You end up | |
1759 // having to overload for literal char arrays specifically which is cumbersome. | |
1760 | |
1761 static_assert(!isSameType<T, const char>(), | |
1762 "Can't implicitly convert literal char array to ArrayPtr because we don't know if " | |
1763 "you meant to include the NUL terminator. We may change this in the future to " | |
1764 "automatically drop the NUL terminator. For now, try explicitly converting to StringPtr, " | |
1765 "which can in turn implicitly convert to ArrayPtr<const char>."); | |
1766 static_assert(!isSameType<T, const char16_t>(), "see above"); | |
1767 static_assert(!isSameType<T, const char32_t>(), "see above"); | |
1768 } | |
1769 | |
1770 inline operator ArrayPtr<const T>() const { | |
1771 return ArrayPtr<const T>(ptr, size_); | |
1772 } | |
1773 inline ArrayPtr<const T> asConst() const { | |
1774 return ArrayPtr<const T>(ptr, size_); | |
1775 } | |
1776 | |
1777 inline constexpr size_t size() const { return size_; } | |
1778 inline const T& operator[](size_t index) const { | |
1779 KJ_IREQUIRE(index < size_, "Out-of-bounds ArrayPtr access."); | |
1780 return ptr[index]; | |
1781 } | |
1782 inline T& operator[](size_t index) { | |
1783 KJ_IREQUIRE(index < size_, "Out-of-bounds ArrayPtr access."); | |
1784 return ptr[index]; | |
1785 } | |
1786 | |
1787 inline T* begin() { return ptr; } | |
1788 inline T* end() { return ptr + size_; } | |
1789 inline T& front() { return *ptr; } | |
1790 inline T& back() { return *(ptr + size_ - 1); } | |
1791 inline constexpr const T* begin() const { return ptr; } | |
1792 inline constexpr const T* end() const { return ptr + size_; } | |
1793 inline const T& front() const { return *ptr; } | |
1794 inline const T& back() const { return *(ptr + size_ - 1); } | |
1795 | |
1796 inline ArrayPtr<const T> slice(size_t start, size_t end) const { | |
1797 KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds ArrayPtr::slice()."); | |
1798 return ArrayPtr<const T>(ptr + start, end - start); | |
1799 } | |
1800 inline ArrayPtr slice(size_t start, size_t end) { | |
1801 KJ_IREQUIRE(start <= end && end <= size_, "Out-of-bounds ArrayPtr::slice()."); | |
1802 return ArrayPtr(ptr + start, end - start); | |
1803 } | |
1804 inline bool startsWith(const ArrayPtr<const T>& other) const { | |
1805 return other.size() <= size_ && slice(0, other.size()) == other; | |
1806 } | |
1807 inline bool endsWith(const ArrayPtr<const T>& other) const { | |
1808 return other.size() <= size_ && slice(size_ - other.size(), size_) == other; | |
1809 } | |
1810 | |
1811 inline Maybe<size_t> findFirst(const T& match) const { | |
1812 for (size_t i = 0; i < size_; i++) { | |
1813 if (ptr[i] == match) { | |
1814 return i; | |
1815 } | |
1816 } | |
1817 return nullptr; | |
1818 } | |
1819 inline Maybe<size_t> findLast(const T& match) const { | |
1820 for (size_t i = size_; i--;) { | |
1821 if (ptr[i] == match) { | |
1822 return i; | |
1823 } | |
1824 } | |
1825 return nullptr; | |
1826 } | |
1827 | |
1828 inline ArrayPtr<PropagateConst<T, byte>> asBytes() const { | |
1829 // Reinterpret the array as a byte array. This is explicitly legal under C++ aliasing | |
1830 // rules. | |
1831 return { reinterpret_cast<PropagateConst<T, byte>*>(ptr), size_ * sizeof(T) }; | |
1832 } | |
1833 inline ArrayPtr<PropagateConst<T, char>> asChars() const { | |
1834 // Reinterpret the array as a char array. This is explicitly legal under C++ aliasing | |
1835 // rules. | |
1836 return { reinterpret_cast<PropagateConst<T, char>*>(ptr), size_ * sizeof(T) }; | |
1837 } | |
1838 | |
1839 inline bool operator==(decltype(nullptr)) const { return size_ == 0; } | |
1840 inline bool operator!=(decltype(nullptr)) const { return size_ != 0; } | |
1841 | |
1842 inline bool operator==(const ArrayPtr& other) const { | |
1843 if (size_ != other.size_) return false; | |
1844 if (isIntegral<RemoveConst<T>>()) { | |
1845 if (size_ == 0) return true; | |
1846 return memcmp(ptr, other.ptr, size_ * sizeof(T)) == 0; | |
1847 } | |
1848 for (size_t i = 0; i < size_; i++) { | |
1849 if (ptr[i] != other[i]) return false; | |
1850 } | |
1851 return true; | |
1852 } | |
1853 #if !__cpp_impl_three_way_comparison | |
1854 inline bool operator!=(const ArrayPtr& other) const { return !(*this == other); } | |
1855 #endif | |
1856 | |
1857 template <typename U> | |
1858 inline bool operator==(const ArrayPtr<U>& other) const { | |
1859 if (size_ != other.size()) return false; | |
1860 for (size_t i = 0; i < size_; i++) { | |
1861 if (ptr[i] != other[i]) return false; | |
1862 } | |
1863 return true; | |
1864 } | |
1865 #if !__cpp_impl_three_way_comparison | |
1866 template <typename U> | |
1867 inline bool operator!=(const ArrayPtr<U>& other) const { return !(*this == other); } | |
1868 #endif | |
1869 | |
1870 template <typename... Attachments> | |
1871 Array<T> attach(Attachments&&... attachments) const KJ_WARN_UNUSED_RESULT; | |
1872 // Like Array<T>::attach(), but also promotes an ArrayPtr to an Array. Generally the attachment | |
1873 // should be an object that actually owns the array that the ArrayPtr is pointing at. | |
1874 // | |
1875 // You must include kj/array.h to call this. | |
1876 | |
1877 private: | |
1878 T* ptr; | |
1879 size_t size_; | |
1880 }; | |
1881 | |
1882 template <> | |
1883 inline Maybe<size_t> ArrayPtr<const char>::findFirst(const char& c) const { | |
1884 const char* pos = reinterpret_cast<const char*>(memchr(ptr, c, size_)); | |
1885 if (pos == nullptr) { | |
1886 return nullptr; | |
1887 } else { | |
1888 return pos - ptr; | |
1889 } | |
1890 } | |
1891 | |
1892 template <> | |
1893 inline Maybe<size_t> ArrayPtr<char>::findFirst(const char& c) const { | |
1894 char* pos = reinterpret_cast<char*>(memchr(ptr, c, size_)); | |
1895 if (pos == nullptr) { | |
1896 return nullptr; | |
1897 } else { | |
1898 return pos - ptr; | |
1899 } | |
1900 } | |
1901 | |
1902 template <> | |
1903 inline Maybe<size_t> ArrayPtr<const byte>::findFirst(const byte& c) const { | |
1904 const byte* pos = reinterpret_cast<const byte*>(memchr(ptr, c, size_)); | |
1905 if (pos == nullptr) { | |
1906 return nullptr; | |
1907 } else { | |
1908 return pos - ptr; | |
1909 } | |
1910 } | |
1911 | |
1912 template <> | |
1913 inline Maybe<size_t> ArrayPtr<byte>::findFirst(const byte& c) const { | |
1914 byte* pos = reinterpret_cast<byte*>(memchr(ptr, c, size_)); | |
1915 if (pos == nullptr) { | |
1916 return nullptr; | |
1917 } else { | |
1918 return pos - ptr; | |
1919 } | |
1920 } | |
1921 | |
1922 // glibc has a memrchr() for reverse search but it's non-standard, so we don't bother optimizing | |
1923 // findLast(), which isn't used much anyway. | |
1924 | |
1925 template <typename T> | |
1926 inline constexpr ArrayPtr<T> arrayPtr(T* ptr KJ_LIFETIMEBOUND, size_t size) { | |
1927 // Use this function to construct ArrayPtrs without writing out the type name. | |
1928 return ArrayPtr<T>(ptr, size); | |
1929 } | |
1930 | |
1931 template <typename T> | |
1932 inline constexpr ArrayPtr<T> arrayPtr(T* begin KJ_LIFETIMEBOUND, T* end KJ_LIFETIMEBOUND) { | |
1933 // Use this function to construct ArrayPtrs without writing out the type name. | |
1934 return ArrayPtr<T>(begin, end); | |
1935 } | |
1936 | |
1937 // ======================================================================================= | |
1938 // Casts | |
1939 | |
1940 template <typename To, typename From> | |
1941 To implicitCast(From&& from) { | |
1942 // `implicitCast<T>(value)` casts `value` to type `T` only if the conversion is implicit. Useful | |
1943 // for e.g. resolving ambiguous overloads without sacrificing type-safety. | |
1944 return kj::fwd<From>(from); | |
1945 } | |
1946 | |
1947 template <typename To, typename From> | |
1948 Maybe<To&> dynamicDowncastIfAvailable(From& from) { | |
1949 // If RTTI is disabled, always returns nullptr. Otherwise, works like dynamic_cast. Useful | |
1950 // in situations where dynamic_cast could allow an optimization, but isn't strictly necessary | |
1951 // for correctness. It is highly recommended that you try to arrange all your dynamic_casts | |
1952 // this way, as a dynamic_cast that is necessary for correctness implies a flaw in the interface | |
1953 // design. | |
1954 | |
1955 // Force a compile error if To is not a subtype of From. Cross-casting is rare; if it is needed | |
1956 // we should have a separate cast function like dynamicCrosscastIfAvailable(). | |
1957 if (false) { | |
1958 kj::implicitCast<From*>(kj::implicitCast<To*>(nullptr)); | |
1959 } | |
1960 | |
1961 #if KJ_NO_RTTI | |
1962 return nullptr; | |
1963 #else | |
1964 return dynamic_cast<To*>(&from); | |
1965 #endif | |
1966 } | |
1967 | |
1968 template <typename To, typename From> | |
1969 To& downcast(From& from) { | |
1970 // Down-cast a value to a sub-type, asserting that the cast is valid. In opt mode this is a | |
1971 // static_cast, but in debug mode (when RTTI is enabled) a dynamic_cast will be used to verify | |
1972 // that the value really has the requested type. | |
1973 | |
1974 // Force a compile error if To is not a subtype of From. | |
1975 if (false) { | |
1976 kj::implicitCast<From*>(kj::implicitCast<To*>(nullptr)); | |
1977 } | |
1978 | |
1979 #if !KJ_NO_RTTI | |
1980 KJ_IREQUIRE(dynamic_cast<To*>(&from) != nullptr, "Value cannot be downcast() to requested type."); | |
1981 #endif | |
1982 | |
1983 return static_cast<To&>(from); | |
1984 } | |
1985 | |
1986 // ======================================================================================= | |
1987 // Defer | |
1988 | |
1989 namespace _ { // private | |
1990 | |
1991 template <typename Func> | |
1992 class Deferred { | |
1993 public: | |
1994 Deferred(Func&& func): maybeFunc(kj::fwd<Func>(func)) {} | |
1995 ~Deferred() noexcept(false) { | |
1996 run(); | |
1997 } | |
1998 KJ_DISALLOW_COPY(Deferred); | |
1999 | |
2000 Deferred(Deferred&&) = default; | |
2001 // Since we use a kj::Maybe, the default move constructor does exactly what we want it to do. | |
2002 | |
2003 void run() { | |
2004 // Move `maybeFunc` to the local scope so that even if we throw, we destroy the functor we had. | |
2005 auto maybeLocalFunc = kj::mv(maybeFunc); | |
2006 KJ_IF_MAYBE(func, maybeLocalFunc) { | |
2007 (*func)(); | |
2008 } | |
2009 } | |
2010 | |
2011 void cancel() { | |
2012 maybeFunc = nullptr; | |
2013 } | |
2014 | |
2015 private: | |
2016 kj::Maybe<Func> maybeFunc; | |
2017 // Note that `Func` may actually be an lvalue reference because `kj::defer` takes its argument via | |
2018 // universal reference. `kj::Maybe` has specializations for lvalue reference types, so this works | |
2019 // out. | |
2020 }; | |
2021 | |
2022 } // namespace _ (private) | |
2023 | |
2024 template <typename Func> | |
2025 _::Deferred<Func> defer(Func&& func) { | |
2026 // Returns an object which will invoke the given functor in its destructor. The object is not | |
2027 // copyable but is move-constructable with the semantics you'd expect. Since the return type is | |
2028 // private, you need to assign to an `auto` variable. | |
2029 // | |
2030 // The KJ_DEFER macro provides slightly more convenient syntax for the common case where you | |
2031 // want some code to run at current scope exit. | |
2032 // | |
2033 // KJ_DEFER does not support move-assignment for its returned objects. If you need to reuse the | |
2034 // variable for your deferred function object, then you will want to write your own class for that | |
2035 // purpose. | |
2036 | |
2037 return _::Deferred<Func>(kj::fwd<Func>(func)); | |
2038 } | |
2039 | |
2040 #define KJ_DEFER(code) auto KJ_UNIQUE_NAME(_kjDefer) = ::kj::defer([&](){code;}) | |
2041 // Run the given code when the function exits, whether by return or exception. | |
2042 | |
2043 } // namespace kj | |
2044 | |
2045 KJ_END_HEADER |