// // Tests for // template // bool operator==(bounded_ptr const& a, bounded_ptr const& b); // // template // bool operator!=(bounded_ptr const& a, bounded_ptr const& b); // #include #include #include #include #include "test_utils.h" #define _assert(...) T_ASSERT_TRUE((__VA_ARGS__), # __VA_ARGS__) struct dummy_policy1 { static constexpr void trap(char const*) { } }; struct dummy_policy2 { static constexpr void trap(char const*) { } }; 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}}; // Pointers with the same bounds { test_bounded_ptr const a(array.begin(), array.begin(), array.end()); test_bounded_ptr const b(array.begin(), array.begin(), array.end()); check_eq(a, b); } { test_bounded_ptr const a(array.begin(), array.begin(), array.end()); test_bounded_ptr const b(array.begin() + 1, array.begin(), array.end()); check_ne(a, b); } { test_bounded_ptr const a(array.begin(), array.begin(), array.end()); test_bounded_ptr const b(array.begin() + 2, array.begin(), array.end()); check_ne(a, b); } { test_bounded_ptr const a(array.begin(), array.begin(), array.end()); test_bounded_ptr const b(array.end(), array.begin(), array.end()); check_ne(a, b); } { test_bounded_ptr const a(array.end(), array.begin(), array.end()); test_bounded_ptr const b(array.end(), array.begin(), array.end()); check_eq(a, b); } // Compare null pointers { test_bounded_ptr const a; test_bounded_ptr const b(array.begin(), array.begin(), array.end()); check_ne(a, b); } { test_bounded_ptr const a; test_bounded_ptr const b; check_eq(a, b); } // Pointers with different bounds { // Overlapping bounds, equal test_bounded_ptr const a(array.begin(), array.begin() + 2, array.end()); test_bounded_ptr const b(array.begin(), array.begin(), array.end()); check_eq(a, b); } { // Overlapping bounds, not equal test_bounded_ptr const a(array.begin(), array.begin() + 2, array.end()); test_bounded_ptr const b(array.begin() + 2, array.begin(), array.end()); check_ne(a, b); } { // Non-overlapping bounds, equal test_bounded_ptr const a(array.begin(), array.begin(), array.begin() + 1); test_bounded_ptr const b(array.begin(), array.begin() + 2, array.end()); check_eq(a, b); } { // Non-overlapping bounds, not equal test_bounded_ptr const a(array.begin(), array.begin(), array.begin() + 1); test_bounded_ptr const b(array.begin() + 3, array.begin() + 2, array.end()); check_ne(a, b); } // Test with different policies { libkern::bounded_ptr const a(array.begin(), array.begin(), array.end()); libkern::bounded_ptr const b(array.begin(), array.begin(), array.end()); check_eq(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); test_bounded_ptr const b(array.begin(), array.begin(), array.end() - 1); check_eq(a, b); } T_DECL(compare_equal, "bounded_ptr.compare.equal", T_META_TAG_VM_PREFERRED) { tests(); tests(); tests(); tests(); tests_convert(); tests_convert(); tests_convert(); tests_convert(); }