Skip to content

Commit

Permalink
Merge branch 'pull-request/#670-span-equality-operators' into develop…
Browse files Browse the repository at this point in the history
…ment
  • Loading branch information
jwellbelove committed Feb 19, 2023
2 parents f66a295 + 8491133 commit 80b3973
Show file tree
Hide file tree
Showing 4 changed files with 324 additions and 62 deletions.
112 changes: 78 additions & 34 deletions include/etl/span.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ SOFTWARE.

#include "platform.h"
#include "iterator.h"
#include "algorithm.h"
#include "circular_iterator.h"
#include "nullptr.h"
#include "hash.h"
Expand Down Expand Up @@ -345,23 +346,24 @@ namespace etl
return pbegin[i];
}

//*************************************************************************
/// Compare two spans for equality.
//*************************************************************************
template <typename Type2, size_t N2, etl::enable_if_t<etl::is_same<etl::remove_cv_t<Type2>, value_type>::value, bool> = true>
ETL_NODISCARD ETL_CONSTEXPR bool operator==(const etl::span<Type2, N2>& other) const ETL_NOEXCEPT
{
return ((pbegin == other.pbegin) && (Extent == other.size()));
}
////*************************************************************************
///// Compare two spans for equality.
////*************************************************************************
//template <typename Type2, size_t N2, typename etl::enable_if<etl::is_same<typename etl::remove_cv<Type2>::type, value_type>::value, bool>::type = true>
//ETL_NODISCARD ETL_CONSTEXPR bool operator==(const etl::span<Type2, N2>& other) const ETL_NOEXCEPT
//{
// return ((begin() == other.begin()) && (Extent == other.size())) ||
// etl::equal(begin(), end(), other.begin(), other.end());
//}

//*************************************************************************
/// Compare two spans for non-equality.
//*************************************************************************
template <typename Type2, size_t N2, etl::enable_if_t<etl::is_same<etl::remove_cv_t<Type2>, value_type>::value, bool> = true>
ETL_NODISCARD ETL_CONSTEXPR bool operator!=(const etl::span<Type2, N2>& other) const ETL_NOEXCEPT
{
return !(*this == other);
}
////*************************************************************************
///// Compare two spans for non-equality.
////*************************************************************************
//template <typename Type2, size_t N2, typename etl::enable_if<etl::is_same<typename etl::remove_cv<Type2>::type, value_type>::value, bool>::type = true>
//ETL_NODISCARD ETL_CONSTEXPR bool operator!=(const etl::span<Type2, N2>& other) const ETL_NOEXCEPT
//{
// return !(*this == other);
//}

//*************************************************************************
/// Obtains a span that is a view over the first COUNT elements of this span.
Expand Down Expand Up @@ -749,23 +751,25 @@ namespace etl
return pbegin[i];
}

//*************************************************************************
/// Compare two spans for equality.
//*************************************************************************
template <typename Type2, etl::enable_if_t<etl::is_same<etl::remove_cv_t<Type2>, value_type>::value, bool> = true>
ETL_NODISCARD ETL_CONSTEXPR bool operator==(const etl::span<Type2>& other) const ETL_NOEXCEPT
{
return ((pbegin == other.pbegin) && (pend == other.pend));
}
////*************************************************************************
///// Compare two spans for equality.
////*************************************************************************
//template <typename Type2, typename etl::enable_if<etl::is_same<typename etl::remove_cv<Type2>::type, value_type>::value, bool>::type = true>
//ETL_NODISCARD ETL_CONSTEXPR bool operator==(const etl::span<Type2>& other) const ETL_NOEXCEPT
//{
// return (empty() && other.empty()) ||
// ((begin() == other.begin()) && (end() == other.end())) ||
// etl::equal(begin(), end(), other.begin(), other.end());
//}

//*************************************************************************
/// Compare two spans for non-equality.
//*************************************************************************
template <typename Type2, etl::enable_if_t<etl::is_same<etl::remove_cv_t<Type2>, value_type>::value, bool> = true>
ETL_NODISCARD ETL_CONSTEXPR bool operator!=(const etl::span<Type2>& other) const ETL_NOEXCEPT
{
return !(*this == other);
}
////*************************************************************************
///// Compare two spans for non-equality.
////*************************************************************************
//template <typename Type2, typename etl::enable_if<etl::is_same<typename etl::remove_cv<Type2>::type, value_type>::value, bool>::type = true>
//ETL_NODISCARD ETL_CONSTEXPR bool operator!=(const etl::span<Type2>& other) const ETL_NOEXCEPT
//{
// return !(*this == other);
//}

