-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[libc++] Fix take_view::__sentinel
's operator==
#74655
Changes from all commits
b3de573
774a106
2cc7f73
3337a0f
4d13e66
ffd4028
65be339
5990388
dd074d4
172a729
3e5a158
ffb8fbb
6adb66e
bc21e0f
a27df91
7445c00
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,10 +8,7 @@ | |
|
||
// UNSUPPORTED: c++03, c++11, c++14, c++17 | ||
|
||
// sentinel() = default; | ||
// constexpr explicit sentinel(sentinel_t<Base> end); | ||
// constexpr sentinel(sentinel<!Const> s) | ||
// requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>; | ||
// constexpr sentinel_t<Base> base() const; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not attached to this line. What is the reason to rename the folder? The folder name is meant to itch the spec section id There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe that's already encoded in the parent directory as all other tests use just "sentinel" and "iterator" |
||
|
||
#include <ranges> | ||
#include <cassert> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// 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 | ||
|
||
// friend constexpr bool operator==(const CI<Const>& y, const sentinel& x); | ||
// template<bool OtherConst = !Const> | ||
// requires sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>> | ||
// friend constexpr bool operator==(const CI<OtherConst>& y, const sentinel& x); | ||
|
||
#include <cassert> | ||
#include <cstddef> | ||
#include <ranges> | ||
#include <type_traits> | ||
#include <utility> | ||
|
||
#include "test_comparisons.h" | ||
#include "test_iterators.h" | ||
|
||
template <bool Const> | ||
using MaybeConstIterator = cpp20_input_iterator<std::conditional_t<Const, const int*, int*>>; | ||
|
||
template <bool Const> | ||
class CrossConstComparableSentinel { | ||
using Base = std::conditional_t<Const, const int*, int*>; | ||
Base base_; | ||
|
||
public: | ||
CrossConstComparableSentinel() = default; | ||
constexpr explicit CrossConstComparableSentinel(Base base) : base_(base) {} | ||
|
||
friend constexpr bool operator==(const MaybeConstIterator<Const>& it, const CrossConstComparableSentinel& se) { | ||
return base(it) == se.base_; | ||
} | ||
|
||
friend constexpr bool operator==(const MaybeConstIterator<!Const>& it, const CrossConstComparableSentinel& se) { | ||
return base(it) == se.base_; | ||
} | ||
}; | ||
|
||
static_assert(std::sentinel_for<CrossConstComparableSentinel<true>, MaybeConstIterator<false>>); | ||
static_assert(std::sentinel_for<CrossConstComparableSentinel<true>, MaybeConstIterator<true>>); | ||
static_assert(std::sentinel_for<CrossConstComparableSentinel<false>, MaybeConstIterator<false>>); | ||
static_assert(std::sentinel_for<CrossConstComparableSentinel<false>, MaybeConstIterator<true>>); | ||
|
||
struct CrossConstComparableView : std::ranges::view_base { | ||
template <std::size_t N> | ||
constexpr explicit CrossConstComparableView(int (&arr)[N]) : b_(arr), e_(arr + N) {} | ||
|
||
constexpr MaybeConstIterator<false> begin() { return MaybeConstIterator<false>{b_}; } | ||
constexpr CrossConstComparableSentinel<false> end() { return CrossConstComparableSentinel<false>{e_}; } | ||
|
||
constexpr MaybeConstIterator<true> begin() const { return MaybeConstIterator<true>{b_}; } | ||
constexpr CrossConstComparableSentinel<true> end() const { return CrossConstComparableSentinel<true>{e_}; } | ||
|
||
private: | ||
int* b_; | ||
int* e_; | ||
}; | ||
|
||
static_assert(std::ranges::range<CrossConstComparableView>); | ||
static_assert(std::ranges::range<const CrossConstComparableView>); | ||
|
||
struct NonCrossConstComparableView : std::ranges::view_base { | ||
int* begin(); | ||
sentinel_wrapper<int*> end(); | ||
|
||
long* begin() const; | ||
sentinel_wrapper<long*> end() const; | ||
}; | ||
|
||
static_assert(std::ranges::range<NonCrossConstComparableView>); | ||
static_assert(std::ranges::range<const NonCrossConstComparableView>); | ||
|
||
template <class T, class U> | ||
concept weakly_equality_comparable_with = requires(const T& t, const U& u) { | ||
t == u; | ||
t != u; | ||
u == t; | ||
u != t; | ||
}; | ||
|
||
constexpr bool test() { | ||
int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8}; | ||
using CrossConstComparableTakeView = std::ranges::take_view<CrossConstComparableView>; | ||
|
||
{ // Compare CI<Const> with sentinel<Const> | ||
{ // Const == true | ||
AssertEqualityReturnBool<std::ranges::iterator_t<const CrossConstComparableTakeView>, | ||
std::ranges::sentinel_t<const CrossConstComparableTakeView>>(); | ||
const CrossConstComparableTakeView tv(CrossConstComparableView{buffer}, 4); | ||
assert(testEquality(std::ranges::next(tv.begin(), 4), tv.end(), true)); | ||
assert(testEquality(tv.begin(), tv.end(), false)); | ||
} | ||
|
||
{ // Const == false | ||
AssertEqualityReturnBool<std::ranges::iterator_t<CrossConstComparableTakeView>, | ||
std::ranges::sentinel_t<CrossConstComparableTakeView>>(); | ||
CrossConstComparableTakeView tv(CrossConstComparableView{buffer}, 4); | ||
assert(testEquality(std::ranges::next(tv.begin(), 4), tv.end(), true)); | ||
assert(testEquality(std::ranges::next(tv.begin(), 1), tv.end(), false)); | ||
} | ||
} | ||
|
||
{ // Compare CI<Const> with sentinel<!Const> | ||
{ // Const == true | ||
AssertEqualityReturnBool<std::ranges::iterator_t<const CrossConstComparableTakeView>, | ||
std::ranges::sentinel_t<CrossConstComparableTakeView>>(); | ||
CrossConstComparableTakeView tv(CrossConstComparableView{buffer}, 4); | ||
assert(testEquality(std::ranges::next(std::as_const(tv).begin(), 4), tv.end(), true)); | ||
assert(testEquality(std::ranges::next(std::as_const(tv).begin(), 2), tv.end(), false)); | ||
} | ||
|
||
{ // Const == false | ||
AssertEqualityReturnBool<std::ranges::iterator_t<CrossConstComparableTakeView>, | ||
std::ranges::sentinel_t<const CrossConstComparableTakeView>>(); | ||
CrossConstComparableTakeView tv(CrossConstComparableView{buffer}, 4); | ||
assert(testEquality(std::ranges::next(tv.begin(), 4), std::as_const(tv).end(), true)); | ||
assert(testEquality(std::ranges::next(tv.begin(), 3), std::as_const(tv).end(), false)); | ||
} | ||
} | ||
|
||
{ // Check invalid comparisons between CI<Const> and sentinel<!Const> | ||
using TakeView = std::ranges::take_view<NonCrossConstComparableView>; | ||
static_assert( | ||
!weakly_equality_comparable_with<std::ranges::iterator_t<const TakeView>, std::ranges::sentinel_t<TakeView>>); | ||
static_assert( | ||
!weakly_equality_comparable_with<std::ranges::iterator_t<TakeView>, std::ranges::sentinel_t<const TakeView>>); | ||
|
||
// Those should be valid | ||
static_assert( | ||
weakly_equality_comparable_with<std::ranges::iterator_t<TakeView>, std::ranges::sentinel_t<TakeView>>); | ||
static_assert(weakly_equality_comparable_with<std::ranges::iterator_t<const TakeView>, | ||
std::ranges::sentinel_t<const TakeView>>); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
int main(int, char**) { | ||
test(); | ||
static_assert(test()); | ||
|
||
return 0; | ||
} |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing to do with your patch, just wanted to point out that we don’t seem to have tests to test the default argument. (you don’t need to do it as this is nothing to do with the bug you are fixing)
template
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tried changing default argument to
_Const
and removing it, and in both cases test failed. I think that current coverage is enough.