diff --git a/include/array_view.h b/include/array_view.h index ecc3d1e..bce3691 100644 --- a/include/array_view.h +++ b/include/array_view.h @@ -1420,11 +1420,42 @@ public: } template , std::remove_cv_t>::value>> - _CONSTEXPR auto operator == (const basic_array_view & other) const -> decltype(this->m_pdata == other.m_pdata && this->m_bounds == other.m_bounds) _NOEXCEPT + _CONSTEXPR bool operator== (const basic_array_view & other) const _NOEXCEPT { - return m_pdata == other.m_pdata && m_bounds == other.m_bounds; + return m_bounds.size() == other.m_bounds.size() && + (m_pdata == other.m_pdata || std::equal(this->begin(), this->end(), other.begin())); } + template , std::remove_cv_t>::value>> + _CONSTEXPR bool operator!= (const basic_array_view & other) const _NOEXCEPT + { + return !(*this == other); + } + + template , std::remove_cv_t>::value>> + _CONSTEXPR bool operator< (const basic_array_view & other) const _NOEXCEPT + { + return std::lexicographical_compare(this->begin(), this->end(), other.begin(), other.end()); + } + + template , std::remove_cv_t>::value>> + _CONSTEXPR bool operator<= (const basic_array_view & other) const _NOEXCEPT + { + return !(other < *this); + } + + template , std::remove_cv_t>::value>> + _CONSTEXPR bool operator> (const basic_array_view & other) const _NOEXCEPT + { + return (other < *this); + } + + template , std::remove_cv_t>::value>> + _CONSTEXPR bool operator>= (const basic_array_view & other) const _NOEXCEPT + { + return !(*this < other); + } + public: template ::value @@ -1603,7 +1634,7 @@ public: { } - _CONSTEXPR array_view(nullptr_t, size_type size) : Base(nullptr, bounds_type{}) + _CONSTEXPR array_view(std::nullptr_t, size_type size) : Base(nullptr, bounds_type{}) { fail_fast_assert(size == 0); } @@ -1795,6 +1826,13 @@ public: { return { &this->operator[](origin), strided_bounds {extents, details::make_stride(Base::bounds())}}; } + + using Base::operator==; + using Base::operator!=; + using Base::operator<; + using Base::operator<=; + using Base::operator>; + using Base::operator>=; }; template diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4e057c2..dee4e28 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -11,8 +11,9 @@ include_directories( add_definitions(-DSAFER_CPP_TESTING) -if(MSVC14 OR MSVC12) - # has the support we need +if(MSVC14 OR MSVC12) # has the support we need + # remove unnecessary warnings about unchecked iterators + add_definitions(-D_SCL_SECURE_NO_WARNINGS) else() include(CheckCXXCompilerFlag) CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14) diff --git a/tests/array_view_tests.cpp b/tests/array_view_tests.cpp index a97bbe3..10c798e 100644 --- a/tests/array_view_tests.cpp +++ b/tests/array_view_tests.cpp @@ -630,15 +630,114 @@ SUITE(array_view_tests) TEST(ArrayViewComparison) { - int arr[10][2]; - auto av1 = as_array_view(arr); - array_view av2 = av1; + { + int arr[10][2]; + auto av1 = as_array_view(arr); + array_view av2 = av1; - CHECK(av1 == av2); + CHECK(av1 == av2); - array_view, 20> av3 = av1.as_array_view(dim<>(20)); - CHECK(av3 == av2 && av3 == av1); + array_view, 20> av3 = av1.as_array_view(dim<>(20)); + CHECK(av3 == av2 && av3 == av1); + } + { + auto av1 = nullptr; + auto av2 = nullptr; + CHECK(av1 == av2); + CHECK(!(av1 != av2)); + CHECK(!(av1 < av2)); + CHECK(av1 <= av2); + CHECK(!(av1 > av2)); + CHECK(av1 >= av2); + CHECK(av2 == av1); + CHECK(!(av2 != av1)); + CHECK(!(av2 < av1)); + CHECK(av2 <= av1); + CHECK(!(av2 > av1)); + CHECK(av2 >= av1); + } + + { + int arr[] = { 2, 1 }; // bigger + + array_view av1 = nullptr; + array_view av2 = arr; + + CHECK(av1 != av2); + CHECK(av2 != av1); + CHECK(!(av1 == av2)); + CHECK(!(av2 == av1)); + CHECK(av1 < av2); + CHECK(!(av2 < av1)); + CHECK(av1 <= av2); + CHECK(!(av2 <= av1)); + CHECK(av2 > av1); + CHECK(!(av1 > av2)); + CHECK(av2 >= av1); + CHECK(!(av1 >= av2)); + } + + { + int arr1[] = { 1, 2 }; + int arr2[] = { 1, 2 }; + array_view av1 = arr1; + array_view av2 = arr2; + + CHECK(av1 == av2); + CHECK(!(av1 != av2)); + CHECK(!(av1 < av2)); + CHECK(av1 <= av2); + CHECK(!(av1 > av2)); + CHECK(av1 >= av2); + CHECK(av2 == av1); + CHECK(!(av2 != av1)); + CHECK(!(av2 < av1)); + CHECK(av2 <= av1); + CHECK(!(av2 > av1)); + CHECK(av2 >= av1); + } + + { + int arr[] = { 1, 2, 3 }; + + array_view av1 = { &arr[0], 2 }; // shorter + array_view av2 = arr; // longer + + CHECK(av1 != av2); + CHECK(av2 != av1); + CHECK(!(av1 == av2)); + CHECK(!(av2 == av1)); + CHECK(av1 < av2); + CHECK(!(av2 < av1)); + CHECK(av1 <= av2); + CHECK(!(av2 <= av1)); + CHECK(av2 > av1); + CHECK(!(av1 > av2)); + CHECK(av2 >= av1); + CHECK(!(av1 >= av2)); + } + + { + int arr1[] = { 1, 2 }; // smaller + int arr2[] = { 2, 1 }; // bigger + + array_view av1 = arr1; + array_view av2 = arr2; + + CHECK(av1 != av2); + CHECK(av2 != av1); + CHECK(!(av1 == av2)); + CHECK(!(av2 == av1)); + CHECK(av1 < av2); + CHECK(!(av2 < av1)); + CHECK(av1 <= av2); + CHECK(!(av2 <= av1)); + CHECK(av2 > av1); + CHECK(!(av1 > av2)); + CHECK(av2 >= av1); + CHECK(!(av1 >= av2)); + } } }