// // Tests for // template // bool operator<(T* a, bounded_ptr const& b); // // template // bool operator<(bounded_ptr const& a, U* b); // // template // bool operator<=(T* a, bounded_ptr const& b); // // template // bool operator<=(bounded_ptr const& a, U* b); // // template // bool operator>(T* a, bounded_ptr const& b); // // template // bool operator>(bounded_ptr const& a, U* b); // // template // bool operator>=(T* a, bounded_ptr const& b); // // template // bool operator>=(bounded_ptr const& a, U* b); // #include #include #include #include #include "test_utils.h" #define _assert(...) T_ASSERT_TRUE((__VA_ARGS__), # __VA_ARGS__) template static void check_lt(T t, U u) { _assert(t < u); _assert(t <= u); _assert(!(t >= u)); _assert(!(t > u)); _assert(!(u < t)); _assert(!(u <= t)); _assert(u > t); _assert(u >= t); } template static void check_eq(T t, U u) { _assert(!(t < u)); _assert(t <= u); _assert(t >= u); _assert(!(t > u)); _assert(!(u < t)); _assert(u <= t); _assert(!(u > t)); _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_lt(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_lt(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_lt(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_lt(b, a); } { test_bounded_ptr a = nullptr; TQual* b = array.begin(); check_lt(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() + 1, array.begin(), array.end() - 1); Related* b = array.begin(); check_lt(b, a); } { test_bounded_ptr const a(array.begin(), array.begin(), array.end() - 1); Derived* b = array.begin() + 1; check_lt(a, b); } // Test comparisons against cv-void* { test_bounded_ptr const a(array.begin(), array.begin(), array.end() - 1); void* b = array.begin() + 1; check_lt(a, b); } } T_DECL(compare_order_raw, "bounded_ptr.compare.order.raw", T_META_TAG_VM_PREFERRED) { tests(); tests(); tests(); tests(); tests_convert(); tests_convert(); tests_convert(); tests_convert(); }