Mostly, remove the global assumption that all ranges have size 8.
I should have called this out during the initial review.
// constexpr V base() && { return std::move(base_); }
#include <ranges>
+
#include <cassert>
+#include <concepts>
-#include "test_macros.h"
#include "types.h"
constexpr bool test() {
{
// Test non-const.
{
- auto rev = std::ranges::reverse_view(BidirRange{buffer});
- assert(rev.base().ptr_ == buffer);
- assert(std::move(rev).base().ptr_ == buffer);
+ auto rev = std::ranges::reverse_view(BidirRange{buffer, buffer + 8});
+
+ std::same_as<BidirRange> auto base = rev.base();
+ assert(base.begin_ == buffer);
+ assert(base.end_ == buffer + 8);
- ASSERT_SAME_TYPE(decltype(rev.base()), BidirRange);
- ASSERT_SAME_TYPE(decltype(std::move(rev).base()), BidirRange);
+ std::same_as<BidirRange> auto moved = std::move(rev).base();
+ assert(moved.begin_ == buffer);
+ assert(moved.end_ == buffer + 8);
}
// Test const.
{
- const auto rev = std::ranges::reverse_view(BidirRange{buffer});
- assert(rev.base().ptr_ == buffer);
- assert(std::move(rev).base().ptr_ == buffer);
+ const auto rev = std::ranges::reverse_view(BidirRange{buffer, buffer + 8});
+
+ std::same_as<BidirRange> auto base = rev.base();
+ assert(base.begin_ == buffer);
+ assert(base.end_ == buffer + 8);
- ASSERT_SAME_TYPE(decltype(rev.base()), BidirRange);
- ASSERT_SAME_TYPE(decltype(std::move(rev).base()), BidirRange);
+ std::same_as<BidirRange> auto moved = std::move(rev).base();
+ assert(moved.begin_ == buffer);
+ assert(moved.end_ == buffer + 8);
}
}
// Test non-common ranges.
{
// Test non-const (also move only).
{
- auto rev = std::ranges::reverse_view(BidirSentRange<MoveOnly>{buffer});
- assert(std::move(rev).base().ptr_ == buffer);
-
- ASSERT_SAME_TYPE(decltype(std::move(rev).base()), BidirSentRange<MoveOnly>);
+ auto rev = std::ranges::reverse_view(BidirSentRange<MoveOnly>{buffer, buffer + 8});
+ std::same_as<BidirSentRange<MoveOnly>> auto base = std::move(rev).base();
+ assert(base.begin_ == buffer);
+ assert(base.end_ == buffer + 8);
}
// Test const.
{
- const auto rev = std::ranges::reverse_view(BidirSentRange<Copyable>{buffer});
- assert(rev.base().ptr_ == buffer);
- assert(std::move(rev).base().ptr_ == buffer);
+ const auto rev = std::ranges::reverse_view(BidirSentRange<Copyable>{buffer, buffer + 8});
+
+ std::same_as<BidirSentRange<Copyable>> auto base = rev.base();
+ assert(base.begin_ == buffer);
+ assert(base.end_ == buffer + 8);
- ASSERT_SAME_TYPE(decltype(rev.base()), BidirSentRange<Copyable>);
- ASSERT_SAME_TYPE(decltype(std::move(rev).base()), BidirSentRange<Copyable>);
+ std::same_as<BidirSentRange<Copyable>> auto moved = std::move(rev).base();
+ assert(moved.begin_ == buffer);
+ assert(moved.end_ == buffer + 8);
}
}
};
struct CountedView : std::ranges::view_base {
- int *ptr_;
+ int* begin_;
+ int* end_;
- CountedView(int *ptr) : ptr_(ptr) {}
+ CountedView(int* b, int* e) : begin_(b), end_(e) { }
- auto begin() { return CountedIter(ptr_); }
- auto begin() const { return CountedIter(ptr_); }
- auto end() { return sentinel_wrapper<CountedIter>(CountedIter(ptr_ + 8)); }
- auto end() const { return sentinel_wrapper<CountedIter>(CountedIter(ptr_ + 8)); }
+ auto begin() { return CountedIter(begin_); }
+ auto begin() const { return CountedIter(begin_); }
+ auto end() { return sentinel_wrapper<CountedIter>(CountedIter(end_)); }
+ auto end() const { return sentinel_wrapper<CountedIter>(CountedIter(end_)); }
};
struct RASentRange : std::ranges::view_base {
using sent_t = sentinel_wrapper<random_access_iterator<int*>>;
using sent_const_t = sentinel_wrapper<random_access_iterator<const int*>>;
- int *ptr_;
+ int* begin_;
+ int* end_;
- constexpr RASentRange(int *ptr) : ptr_(ptr) {}
+ constexpr RASentRange(int* b, int* e) : begin_(b), end_(e) { }
- constexpr random_access_iterator<int*> begin() { return random_access_iterator<int*>{ptr_}; }
- constexpr random_access_iterator<const int*> begin() const { return random_access_iterator<const int*>{ptr_}; }
- constexpr sent_t end() { return sent_t{random_access_iterator<int*>{ptr_ + 8}}; }
- constexpr sent_const_t end() const { return sent_const_t{random_access_iterator<const int*>{ptr_ + 8}}; }
+ constexpr random_access_iterator<int*> begin() { return random_access_iterator<int*>{begin_}; }
+ constexpr random_access_iterator<const int*> begin() const { return random_access_iterator<const int*>{begin_}; }
+ constexpr sent_t end() { return sent_t{random_access_iterator<int*>{end_}}; }
+ constexpr sent_const_t end() const { return sent_const_t{random_access_iterator<const int*>{end_}}; }
};
template<class T>
// Common bidirectional range.
{
- auto rev = std::ranges::reverse_view(BidirRange{buffer});
+ auto rev = std::ranges::reverse_view(BidirRange{buffer, buffer + 8});
assert(rev.begin().base().base() == buffer + 8);
assert(std::move(rev).begin().base().base() == buffer + 8);
}
// Const common bidirectional range.
{
- const auto rev = std::ranges::reverse_view(BidirRange{buffer});
+ const auto rev = std::ranges::reverse_view(BidirRange{buffer, buffer + 8});
assert(rev.begin().base().base() == buffer + 8);
assert(std::move(rev).begin().base().base() == buffer + 8);
}
// Non-common, non-const (move only) bidirectional range.
{
- auto rev = std::ranges::reverse_view(BidirSentRange<MoveOnly>{buffer});
+ auto rev = std::ranges::reverse_view(BidirSentRange<MoveOnly>{buffer, buffer + 8});
assert(std::move(rev).begin().base().base() == buffer + 8);
ASSERT_SAME_TYPE(decltype(std::move(rev).begin()), std::reverse_iterator<bidirectional_iterator<int*>>);
}
// Non-common, non-const bidirectional range.
{
- auto rev = std::ranges::reverse_view(BidirSentRange<Copyable>{buffer});
+ auto rev = std::ranges::reverse_view(BidirSentRange<Copyable>{buffer, buffer + 8});
assert(rev.begin().base().base() == buffer + 8);
assert(std::move(rev).begin().base().base() == buffer + 8);
// Note: const overload invalid for non-common ranges, though it would not be imposible
// to implement for random access ranges.
{
- auto rev = std::ranges::reverse_view(RASentRange{buffer});
+ auto rev = std::ranges::reverse_view(RASentRange{buffer, buffer + 8});
assert(rev.begin().base().base() == buffer + 8);
assert(std::move(rev).begin().base().base() == buffer + 8);
{
// Make sure we cache begin.
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
- CountedView view{buffer};
+ CountedView view{buffer, buffer + 8};
std::ranges::reverse_view rev(view);
assert(rev.begin().base().ptr_ == buffer + 8);
assert(globalCount == 8);
+++ /dev/null
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17
-// UNSUPPORTED: libcpp-no-concepts
-// UNSUPPORTED: libcpp-has-no-incomplete-ranges
-
-// template<class R>
-// reverse_view(R&&) -> reverse_view<views::all_t<R>>;
-
-#include <ranges>
-#include <cassert>
-#include <concepts>
-
-#include "test_iterators.h"
-
-struct View : std::ranges::view_base {
- friend int* begin(View&);
- friend int* begin(View const&);
- friend sentinel_wrapper<int*> end(View&);
- friend sentinel_wrapper<int*> end(View const&);
-};
-
-struct Range {
- friend int* begin(Range&);
- friend int* begin(Range const&);
- friend sentinel_wrapper<int*> end(Range&);
- friend sentinel_wrapper<int*> end(Range const&);
-};
-
-struct BorrowedRange {
- friend int* begin(BorrowedRange&);
- friend int* begin(BorrowedRange const&);
- friend sentinel_wrapper<int*> end(BorrowedRange&);
- friend sentinel_wrapper<int*> end(BorrowedRange const&);
-};
-
-template<>
-inline constexpr bool std::ranges::enable_borrowed_range<BorrowedRange> = true;
-
-void testCTAD() {
- View v;
- Range r;
- BorrowedRange br;
- static_assert(std::same_as<
- decltype(std::ranges::reverse_view(v)),
- std::ranges::reverse_view<View>
- >);
- static_assert(std::same_as<
- decltype(std::ranges::reverse_view(r)),
- std::ranges::reverse_view<std::ranges::ref_view<Range>>
- >);
- // std::ranges::reverse_view(std::move(r)) invalid. RValue range must be borrowed.
- static_assert(std::same_as<
- decltype(std::ranges::reverse_view(br)),
- std::ranges::reverse_view<std::ranges::ref_view<BorrowedRange>>
- >);
- static_assert(std::same_as<
- decltype(std::ranges::reverse_view(std::move(br))),
- std::ranges::reverse_view<std::ranges::subrange<
- int *, sentinel_wrapper<int *>, std::ranges::subrange_kind::unsized>>
- >);
-}
--- /dev/null
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-no-concepts
+// UNSUPPORTED: libcpp-has-no-incomplete-ranges
+
+// template<class R>
+// reverse_view(R&&) -> reverse_view<views::all_t<R>>;
+
+#include <ranges>
+
+#include <concepts>
+#include <utility>
+
+#include "test_iterators.h"
+
+struct View : std::ranges::view_base {
+ friend int* begin(View&) { return nullptr; }
+ friend int* begin(View const&) { return nullptr; }
+ friend sentinel_wrapper<int*> end(View&) { return sentinel_wrapper<int*>(nullptr); }
+ friend sentinel_wrapper<int*> end(View const&) { return sentinel_wrapper<int*>(nullptr); }
+};
+
+struct Range {
+ friend int* begin(Range&) { return nullptr; }
+ friend int* begin(Range const&) { return nullptr; }
+ friend sentinel_wrapper<int*> end(Range&) { return sentinel_wrapper<int*>(nullptr); }
+ friend sentinel_wrapper<int*> end(Range const&) { return sentinel_wrapper<int*>(nullptr); }
+};
+
+struct BorrowedRange {
+ friend int* begin(BorrowedRange&) { return nullptr; }
+ friend int* begin(BorrowedRange const&) { return nullptr; }
+ friend sentinel_wrapper<int*> end(BorrowedRange&) { return sentinel_wrapper<int*>(nullptr); }
+ friend sentinel_wrapper<int*> end(BorrowedRange const&) { return sentinel_wrapper<int*>(nullptr); }
+};
+
+template<>
+inline constexpr bool std::ranges::enable_borrowed_range<BorrowedRange> = true;
+
+int main(int, char**) {
+ View v;
+ Range r;
+ BorrowedRange br;
+
+ {
+ std::same_as<std::ranges::reverse_view<View>> auto x = std::ranges::reverse_view(v);
+ (void)x;
+ }
+ {
+ std::same_as<std::ranges::reverse_view<std::ranges::ref_view<Range>>> auto x = std::ranges::reverse_view(r);
+ (void)x;
+ // std::ranges::reverse_view(std::move(r)) is invalid. RValue range must be borrowed.
+ }
+ {
+ std::same_as<std::ranges::reverse_view<std::ranges::ref_view<BorrowedRange>>> auto x = std::ranges::reverse_view(br);
+ (void)x;
+ }
+ {
+ using Subrange = std::ranges::subrange<int *, sentinel_wrapper<int *>, std::ranges::subrange_kind::unsized>;
+ std::same_as<std::ranges::reverse_view<Subrange>> auto x = std::ranges::reverse_view(std::move(br));
+ (void)x;
+ }
+
+ return 0;
+}
#include <ranges>
#include <cassert>
-#include "test_macros.h"
#include "types.h"
enum CtorKind { DefaultCtor, PtrCtor };
// constexpr explicit reverse_view(V r);
#include <ranges>
+
#include <cassert>
+#include <type_traits>
+#include <utility>
-#include "test_macros.h"
#include "types.h"
constexpr bool test() {
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};
{
- BidirRange r{buffer};
+ BidirRange r{buffer, buffer + 8};
std::ranges::reverse_view<BidirRange> rev(r);
- assert(rev.base().ptr_ == buffer);
+ assert(rev.base().begin_ == buffer);
+ assert(rev.base().end_ == buffer + 8);
}
{
- const BidirRange r{buffer};
+ const BidirRange r{buffer, buffer + 8};
const std::ranges::reverse_view<BidirRange> rev(r);
- assert(rev.base().ptr_ == buffer);
+ assert(rev.base().begin_ == buffer);
+ assert(rev.base().end_ == buffer + 8);
}
{
- std::ranges::reverse_view<BidirSentRange<MoveOnly>> rev(BidirSentRange<MoveOnly>{buffer});
- assert(std::move(rev).base().ptr_ == buffer);
+ std::ranges::reverse_view<BidirSentRange<MoveOnly>> rev(BidirSentRange<MoveOnly>{buffer, buffer + 8});
+ auto moved = std::move(rev).base();
+ assert(moved.begin_ == buffer);
+ assert(moved.end_ == buffer + 8);
}
{
- const std::ranges::reverse_view<BidirSentRange<Copyable>> rev(BidirSentRange<Copyable>{buffer});
- assert(rev.base().ptr_ == buffer);
+ const std::ranges::reverse_view<BidirSentRange<Copyable>> rev(BidirSentRange<Copyable>{buffer, buffer + 8});
+ assert(rev.base().begin_ == buffer);
+ assert(rev.base().end_ == buffer + 8);
}
{
// Make sure this ctor is marked as "explicit".
// constexpr auto end() const requires common_range<const V>;
#include <ranges>
+
#include <cassert>
+#include <utility>
#include "test_macros.h"
#include "types.h"
// Common bidirectional range.
{
- auto rev = std::ranges::reverse_view(BidirRange{buffer});
+ auto rev = std::ranges::reverse_view(BidirRange{buffer, buffer + 8});
assert(rev.end().base().base() == buffer);
assert(std::move(rev).end().base().base() == buffer);
}
// Const common bidirectional range.
{
- const auto rev = std::ranges::reverse_view(BidirRange{buffer});
+ const auto rev = std::ranges::reverse_view(BidirRange{buffer, buffer + 8});
assert(rev.end().base().base() == buffer);
assert(std::move(rev).end().base().base() == buffer);
}
// Non-common, non-const (move only) bidirectional range.
{
- auto rev = std::ranges::reverse_view(BidirSentRange<MoveOnly>{buffer});
+ auto rev = std::ranges::reverse_view(BidirSentRange<MoveOnly>{buffer, buffer + 8});
assert(std::move(rev).end().base().base() == buffer);
ASSERT_SAME_TYPE(decltype(std::move(rev).end()), std::reverse_iterator<bidirectional_iterator<int*>>);
}
// Non-common, const bidirectional range.
{
- auto rev = std::ranges::reverse_view(BidirSentRange<Copyable>{buffer});
+ auto rev = std::ranges::reverse_view(BidirSentRange<Copyable>{buffer, buffer + 8});
assert(rev.end().base().base() == buffer);
assert(std::move(rev).end().base().base() == buffer);
// constexpr auto size() const requires sized_range<const V>;
#include <ranges>
+
#include <cassert>
+#include <utility>
#include "test_macros.h"
#include "types.h"
#include "test_iterators.h"
struct BidirRange : std::ranges::view_base {
- int *ptr_;
+ int *begin_;
+ int* end_;
- constexpr BidirRange(int *ptr) : ptr_(ptr) {}
+ constexpr BidirRange(int* b, int* e) : begin_(b), end_(e) { }
- constexpr bidirectional_iterator<int*> begin() { return bidirectional_iterator<int*>{ptr_}; }
- constexpr bidirectional_iterator<const int*> begin() const { return bidirectional_iterator<const int*>{ptr_}; }
- constexpr bidirectional_iterator<int*> end() { return bidirectional_iterator<int*>{ptr_ + 8}; }
- constexpr bidirectional_iterator<const int*> end() const { return bidirectional_iterator<const int*>{ptr_ + 8}; }
+ constexpr bidirectional_iterator<int*> begin() { return bidirectional_iterator<int*>{begin_}; }
+ constexpr bidirectional_iterator<const int*> begin() const { return bidirectional_iterator<const int*>{begin_}; }
+ constexpr bidirectional_iterator<int*> end() { return bidirectional_iterator<int*>{end_}; }
+ constexpr bidirectional_iterator<const int*> end() const { return bidirectional_iterator<const int*>{end_}; }
};
enum CopyCategory { MoveOnly, Copyable };
using sent_t = sentinel_wrapper<bidirectional_iterator<int*>>;
using sent_const_t = sentinel_wrapper<bidirectional_iterator<const int*>>;
- int *ptr_;
+ int* begin_;
+ int* end_;
- constexpr BidirSentRange(int *ptr) : ptr_(ptr) {}
+ constexpr BidirSentRange(int* b, int* e) : begin_(b), end_(e) { }
constexpr BidirSentRange(const BidirSentRange &) requires (CC == Copyable) = default;
constexpr BidirSentRange(BidirSentRange &&) requires (CC == MoveOnly) = default;
constexpr BidirSentRange& operator=(const BidirSentRange &) requires (CC == Copyable) = default;
constexpr BidirSentRange& operator=(BidirSentRange &&) requires (CC == MoveOnly) = default;
- constexpr bidirectional_iterator<int*> begin() { return bidirectional_iterator<int*>{ptr_}; }
- constexpr bidirectional_iterator<const int*> begin() const { return bidirectional_iterator<const int*>{ptr_}; }
- constexpr sent_t end() { return sent_t{bidirectional_iterator<int*>{ptr_ + 8}}; }
- constexpr sent_const_t end() const { return sent_const_t{bidirectional_iterator<const int*>{ptr_ + 8}}; }
+ constexpr bidirectional_iterator<int*> begin() { return bidirectional_iterator<int*>{begin_}; }
+ constexpr bidirectional_iterator<const int*> begin() const { return bidirectional_iterator<const int*>{begin_}; }
+ constexpr sent_t end() { return sent_t{bidirectional_iterator<int*>{end_}}; }
+ constexpr sent_const_t end() const { return sent_const_t{bidirectional_iterator<const int*>{end_}}; }
};
#endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_REVERSE_TYPES_H