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