diff --git a/include/span.h b/include/span.h index 7e8c119..032779c 100644 --- a/include/span.h +++ b/include/span.h @@ -234,19 +234,50 @@ public: ~span() noexcept = default; constexpr span& operator=(const span& other) noexcept = default; constexpr span& operator=(span&& other) noexcept = default; -#if 0 // TODO // [span.sub], span subviews template - constexpr span first() const; + constexpr span first() const + { + Expects(Count >= 0 && Count <= size()); + return { data(), Count }; + } + template - constexpr span last() const; + constexpr span last() const + { + Expects(Count >= 0 && Count <= size()); + return{ Count == 0 ? data() : data() + (size() - Count), Count }; + } + template - constexpr span subspan() const; - constexpr span first(index_type count) const; - constexpr span last(index_type count) const; - constexpr span subspan(index_type offset, index_type count = dynamic_extent) const; -#endif + constexpr span subspan() 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 }; + } + + constexpr span first(index_type count) const + { + Expects(count >= 0 && count <= size()); + return { data(), count }; + } + + constexpr span last(index_type count) const + { + Expects(count >= 0 && count <= size()); + return { count == 0 ? data() : data() + (size() - count), count }; + } + + constexpr span 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 constexpr index_type length() const noexcept { return size(); } constexpr index_type size() const noexcept { return storage_.size(); } diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp index 8534b3e..01784f6 100644 --- a/tests/span_tests.cpp +++ b/tests/span_tests.cpp @@ -588,7 +588,6 @@ SUITE(span_tests) s1 = get_temp_span(); CHECK(s1.length() == 2 && s1.data() == &arr[1]); } -#if 0 TEST(first) { @@ -596,21 +595,18 @@ SUITE(span_tests) { span av = arr; - CHECK((av.first<2>().bounds() == static_bounds<2>())); CHECK(av.first<2>().length() == 2); CHECK(av.first(2).length() == 2); } { span av = arr; - CHECK((av.first<0>().bounds() == static_bounds<0>())); CHECK(av.first<0>().length() == 0); CHECK(av.first(0).length() == 0); } { span av = arr; - CHECK((av.first<5>().bounds() == static_bounds<5>())); CHECK(av.first<5>().length() == 5); CHECK(av.first(5).length() == 5); } @@ -618,7 +614,6 @@ SUITE(span_tests) { span av = arr; #ifdef CONFIRM_COMPILATION_ERRORS - CHECK(av.first<6>().bounds() == static_bounds<6>()); CHECK(av.first<6>().length() == 6); CHECK(av.first<-1>().length() == -1); #endif @@ -626,8 +621,7 @@ SUITE(span_tests) } { - span av; - CHECK((av.first<0>().bounds() == static_bounds<0>())); + span av; CHECK(av.first<0>().length() == 0); CHECK(av.first(0).length() == 0); } @@ -639,21 +633,18 @@ SUITE(span_tests) { span av = arr; - CHECK((av.last<2>().bounds() == static_bounds<2>())); CHECK(av.last<2>().length() == 2); CHECK(av.last(2).length() == 2); } { span av = arr; - CHECK((av.last<0>().bounds() == static_bounds<0>())); CHECK(av.last<0>().length() == 0); CHECK(av.last(0).length() == 0); } { span av = arr; - CHECK((av.last<5>().bounds() == static_bounds<5>())); CHECK(av.last<5>().length() == 5); CHECK(av.last(5).length() == 5); } @@ -661,15 +652,13 @@ SUITE(span_tests) { span av = arr; #ifdef CONFIRM_COMPILATION_ERRORS - CHECK((av.last<6>().bounds() == static_bounds<6>())); CHECK(av.last<6>().length() == 6); #endif CHECK_THROW(av.last(6).length(), fail_fast); } { - span av; - CHECK((av.last<0>().bounds() == static_bounds<0>())); + span av; CHECK(av.last<0>().length() == 0); CHECK(av.last(0).length() == 0); } @@ -681,7 +670,6 @@ SUITE(span_tests) { span 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, 3).length() == 3); @@ -689,14 +677,12 @@ SUITE(span_tests) { span 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); } { span 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_THROW(av.subspan(0, 6).length(), fail_fast); @@ -705,15 +691,14 @@ SUITE(span_tests) { span av = arr; - CHECK((av.subspan<5, 0>().bounds() == static_bounds<0>())); - CHECK((av.subspan<5, 0>().length() == 0)); + CHECK((av.subspan<4, 0>().length() == 0)); + CHECK(av.subspan(4, 0).length() == 0); CHECK(av.subspan(5, 0).length() == 0); CHECK_THROW(av.subspan(6, 0).length(), fail_fast); } { - span av; - CHECK((av.subspan<0, 0>().bounds() == static_bounds<0>())); + span av; CHECK((av.subspan<0, 0>().length() == 0)); CHECK(av.subspan(0, 0).length() == 0); 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); } } - - TEST(rank) - { - int arr[2] = {1, 2}; - - { - span s; - CHECK(s.rank() == 1); - } - - { - span s = arr; - CHECK(s.rank() == 1); - } - - int arr2d[1][1] = {}; - { - span s = arr2d; - CHECK(s.rank() == 2); - } - } - - TEST(extent) - { - { - span 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 s; - CHECK(s.extent() == 0); - CHECK(s.extent(0) == 0); - CHECK_THROW(s.extent(1), fail_fast); - } - - { - int arr2d[1][2] = {}; - - span 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 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); - } - } - +#if 0 TEST(operator_function_call) { int arr[4] = {1, 2, 3, 4};