Implemented first, last, subspan.

This commit is contained in:
Neil MacIntosh 2016-03-18 16:49:29 -07:00
parent 3d4c34966a
commit c8a412f028
2 changed files with 45 additions and 94 deletions

View File

@ -234,19 +234,50 @@ public:
~span() noexcept = default; ~span() noexcept = default;
constexpr span& operator=(const span& other) noexcept = default; constexpr span& operator=(const span& other) noexcept = default;
constexpr span& operator=(span&& other) noexcept = default; constexpr span& operator=(span&& other) noexcept = default;
#if 0 // TODO
// [span.sub], span subviews // [span.sub], span subviews
template <ptrdiff_t Count> template <ptrdiff_t Count>
constexpr span<element_type, Count> first() const; constexpr span<element_type, Count> first() const
{
Expects(Count >= 0 && Count <= size());
return { data(), Count };
}
template <ptrdiff_t Count> template <ptrdiff_t Count>
constexpr span<element_type, Count> last() const; constexpr span<element_type, Count> last() const
{
Expects(Count >= 0 && Count <= size());
return{ Count == 0 ? data() : data() + (size() - Count), Count };
}
template <ptrdiff_t Offset, ptrdiff_t Count = dynamic_extent> template <ptrdiff_t Offset, ptrdiff_t Count = dynamic_extent>
constexpr span<element_type, Count> subspan() const; constexpr span<element_type, Count> subspan() const
constexpr span<element_type, dynamic_extent> first(index_type count) const; {
constexpr span<element_type, dynamic_extent> last(index_type count) const; Expects((Offset == 0 || Offset > 0 && Offset <= size()) &&
constexpr span<element_type, dynamic_extent> subspan(index_type offset, index_type count = dynamic_extent) const; (Count == dynamic_extent || Count >= 0 && Offset + Count <= size()));
#endif return { data() + Offset, Count == dynamic_extent ? size() - Offset : Count };
}
constexpr span<element_type, dynamic_extent> first(index_type count) const
{
Expects(count >= 0 && count <= size());
return { data(), count };
}
constexpr span<element_type, dynamic_extent> last(index_type count) const
{
Expects(count >= 0 && count <= size());
return { count == 0 ? data() : data() + (size() - count), count };
}
constexpr span<element_type, dynamic_extent> subspan(index_type offset,
index_type count = dynamic_extent) const
{
Expects((offset == 0 || offset > 0 && offset <= size()) &&
(count == dynamic_extent || count >= 0 && offset + count <= size()));
return { data() + offset, count == dynamic_extent ? size() - offset : count };
}
// [span.obs], span observers // [span.obs], span observers
constexpr index_type length() const noexcept { return size(); } constexpr index_type length() const noexcept { return size(); }
constexpr index_type size() const noexcept { return storage_.size(); } constexpr index_type size() const noexcept { return storage_.size(); }

View File

