// // Tests for // template // bool operator==(bounded_ptr const& a, U* b); // // template // bool operator==(U* a, bounded_ptr const& b); // // template // bool operator!=(bounded_ptr const& a, U* b); // // template // bool operator!=(U* a, bounded_ptr const& b); // #include #include #include #include #include "test_utils.h" #define _assert(...) T_ASSERT_TRUE((__VA_ARGS__), # __VA_ARGS__) template static void check_eq(T t, U u) { _assert(t == u); _assert(u == t); _assert(!(t != u)); _assert(!(u != t)); } template static void check_ne(T t, U u) { _assert(!(t == u)); _assert(!(u == t)); _assert(t != u); _assert(u != t); } template static void tests() { std::array array = {T{0}, T{1}, T{2}, T{3}, T{4}}; // Compare pointers within the bounds { // T{0} T{1} T{2} T{3} T{4} // ^ ^ // | | // begin,a,b end test_bounded_ptr const a(array.begin(), array.begin(), array.end()); TQual* b = array.begin(); check_eq(a, b); } { // T{0} T{1} T{2} T{3} T{4} // ^ ^ ^ // | | | // begin a,b end test_bounded_ptr const a(array.begin() + 1, array.begin(), array.end()); TQual* b = array.begin() + 1; check_eq(a, b); } { // T{0} T{1} T{2} T{3} T{4} // ^ ^ ^ // | | | // begin,a b end test_bounded_ptr const a(array.begin(), array.begin(), array.end()); TQual* b = array.begin() + 2; check_ne(a, b); } { // T{0} T{1} T{2} T{3} T{4} // ^ ^ // | | // begin end,a,b test_bounded_ptr const a(array.end(), array.begin(), array.end()); TQual* b = array.end(); check_eq(a, b); } { // T{0} T{1} T{2} T{3} T{4} // ^ ^ ^ ^ // | | | | // begin a end b test_bounded_ptr const a(array.begin() + 2, array.begin(), array.begin() + 3); TQual* b = array.begin() + 4; check_ne(a, b); } // Check when the bounded_ptr is outside of its bounds { // T{0} T{1} T{2} T{3} T{4} // ^ ^ ^ // | | | // a,b begin end test_bounded_ptr const a(array.begin(), array.begin() + 2, array.end()); TQual* b = array.begin(); check_eq(a, b); } { // T{0} T{1} T{2} T{3} T{4} // ^ ^ ^ // | | | // begin end a,b test_bounded_ptr const a(array.end() - 1, array.begin(), array.end() - 2); TQual* b = array.end() - 1; check_eq(a, b); } { // T{0} T{1} T{2} T{3} T{4} // ^ ^ ^ // | | | // begin end a,b test_bounded_ptr const a(array.end(), array.begin(), array.end() - 1); TQual* b = array.end(); check_eq(a, b); } { // T{0} T{1} T{2} T{3} T{4} // ^ ^ ^ ^ // | | | | // begin end a b test_bounded_ptr const a(array.end() - 1, array.begin(), array.end() - 2); TQual* b = array.end(); check_ne(a, b); } // Test comparing against a null pointer { test_bounded_ptr a = nullptr; TQual* b = nullptr; check_eq(a, b); } { test_bounded_ptr a(array.end() - 1, array.begin(), array.end() - 2); TQual* b = nullptr; check_ne(a, b); } { test_bounded_ptr a = nullptr; TQual* b = array.begin(); check_ne(a, b); } } struct Base { int i; }; struct Derived : Base { }; template static void tests_convert() { std::array array = {Derived{0}, Derived{1}, Derived{2}, Derived{3}, Derived{4}}; { test_bounded_ptr const a(array.begin(), array.begin(), array.end() - 1); Related* b = array.begin(); check_eq(a, b); } { test_bounded_ptr const a(array.begin(), array.begin(), array.end() - 1); Derived* b = array.begin(); check_eq(a, b); } // Test comparisons against cv-void* { test_bounded_ptr const a(array.begin(), array.begin(), array.end() - 1); void* b = array.begin(); check_eq(a, b); } } T_DECL(compare_equal_raw, "bounded_ptr.compare.equal.raw", T_META_TAG_VM_PREFERRED) { tests(); tests(); tests(); tests(); tests_convert(); tests_convert(); tests_convert(); tests_convert(); }