#include "operator_hijacker.h"
#include "test_iterators.h"
-void test() {
+void test(cpp17_input_iterator<operator_hijacker*> i) {
{
std::vector<operator_hijacker> v;
- cpp17_input_iterator<std::vector<operator_hijacker>::iterator> i;
v.insert(v.end(), i, i);
}
{
{
std::vector<adl::S> s;
- s.insert(s.end(), cpp17_input_iterator<adl::S*>(), cpp17_input_iterator<adl::S*>());
+ s.insert(s.end(), cpp17_input_iterator<adl::S*>(nullptr), cpp17_input_iterator<adl::S*>(nullptr));
}
return 0;
#include <array>
#include <cassert>
+#include <cstddef>
#include "test_iterators.h"
std::ptrdiff_t count_ = 0;
};
-template <std::input_or_output_iterator It, std::sentinel_for<It> Sent = It>
-constexpr void check_assignable_case(std::ptrdiff_t const n) {
+template <class It, class Sent = It>
+constexpr void check_assignable_case() {
auto range = range_t{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- auto first = stride_counting_iterator(It(range.begin()));
- std::ranges::advance(first, stride_counting_iterator(Sent(It(range.begin() + n))));
- assert(first.base().base() == range.begin() + n);
- assert(first.stride_count() == 0); // because we got here by assigning from last, not by incrementing
+
+ for (std::ptrdiff_t n = 0; n != 9; ++n) {
+ {
+ It first(range.begin());
+ Sent last(It(range.begin() + n));
+ std::ranges::advance(first, last);
+ assert(base(first) == range.begin() + n);
+ }
+
+ // Count operations
+ if constexpr (std::is_same_v<It, Sent>) {
+ stride_counting_iterator<It> first(It(range.begin()));
+ stride_counting_iterator<It> last(It(range.begin() + n));
+ std::ranges::advance(first, last);
+ assert(first.base().base() == range.begin() + n);
+ assert(first.stride_count() == 0); // because we got here by assigning from last, not by incrementing
+ }
+ }
}
-template <std::input_or_output_iterator It>
-constexpr void check_sized_sentinel_case(std::ptrdiff_t const n) {
+template <class It>
+constexpr void check_sized_sentinel_case() {
auto range = range_t{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- auto first = stride_counting_iterator(It(range.begin()));
- std::ranges::advance(first, distance_apriori_sentinel(n));
-
- assert(first.base().base() == range.begin() + n);
- if constexpr (std::random_access_iterator<It>) {
- assert(first.stride_count() == 1);
- assert(first.stride_displacement() == 1);
- } else {
- assert(first.stride_count() == n);
- assert(first.stride_displacement() == n);
+
+ for (std::ptrdiff_t n = 0; n != 9; ++n) {
+ {
+ It first(range.begin());
+ distance_apriori_sentinel last(n);
+ std::ranges::advance(first, last);
+ assert(base(first) == range.begin() + n);
+ }
+
+ // Count operations
+ {
+ stride_counting_iterator<It> first(It(range.begin()));
+ distance_apriori_sentinel last(n);
+ std::ranges::advance(first, last);
+
+ assert(first.base().base() == range.begin() + n);
+ if constexpr (std::random_access_iterator<It>) {
+ assert(first.stride_count() == 1);
+ assert(first.stride_displacement() == 1);
+ } else {
+ assert(first.stride_count() == n);
+ assert(first.stride_displacement() == n);
+ }
+ }
}
}
-template <std::input_or_output_iterator It>
-constexpr void check_sentinel_case(std::ptrdiff_t const n) {
+template <class It>
+constexpr void check_sentinel_case() {
auto range = range_t{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- auto first = stride_counting_iterator(It(range.begin()));
- auto const last = It(range.begin() + n);
- std::ranges::advance(first, sentinel_wrapper(last));
- assert(first.base() == last);
- assert(first.stride_count() == n);
+
+ for (std::ptrdiff_t n = 0; n != 9; ++n) {
+ {
+ It first(range.begin());
+ sentinel_wrapper<It> last(It(range.begin() + n));
+ std::ranges::advance(first, last);
+ assert(base(first) == range.begin() + n);
+ }
+
+ // Count operations
+ {
+ stride_counting_iterator<It> first(It(range.begin()));
+ sentinel_wrapper<It> last(It(range.begin() + n));
+ std::ranges::advance(first, last);
+ assert(first.base() == last);
+ assert(first.stride_count() == n);
+ }
+ }
}
constexpr bool test() {
- check_assignable_case<cpp17_input_iterator<range_t::const_iterator> >(1);
- check_assignable_case<forward_iterator<range_t::const_iterator> >(3);
- check_assignable_case<bidirectional_iterator<range_t::const_iterator> >(4);
- check_assignable_case<random_access_iterator<range_t::const_iterator> >(5);
- check_assignable_case<contiguous_iterator<range_t::const_iterator> >(6);
-
- check_sized_sentinel_case<cpp17_input_iterator<range_t::const_iterator> >(7);
- check_sized_sentinel_case<cpp20_input_iterator<range_t::const_iterator> >(6);
- check_sized_sentinel_case<forward_iterator<range_t::const_iterator> >(5);
- check_sized_sentinel_case<bidirectional_iterator<range_t::const_iterator> >(4);
- check_sized_sentinel_case<random_access_iterator<range_t::const_iterator> >(3);
- check_sized_sentinel_case<contiguous_iterator<range_t::const_iterator> >(2);
-
- check_sentinel_case<cpp17_input_iterator<range_t::const_iterator> >(1);
+ using It = range_t::const_iterator;
+ check_assignable_case<cpp17_input_iterator<It>, sentinel_wrapper<cpp17_input_iterator<It>>>();
+ check_assignable_case<forward_iterator<It>>();
+ check_assignable_case<bidirectional_iterator<It>>();
+ check_assignable_case<random_access_iterator<It>>();
+ check_assignable_case<contiguous_iterator<It>>();
+
+ check_sized_sentinel_case<cpp17_input_iterator<It>>();
+ check_sized_sentinel_case<cpp20_input_iterator<It>>();
+ check_sized_sentinel_case<forward_iterator<It>>();
+ check_sized_sentinel_case<bidirectional_iterator<It>>();
+ check_sized_sentinel_case<random_access_iterator<It>>();
+ check_sized_sentinel_case<contiguous_iterator<It>>();
+
+ check_sentinel_case<cpp17_input_iterator<It>>();
// cpp20_input_iterator not copyable, so is omitted
- check_sentinel_case<forward_iterator<range_t::const_iterator> >(3);
- check_sentinel_case<bidirectional_iterator<range_t::const_iterator> >(4);
- check_sentinel_case<random_access_iterator<range_t::const_iterator> >(5);
- check_sentinel_case<contiguous_iterator<range_t::const_iterator> >(6);
+ check_sentinel_case<forward_iterator<It>>();
+ check_sentinel_case<bidirectional_iterator<It>>();
+ check_sentinel_case<random_access_iterator<It>>();
+ check_sentinel_case<contiguous_iterator<It>>();
return true;
}
#include <iterator>
#include <cassert>
+#include <type_traits>
#include "test_iterators.h"
-template <std::input_or_output_iterator It>
-constexpr void check(It it, std::ptrdiff_t n, It last) {
+template <class It, class Sent = It>
+constexpr void check(It it, std::ptrdiff_t n, Sent last) {
{
It result = std::ranges::next(it, n, last);
assert(result == last);
}
// Count the number of operations
- {
+ if constexpr (std::is_same_v<It, Sent>) {
stride_counting_iterator<It> strided_it(it);
stride_counting_iterator<It> strided_last(last);
stride_counting_iterator<It> result = std::ranges::next(strided_it, n, strided_last);
constexpr bool test() {
int range[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- check(cpp17_input_iterator(&range[0]), 1, cpp17_input_iterator(&range[1]));
+ check(cpp17_input_iterator(&range[0]), 1, sentinel_wrapper(cpp17_input_iterator(&range[1])));
check(forward_iterator(&range[0]), 2, forward_iterator(&range[2]));
check(bidirectional_iterator(&range[2]), 6, bidirectional_iterator(&range[8]));
check(random_access_iterator(&range[3]), 2, random_access_iterator(&range[5]));
check(contiguous_iterator(&range[0]), 5, contiguous_iterator(&range[5]));
- check(cpp17_input_iterator(&range[0]), 0, cpp17_input_iterator(&range[0]));
+ check(cpp17_input_iterator(&range[0]), 0, sentinel_wrapper(cpp17_input_iterator(&range[0])));
check(forward_iterator(&range[0]), 0, forward_iterator(&range[0]));
check(bidirectional_iterator(&range[2]), 0, bidirectional_iterator(&range[2]));
check(random_access_iterator(&range[3]), 0, random_access_iterator(&range[3]));
using range_t = std::array<int, 10>;
+// Sentinel type that can be assigned to an iterator. This is to test the case where
+// std::ranges::next uses assignment instead of successive increments below.
+template <class It>
+class assignable_sentinel {
+public:
+ explicit assignable_sentinel() = default;
+ constexpr explicit assignable_sentinel(const It& it) : base_(base(it)) {}
+ constexpr operator It() const { return It(base_); }
+ constexpr bool operator==(const It& other) const { return base_ == base(other); }
+ friend constexpr It base(const assignable_sentinel& s) { return It(s.base_); }
+private:
+ decltype(base(std::declval<It>())) base_;
+};
+
class distance_apriori_sentinel {
public:
distance_apriori_sentinel() = default;
std::ptrdiff_t count_ = 0;
};
-template <std::input_or_output_iterator It>
-constexpr void check_assignable(It it, It last, int const* expected) {
+template <bool Count, typename It>
+constexpr void check_assignable(int* it, int* last, int const* expected) {
{
- It result = std::ranges::next(std::move(it), std::move(last));
- assert(&*result == expected);
+ It result = std::ranges::next(It(it), assignable_sentinel(It(last)));
+ assert(base(result) == expected);
}
// Count operations
- {
- auto strided_it = stride_counting_iterator(std::move(it));
- auto strided_last = stride_counting_iterator(std::move(last));
- auto result = std::ranges::next(std::move(strided_it), std::move(strided_last));
- assert(&*result == expected);
+ if constexpr (Count) {
+ auto strided_it = stride_counting_iterator(It(it));
+ auto strided_last = assignable_sentinel(stride_counting_iterator(It(last)));
+ stride_counting_iterator<It> result = std::ranges::next(std::move(strided_it), std::move(strided_last));
+ assert(base(result.base()) == expected);
assert(result.stride_count() == 0); // because we got here by assigning from last, not by incrementing
}
}
-template <std::input_or_output_iterator It>
-constexpr void check_sized_sentinel(It it, It last, int const* expected) {
- auto n = (last.base() - it.base());
+template <typename It>
+constexpr void check_sized_sentinel(int* it, int* last, int const* expected) {
+ auto n = (last - it);
{
auto sent = distance_apriori_sentinel(n);
- auto result = std::ranges::next(std::move(it), sent);
- assert(&*result == expected);
+ auto result = std::ranges::next(It(it), sent);
+ assert(base(result) == expected);
}
// Count operations
{
- auto strided_it = stride_counting_iterator(std::move(it));
+ auto strided_it = stride_counting_iterator(It(it));
auto sent = distance_apriori_sentinel(n);
auto result = std::ranges::next(std::move(strided_it), sent);
- assert(&*result == expected);
+ assert(base(result.base()) == expected);
if constexpr (std::random_access_iterator<It>) {
assert(result.stride_count() == 1); // should have used exactly one +=
}
}
-template <std::input_or_output_iterator It>
-constexpr void check_sentinel(It it, It last, int const* expected) {
- auto n = (last.base() - it.base());
+template <bool Count, typename It>
+constexpr void check_sentinel(int* it, int* last, int const* expected) {
+ auto n = (last - it);
{
- auto sent = sentinel_wrapper(last);
- It result = std::ranges::next(std::move(it), sent);
- assert(&*result == expected);
+ auto sent = sentinel_wrapper(It(last));
+ It result = std::ranges::next(It(it), sent);
+ assert(base(result) == expected);
}
// Count operations
- {
- auto strided_it = stride_counting_iterator(it);
- auto sent = sentinel_wrapper(stride_counting_iterator(last));
+ if constexpr (Count) {
+ auto strided_it = stride_counting_iterator(It(it));
+ auto sent = sentinel_wrapper(stride_counting_iterator(It(last)));
stride_counting_iterator result = std::ranges::next(std::move(strided_it), sent);
- assert(&*result == expected);
+ assert(base(result.base()) == expected);
assert(result.stride_count() == n); // must have used ++ until it hit the sentinel
}
}
constexpr bool test() {
int range[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
- check_assignable(cpp17_input_iterator(&range[0]), cpp17_input_iterator(&range[2]), &range[2]);
- check_assignable(forward_iterator(&range[0]), forward_iterator(&range[3]), &range[3]);
- check_assignable(bidirectional_iterator(&range[0]), bidirectional_iterator(&range[4]), &range[4]);
- check_assignable(random_access_iterator(&range[0]), random_access_iterator(&range[5]), &range[5]);
- check_assignable(contiguous_iterator(&range[0]), contiguous_iterator(&range[6]), &range[6]);
+ check_assignable<false, cpp17_input_iterator<int*>>( &range[0], &range[2], &range[2]);
+ check_assignable<true, forward_iterator<int*>>( &range[0], &range[3], &range[3]);
+ check_assignable<true, bidirectional_iterator<int*>>(&range[0], &range[4], &range[4]);
+ check_assignable<true, random_access_iterator<int*>>(&range[0], &range[5], &range[5]);
+ check_assignable<true, contiguous_iterator<int*>>( &range[0], &range[6], &range[6]);
- check_sized_sentinel(cpp17_input_iterator(&range[0]), cpp17_input_iterator(&range[7]), &range[7]);
- check_sized_sentinel(cpp20_input_iterator(&range[0]), cpp20_input_iterator(&range[6]), &range[6]);
- check_sized_sentinel(forward_iterator(&range[0]), forward_iterator(&range[5]), &range[5]);
- check_sized_sentinel(bidirectional_iterator(&range[0]), bidirectional_iterator(&range[4]), &range[4]);
- check_sized_sentinel(random_access_iterator(&range[0]), random_access_iterator(&range[3]), &range[3]);
- check_sized_sentinel(contiguous_iterator(&range[0]), contiguous_iterator(&range[2]), &range[2]);
+ check_sized_sentinel<cpp17_input_iterator<int*>>( &range[0], &range[7], &range[7]);
+ check_sized_sentinel<cpp20_input_iterator<int*>>( &range[0], &range[6], &range[6]);
+ check_sized_sentinel<forward_iterator<int*>>( &range[0], &range[5], &range[5]);
+ check_sized_sentinel<bidirectional_iterator<int*>>(&range[0], &range[4], &range[4]);
+ check_sized_sentinel<random_access_iterator<int*>>(&range[0], &range[3], &range[3]);
+ check_sized_sentinel<contiguous_iterator<int*>>( &range[0], &range[2], &range[2]);
- check_sentinel(cpp17_input_iterator(&range[0]), cpp17_input_iterator(&range[1]), &range[1]);
+ check_sentinel<false, cpp17_input_iterator<int*>>( &range[0], &range[1], &range[1]);
// cpp20_input_iterator not copyable, so is omitted
- check_sentinel(forward_iterator(&range[0]), forward_iterator(&range[3]), &range[3]);
- check_sentinel(bidirectional_iterator(&range[0]), bidirectional_iterator(&range[4]), &range[4]);
- check_sentinel(random_access_iterator(&range[0]), random_access_iterator(&range[5]), &range[5]);
- check_sentinel(contiguous_iterator(&range[0]), contiguous_iterator(&range[6]), &range[6]);
+ check_sentinel<true, forward_iterator<int*>>( &range[0], &range[3], &range[3]);
+ check_sentinel<true, bidirectional_iterator<int*>>(&range[0], &range[4], &range[4]);
+ check_sentinel<true, random_access_iterator<int*>>(&range[0], &range[5], &range[5]);
+ check_sentinel<true, contiguous_iterator<int*>>( &range[0], &range[6], &range[6]);
return true;
}
#include "test_iterators.h"
constexpr bool test() {
- static_assert( std::default_initializable<std::counted_iterator<cpp17_input_iterator<int*>>>);
- static_assert(!std::default_initializable<std::counted_iterator<cpp20_input_iterator<int*>>>);
+ static_assert(!std::default_initializable<std::counted_iterator<cpp17_input_iterator<int*>>>);
+ static_assert( std::default_initializable<std::counted_iterator<forward_iterator<int*>>>);
- std::counted_iterator<cpp17_input_iterator<int*>> iter;
- assert(iter.base() == cpp17_input_iterator<int*>());
+ std::counted_iterator<forward_iterator<int*>> iter;
+ assert(iter.base() == forward_iterator<int*>());
assert(iter.count() == 0);
return true;
int main(int, char**)
{
- test<cpp17_input_iterator<char*> >();
+ // we don't have a test iterator that is both input and default-constructible, so not testing that case
test<forward_iterator<char*> >();
test<bidirectional_iterator<char*> >();
test<random_access_iterator<char*> >();
test(U u)
{
const std::move_iterator<U> r2(u);
- std::move_iterator<It> r1;
+ std::move_iterator<It> r1(It(nullptr));
std::move_iterator<It>& rr = (r1 = r2);
assert(r1.base() == u);
assert(&rr == &r1);
T *ptr_;
constexpr DefaultCtorParent(T *ptr) : ptr_(ptr) {}
- constexpr cpp17_input_iterator<T *> begin() { return cpp17_input_iterator<T *>(ptr_); }
- constexpr cpp17_input_iterator<const T *> begin() const { return cpp17_input_iterator<const T *>(ptr_); }
+ constexpr forward_iterator<T *> begin() { return forward_iterator<T *>(ptr_); }
+ constexpr forward_iterator<const T *> begin() const { return forward_iterator<const T *>(ptr_); }
constexpr T *end() { return ptr_ + 4; }
constexpr const T *end() const { return ptr_ + 4; }
};
template<class T>
-constexpr bool operator==(const cpp17_input_iterator<T*> &lhs, const T *rhs) { return lhs.base() == rhs; }
+constexpr bool operator==(const forward_iterator<T*> &lhs, const T *rhs) { return lhs.base() == rhs; }
template<class T>
-constexpr bool operator==(const T *lhs, const cpp17_input_iterator<T*> &rhs) { return rhs.base() == lhs; }
+constexpr bool operator==(const T *lhs, const forward_iterator<T*> &rhs) { return rhs.base() == lhs; }
constexpr bool test() {
using Base = DefaultCtorParent<ChildView>;
template<class T>
struct ForwardView : std::ranges::view_base {
- friend forward_iterator<T*> begin(ForwardView&) { return forward_iterator<T*>(nullptr); }
- friend forward_iterator<T*> begin(ForwardView const&) { return forward_iterator<T*>(nullptr); }
- friend forward_iterator<T*> end(ForwardView&) { return forward_iterator<T*>(nullptr); }
- friend forward_iterator<T*> end(ForwardView const&) { return forward_iterator<T*>(nullptr); }
+ forward_iterator<T*> begin() const;
+ sentinel_wrapper<forward_iterator<T*>> end() const;
};
template<class T>
struct InputView : std::ranges::view_base {
- friend cpp17_input_iterator<T*> begin(InputView&) { return cpp17_input_iterator<T*>(nullptr); }
- friend cpp17_input_iterator<T*> begin(InputView const&) { return cpp17_input_iterator<T*>(nullptr); }
- friend cpp17_input_iterator<T*> end(InputView&) { return cpp17_input_iterator<T*>(nullptr); }
- friend cpp17_input_iterator<T*> end(InputView const&) { return cpp17_input_iterator<T*>(nullptr); }
+ cpp17_input_iterator<T*> begin() const;
+ sentinel_wrapper<cpp17_input_iterator<T*>> end() const;
};
template<class T>
static_assert(std::same_as<std::ranges::sentinel_t<test_range<cpp20_input_iterator> >, sentinel>);
static_assert(std::same_as<std::ranges::sentinel_t<test_range<cpp20_input_iterator> const>, sentinel>);
static_assert(std::same_as<std::ranges::sentinel_t<test_non_const_range<cpp20_input_iterator> >, sentinel>);
-static_assert(std::same_as<std::ranges::sentinel_t<test_common_range<cpp17_input_iterator> >, cpp17_input_iterator<int*> >);
-static_assert(std::same_as<std::ranges::sentinel_t<test_common_range<cpp17_input_iterator> const>, cpp17_input_iterator<int const*> >);
-static_assert(std::same_as<std::ranges::sentinel_t<test_non_const_common_range<cpp17_input_iterator> >, cpp17_input_iterator<int*> >);
+static_assert(std::same_as<std::ranges::sentinel_t<test_common_range<forward_iterator> >, forward_iterator<int*> >);
+static_assert(std::same_as<std::ranges::sentinel_t<test_common_range<forward_iterator> const>, forward_iterator<int const*> >);
+static_assert(std::same_as<std::ranges::sentinel_t<test_non_const_common_range<forward_iterator> >, forward_iterator<int*> >);
#include <ranges>
#include "test_iterators.h"
-#include "test_range.h"
+template<class It> struct Common { It begin() const; It end() const; };
+template<class It> struct NonCommon { It begin() const; sentinel_wrapper<It> end() const; };
+template<class It, class Sent> struct Range { It begin() const; Sent end() const; };
+static_assert(!std::ranges::common_range<Common<cpp17_input_iterator<int*>>>); // not a sentinel for itself
+static_assert(!std::ranges::common_range<Common<cpp20_input_iterator<int*>>>); // not a sentinel for itself
+static_assert( std::ranges::common_range<Common<forward_iterator<int*>>>);
+static_assert( std::ranges::common_range<Common<bidirectional_iterator<int*>>>);
+static_assert( std::ranges::common_range<Common<random_access_iterator<int*>>>);
+static_assert( std::ranges::common_range<Common<contiguous_iterator<int*>>>);
+static_assert( std::ranges::common_range<Common<int*>>);
-static_assert(!std::ranges::common_range<test_range<cpp17_input_iterator> >);
-static_assert(!std::ranges::common_range<test_range<cpp17_input_iterator> const>);
+static_assert(!std::ranges::common_range<NonCommon<cpp17_input_iterator<int*>>>);
+static_assert(!std::ranges::common_range<NonCommon<cpp20_input_iterator<int*>>>);
+static_assert(!std::ranges::common_range<NonCommon<forward_iterator<int*>>>);
+static_assert(!std::ranges::common_range<NonCommon<bidirectional_iterator<int*>>>);
+static_assert(!std::ranges::common_range<NonCommon<random_access_iterator<int*>>>);
+static_assert(!std::ranges::common_range<NonCommon<contiguous_iterator<int*>>>);
+static_assert(!std::ranges::common_range<NonCommon<int*>>);
-static_assert(!std::ranges::common_range<test_non_const_range<cpp17_input_iterator> >);
-static_assert(!std::ranges::common_range<test_non_const_range<cpp17_input_iterator> const>);
+// Test when begin() and end() only differ by their constness.
+static_assert(!std::ranges::common_range<Range<int*, int const*>>);
-static_assert(std::ranges::common_range<test_common_range<cpp17_input_iterator> >);
-static_assert(std::ranges::common_range<test_common_range<cpp17_input_iterator> const>);
+// Simple test with a sized_sentinel.
+static_assert(!std::ranges::common_range<Range<int*, sized_sentinel<int*>>>);
-static_assert(std::ranges::common_range<test_non_const_common_range<cpp17_input_iterator> >);
-static_assert(!std::ranges::common_range<test_non_const_common_range<cpp17_input_iterator> const>);
+// Make sure cv-qualification doesn't impact the concept when begin() and end() have matching qualifiers.
+static_assert( std::ranges::common_range<Common<forward_iterator<int*>> const>);
+static_assert(!std::ranges::common_range<NonCommon<forward_iterator<int*>> const>);
-struct subtly_not_common {
- int* begin() const;
+// Test with a range that's a common_range only when const-qualified.
+struct Range1 {
+ int* begin();
+ int const* begin() const;
int const* end() const;
};
-static_assert(std::ranges::range<subtly_not_common> && !std::ranges::common_range<subtly_not_common>);
-static_assert(std::ranges::range<subtly_not_common const> && !std::ranges::common_range<subtly_not_common const>);
+static_assert(!std::ranges::common_range<Range1>);
+static_assert( std::ranges::common_range<Range1 const>);
-struct common_range_non_const_only {
+// Test with a range that's a common_range only when not const-qualified.
+struct Range2 {
int* begin() const;
int* end();
int const* end() const;
};
-static_assert(std::ranges::range<common_range_non_const_only>&& std::ranges::common_range<common_range_non_const_only>);
-static_assert(std::ranges::range<common_range_non_const_only const> && !std::ranges::common_range<common_range_non_const_only const>);
-
-struct common_range_const_only {
- int* begin();
- int const* begin() const;
- int const* end() const;
-};
-static_assert(std::ranges::range<common_range_const_only> && !std::ranges::common_range<common_range_const_only>);
-static_assert(std::ranges::range<common_range_const_only const>&& std::ranges::common_range<common_range_const_only const>);
+static_assert( std::ranges::common_range<Range2>);
+static_assert(!std::ranges::common_range<Range2 const>);
static_assert(!std::ranges::input_range<test_non_const_range<cpp17_input_iterator> const>);
static_assert(!std::ranges::input_range<test_non_const_range<cpp20_input_iterator> const>);
-static_assert(std::ranges::input_range<test_common_range<cpp17_input_iterator> >);
+static_assert(std::ranges::input_range<test_common_range<forward_iterator> >);
static_assert(!std::ranges::input_range<test_common_range<cpp20_input_iterator> >);
-static_assert(std::ranges::input_range<test_common_range<cpp17_input_iterator> const>);
+static_assert(std::ranges::input_range<test_common_range<forward_iterator> const>);
static_assert(!std::ranges::input_range<test_common_range<cpp20_input_iterator> const>);
-static_assert(std::ranges::input_range<test_non_const_common_range<cpp17_input_iterator> >);
+static_assert(std::ranges::input_range<test_non_const_common_range<forward_iterator> >);
static_assert(!std::ranges::input_range<test_non_const_common_range<cpp20_input_iterator> >);
-static_assert(!std::ranges::input_range<test_non_const_common_range<cpp17_input_iterator> const>);
+static_assert(!std::ranges::input_range<test_non_const_common_range<forward_iterator> const>);
static_assert(!std::ranges::input_range<test_non_const_common_range<cpp20_input_iterator> const>);
assert(a4.begin() == globalBuff + 4);
assert(a4.size() == 4);
- std::ranges::subrange<InputIter> b(InputIter(globalBuff), InputIter(globalBuff + 8));
+ std::ranges::subrange<InputIter, sentinel_wrapper<InputIter>> b(InputIter(globalBuff), sentinel_wrapper(InputIter(globalBuff + 8)));
auto b1 = std::move(b).next();
assert(b1.begin().base() == globalBuff + 1);
typedef ThrowingIterator<char> TIter;
typedef cpp17_input_iterator<TIter> IIter;
const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- test_exceptions(S(), IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter());
- test_exceptions(S(), IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter());
- test_exceptions(S(), IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter());
+ test_exceptions(S(), IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter(TIter()));
+ test_exceptions(S(), IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter(TIter()));
+ test_exceptions(S(), IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter(TIter()));
test_exceptions(S(), TIter(s, s+10, 4, TIter::TAIncrement), TIter());
test_exceptions(S(), TIter(s, s+10, 5, TIter::TADereference), TIter());
typedef ThrowingIterator<char> TIter;
typedef cpp17_input_iterator<TIter> IIter;
const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- test_exceptions(S(), IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter());
- test_exceptions(S(), IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter());
- test_exceptions(S(), IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter());
+ test_exceptions(S(), IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter(TIter()));
+ test_exceptions(S(), IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter(TIter()));
+ test_exceptions(S(), IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter(TIter()));
test_exceptions(S(), TIter(s, s+10, 4, TIter::TAIncrement), TIter());
test_exceptions(S(), TIter(s, s+10, 5, TIter::TADereference), TIter());
typedef ThrowingIterator<char> TIter;
typedef cpp17_input_iterator<TIter> IIter;
const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- test_exceptions(S(), 0, IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter());
- test_exceptions(S(), 0, IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter());
- test_exceptions(S(), 0, IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter());
+ test_exceptions(S(), 0, IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter(TIter()));
+ test_exceptions(S(), 0, IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter(TIter()));
+ test_exceptions(S(), 0, IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter(TIter()));
test_exceptions(S(), 0, TIter(s, s+10, 4, TIter::TAIncrement), TIter());
test_exceptions(S(), 0, TIter(s, s+10, 5, TIter::TADereference), TIter());
typedef ThrowingIterator<char> TIter;
typedef cpp17_input_iterator<TIter> IIter;
const char* s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter());
- test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter());
- test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter());
+ test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 4, TIter::TAIncrement)), IIter(TIter()));
+ test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 5, TIter::TADereference)), IIter(TIter()));
+ test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, IIter(TIter(s, s+10, 6, TIter::TAComparison)), IIter(TIter()));
test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, TIter(s, s+10, 4, TIter::TAIncrement), TIter());
test_exceptions(S("abcdefghijklmnopqrst"), 10, 5, TIter(s, s+10, 5, TIter::TADereference), TIter());
TEST_CONSTEXPR_CXX14 It base() const {return it_;}
- TEST_CONSTEXPR_CXX14 cpp17_input_iterator() : it_() {}
explicit TEST_CONSTEXPR_CXX14 cpp17_input_iterator(It it) : it_(it) {}
template <class U, class T>
TEST_CONSTEXPR_CXX14 cpp17_input_iterator(const cpp17_input_iterator<U, T>& u) :it_(u.it_) {}