Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 31 additions & 25 deletions tests/std/include/range_algorithm_support.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ namespace test {
enum class ProxyRef : bool { no, yes };
enum class IsWrapped : bool { no, yes };

template <class T>
[[nodiscard]] constexpr bool to_bool(T const t) noexcept {
STATIC_ASSERT(std::is_enum_v<T> && std::same_as<std::underlying_type_t<T>, bool>);
return static_cast<bool>(t);
}

template <class Element, IsWrapped Wrapped = IsWrapped::yes>
class sentinel {
Element* ptr_ = nullptr;
Expand All @@ -103,13 +109,13 @@ namespace test {

using unwrap = sentinel<Element, IsWrapped::no>;

[[nodiscard]] constexpr auto _Unwrapped() const noexcept requires(bool(Wrapped)) {
[[nodiscard]] constexpr auto _Unwrapped() const noexcept requires(to_bool(Wrapped)) {
return unwrap{ptr_};
}

static constexpr bool _Unwrap_when_unverified = true;

constexpr void _Seek_to(unwrap const& s) noexcept requires(bool(Wrapped)) {
constexpr void _Seek_to(unwrap const& s) noexcept requires(to_bool(Wrapped)) {
ptr_ = s.base();
}
};
Expand Down Expand Up @@ -168,15 +174,15 @@ namespace test {
ProxyRef Proxy = ProxyRef{!derived_from<Category, contiguous>},
// Interact with the STL's iterator unwrapping machinery?
IsWrapped Wrapped = IsWrapped::yes>
requires (bool(Eq) || !derived_from<Category, fwd>)
&& (!bool(Proxy) || !derived_from<Category, contiguous>)
requires (to_bool(Eq) || !derived_from<Category, fwd>)
&& (!to_bool(Proxy) || !derived_from<Category, contiguous>)
class iterator {
Element* ptr_;

template <class T>
static constexpr bool at_least = derived_from<Category, T>;

using ReferenceType = conditional_t<bool(Proxy), proxy_reference<Category, Element>, Element&>;
using ReferenceType = conditional_t<to_bool(Proxy), proxy_reference<Category, Element>, Element&>;

public:
// output iterator operations
Expand All @@ -190,7 +196,7 @@ namespace test {
return *this;
}

[[nodiscard]] constexpr Element* base() const& noexcept requires (bool(Eq)) {
[[nodiscard]] constexpr Element* base() const& noexcept requires (to_bool(Eq)) {
return ptr_;
}
[[nodiscard]] constexpr Element* base() && noexcept {
Expand Down Expand Up @@ -264,12 +270,12 @@ namespace test {
}

// sentinel operations (implied by forward iterator):
iterator(iterator const&) requires (bool(Eq)) = default;
iterator& operator=(iterator const&) requires (bool(Eq)) = default;
[[nodiscard]] constexpr boolish operator==(iterator const& that) const noexcept requires (bool(Eq)) {
iterator(iterator const&) requires (to_bool(Eq)) = default;
iterator& operator=(iterator const&) requires (to_bool(Eq)) = default;
[[nodiscard]] constexpr boolish operator==(iterator const& that) const noexcept requires (to_bool(Eq)) {
return {ptr_ == that.ptr_};
}
[[nodiscard]] constexpr boolish operator!=(iterator const& that) const noexcept requires (bool(Eq)) {
[[nodiscard]] constexpr boolish operator!=(iterator const& that) const noexcept requires (to_bool(Eq)) {
return !(*this == that);
}

Expand Down Expand Up @@ -326,15 +332,15 @@ namespace test {

// sized_sentinel_for operations:
[[nodiscard]] constexpr ptrdiff_t operator-(iterator const& that) const noexcept
requires (bool(Diff) && bool(Eq)) || at_least<random> {
requires (to_bool(Diff) && to_bool(Eq)) || at_least<random> {
return ptr_ - that.ptr_;
}
[[nodiscard]] constexpr ptrdiff_t operator-(sentinel<Element, Wrapped> const& s) const noexcept
requires (bool(Diff)) {
requires (to_bool(Diff)) {
return ptr_ - s.base();
}
[[nodiscard]] friend constexpr ptrdiff_t operator-(
sentinel<Element, Wrapped> const& s, iterator const& i) noexcept requires (bool(Diff)) {
sentinel<Element, Wrapped> const& s, iterator const& i) noexcept requires (to_bool(Diff)) {
return -(i - s);
}

Expand All @@ -343,21 +349,21 @@ namespace test {

using unwrap = iterator<Category, Element, Diff, Eq, Proxy, IsWrapped::no>;

[[nodiscard]] constexpr auto _Unwrapped() const& noexcept requires (bool(Wrapped) && bool(Eq)) {
[[nodiscard]] constexpr auto _Unwrapped() const& noexcept requires (to_bool(Wrapped) && to_bool(Eq)) {
return unwrap{ptr_};
}

[[nodiscard]] constexpr auto _Unwrapped() && noexcept requires (bool(Wrapped)) {
[[nodiscard]] constexpr auto _Unwrapped() && noexcept requires (to_bool(Wrapped)) {
return unwrap{exchange(ptr_, nullptr)};
}

static constexpr bool _Unwrap_when_unverified = true;

constexpr void _Seek_to(unwrap const& i) noexcept requires (bool(Wrapped) && bool(Eq)) {
constexpr void _Seek_to(unwrap const& i) noexcept requires (to_bool(Wrapped) && to_bool(Eq)) {
ptr_ = i.base();
}

constexpr void _Seek_to(unwrap&& i) noexcept requires (bool(Wrapped)) {
constexpr void _Seek_to(unwrap&& i) noexcept requires (to_bool(Wrapped)) {
ptr_ = std::move(i).base();
}
};
Expand All @@ -369,8 +375,8 @@ template <class Category, class Element, ::test::CanDifference Diff, ::test::Can
struct std::iterator_traits<::test::iterator<Category, Element, Diff, Eq, Proxy, Wrapped>> {
using iterator_concept = Category;
using iterator_category = conditional_t<derived_from<Category, forward_iterator_tag>, //
conditional_t<bool(Proxy), input_iterator_tag, Category>, //
conditional_t<bool(Eq), Category, void>>; // TRANSITION, LWG-3289
conditional_t<static_cast<bool>(Proxy), input_iterator_tag, Category>, //
conditional_t<static_cast<bool>(Eq), Category, void>>; // TRANSITION, LWG-3289
using value_type = remove_cv_t<Element>;
using difference_type = ptrdiff_t;
using pointer = conditional_t<derived_from<Category, contiguous_iterator_tag>, Element*, void>;
Expand Down Expand Up @@ -406,16 +412,16 @@ namespace test {
CanCompare Eq = CanCompare{derived_from<Category, fwd>},
// Use a ProxyRef reference type?
ProxyRef Proxy = ProxyRef{!derived_from<Category, contiguous>}>
requires (!bool(IsCommon) || bool(Eq))
&& (bool(Eq) || !derived_from<Category, fwd>)
&& (!bool(Proxy) || !derived_from<Category, contiguous>)
requires (!to_bool(IsCommon) || to_bool(Eq))
&& (to_bool(Eq) || !derived_from<Category, fwd>)
&& (!to_bool(Proxy) || !derived_from<Category, contiguous>)
class range : ranges::view_base {
span<Element> elements_;
mutable bool begin_called_ = false;

public:
using I = iterator<Category, Element, Diff, Eq, Proxy, IsWrapped::yes>;
using S = conditional_t<bool(IsCommon), I, sentinel<Element, IsWrapped::yes>>;
using S = conditional_t<to_bool(IsCommon), I, sentinel<Element, IsWrapped::yes>>;

range() = default;
constexpr explicit range(span<Element> elements) noexcept : elements_{elements} {}
Expand Down Expand Up @@ -443,7 +449,7 @@ namespace test {
return S{elements_.data() + elements_.size()};
}

[[nodiscard]] constexpr ptrdiff_t size() const noexcept requires (bool(IsSized)) {
[[nodiscard]] constexpr ptrdiff_t size() const noexcept requires (to_bool(IsSized)) {
if constexpr (!derived_from<Category, fwd>) {
assert(!begin_called_);
}
Expand All @@ -455,7 +461,7 @@ namespace test {
}

using UI = iterator<Category, Element, Diff, Eq, Proxy, IsWrapped::no>;
using US = conditional_t<bool(IsCommon), I, sentinel<Element, IsWrapped::no>>;
using US = conditional_t<to_bool(IsCommon), I, sentinel<Element, IsWrapped::no>>;

[[nodiscard]] constexpr UI _Unchecked_begin() const noexcept {
return UI{elements_.data()};
Expand Down
8 changes: 4 additions & 4 deletions tests/std/tests/P0896R4_ranges_subrange/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,20 +91,20 @@ namespace test_view_interface {
t[42];
};

using test::Common, test::CanDifference, test::CanCompare, test::ProxyRef;
using test::CanCompare, test::CanDifference, test::Common, test::ProxyRef, test::to_bool;
enum class ConstRange : bool { no, yes };

// clang-format off
template <class Cat, Common IsCommon, CanDifference Diff, ConstRange HasConstRange>
struct fake_view : ranges::view_interface<fake_view<Cat, IsCommon, Diff, HasConstRange>> {
using I = test::iterator<Cat, int, Diff, CanCompare::yes, ProxyRef::no>;
using S = std::conditional_t<bool(IsCommon), I, test::sentinel<int>>;
using S = std::conditional_t<to_bool(IsCommon), I, test::sentinel<int>>;

I begin();
I begin() const requires (bool(HasConstRange));
I begin() const requires (to_bool(HasConstRange));

S end();
S end() const requires (bool(HasConstRange));
S end() const requires (to_bool(HasConstRange));
};
// clang-format on

Expand Down
20 changes: 10 additions & 10 deletions tests/std/tests/P0896R4_ranges_test_machinery/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ using namespace std;

int main() {} // COMPILE-ONLY

using test::CanDifference, test::CanCompare, test::ProxyRef, test::IsWrapped;
using test::CanCompare, test::CanDifference, test::IsWrapped, test::ProxyRef, test::to_bool;

// Validate test::iterator and test::sentinel
template <class Category, class Element, CanDifference Diff, CanCompare Eq, ProxyRef Proxy, IsWrapped Wrapped>
Expand All @@ -39,11 +39,11 @@ constexpr bool iter_test() {

using S = sentinel<Element, Wrapped>;
STATIC_ASSERT(sentinel_for<S, I>);
STATIC_ASSERT(!bool(Diff) || sized_sentinel_for<S, I>);
STATIC_ASSERT(!bool(Eq) || sentinel_for<I, I>);
STATIC_ASSERT(!bool(Eq) || !bool(Diff) || sized_sentinel_for<I, I>);
STATIC_ASSERT(!to_bool(Diff) || sized_sentinel_for<S, I>);
STATIC_ASSERT(!to_bool(Eq) || sentinel_for<I, I>);
STATIC_ASSERT(!to_bool(Eq) || !to_bool(Diff) || sized_sentinel_for<I, I>);

if constexpr (bool(Wrapped)) {
if constexpr (to_bool(Wrapped)) {
STATIC_ASSERT(same_as<_Unwrapped_t<I>, iterator<Category, Element, Diff, Eq, Proxy, IsWrapped::no>>);
STATIC_ASSERT(same_as<_Unwrapped_t<S>, sentinel<Element, IsWrapped::no>>);
}
Expand Down Expand Up @@ -170,18 +170,18 @@ constexpr bool range_test() {
STATIC_ASSERT(!derived_from<Category, random_access_iterator_tag> || ranges::random_access_range<R>);
STATIC_ASSERT(!derived_from<Category, contiguous_iterator_tag> || ranges::contiguous_range<R>);

if constexpr (bool(IsCommon)) {
STATIC_ASSERT(bool(Eq));
if constexpr (to_bool(IsCommon)) {
STATIC_ASSERT(to_bool(Eq));
STATIC_ASSERT(ranges::common_range<R>);
} else {
STATIC_ASSERT(same_as<S, test::sentinel<Element, IsWrapped::yes>>);
}

STATIC_ASSERT(!bool(Eq) || sentinel_for<I, I>);
STATIC_ASSERT(!to_bool(Eq) || sentinel_for<I, I>);

constexpr bool is_sized = bool(IsSized) || (bool(Diff) && derived_from<Category, forward_iterator_tag>);
constexpr bool is_sized = to_bool(IsSized) || (to_bool(Diff) && derived_from<Category, forward_iterator_tag>);
STATIC_ASSERT(ranges::sized_range<R> == is_sized);
if constexpr (bool(IsSized)) {
if constexpr (to_bool(IsSized)) {
STATIC_ASSERT(has_member_size<R>);
}

Expand Down