comparison osx/include/kj/common.h @ 147:45360b968bf4

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 41e769c91eca
children
comparison
equal deleted inserted replaced
146:206f0eb279b8 147:45360b968bf4
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