@ -588,7 +588,6 @@ SUITE(span_tests)
s1 = get_temp_span(); s1 = get_temp_span();
CHECK(s1.length() == 2 && s1.data() == &arr[1]); CHECK(s1.length() == 2 && s1.data() == &arr[1]);
} }
#if 0
TEST(first) TEST(first)
{ {
@ -596,21 +595,18 @@ SUITE(span_tests)
{ {
span<int, 5> av = arr; span<int, 5> av = arr;
CHECK((av.first<2>().bounds() == static_bounds<2>()));
CHECK(av.first<2>().length() == 2); CHECK(av.first<2>().length() == 2);
CHECK(av.first(2).length() == 2); CHECK(av.first(2).length() == 2);
} }
{ {
span<int, 5> av = arr; span<int, 5> av = arr;
CHECK((av.first<0>().bounds() == static_bounds<0>()));
CHECK(av.first<0>().length() == 0); CHECK(av.first<0>().length() == 0);
CHECK(av.first(0).length() == 0); CHECK(av.first(0).length() == 0);
} }
{ {
span<int, 5> av = arr; span<int, 5> av = arr;
CHECK((av.first<5>().bounds() == static_bounds<5>()));
CHECK(av.first<5>().length() == 5); CHECK(av.first<5>().length() == 5);
CHECK(av.first(5).length() == 5); CHECK(av.first(5).length() == 5);
} }
@ -618,7 +614,6 @@ SUITE(span_tests)
{ {
span<int, 5> av = arr; span<int, 5> av = arr;
#ifdef CONFIRM_COMPILATION_ERRORS #ifdef CONFIRM_COMPILATION_ERRORS
CHECK(av.first<6>().bounds() == static_bounds<6>());
CHECK(av.first<6>().length() == 6); CHECK(av.first<6>().length() == 6);
CHECK(av.first<-1>().length() == -1); CHECK(av.first<-1>().length() == -1);
#endif #endif
@ -626,8 +621,7 @@ SUITE(span_tests)
} }
{ {
span<int, dynamic_range> av; span<int> av;
CHECK((av.first<0>().bounds() == static_bounds<0>()));
CHECK(av.first<0>().length() == 0); CHECK(av.first<0>().length() == 0);
CHECK(av.first(0).length() == 0); CHECK(av.first(0).length() == 0);
} }
@ -639,21 +633,18 @@ SUITE(span_tests)
{ {
span<int, 5> av = arr; span<int, 5> av = arr;
CHECK((av.last<2>().bounds() == static_bounds<2>()));
CHECK(av.last<2>().length() == 2); CHECK(av.last<2>().length() == 2);
CHECK(av.last(2).length() == 2); CHECK(av.last(2).length() == 2);
} }
{ {
span<int, 5> av = arr; span<int, 5> av = arr;
CHECK((av.last<0>().bounds() == static_bounds<0>()));
CHECK(av.last<0>().length() == 0); CHECK(av.last<0>().length() == 0);
CHECK(av.last(0).length() == 0); CHECK(av.last(0).length() == 0);
} }
{ {
span<int, 5> av = arr; span<int, 5> av = arr;
CHECK((av.last<5>().bounds() == static_bounds<5>()));
CHECK(av.last<5>().length() == 5); CHECK(av.last<5>().length() == 5);
CHECK(av.last(5).length() == 5); CHECK(av.last(5).length() == 5);
} }
@ -661,15 +652,13 @@ SUITE(span_tests)
{ {
span<int, 5> av = arr; span<int, 5> av = arr;
#ifdef CONFIRM_COMPILATION_ERRORS #ifdef CONFIRM_COMPILATION_ERRORS
CHECK((av.last<6>().bounds() == static_bounds<6>()));
CHECK(av.last<6>().length() == 6); CHECK(av.last<6>().length() == 6);
#endif #endif
CHECK_THROW(av.last(6).length(), fail_fast); CHECK_THROW(av.last(6).length(), fail_fast);
} }
{ {
span<int, dynamic_range> av; span<int> av;
CHECK((av.last<0>().bounds() == static_bounds<0>()));
CHECK(av.last<0>().length() == 0); CHECK(av.last<0>().length() == 0);
CHECK(av.last(0).length() == 0); CHECK(av.last(0).length() == 0);
} }
@ -681,7 +670,6 @@ SUITE(span_tests)
{ {
span<int, 5> av = arr; span<int, 5> av = arr;
CHECK((av.subspan<2, 2>().bounds() == static_bounds<2>()));
CHECK((av.subspan<2, 2>().length() == 2)); CHECK((av.subspan<2, 2>().length() == 2));
CHECK(av.subspan(2, 2).length() == 2); CHECK(av.subspan(2, 2).length() == 2);
CHECK(av.subspan(2, 3).length() == 3); CHECK(av.subspan(2, 3).length() == 3);
@ -689,14 +677,12 @@ SUITE(span_tests)
{ {
span<int, 5> av = arr; span<int, 5> av = arr;
CHECK((av.subspan<0, 0>().bounds() == static_bounds<0>()));
CHECK((av.subspan<0, 0>().length() == 0)); CHECK((av.subspan<0, 0>().length() == 0));
CHECK(av.subspan(0, 0).length() == 0); CHECK(av.subspan(0, 0).length() == 0);
} }
{ {
span<int, 5> av = arr; span<int, 5> av = arr;
CHECK((av.subspan<0, 5>().bounds() == static_bounds<5>()));
CHECK((av.subspan<0, 5>().length() == 5)); CHECK((av.subspan<0, 5>().length() == 5));
CHECK(av.subspan(0, 5).length() == 5); CHECK(av.subspan(0, 5).length() == 5);
CHECK_THROW(av.subspan(0, 6).length(), fail_fast); CHECK_THROW(av.subspan(0, 6).length(), fail_fast);
@ -705,15 +691,14 @@ SUITE(span_tests)
{ {
span<int, 5> av = arr; span<int, 5> av = arr;
CHECK((av.subspan<5, 0>().bounds() == static_bounds<0>())); CHECK((av.subspan<4, 0>().length() == 0));
CHECK((av.subspan<5, 0>().length() == 0)); CHECK(av.subspan(4, 0).length() == 0);
CHECK(av.subspan(5, 0).length() == 0); CHECK(av.subspan(5, 0).length() == 0);
CHECK_THROW(av.subspan(6, 0).length(), fail_fast); CHECK_THROW(av.subspan(6, 0).length(), fail_fast);
} }
{ {
span<int, dynamic_range> av; span<int> av;
CHECK((av.subspan<0, 0>().bounds() == static_bounds<0>()));
CHECK((av.subspan<0, 0>().length() == 0)); CHECK((av.subspan<0, 0>().length() == 0));
CHECK(av.subspan(0, 0).length() == 0); CHECK(av.subspan(0, 0).length() == 0);
CHECK_THROW((av.subspan<1, 0>().length()), fail_fast); CHECK_THROW((av.subspan<1, 0>().length()), fail_fast);
@ -747,72 +732,7 @@ SUITE(span_tests)
for (int i = 0; i < 4; ++i) CHECK(av2[i] == i + 2); for (int i = 0; i < 4; ++i) CHECK(av2[i] == i + 2);
} }
} }
#if 0
TEST(rank)
{
int arr[2] = {1, 2};
{
span<int> s;
CHECK(s.rank() == 1);
}
{
span<int, 2> s = arr;
CHECK(s.rank() == 1);
}
int arr2d[1][1] = {};
{
span<int, 1, 1> s = arr2d;
CHECK(s.rank() == 2);
}
}
TEST(extent)
{
{
span<int> s;
CHECK(s.extent() == 0);
CHECK(s.extent(0) == 0);
CHECK_THROW(s.extent(1), fail_fast);
#ifdef CONFIRM_COMPILATION_ERRORS
CHECK(s.extent<1>() == 0);
#endif
}
{
span<int, 0> s;
CHECK(s.extent() == 0);
CHECK(s.extent(0) == 0);
CHECK_THROW(s.extent(1), fail_fast);
}
{
int arr2d[1][2] = {};
span<int, 1, 2> s = arr2d;
CHECK(s.extent() == 1);
CHECK(s.extent<0>() == 1);
CHECK(s.extent<1>() == 2);
CHECK(s.extent(0) == 1);
CHECK(s.extent(1) == 2);
CHECK_THROW(s.extent(3), fail_fast);
}
{
int arr2d[1][2] = {};
span<int, 0, 2> s = arr2d;
CHECK(s.extent() == 0);
CHECK(s.extent<0>() == 0);
CHECK(s.extent<1>() == 2);
CHECK(s.extent(0) == 0);
CHECK(s.extent(1) == 2);
CHECK_THROW(s.extent(3), fail_fast);
}
}
TEST(operator_function_call) TEST(operator_function_call)
{ {
int arr[4] = {1, 2, 3, 4}; int arr[4] = {1, 2, 3, 4};