|  | 
| 7 | 7 | #include <stdx/span.hpp> | 
| 8 | 8 | 
 | 
| 9 | 9 | #include <array> | 
|  | 10 | +#include <type_traits> | 
| 10 | 11 | 
 | 
| 11 | 12 | #if __has_include(<span>) | 
| 12 | 13 | #include <span> | 
| @@ -67,3 +68,110 @@ TEST_CASE("compile-time capacity variable template (const)", "[iterator]") { | 
| 67 | 68 |     std::array const a{1, 2, 3, 4}; | 
| 68 | 69 |     STATIC_REQUIRE(stdx::ct_capacity_v<decltype(a)> == 4u); | 
| 69 | 70 | } | 
|  | 71 | + | 
|  | 72 | +TEST_CASE("default counting_iterator traits", "[iterator]") { | 
|  | 73 | +    using T = std::iterator_traits<stdx::counting_iterator<>>; | 
|  | 74 | +    STATIC_REQUIRE(std::is_same_v<typename T::difference_type, int>); | 
|  | 75 | +    STATIC_REQUIRE(std::is_same_v<typename T::value_type, int>); | 
|  | 76 | +    STATIC_REQUIRE(std::is_same_v<typename T::pointer, int *>); | 
|  | 77 | +    STATIC_REQUIRE(std::is_same_v<typename T::reference, int &>); | 
|  | 78 | + | 
|  | 79 | +#if __cplusplus >= 202002L | 
|  | 80 | +    STATIC_REQUIRE(std::is_same_v<typename T::iterator_category, | 
|  | 81 | +                                  std::contiguous_iterator_tag>); | 
|  | 82 | +#else | 
|  | 83 | +    STATIC_REQUIRE(std::is_same_v<typename T::iterator_category, | 
|  | 84 | +                                  std::random_access_iterator_tag>); | 
|  | 85 | +#endif | 
|  | 86 | +} | 
|  | 87 | + | 
|  | 88 | +TEST_CASE("default counting_iterator value is 0, increment is 1", | 
|  | 89 | +          "[iterator]") { | 
|  | 90 | +    auto i = stdx::counting_iterator{}; | 
|  | 91 | +    CHECK(*i == 0); | 
|  | 92 | +    ++i; | 
|  | 93 | +    CHECK(*i == 1); | 
|  | 94 | +} | 
|  | 95 | + | 
|  | 96 | +TEST_CASE("counting_iterator is an input iterator", "[iterator]") { | 
|  | 97 | +    auto i = stdx::counting_iterator{}; | 
|  | 98 | +    auto v = *i; | 
|  | 99 | +    CHECK(v == 0); | 
|  | 100 | +    ++i; | 
|  | 101 | +    CHECK(*i != v); | 
|  | 102 | +} | 
|  | 103 | + | 
|  | 104 | +TEST_CASE("counting_iterator is a forward iterator", "[iterator]") { | 
|  | 105 | +    auto i = stdx::counting_iterator{}; | 
|  | 106 | +    auto v = *i; | 
|  | 107 | +    auto j = i++; | 
|  | 108 | +    CHECK(*j == v); | 
|  | 109 | +    CHECK(*i - v == 1); | 
|  | 110 | +    ++j; | 
|  | 111 | +    CHECK(*i == *j); | 
|  | 112 | +} | 
|  | 113 | + | 
|  | 114 | +TEST_CASE("counting_iterator is a bidi iterator", "[iterator]") { | 
|  | 115 | +    auto i = stdx::counting_iterator{}; | 
|  | 116 | +    auto v = *i; | 
|  | 117 | +    auto j = i--; | 
|  | 118 | +    CHECK(*j == v); | 
|  | 119 | +    CHECK(v - *i == 1); | 
|  | 120 | +    --j; | 
|  | 121 | +    CHECK(*i == *j); | 
|  | 122 | +} | 
|  | 123 | + | 
|  | 124 | +TEST_CASE("counting_iterator is a random access iterator", "[iterator]") { | 
|  | 125 | +    auto i = stdx::counting_iterator{}; | 
|  | 126 | +    CHECK(*(i + 1) - *i == 1); | 
|  | 127 | +    CHECK(*i - *(i - 1) == 1); | 
|  | 128 | + | 
|  | 129 | +    i += 1; | 
|  | 130 | +    CHECK(*i == 1); | 
|  | 131 | +    CHECK(i - stdx::counting_iterator{} == 1); | 
|  | 132 | +    i -= 1; | 
|  | 133 | +    CHECK(*i == 0); | 
|  | 134 | +} | 
|  | 135 | + | 
|  | 136 | +TEST_CASE("counting_iterator equality", "[iterator]") { | 
|  | 137 | +    auto i = stdx::counting_iterator{}; | 
|  | 138 | +    CHECK(i == stdx::counting_iterator{}); | 
|  | 139 | +} | 
|  | 140 | + | 
|  | 141 | +TEST_CASE("counting_iterator comparison", "[iterator]") { | 
|  | 142 | +    auto i = stdx::counting_iterator{}; | 
|  | 143 | +    auto j = i++; | 
|  | 144 | +    CHECK(j < i); | 
|  | 145 | +    CHECK(j <= i); | 
|  | 146 | +    CHECK(i > j); | 
|  | 147 | +    CHECK(i >= j); | 
|  | 148 | +} | 
|  | 149 | + | 
|  | 150 | +#if __cpp_impl_three_way_comparison >= 201907L | 
|  | 151 | +TEST_CASE("counting_iterator spaceship comparison", "[iterator]") { | 
|  | 152 | +    auto i = stdx::counting_iterator{}; | 
|  | 153 | +    auto j = i++; | 
|  | 154 | +    CHECK(i <=> i == std::strong_ordering::equal); | 
|  | 155 | +    CHECK(j <=> i == std::strong_ordering::less); | 
|  | 156 | +} | 
|  | 157 | +#endif | 
|  | 158 | + | 
|  | 159 | +TEST_CASE("counting_iterator can be given a starting value", "[iterator]") { | 
|  | 160 | +    auto i = stdx::counting_iterator{17}; | 
|  | 161 | +    CHECK(*i == 17); | 
|  | 162 | +    ++i; | 
|  | 163 | +    CHECK(*i == 18); | 
|  | 164 | +} | 
|  | 165 | + | 
|  | 166 | +TEST_CASE("counting_iterator can be given a different type", "[iterator]") { | 
|  | 167 | +    auto i = stdx::counting_iterator{'A'}; | 
|  | 168 | +    CHECK(*i == 'A'); | 
|  | 169 | +    ++i; | 
|  | 170 | +    CHECK(*i == 'B'); | 
|  | 171 | + | 
|  | 172 | +    using T = std::iterator_traits<decltype(i)>; | 
|  | 173 | +    STATIC_REQUIRE(std::is_same_v<typename T::difference_type, int>); | 
|  | 174 | +    STATIC_REQUIRE(std::is_same_v<typename T::value_type, char>); | 
|  | 175 | +    STATIC_REQUIRE(std::is_same_v<typename T::pointer, char *>); | 
|  | 176 | +    STATIC_REQUIRE(std::is_same_v<typename T::reference, char &>); | 
|  | 177 | +} | 
0 commit comments