//*************************************************************************
/// Obtains a span that is a view over the first COUNT elements of this span.
Expand Down Expand Up @@ -845,6 +849,46 @@ namespace etl
pointer pend;
};

//*************************************************************************
/// Compare two spans for equality.
//*************************************************************************
template <typename T1, size_t N1, typename T2, size_t N2>
ETL_NODISCARD
ETL_CONSTEXPR
typename etl::enable_if<etl::is_same<typename etl::remove_cv<T1>::type, typename etl::remove_cv<T2>::type>::value, bool>::type
operator ==(const etl::span<T1, N1>& lhs, const etl::span<T2, N2>& rhs) ETL_NOEXCEPT
{
return (lhs.begin() == rhs.begin()) && (lhs.size() == rhs.size());
}

//*************************************************************************
/// Compare two spans for inequality.
//*************************************************************************
template <typename T1, size_t N1, typename T2, size_t N2>
ETL_NODISCARD
ETL_CONSTEXPR
bool operator !=(const etl::span<T1, N1>& lhs, const etl::span<T2, N2>& rhs) ETL_NOEXCEPT
{
return !(lhs == rhs);
}

//*************************************************************************
/// Equality function.
/// Performs a comparision of the range values.
/// Returns <b>true</b> if one of the following are <b>true</b>
/// 1. Both spans are empty.
/// 2. They both point to the same range of data.
/// 3. The values in the two ranges are equal.
//*************************************************************************
template <typename T1, size_t N1, typename T2, size_t N2>
etl::enable_if_t<etl::is_same_v<etl::remove_cv_t<T1>, etl::remove_cv_t<T2>>, bool>
equal(const etl::span<T1, N1>& lhs, const etl::span<T2, N2>& rhs)
{
return (lhs.empty() && rhs.empty()) ||
((lhs.begin() == rhs.begin()) && (lhs.size() == rhs.size())) ||
etl::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}

//*************************************************************************
/// Template deduction guides.
//*************************************************************************
Expand All @@ -869,7 +913,7 @@ namespace etl
span(const etl::array<T, N>&)
-> span<const T, N>;

#if ETL_USING_STL
#if ETL_USING_STL && ETL_USING_CPP11
template <typename T, size_t N>
span(std::array<T, N>&)
->span<T, N>;
Expand All @@ -890,7 +934,7 @@ namespace etl
size_t operator()(const etl::span<T>& view) const
{
return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&view[0]),
reinterpret_cast<const uint8_t*>(&view[view.size()]));
reinterpret_cast<const uint8_t*>(&view[view.size()]));
}
};
#endif
Expand Down
153 changes: 139 additions & 14 deletions test/test_span_dynamic_extent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -973,29 +973,154 @@ namespace
//*************************************************************************
TEST(test_operator_equality)
{
etl::array data1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
etl::array data2{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

View view1{data1};
View view2{data1};
View view3{data2};
etl::array data1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 };
etl::array data4{ 0, 1, 2, 3, 5, 6, 7, 8, 9 };

int i;

View view1{ data1 };
View view2{ data1 };
View view3{ data2 };
View view4{ data3 };
View view5{ data4 };
View view6;
View view7;
View view8(&i, &i);

CHECK_TRUE(etl::equal(view1, view2));
CHECK_TRUE(etl::equal(view1, view3));
CHECK_FALSE(etl::equal(view1, view4));
CHECK_FALSE(etl::equal(view1, view5));
CHECK_TRUE(etl::equal(view6, view6));
CHECK_TRUE(etl::equal(view6, view7));
CHECK_TRUE(etl::equal(view6, view8));
CHECK_TRUE(etl::equal(view8, view8));

CHECK_TRUE(view1 == view2);
CHECK_FALSE(view1 == view3);
CHECK_FALSE(view1 == view4);
CHECK_FALSE(view1 == view5);
CHECK_TRUE(view6 == view6);
CHECK_TRUE(view6 == view7);
CHECK_FALSE(view6 == view8);
CHECK_TRUE(view8 == view8);
}

