1 // 2 // Tests for 3 // template <typename T, typename U, typename P1, typename P2> 4 // bool operator<(bounded_ptr<T, P1> const& a, bounded_ptr<U, P2> const& b); 5 // 6 // template <typename T, typename U, typename P1, typename P2> 7 // bool operator<=(bounded_ptr<T, P1> const& a, bounded_ptr<U, P2> const& b); 8 // 9 // template <typename T, typename U, typename P1, typename P2> 10 // bool operator>(bounded_ptr<T, P1> const& a, bounded_ptr<U, P2> const& b); 11 // 12 // template <typename T, typename U, typename P1, typename P2> 13 // bool operator>=(bounded_ptr<T, P1> const& a, bounded_ptr<U, P2> const& b); 14 // 15 16 #include <libkern/c++/bounded_ptr.h> 17 #include <array> 18 #include <darwintest.h> 19 #include <darwintest_utils.h> 20 #include "test_utils.h" 21 22 #define _assert(...) T_ASSERT_TRUE((__VA_ARGS__), # __VA_ARGS__) 23 24 struct dummy_policy1 { 25 static constexpr void 26 trap(char const*) 27 { 28 } 29 }; 30 struct dummy_policy2 { 31 static constexpr void 32 trap(char const*) 33 { 34 } 35 }; 36 37 template <typename T, typename U> 38 static void 39 check_lt(T t, U u) 40 { 41 _assert(t < u); 42 _assert(t <= u); 43 _assert(!(t >= u)); 44 _assert(!(t > u)); 45 46 _assert(!(u < t)); 47 _assert(!(u <= t)); 48 _assert(u > t); 49 _assert(u >= t); 50 } 51 52 template <typename T, typename U> 53 static void 54 check_eq(T t, U u) 55 { 56 _assert(!(t < u)); 57 _assert(t <= u); 58 _assert(t >= u); 59 _assert(!(t > u)); 60 61 _assert(!(u < t)); 62 _assert(u <= t); 63 _assert(!(u > t)); 64 _assert(u >= t); 65 } 66 67 template <typename T, typename TQual> 68 static void 69 tests() 70 { 71 std::array<T, 5> array = {T{0}, T{1}, T{2}, T{3}, T{4}}; 72 73 // Pointers with the same bounds 74 { 75 test_bounded_ptr<TQual> const a(array.begin(), array.begin(), array.end()); 76 test_bounded_ptr<TQual> const b(array.begin(), array.begin(), array.end()); 77 check_eq(a, b); 78 } 79 { 80 test_bounded_ptr<TQual> const a(array.begin(), array.begin(), array.end()); 81 test_bounded_ptr<TQual> const b(array.begin() + 1, array.begin(), array.end()); 82 check_lt(a, b); 83 } 84 { 85 test_bounded_ptr<TQual> const a(array.begin(), array.begin(), array.end()); 86 test_bounded_ptr<TQual> const b(array.begin() + 2, array.begin(), array.end()); 87 check_lt(a, b); 88 } 89 { 90 test_bounded_ptr<TQual> const a(array.begin(), array.begin(), array.end()); 91 test_bounded_ptr<TQual> const b(array.end(), array.begin(), array.end()); 92 check_lt(a, b); 93 } 94 { 95 test_bounded_ptr<TQual> const a(array.end(), array.begin(), array.end()); 96 test_bounded_ptr<TQual> const b(array.end(), array.begin(), array.end()); 97 check_eq(a, b); 98 } 99 100 // Compare null pointers 101 { 102 test_bounded_ptr<TQual> const a; 103 test_bounded_ptr<TQual> const b(array.begin(), array.begin(), array.end()); 104 check_lt(a, b); 105 } 106 { 107 test_bounded_ptr<TQual> const a; 108 test_bounded_ptr<TQual> const b; 109 check_eq(a, b); 110 } 111 112 // Pointers with different bounds 113 { 114 // Overlapping bounds, equal 115 test_bounded_ptr<TQual> const a(array.begin(), array.begin() + 2, array.end()); 116 test_bounded_ptr<TQual> const b(array.begin(), array.begin(), array.end()); 117 check_eq(a, b); 118 } 119 { 120 // Overlapping bounds, not equal 121 test_bounded_ptr<TQual> const a(array.begin(), array.begin() + 2, array.end()); 122 test_bounded_ptr<TQual> const b(array.begin() + 2, array.begin(), array.end()); 123 check_lt(a, b); 124 } 125 { 126 // Non-overlapping bounds, equal 127 test_bounded_ptr<TQual> const a(array.begin(), array.begin(), array.begin() + 1); 128 test_bounded_ptr<TQual> const b(array.begin(), array.begin() + 2, array.end()); 129 check_eq(a, b); 130 } 131 { 132 // Non-overlapping bounds, not equal 133 test_bounded_ptr<TQual> const a(array.begin(), array.begin(), array.begin() + 1); 134 test_bounded_ptr<TQual> const b(array.begin() + 3, array.begin() + 2, array.end()); 135 check_lt(a, b); 136 } 137 138 // Test with different policies 139 { 140 libkern::bounded_ptr<TQual, dummy_policy1> const a(array.begin(), array.begin(), array.end()); 141 libkern::bounded_ptr<TQual, dummy_policy2> const b(array.begin(), array.begin(), array.end()); 142 check_eq(a, b); 143 } 144 } 145 146 struct Base { int i; }; 147 struct Derived : Base { }; 148 149 template <typename Related> 150 static void 151 tests_convert() 152 { 153 std::array<Derived, 5> array = {Derived{0}, Derived{1}, Derived{2}, Derived{3}, Derived{4}}; 154 test_bounded_ptr<Derived> const a(array.begin(), array.begin(), array.end() - 1); 155 test_bounded_ptr<Related> const b(array.begin(), array.begin(), array.end() - 1); 156 check_eq(a, b); 157 } 158 159 T_DECL(compare_order, "bounded_ptr.compare.order") { 160 tests<Derived, Derived>(); 161 tests<Derived, Derived const>(); 162 tests<Derived, Derived volatile>(); 163 tests<Derived, Derived const volatile>(); 164 tests_convert<Base>(); 165 tests_convert<Base const>(); 166 tests_convert<Base volatile>(); 167 tests_convert<Base const volatile>(); 168 } 169