Merge pull request #4 from neilmacintosh/dev/neilmac/operators

Adding comparison operators to array_view.
This commit is contained in:
Neil MacIntosh 2015-08-28 12:59:16 -07:00
commit a2a6a1fc52
3 changed files with 149 additions and 11 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>>
_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()));
}
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:
template <typename OtherValueType, typename OtherBounds,
typename Dummy = std::enable_if_t<std::is_convertible<OtherValueType(*)[], value_type(*)[]>::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<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>

View File

@ -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)

View File

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