Added tests for span iterators, fixed implementation.

This commit is contained in:
Neil MacIntosh 2016-07-18 11:38:01 -07:00
parent 8855c59579
commit 30a038ca6a
3 changed files with 141 additions and 13 deletions

View File

@ -19,10 +19,10 @@
#ifndef GSL_GSL_H #ifndef GSL_GSL_H
#define GSL_GSL_H #define GSL_GSL_H
#include "gsl_assert.h" // Ensures/Expects #include "gsl_assert.h" // Ensures/Expects
#include "gsl_util.h" // finally()/narrow()/narrow_cast()... #include "gsl_util.h" // finally()/narrow()/narrow_cast()...
#include "span.h" // span #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 "string_span.h" // zstring, string_span, zstring_builder...
#include <memory> #include <memory>

View File

@ -192,7 +192,7 @@ public:
constexpr const_span_iterator& operator--() noexcept constexpr const_span_iterator& operator--() noexcept
{ {
Expects(span_ && index > 0 && index_ <= span_->length()); Expects(span_ && index_ > 0 && index_ <= span_->length());
--index_; --index_;
return *this; return *this;
} }
@ -366,7 +366,7 @@ public:
using reference = element_type&; using reference = element_type&;
using iterator = details::span_iterator<span<ElementType, Extent>>; using iterator = details::span_iterator<span<ElementType, Extent>>;
using const_iterator = details::span_iterator<span>; using const_iterator = details::const_span_iterator<span>;
using reverse_iterator = std::reverse_iterator<iterator>; using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>;
@ -513,12 +513,16 @@ public:
iterator begin() const noexcept { return {this, 0}; } iterator begin() const noexcept { return {this, 0}; }
iterator end() const noexcept { return {this, length()}; } iterator end() const noexcept { return {this, length()}; }
reverse_iterator rbegin() const noexcept { return {this, length()}; } const_iterator cbegin() const noexcept { return {this, 0}; }
reverse_iterator rend() const noexcept { return {this, 0}; } const_iterator cend() const noexcept { return {this, length()}; }
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: private:
constexpr static const bool is_span_type = true;
template <index_type Extent> template <index_type Extent>
class extent_type; class extent_type;

View File

@ -799,8 +799,6 @@ SUITE(span_tests)
span<int>::const_iterator it1; span<int>::const_iterator it1;
span<int>::const_iterator it2; span<int>::const_iterator it2;
CHECK(it1 == it2); CHECK(it1 == it2);
} }
TEST(begin_end) TEST(begin_end)
@ -809,12 +807,12 @@ SUITE(span_tests)
int a[] = { 1, 2, 3, 4 }; int a[] = { 1, 2, 3, 4 };
span<int> s = a; span<int> s = a;
span<int>::iterator it = s.begin(); auto it = s.begin();
auto first = it; auto first = it;
CHECK(it == first); CHECK(it == first);
CHECK(*it == 1); CHECK(*it == 1);
span<int>::iterator beyond = s.end(); auto beyond = s.end();
CHECK(it != beyond); CHECK(it != beyond);
CHECK_THROW(*beyond, fail_fast); CHECK_THROW(*beyond, fail_fast);
@ -845,6 +843,132 @@ SUITE(span_tests)
} }
} }
TEST(cbegin_cend)
{
{
int a[] = {1, 2, 3, 4};
span<int> 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<int> 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<int> 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) TEST(comparison_operators)
{ {
{ {