From 9f9fad96207d7dbe3a53afa80d7b5847cd8a0e30 Mon Sep 17 00:00:00 2001 From: Neil MacIntosh Date: Thu, 27 Aug 2015 18:13:49 -0700 Subject: [PATCH] Implemented comparison operators on array_view. --- include/array_view.h | 42 +++++++++++++- tests/array_view_tests.cpp | 111 +++++++++++++++++++++++++++++++++++-- 2 files changed, 145 insertions(+), 8 deletions(-) diff --git a/include/array_view.h b/include/array_view.h index ecc3d1e..4692e43 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(), other.end())); } + 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 @@ -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/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)); + } } }