1 // 2 // Tests for 3 // template <typename T, typename U, typename P> 4 // bool operator<(T* a, bounded_ptr<U, P> const& b); 5 // 6 // template <typename T, typename U, typename P> 7 // bool operator<(bounded_ptr<T, P> const& a, U* b); 8 // 9 // template <typename T, typename U, typename P> 10 // bool operator<=(T* a, bounded_ptr<U, P> const& b); 11 // 12 // template <typename T, typename U, typename P> 13 // bool operator<=(bounded_ptr<T, P> const& a, U* b); 14 // 15 // template <typename T, typename U, typename P> 16 // bool operator>(T* a, bounded_ptr<U, P> const& b); 17 // 18 // template <typename T, typename U, typename P> 19 // bool operator>(bounded_ptr<T, P> const& a, U* b); 20 // 21 // template <typename T, typename U, typename P> 22 // bool operator>=(T* a, bounded_ptr<U, P> const& b); 23 // 24 // template <typename T, typename U, typename P> 25 // bool operator>=(bounded_ptr<T, P> const& a, U* b); 26 // 27 28 #include <libkern/c++/bounded_ptr.h> 29 #include <array> 30 #include <darwintest.h> 31 #include <darwintest_utils.h> 32 #include "test_utils.h" 33 34 #define _assert(...) T_ASSERT_TRUE((__VA_ARGS__), # __VA_ARGS__) 35 36 template <typename T, typename U> 37 static void 38 check_lt(T t, U u) 39 { 40 _assert(t < u); 41 _assert(t <= u); 42 _assert(!(t >= u)); 43 _assert(!(t > u)); 44 45 _assert(!(u < t)); 46 _assert(!(u <= t)); 47 _assert(u > t); 48 _assert(u >= t); 49 } 50 51 template <typename T, typename U> 52 static void 53 check_eq(T t, U u) 54 { 55 _assert(!(t < u)); 56 _assert(t <= u); 57 _assert(t >= u); 58 _assert(!(t > u)); 59 60 _assert(!(u < t)); 61 _assert(u <= t); 62 _assert(!(u > t)); 63 _assert(u >= t); 64 } 65 66 template <typename T, typename TQual> 67 static void 68 tests() 69 { 70 std::array<T, 5> array = {T{0}, T{1}, T{2}, T{3}, T{4}}; 71 72 // Compare pointers within the bounds 73 { 74 // T{0} T{1} T{2} T{3} T{4} <one-past-last> 75 // ^ ^ 76 // | | 77 // begin,a,b end 78 test_bounded_ptr<TQual> const a(array.begin(), array.begin(), array.end()); 79 TQual* b = array.begin(); 80 check_eq(a, b); 81 } 82 { 83 // T{0} T{1} T{2} T{3} T{4} <one-past-last> 84 // ^ ^ ^ 85 // | | | 86 // begin a,b end 87 test_bounded_ptr<TQual> const a(array.begin() + 1, array.begin(), array.end()); 88 TQual* b = array.begin() + 1; 89 check_eq(a, b); 90 } 91 { 92 // T{0} T{1} T{2} T{3} T{4} <one-past-last> 93 // ^ ^ ^ 94 // | | | 95 // begin,a b end 96 test_bounded_ptr<TQual> const a(array.begin(), array.begin(), array.end()); 97 TQual* b = array.begin() + 2; 98 check_lt(a, b); 99 } 100 { 101 // T{0} T{1} T{2} T{3} T{4} <one-past-last> 102 // ^ ^ 103 // | | 104 // begin end,a,b 105 test_bounded_ptr<TQual> const a(array.end(), array.begin(), array.end()); 106 TQual* b = array.end(); 107 check_eq(a, b); 108 } 109 { 110 // T{0} T{1} T{2} T{3} T{4} <one-past-last> 111 // ^ ^ ^ ^ 112 // | | | | 113 // begin a end b 114 test_bounded_ptr<TQual> const a(array.begin() + 2, array.begin(), array.begin() + 3); 115 TQual* b = array.begin() + 4; 116 check_lt(a, b); 117 } 118 119 // Check when the bounded_ptr is outside of its bounds 120 { 121 // T{0} T{1} T{2} T{3} T{4} <one-past-last> 122 // ^ ^ ^ 123 // | | | 124 // a,b begin end 125 test_bounded_ptr<TQual> const a(array.begin(), array.begin() + 2, array.end()); 126 TQual* b = array.begin(); 127 check_eq(a, b); 128 } 129 { 130 // T{0} T{1} T{2} T{3} T{4} <one-past-last> 131 // ^ ^ ^ 132 // | | | 133 // begin end a,b 134 test_bounded_ptr<TQual> const a(array.end() - 1, array.begin(), array.end() - 2); 135 TQual* b = array.end() - 1; 136 check_eq(a, b); 137 } 138 { 139 // T{0} T{1} T{2} T{3} T{4} <one-past-last> 140 // ^ ^ ^ 141 // | | | 142 // begin end a,b 143 test_bounded_ptr<TQual> const a(array.end(), array.begin(), array.end() - 1); 144 TQual* b = array.end(); 145 check_eq(a, b); 146 } 147 { 148 // T{0} T{1} T{2} T{3} T{4} <one-past-last> 149 // ^ ^ ^ ^ 150 // | | | | 151 // begin end a b 152 test_bounded_ptr<TQual> const a(array.end() - 1, array.begin(), array.end() - 2); 153 TQual* b = array.end(); 154 check_lt(a, b); 155 } 156 157 // Test comparing against a null pointer 158 { 159 test_bounded_ptr<TQual> a = nullptr; 160 TQual* b = nullptr; 161 check_eq(a, b); 162 } 163 { 164 test_bounded_ptr<TQual> a(array.end() - 1, array.begin(), array.end() - 2); 165 TQual* b = nullptr; 166 check_lt(b, a); 167 } 168 { 169 test_bounded_ptr<TQual> a = nullptr; 170 TQual* b = array.begin(); 171 check_lt(a, b); 172 } 173 } 174 175 struct Base { int i; }; 176 struct Derived : Base { }; 177 178 template <typename Related> 179 static void 180 tests_convert() 181 { 182 std::array<Derived, 5> array = {Derived{0}, Derived{1}, Derived{2}, Derived{3}, Derived{4}}; 183 184 { 185 test_bounded_ptr<Derived> const a(array.begin() + 1, array.begin(), array.end() - 1); 186 Related* b = array.begin(); 187 check_lt(b, a); 188 } 189 { 190 test_bounded_ptr<Related> const a(array.begin(), array.begin(), array.end() - 1); 191 Derived* b = array.begin() + 1; 192 check_lt(a, b); 193 } 194 195 // Test comparisons against cv-void* 196 { 197 test_bounded_ptr<Related> const a(array.begin(), array.begin(), array.end() - 1); 198 void* b = array.begin() + 1; 199 check_lt(a, b); 200 } 201 } 202 203 T_DECL(compare_order_raw, "bounded_ptr.compare.order.raw") { 204 tests<Derived, Derived>(); 205 tests<Derived, Derived const>(); 206 tests<Derived, Derived volatile>(); 207 tests<Derived, Derived const volatile>(); 208 tests_convert<Base>(); 209 tests_convert<Base const>(); 210 tests_convert<Base volatile>(); 211 tests_convert<Base const volatile>(); 212 } 213