Implemented comparison operators on array_view.

This commit is contained in:
Neil MacIntosh 2015-08-27 18:13:49 -07:00
parent 3c9dc3b824
commit 9f9fad9620
2 changed files with 145 additions and 8 deletions

View File

@ -1420,11 +1420,42 @@ public:
} }
template <typename OtherValueType, typename OtherBoundsType, typename Dummy = std::enable_if_t<std::is_same<std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>> template <typename OtherValueType, typename OtherBoundsType, typename Dummy = std::enable_if_t<std::is_same<std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
_CONSTEXPR auto operator == (const basic_array_view<OtherValueType, OtherBoundsType> & other) const -> decltype(this->m_pdata == other.m_pdata && this->m_bounds == other.m_bounds) _NOEXCEPT _CONSTEXPR bool operator== (const basic_array_view<OtherValueType, OtherBoundsType> & 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 <typename OtherValueType, typename OtherBoundsType, typename Dummy = std::enable_if_t<std::is_same<std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
_CONSTEXPR bool operator!= (const basic_array_view<OtherValueType, OtherBoundsType> & other) const _NOEXCEPT
{
return !(*this == other);
}
template <typename OtherValueType, typename OtherBoundsType, typename Dummy = std::enable_if_t<std::is_same<std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
_CONSTEXPR bool operator< (const basic_array_view<OtherValueType, OtherBoundsType> & other) const _NOEXCEPT
{
return std::lexicographical_compare(this->begin(), this->end(), other.begin(), other.end());
}
template <typename OtherValueType, typename OtherBoundsType, typename Dummy = std::enable_if_t<std::is_same<std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
_CONSTEXPR bool operator<= (const basic_array_view<OtherValueType, OtherBoundsType> & other) const _NOEXCEPT
{
return !(other < *this);
}
template <typename OtherValueType, typename OtherBoundsType, typename Dummy = std::enable_if_t<std::is_same<std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
_CONSTEXPR bool operator> (const basic_array_view<OtherValueType, OtherBoundsType> & other) const _NOEXCEPT
{
return (other < *this);
}
template <typename OtherValueType, typename OtherBoundsType, typename Dummy = std::enable_if_t<std::is_same<std::remove_cv_t<value_type>, std::remove_cv_t<OtherValueType>>::value>>
_CONSTEXPR bool operator>= (const basic_array_view<OtherValueType, OtherBoundsType> & other) const _NOEXCEPT
{
return !(*this < other);
}
public: public:
template <typename OtherValueType, typename OtherBounds, template <typename OtherValueType, typename OtherBounds,
typename Dummy = std::enable_if_t<std::is_convertible<OtherValueType(*)[], value_type(*)[]>::value typename Dummy = std::enable_if_t<std::is_convertible<OtherValueType(*)[], value_type(*)[]>::value
@ -1795,6 +1826,13 @@ public:
{ {
return { &this->operator[](origin), strided_bounds<rank, size_type> {extents, details::make_stride(Base::bounds())}}; return { &this->operator[](origin), strided_bounds<rank, size_type> {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 <typename T, size_t... Dimensions> template <typename T, size_t... Dimensions>

View File

@ -630,15 +630,114 @@ SUITE(array_view_tests)
TEST(ArrayViewComparison) TEST(ArrayViewComparison)
{ {
int arr[10][2]; {
auto av1 = as_array_view(arr); int arr[10][2];
array_view<const int, dynamic_range, 2> av2 = av1; auto av1 = as_array_view(arr);
array_view<const int, dynamic_range, 2> av2 = av1;
CHECK(av1 == av2); CHECK(av1 == av2);
array_view<array_view_options<int, char>, 20> av3 = av1.as_array_view(dim<>(20)); array_view<array_view_options<int, char>, 20> av3 = av1.as_array_view(dim<>(20));
CHECK(av3 == av2 && av3 == av1); 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<int> av1 = nullptr;
array_view<int> 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<int> av1 = arr1;
array_view<int> 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<int> av1 = { &arr[0], 2 }; // shorter
array_view<int> 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<int> av1 = arr1;
array_view<int> 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));
}
} }
} }