diff --git a/include/gsl.h b/include/gsl.h index 4eb555b..f4c9178 100644 --- a/include/gsl.h +++ b/include/gsl.h @@ -19,10 +19,10 @@ #ifndef GSL_GSL_H #define GSL_GSL_H -#include "gsl_assert.h" // Ensures/Expects -#include "gsl_util.h" // finally()/narrow()/narrow_cast()... +#include "gsl_assert.h" // Ensures/Expects +#include "gsl_util.h" // finally()/narrow()/narrow_cast()... #include "span.h" // span -#include "multi_span.h" // multi_span, strided_span... +#include "multi_span.h" // multi_span, strided_span... #include "string_span.h" // zstring, string_span, zstring_builder... #include diff --git a/include/span.h b/include/span.h index 053b488..3f3b8fe 100644 --- a/include/span.h +++ b/include/span.h @@ -192,7 +192,7 @@ public: constexpr const_span_iterator& operator--() noexcept { - Expects(span_ && index > 0 && index_ <= span_->length()); + Expects(span_ && index_ > 0 && index_ <= span_->length()); --index_; return *this; } @@ -366,7 +366,7 @@ public: using reference = element_type&; using iterator = details::span_iterator>; - using const_iterator = details::span_iterator; + using const_iterator = details::const_span_iterator; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; @@ -512,13 +512,17 @@ public: // [span.iter], span iterator support iterator begin() const noexcept { return {this, 0}; } iterator end() const noexcept { return {this, length()}; } + + const_iterator cbegin() const noexcept { return {this, 0}; } + const_iterator cend() const noexcept { return {this, length()}; } - reverse_iterator rbegin() const noexcept { return {this, length()}; } - reverse_iterator rend() const noexcept { return {this, 0}; } + reverse_iterator rbegin() const noexcept { return reverse_iterator{{this, length()}}; } + reverse_iterator rend() const noexcept { return reverse_iterator{{this, 0}}; } + + const_reverse_iterator crbegin() const noexcept { return reverse_iterator{{this, length()}}; } + const_reverse_iterator crend() const noexcept { return reverse_iterator{{this, 0}}; } private: - constexpr static const bool is_span_type = true; - template class extent_type; diff --git a/tests/span_tests.cpp b/tests/span_tests.cpp index ae3c32e..7652ff9 100644 --- a/tests/span_tests.cpp +++ b/tests/span_tests.cpp @@ -799,8 +799,6 @@ SUITE(span_tests) span::const_iterator it1; span::const_iterator it2; CHECK(it1 == it2); - - } TEST(begin_end) @@ -809,12 +807,12 @@ SUITE(span_tests) int a[] = { 1, 2, 3, 4 }; span s = a; - span::iterator it = s.begin(); + auto it = s.begin(); auto first = it; CHECK(it == first); CHECK(*it == 1); - span::iterator beyond = s.end(); + auto beyond = s.end(); CHECK(it != beyond); CHECK_THROW(*beyond, fail_fast); @@ -845,6 +843,132 @@ SUITE(span_tests) } } + TEST(cbegin_cend) + { + { + int a[] = {1, 2, 3, 4}; + span s = a; + + auto it = s.cbegin(); + auto first = it; + CHECK(it == first); + CHECK(*it == 1); + + auto beyond = s.cend(); + CHECK(it != beyond); + CHECK_THROW(*beyond, fail_fast); + + CHECK(beyond - first == 4); + CHECK(first - first == 0); + CHECK(beyond - beyond == 0); + + ++it; + CHECK(it - first == 1); + CHECK(*it == 2); + *it = 22; + CHECK(*it == 22); + CHECK(beyond - it == 3); + + it = first; + CHECK(it == first); + while (it != s.cend()) + { + *it = 5; + ++it; + } + + CHECK(it == beyond); + CHECK(it - beyond == 0); + + for (auto& n : s) + CHECK(n == 5); + } + } + + TEST(rbegin_rend) + { + { + int a[] = {1, 2, 3, 4}; + span s = a; + + auto it = s.rbegin(); + auto first = it; + CHECK(it == first); + CHECK(*it == 4); + + auto beyond = s.rend(); + CHECK(it != beyond); + CHECK_THROW(*beyond, fail_fast); + + CHECK(beyond - first == 4); + CHECK(first - first == 0); + CHECK(beyond - beyond == 0); + + ++it; + CHECK(it - first == 1); + CHECK(*it == 3); + *it = 22; + CHECK(*it == 22); + CHECK(beyond - it == 3); + + it = first; + CHECK(it == first); + while (it != s.rend()) + { + *it = 5; + ++it; + } + + CHECK(it == beyond); + CHECK(it - beyond == 0); + + for (auto& n : s) + CHECK(n == 5); + } + } + + TEST(crbegin_crend) + { + { + int a[] = {1, 2, 3, 4}; + span s = a; + + auto it = s.crbegin(); + auto first = it; + CHECK(it == first); + CHECK(*it == 4); + + auto beyond = s.crend(); + CHECK(it != beyond); + CHECK_THROW(*beyond, fail_fast); + + CHECK(beyond - first == 4); + CHECK(first - first == 0); + CHECK(beyond - beyond == 0); + + ++it; + CHECK(it - first == 1); + CHECK(*it == 3); + *it = 22; + CHECK(*it == 22); + CHECK(beyond - it == 3); + + it = first; + CHECK(it == first); + while (it != s.crend()) + { + *it = 5; + ++it; + } + + CHECK(it == beyond); + CHECK(it - beyond == 0); + + for (auto& n : s) + CHECK(n == 5); + } + } + TEST(comparison_operators) { {