CHECK_TRUE((view1 == view2));
CHECK_FALSE((view1 == view3));
//*************************************************************************
TEST(test_operator_equality_one_is_const)
{
etl::array data1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 };
etl::array data4{ 0, 1, 2, 3, 5, 6, 7, 8, 9 };

int i;

View view1{ data1 };
CView view2{ data1 };
CView view3{ data2 };
CView view4{ data3 };
CView view5{ data4 };
View view6;
CView view7;
CView view8(&i, &i);

CHECK_TRUE(etl::equal(view1, view2));
CHECK_TRUE(etl::equal(view1, view3));
CHECK_FALSE(etl::equal(view1, view4));
CHECK_FALSE(etl::equal(view1, view5));
CHECK_TRUE(etl::equal(view6, view6));
CHECK_TRUE(etl::equal(view6, view7));
CHECK_TRUE(etl::equal(view6, view8));
CHECK_TRUE(etl::equal(view8, view8));

CHECK_TRUE(view1 == view2);
CHECK_FALSE(view1 == view3);
CHECK_FALSE(view1 == view4);
CHECK_FALSE(view1 == view5);
CHECK_TRUE(view6 == view6);
CHECK_TRUE(view6 == view7);
CHECK_FALSE(view6 == view8);
CHECK_TRUE(view8 == view8);
}

//*************************************************************************
TEST(test_operator_not_equal)
{
etl::array data1{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
etl::array data2{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 };
etl::array data4{ 0, 1, 2, 3, 5, 6, 7, 8, 9 };

int i;

View view1{ data1 };
View view2{ data1 };
View view3{ data2 };
View view4{ data3 };
View view5{ data4 };
View view6;
View view7;
View view8(&i, &i);

CHECK_TRUE(etl::equal(view1, view2));
CHECK_TRUE(etl::equal(view1, view3));
CHECK_FALSE(etl::equal(view1, view4));
CHECK_FALSE(etl::equal(view1, view5));
CHECK_TRUE(etl::equal(view6, view6));
CHECK_TRUE(etl::equal(view6, view7));
CHECK_TRUE(etl::equal(view6, view8));
CHECK_TRUE(etl::equal(view8, view8));

CHECK_FALSE(view1 != view2);
CHECK_TRUE(view1 != view3);
CHECK_TRUE(view1 != view4);
CHECK_TRUE(view1 != view5);
CHECK_FALSE(view6 != view6);
CHECK_FALSE(view6 != view7);
CHECK_TRUE(view6 != view8);
CHECK_FALSE(view8 != view8);
}

View view1{data1};
View view2{data1};
View view3{data2};

CHECK_FALSE((view1 != view2));
CHECK_TRUE((view1 != view3));
//*************************************************************************
TEST(test_operator_not_equal_one_is_const)
{
etl::array data1{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data2{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::array data3{ 0, 1, 2, 3, 4, 4, 6, 7, 8, 9 };
etl::array data4{ 0, 1, 2, 3, 5, 6, 7, 8, 9 };

int i;

View view1{ data1 };
CView view2{ data1 };
CView view3{ data2 };
CView view4{ data3 };
CView view5{ data4 };
View view6;
View view7;
View view8(&i, &i);

CHECK_TRUE(etl::equal(view1, view2));
CHECK_TRUE(etl::equal(view1, view3));
CHECK_FALSE(etl::equal(view1, view4));
CHECK_FALSE(etl::equal(view1, view5));
CHECK_TRUE(etl::equal(view6, view6));
CHECK_TRUE(etl::equal(view6, view7));
CHECK_TRUE(etl::equal(view6, view8));
CHECK_TRUE(etl::equal(view8, view8));

CHECK_FALSE(view1 != view1);
CHECK_FALSE(view1 != view2);
CHECK_TRUE(view1 != view3);
CHECK_TRUE(view1 != view4);
CHECK_TRUE(view1 != view5);
CHECK_FALSE(view6 != view6);
CHECK_FALSE(view6 != view7);
CHECK_TRUE(view6 != view8);
CHECK_FALSE(view8 != view8);
}

#include "etl/private/diagnostic_pop.h"
Expand Down
Loading

0 comments on commit 80b3973

Please sign in to comment.