Mercurial > hg > sv-dependency-builds
comparison osx/include/kj/common.h @ 62:0994c39f1e94
Cap'n Proto v0.6 + build for OSX
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Mon, 22 May 2017 10:01:37 +0100 |
parents | 3ab5a40c4e3b |
children |
comparison
equal
deleted
inserted
replaced
61:d101c4099725 | 62:0994c39f1e94 |
---|---|
61 #endif | 61 #endif |
62 #endif | 62 #endif |
63 #elif defined(_MSC_VER) | 63 #elif defined(_MSC_VER) |
64 #if _MSC_VER < 1900 | 64 #if _MSC_VER < 1900 |
65 #error "You need Visual Studio 2015 or better to compile this code." | 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 | 66 #endif |
70 #else | 67 #else |
71 #warning "I don't recognize your compiler. As of this writing, Clang and GCC are the only "\ | 68 #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. "\ | 69 "known compilers with enough C++11 support for this library. "\ |
73 "#define KJ_NO_COMPILER_CHECK to make this warning go away." | 70 "#define KJ_NO_COMPILER_CHECK to make this warning go away." |
84 // widely present in the wild e.g. on Ubuntu 14.04. | 81 // widely present in the wild e.g. on Ubuntu 14.04. |
85 #undef _GLIBCXX_HAVE_GETS | 82 #undef _GLIBCXX_HAVE_GETS |
86 #endif | 83 #endif |
87 | 84 |
88 #if defined(_MSC_VER) | 85 #if defined(_MSC_VER) |
86 #ifndef NOMINMAX | |
87 #define NOMINMAX 1 | |
88 #endif | |
89 #include <intrin.h> // __popcnt | 89 #include <intrin.h> // __popcnt |
90 #endif | 90 #endif |
91 | 91 |
92 // ======================================================================================= | 92 // ======================================================================================= |
93 | 93 |
147 #define KJ_LIKELY(condition) (condition) | 147 #define KJ_LIKELY(condition) (condition) |
148 #define KJ_UNLIKELY(condition) (condition) | 148 #define KJ_UNLIKELY(condition) (condition) |
149 #endif | 149 #endif |
150 | 150 |
151 #if defined(KJ_DEBUG) || __NO_INLINE__ | 151 #if defined(KJ_DEBUG) || __NO_INLINE__ |
152 #define KJ_ALWAYS_INLINE(prototype) inline prototype | 152 #define KJ_ALWAYS_INLINE(...) inline __VA_ARGS__ |
153 // Don't force inline in debug mode. | 153 // Don't force inline in debug mode. |
154 #else | 154 #else |
155 #if defined(_MSC_VER) | 155 #if defined(_MSC_VER) |
156 #define KJ_ALWAYS_INLINE(prototype) __forceinline prototype | 156 #define KJ_ALWAYS_INLINE(...) __forceinline __VA_ARGS__ |
157 #else | 157 #else |
158 #define KJ_ALWAYS_INLINE(prototype) inline prototype __attribute__((always_inline)) | 158 #define KJ_ALWAYS_INLINE(...) inline __VA_ARGS__ __attribute__((always_inline)) |
159 #endif | 159 #endif |
160 // Force a function to always be inlined. Apply only to the prototype, not to the definition. | 160 // Force a function to always be inlined. Apply only to the prototype, not to the definition. |
161 #endif | 161 #endif |
162 | 162 |
163 #if defined(_MSC_VER) | 163 #if defined(_MSC_VER) |
364 // | 364 // |
365 // Note that due to C++ rules about implicit copy constructors and assignment operators, any | 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 | 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. | 367 // disallow const copies. Hey, cool, that's exactly what we want. |
368 | 368 |
369 #if CAPNP_DEBUG_TYPES | |
370 // Alas! Declaring a defaulted non-const copy constructor tickles a bug which causes GCC and | |
371 // Clang to disagree on ABI, using different calling conventions to pass this type, leading to | |
372 // immediate segfaults. See: | |
373 // https://bugs.llvm.org/show_bug.cgi?id=23764 | |
374 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58074 | |
375 // | |
376 // Because of this, we can't use this technique. We guard it by CAPNP_DEBUG_TYPES so that it | |
377 // still applies to the Cap'n Proto developers during internal testing. | |
378 | |
369 DisallowConstCopy() = default; | 379 DisallowConstCopy() = default; |
370 DisallowConstCopy(DisallowConstCopy&) = default; | 380 DisallowConstCopy(DisallowConstCopy&) = default; |
371 DisallowConstCopy(DisallowConstCopy&&) = default; | 381 DisallowConstCopy(DisallowConstCopy&&) = default; |
372 DisallowConstCopy& operator=(DisallowConstCopy&) = default; | 382 DisallowConstCopy& operator=(DisallowConstCopy&) = default; |
373 DisallowConstCopy& operator=(DisallowConstCopy&&) = default; | 383 DisallowConstCopy& operator=(DisallowConstCopy&&) = default; |
384 #endif | |
374 }; | 385 }; |
386 | |
387 #if _MSC_VER | |
388 | |
389 #define KJ_CPCAP(obj) obj=::kj::cp(obj) | |
390 // TODO(msvc): MSVC refuses to invoke non-const versions of copy constructors in by-value lambda | |
391 // captures. Wrap your captured object in this macro to force the compiler to perform a copy. | |
392 // Example: | |
393 // | |
394 // struct Foo: DisallowConstCopy {}; | |
395 // Foo foo; | |
396 // auto lambda = [KJ_CPCAP(foo)] {}; | |
397 | |
398 #else | |
399 | |
400 #define KJ_CPCAP(obj) obj | |
401 // Clang and gcc both already perform copy capturing correctly with non-const copy constructors. | |
402 | |
403 #endif | |
375 | 404 |
376 template <typename T> | 405 template <typename T> |
377 struct DisallowConstCopyIfNotConst: public DisallowConstCopy { | 406 struct DisallowConstCopyIfNotConst: public DisallowConstCopy { |
378 // Inherit from this when implementing a template that contains a pointer to T and which should | 407 // 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 | 408 // enforce transitive constness. If T is a const type, this has no effect. Otherwise, it is |
435 template <typename T, typename U> | 464 template <typename T, typename U> |
436 constexpr bool canConvert() { | 465 constexpr bool canConvert() { |
437 return sizeof(CanConvert_<U>::sfinae(instance<T>())) == sizeof(int); | 466 return sizeof(CanConvert_<U>::sfinae(instance<T>())) == sizeof(int); |
438 } | 467 } |
439 | 468 |
440 #if __clang__ | 469 #if __GNUC__ && !__clang__ && __GNUC__ < 5 |
441 template <typename T> | 470 template <typename T> |
442 constexpr bool canMemcpy() { | 471 constexpr bool canMemcpy() { |
443 // Returns true if T can be copied using memcpy instead of using the copy constructor or | 472 // Returns true if T can be copied using memcpy instead of using the copy constructor or |
444 // assignment operator. | 473 // assignment operator. |
445 | 474 |
446 // Clang unhelpfully defines __has_trivial_{copy,assign}(T) to be true if the copy constructor / | 475 // GCC 4 does not have __is_trivially_constructible and friends, and there doesn't seem to be |
447 // assign operator are deleted, on the basis that a strict reading of the definition of "trivial" | 476 // any reliable alternative. __has_trivial_copy() and __has_trivial_assign() return the right |
448 // according to the standard says that deleted functions are in fact trivial. Meanwhile Clang | 477 // thing at one point but later on they changed such that a deleted copy constructor was |
449 // provides these admittedly-better intrinsics, but GCC does not. | 478 // considered "trivial" (apparently technically correct, though useless). So, on GCC 4 we give up |
450 return __is_trivially_constructible(T, const T&) && __is_trivially_assignable(T, const T&); | 479 // and assume we can't memcpy() at all, and must explicitly copy-construct everything. |
451 } | 480 return false; |
481 } | |
482 #define KJ_ASSERT_CAN_MEMCPY(T) | |
452 #else | 483 #else |
453 template <typename T> | 484 template <typename T> |
454 constexpr bool canMemcpy() { | 485 constexpr bool canMemcpy() { |
455 // Returns true if T can be copied using memcpy instead of using the copy constructor or | 486 // Returns true if T can be copied using memcpy instead of using the copy constructor or |
456 // assignment operator. | 487 // assignment operator. |
457 | 488 |
458 // GCC defines these to mean what we want them to mean. | 489 return __is_trivially_constructible(T, const T&) && __is_trivially_assignable(T, const T&); |
459 return __has_trivial_copy(T) && __has_trivial_assign(T); | 490 } |
460 } | 491 #define KJ_ASSERT_CAN_MEMCPY(T) \ |
492 static_assert(kj::canMemcpy<T>(), "this code expects this type to be memcpy()-able"); | |
461 #endif | 493 #endif |
462 | 494 |
463 // ======================================================================================= | 495 // ======================================================================================= |
464 // Equivalents to std::move() and std::forward(), since these are very commonly needed and the | 496 // 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. | 497 // std header <utility> pulls in lots of other stuff. |
473 | 505 |
474 template<typename T> constexpr T cp(T& t) noexcept { return t; } | 506 template<typename T> constexpr T cp(T& t) noexcept { return t; } |
475 template<typename T> constexpr T cp(const T& t) noexcept { return t; } | 507 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&&. | 508 // Useful to force a copy, particularly to pass into a function that expects T&&. |
477 | 509 |
478 template <typename T, typename U, bool takeT> struct MinType_; | 510 template <typename T, typename U, bool takeT, bool uOK = true> struct ChooseType_; |
479 template <typename T, typename U> struct MinType_<T, U, true> { typedef T Type; }; | 511 template <typename T, typename U> struct ChooseType_<T, U, true, true> { typedef T Type; }; |
480 template <typename T, typename U> struct MinType_<T, U, false> { typedef U Type; }; | 512 template <typename T, typename U> struct ChooseType_<T, U, true, false> { typedef T Type; }; |
513 template <typename T, typename U> struct ChooseType_<T, U, false, true> { typedef U Type; }; | |
481 | 514 |
482 template <typename T, typename U> | 515 template <typename T, typename U> |
483 using MinType = typename MinType_<T, U, sizeof(T) <= sizeof(U)>::Type; | 516 using WiderType = typename ChooseType_<T, U, sizeof(T) >= sizeof(U)>::Type; |
484 // Resolves to the smaller of the two input types. | |
485 | 517 |
486 template <typename T, typename U> | 518 template <typename T, typename U> |
487 inline constexpr auto min(T&& a, U&& b) -> MinType<Decay<T>, Decay<U>> { | 519 inline constexpr auto min(T&& a, U&& b) -> WiderType<Decay<T>, Decay<U>> { |
488 return a < b ? MinType<Decay<T>, Decay<U>>(a) : MinType<Decay<T>, Decay<U>>(b); | 520 return a < b ? WiderType<Decay<T>, Decay<U>>(a) : WiderType<Decay<T>, Decay<U>>(b); |
489 } | 521 } |
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 | 522 |
495 template <typename T, typename U> | 523 template <typename T, typename U> |
496 using MaxType = typename MaxType_<T, U, sizeof(T) >= sizeof(U)>::Type; | 524 inline constexpr auto max(T&& a, U&& b) -> WiderType<Decay<T>, Decay<U>> { |
497 // Resolves to the larger of the two input types. | 525 return a > b ? WiderType<Decay<T>, Decay<U>>(a) : WiderType<Decay<T>, Decay<U>>(b); |
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 } | 526 } |
503 | 527 |
504 template <typename T, size_t s> | 528 template <typename T, size_t s> |
505 inline constexpr size_t size(T (&arr)[s]) { return s; } | 529 inline constexpr size_t size(T (&arr)[s]) { return s; } |
506 template <typename T> | 530 template <typename T> |
580 // of that type. This is useful to use as e.g. a parameter to a function because it will be robust | 604 // 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. | 605 // in the face of changes to the parameter's type. |
582 // | 606 // |
583 // `char` is not supported, but `signed char` and `unsigned char` are. | 607 // `char` is not supported, but `signed char` and `unsigned char` are. |
584 | 608 |
609 template <typename T> | |
610 inline bool operator==(T t, MaxValue_) { return t == Decay<T>(maxValue); } | |
611 template <typename T> | |
612 inline bool operator==(T t, MinValue_) { return t == Decay<T>(minValue); } | |
613 | |
614 template <uint bits> | |
615 inline constexpr unsigned long long maxValueForBits() { | |
616 // Get the maximum integer representable in the given number of bits. | |
617 | |
618 // 1ull << 64 is unfortunately undefined. | |
619 return (bits == 64 ? 0 : (1ull << bits)) - 1; | |
620 } | |
621 | |
622 struct ThrowOverflow { | |
623 // Functor which throws an exception complaining about integer overflow. Usually this is used | |
624 // with the interfaces in units.h, but is defined here because Cap'n Proto wants to avoid | |
625 // including units.h when not using CAPNP_DEBUG_TYPES. | |
626 void operator()() const; | |
627 }; | |
628 | |
585 #if __GNUC__ | 629 #if __GNUC__ |
586 inline constexpr float inf() { return __builtin_huge_valf(); } | 630 inline constexpr float inf() { return __builtin_huge_valf(); } |
587 inline constexpr float nan() { return __builtin_nanf(""); } | 631 inline constexpr float nan() { return __builtin_nanf(""); } |
588 | 632 |
589 #elif _MSC_VER | 633 #elif _MSC_VER |
623 | 667 |
624 template <typename T> | 668 template <typename T> |
625 class Range { | 669 class Range { |
626 public: | 670 public: |
627 inline constexpr Range(const T& begin, const T& end): begin_(begin), end_(end) {} | 671 inline constexpr Range(const T& begin, const T& end): begin_(begin), end_(end) {} |
672 inline explicit constexpr Range(const T& end): begin_(0), end_(end) {} | |
628 | 673 |
629 class Iterator { | 674 class Iterator { |
630 public: | 675 public: |
631 Iterator() = default; | 676 Iterator() = default; |
632 inline Iterator(const T& value): value(value) {} | 677 inline Iterator(const T& value): value(value) {} |
662 private: | 707 private: |
663 T begin_; | 708 T begin_; |
664 T end_; | 709 T end_; |
665 }; | 710 }; |
666 | 711 |
712 template <typename T, typename U> | |
713 inline constexpr Range<WiderType<Decay<T>, Decay<U>>> range(T begin, U end) { | |
714 return Range<WiderType<Decay<T>, Decay<U>>>(begin, end); | |
715 } | |
716 | |
667 template <typename T> | 717 template <typename T> |
668 inline constexpr Range<Decay<T>> range(T begin, T end) { return Range<Decay<T>>(begin, end); } | 718 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` | 719 // Returns a fake iterable container containing all values of T from `begin` (inclusive) to `end` |
670 // (exclusive). Example: | 720 // (exclusive). Example: |
671 // | 721 // |
672 // // Prints 1, 2, 3, 4, 5, 6, 7, 8, 9. | 722 // // Prints 1, 2, 3, 4, 5, 6, 7, 8, 9. |
673 // for (int i: kj::range(1, 10)) { print(i); } | 723 // for (int i: kj::range(1, 10)) { print(i); } |
724 | |
725 template <typename T> | |
726 inline constexpr Range<Decay<T>> zeroTo(T end) { return Range<Decay<T>>(end); } | |
727 // Returns a fake iterable container containing all values of T from zero (inclusive) to `end` | |
728 // (exclusive). Example: | |
729 // | |
730 // // Prints 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. | |
731 // for (int i: kj::zeroTo(10)) { print(i); } | |
674 | 732 |
675 template <typename T> | 733 template <typename T> |
676 inline constexpr Range<size_t> indices(T&& container) { | 734 inline constexpr Range<size_t> indices(T&& container) { |
677 // Shortcut for iterating over the indices of a container: | 735 // Shortcut for iterating over the indices of a container: |
678 // | 736 // |
717 | 775 |
718 inline Iterator begin() const { return Iterator(value, 0); } | 776 inline Iterator begin() const { return Iterator(value, 0); } |
719 inline Iterator end() const { return Iterator(value, count); } | 777 inline Iterator end() const { return Iterator(value, count); } |
720 | 778 |
721 inline size_t size() const { return count; } | 779 inline size_t size() const { return count; } |
780 inline const T& operator[](ptrdiff_t) const { return value; } | |
722 | 781 |
723 private: | 782 private: |
724 T value; | 783 T value; |
725 size_t count; | 784 size_t count; |
726 }; | 785 }; |
792 template <typename T> | 851 template <typename T> |
793 class Maybe; | 852 class Maybe; |
794 | 853 |
795 namespace _ { // private | 854 namespace _ { // private |
796 | 855 |
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> | 856 template <typename T> |
807 class NullableValue { | 857 class NullableValue { |
808 // Class whose interface behaves much like T*, but actually contains an instance of T and a | 858 // Class whose interface behaves much like T*, but actually contains an instance of T and a |
809 // boolean flag indicating nullness. | 859 // boolean flag indicating nullness. |
810 | 860 |
825 : isSet(other.isSet) { | 875 : isSet(other.isSet) { |
826 if (isSet) { | 876 if (isSet) { |
827 ctor(value, other.value); | 877 ctor(value, other.value); |
828 } | 878 } |
829 } | 879 } |
830 inline ~NullableValue() noexcept(MSVC_NOEXCEPT_DTOR_WORKAROUND(T)) { | 880 inline ~NullableValue() |
881 #if _MSC_VER | |
882 // TODO(msvc): MSVC has a hard time with noexcept specifier expressions that are more complex | |
883 // than `true` or `false`. We had a workaround for VS2015, but VS2017 regressed. | |
884 noexcept(false) | |
885 #else | |
886 noexcept(noexcept(instance<T&>().~T())) | |
887 #endif | |
888 { | |
831 if (isSet) { | 889 if (isSet) { |
832 dtor(value); | 890 dtor(value); |
833 } | 891 } |
834 } | 892 } |
835 | 893 |
1001 Maybe(Maybe& other): ptr(other.ptr) {} | 1059 Maybe(Maybe& other): ptr(other.ptr) {} |
1002 | 1060 |
1003 template <typename U> | 1061 template <typename U> |
1004 Maybe(Maybe<U>&& other) noexcept(noexcept(T(instance<U&&>()))) { | 1062 Maybe(Maybe<U>&& other) noexcept(noexcept(T(instance<U&&>()))) { |
1005 KJ_IF_MAYBE(val, kj::mv(other)) { | 1063 KJ_IF_MAYBE(val, kj::mv(other)) { |
1006 ptr = *val; | 1064 ptr.emplace(kj::mv(*val)); |
1007 } | 1065 } |
1008 } | 1066 } |
1009 template <typename U> | 1067 template <typename U> |
1010 Maybe(const Maybe<U>& other) { | 1068 Maybe(const Maybe<U>& other) { |
1011 KJ_IF_MAYBE(val, other) { | 1069 KJ_IF_MAYBE(val, other) { |
1012 ptr = *val; | 1070 ptr.emplace(*val); |
1013 } | 1071 } |
1014 } | 1072 } |
1015 | 1073 |
1016 Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {} | 1074 Maybe(decltype(nullptr)) noexcept: ptr(nullptr) {} |
1017 | 1075 |