xref: /llvm-project/libcxx/test/std/ranges/range.adaptors/range.take/range.take.sentinel/eq.pass.cpp (revision 808d794a45e169601ff16f72beae2f7bd79342a2)
10b46606cSJakub Mazurkiewicz //===----------------------------------------------------------------------===//
20b46606cSJakub Mazurkiewicz //
30b46606cSJakub Mazurkiewicz // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b46606cSJakub Mazurkiewicz // See https://llvm.org/LICENSE.txt for license information.
50b46606cSJakub Mazurkiewicz // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b46606cSJakub Mazurkiewicz //
70b46606cSJakub Mazurkiewicz //===----------------------------------------------------------------------===//
80b46606cSJakub Mazurkiewicz 
90b46606cSJakub Mazurkiewicz // UNSUPPORTED: c++03, c++11, c++14, c++17
100b46606cSJakub Mazurkiewicz 
110b46606cSJakub Mazurkiewicz // friend constexpr bool operator==(const CI<Const>& y, const sentinel& x);
120b46606cSJakub Mazurkiewicz // template<bool OtherConst = !Const>
130b46606cSJakub Mazurkiewicz //   requires sentinel_for<sentinel_t<Base>, iterator_t<maybe-const<OtherConst, V>>>
140b46606cSJakub Mazurkiewicz // friend constexpr bool operator==(const CI<OtherConst>& y, const sentinel& x);
150b46606cSJakub Mazurkiewicz 
160b46606cSJakub Mazurkiewicz #include <cassert>
170b46606cSJakub Mazurkiewicz #include <cstddef>
180b46606cSJakub Mazurkiewicz #include <ranges>
190b46606cSJakub Mazurkiewicz #include <type_traits>
200b46606cSJakub Mazurkiewicz #include <utility>
210b46606cSJakub Mazurkiewicz 
220b46606cSJakub Mazurkiewicz #include "test_comparisons.h"
230b46606cSJakub Mazurkiewicz #include "test_iterators.h"
24*808d794aSWill Hawkins #include "test_range.h"
250b46606cSJakub Mazurkiewicz 
260b46606cSJakub Mazurkiewicz template <bool Const>
270b46606cSJakub Mazurkiewicz using MaybeConstIterator = cpp20_input_iterator<std::conditional_t<Const, const int*, int*>>;
280b46606cSJakub Mazurkiewicz 
290b46606cSJakub Mazurkiewicz template <bool Const>
300b46606cSJakub Mazurkiewicz class CrossConstComparableSentinel {
310b46606cSJakub Mazurkiewicz   using Base = std::conditional_t<Const, const int*, int*>;
320b46606cSJakub Mazurkiewicz   Base base_;
330b46606cSJakub Mazurkiewicz 
340b46606cSJakub Mazurkiewicz public:
350b46606cSJakub Mazurkiewicz   CrossConstComparableSentinel() = default;
CrossConstComparableSentinel(Base base)360b46606cSJakub Mazurkiewicz   constexpr explicit CrossConstComparableSentinel(Base base) : base_(base) {}
370b46606cSJakub Mazurkiewicz 
operator ==(const MaybeConstIterator<Const> & it,const CrossConstComparableSentinel & se)380b46606cSJakub Mazurkiewicz   friend constexpr bool operator==(const MaybeConstIterator<Const>& it, const CrossConstComparableSentinel& se) {
390b46606cSJakub Mazurkiewicz     return base(it) == se.base_;
400b46606cSJakub Mazurkiewicz   }
410b46606cSJakub Mazurkiewicz 
operator ==(const MaybeConstIterator<!Const> & it,const CrossConstComparableSentinel & se)420b46606cSJakub Mazurkiewicz   friend constexpr bool operator==(const MaybeConstIterator<!Const>& it, const CrossConstComparableSentinel& se) {
430b46606cSJakub Mazurkiewicz     return base(it) == se.base_;
440b46606cSJakub Mazurkiewicz   }
450b46606cSJakub Mazurkiewicz };
460b46606cSJakub Mazurkiewicz 
470b46606cSJakub Mazurkiewicz static_assert(std::sentinel_for<CrossConstComparableSentinel<true>, MaybeConstIterator<false>>);
480b46606cSJakub Mazurkiewicz static_assert(std::sentinel_for<CrossConstComparableSentinel<true>, MaybeConstIterator<true>>);
490b46606cSJakub Mazurkiewicz static_assert(std::sentinel_for<CrossConstComparableSentinel<false>, MaybeConstIterator<false>>);
500b46606cSJakub Mazurkiewicz static_assert(std::sentinel_for<CrossConstComparableSentinel<false>, MaybeConstIterator<true>>);
510b46606cSJakub Mazurkiewicz 
520b46606cSJakub Mazurkiewicz struct CrossConstComparableView : std::ranges::view_base {
530b46606cSJakub Mazurkiewicz   template <std::size_t N>
CrossConstComparableViewCrossConstComparableView540b46606cSJakub Mazurkiewicz   constexpr explicit CrossConstComparableView(int (&arr)[N]) : b_(arr), e_(arr + N) {}
550b46606cSJakub Mazurkiewicz 
beginCrossConstComparableView560b46606cSJakub Mazurkiewicz   constexpr MaybeConstIterator<false> begin() { return MaybeConstIterator<false>{b_}; }
endCrossConstComparableView570b46606cSJakub Mazurkiewicz   constexpr CrossConstComparableSentinel<false> end() { return CrossConstComparableSentinel<false>{e_}; }
580b46606cSJakub Mazurkiewicz 
beginCrossConstComparableView590b46606cSJakub Mazurkiewicz   constexpr MaybeConstIterator<true> begin() const { return MaybeConstIterator<true>{b_}; }
endCrossConstComparableView600b46606cSJakub Mazurkiewicz   constexpr CrossConstComparableSentinel<true> end() const { return CrossConstComparableSentinel<true>{e_}; }
610b46606cSJakub Mazurkiewicz 
620b46606cSJakub Mazurkiewicz private:
630b46606cSJakub Mazurkiewicz   int* b_;
640b46606cSJakub Mazurkiewicz   int* e_;
650b46606cSJakub Mazurkiewicz };
660b46606cSJakub Mazurkiewicz 
670b46606cSJakub Mazurkiewicz static_assert(std::ranges::range<CrossConstComparableView>);
680b46606cSJakub Mazurkiewicz static_assert(std::ranges::range<const CrossConstComparableView>);
690b46606cSJakub Mazurkiewicz 
700b46606cSJakub Mazurkiewicz struct NonCrossConstComparableView : std::ranges::view_base {
710b46606cSJakub Mazurkiewicz   int* begin();
720b46606cSJakub Mazurkiewicz   sentinel_wrapper<int*> end();
730b46606cSJakub Mazurkiewicz 
740b46606cSJakub Mazurkiewicz   long* begin() const;
750b46606cSJakub Mazurkiewicz   sentinel_wrapper<long*> end() const;
760b46606cSJakub Mazurkiewicz };
770b46606cSJakub Mazurkiewicz 
780b46606cSJakub Mazurkiewicz static_assert(std::ranges::range<NonCrossConstComparableView>);
790b46606cSJakub Mazurkiewicz static_assert(std::ranges::range<const NonCrossConstComparableView>);
800b46606cSJakub Mazurkiewicz 
test()810b46606cSJakub Mazurkiewicz constexpr bool test() {
820b46606cSJakub Mazurkiewicz   int buffer[8]                      = {1, 2, 3, 4, 5, 6, 7, 8};
830b46606cSJakub Mazurkiewicz   using CrossConstComparableTakeView = std::ranges::take_view<CrossConstComparableView>;
840b46606cSJakub Mazurkiewicz 
850b46606cSJakub Mazurkiewicz   {   // Compare CI<Const> with sentinel<Const>
860b46606cSJakub Mazurkiewicz     { // Const == true
870b46606cSJakub Mazurkiewicz       AssertEqualityReturnBool<std::ranges::iterator_t<const CrossConstComparableTakeView>,
880b46606cSJakub Mazurkiewicz                                std::ranges::sentinel_t<const CrossConstComparableTakeView>>();
890b46606cSJakub Mazurkiewicz       const CrossConstComparableTakeView tv(CrossConstComparableView{buffer}, 4);
900b46606cSJakub Mazurkiewicz       assert(testEquality(std::ranges::next(tv.begin(), 4), tv.end(), true));
910b46606cSJakub Mazurkiewicz       assert(testEquality(tv.begin(), tv.end(), false));
920b46606cSJakub Mazurkiewicz     }
930b46606cSJakub Mazurkiewicz 
940b46606cSJakub Mazurkiewicz     { // Const == false
950b46606cSJakub Mazurkiewicz       AssertEqualityReturnBool<std::ranges::iterator_t<CrossConstComparableTakeView>,
960b46606cSJakub Mazurkiewicz                                std::ranges::sentinel_t<CrossConstComparableTakeView>>();
970b46606cSJakub Mazurkiewicz       CrossConstComparableTakeView tv(CrossConstComparableView{buffer}, 4);
980b46606cSJakub Mazurkiewicz       assert(testEquality(std::ranges::next(tv.begin(), 4), tv.end(), true));
990b46606cSJakub Mazurkiewicz       assert(testEquality(std::ranges::next(tv.begin(), 1), tv.end(), false));
1000b46606cSJakub Mazurkiewicz     }
1010b46606cSJakub Mazurkiewicz   }
1020b46606cSJakub Mazurkiewicz 
1030b46606cSJakub Mazurkiewicz   {   // Compare CI<Const> with sentinel<!Const>
1040b46606cSJakub Mazurkiewicz     { // Const == true
1050b46606cSJakub Mazurkiewicz       AssertEqualityReturnBool<std::ranges::iterator_t<const CrossConstComparableTakeView>,
1060b46606cSJakub Mazurkiewicz                                std::ranges::sentinel_t<CrossConstComparableTakeView>>();
1070b46606cSJakub Mazurkiewicz       CrossConstComparableTakeView tv(CrossConstComparableView{buffer}, 4);
1080b46606cSJakub Mazurkiewicz       assert(testEquality(std::ranges::next(std::as_const(tv).begin(), 4), tv.end(), true));
1090b46606cSJakub Mazurkiewicz       assert(testEquality(std::ranges::next(std::as_const(tv).begin(), 2), tv.end(), false));
1100b46606cSJakub Mazurkiewicz     }
1110b46606cSJakub Mazurkiewicz 
1120b46606cSJakub Mazurkiewicz     { // Const == false
1130b46606cSJakub Mazurkiewicz       AssertEqualityReturnBool<std::ranges::iterator_t<CrossConstComparableTakeView>,
1140b46606cSJakub Mazurkiewicz                                std::ranges::sentinel_t<const CrossConstComparableTakeView>>();
1150b46606cSJakub Mazurkiewicz       CrossConstComparableTakeView tv(CrossConstComparableView{buffer}, 4);
1160b46606cSJakub Mazurkiewicz       assert(testEquality(std::ranges::next(tv.begin(), 4), std::as_const(tv).end(), true));
1170b46606cSJakub Mazurkiewicz       assert(testEquality(std::ranges::next(tv.begin(), 3), std::as_const(tv).end(), false));
1180b46606cSJakub Mazurkiewicz     }
1190b46606cSJakub Mazurkiewicz   }
1200b46606cSJakub Mazurkiewicz 
1210b46606cSJakub Mazurkiewicz   { // Check invalid comparisons between CI<Const> and sentinel<!Const>
1220b46606cSJakub Mazurkiewicz     using TakeView = std::ranges::take_view<NonCrossConstComparableView>;
1230b46606cSJakub Mazurkiewicz     static_assert(
1240b46606cSJakub Mazurkiewicz         !weakly_equality_comparable_with<std::ranges::iterator_t<const TakeView>, std::ranges::sentinel_t<TakeView>>);
1250b46606cSJakub Mazurkiewicz     static_assert(
1260b46606cSJakub Mazurkiewicz         !weakly_equality_comparable_with<std::ranges::iterator_t<TakeView>, std::ranges::sentinel_t<const TakeView>>);
1270b46606cSJakub Mazurkiewicz 
1280b46606cSJakub Mazurkiewicz     // Those should be valid
1290b46606cSJakub Mazurkiewicz     static_assert(
1300b46606cSJakub Mazurkiewicz         weakly_equality_comparable_with<std::ranges::iterator_t<TakeView>, std::ranges::sentinel_t<TakeView>>);
1310b46606cSJakub Mazurkiewicz     static_assert(weakly_equality_comparable_with<std::ranges::iterator_t<const TakeView>,
1320b46606cSJakub Mazurkiewicz                                                   std::ranges::sentinel_t<const TakeView>>);
1330b46606cSJakub Mazurkiewicz   }
1340b46606cSJakub Mazurkiewicz 
1350b46606cSJakub Mazurkiewicz   return true;
1360b46606cSJakub Mazurkiewicz }
1370b46606cSJakub Mazurkiewicz 
main(int,char **)1380b46606cSJakub Mazurkiewicz int main(int, char**) {
1390b46606cSJakub Mazurkiewicz   test();
1400b46606cSJakub Mazurkiewicz   static_assert(test());
1410b46606cSJakub Mazurkiewicz 
1420b46606cSJakub Mazurkiewicz   return 0;
1430b46606cSJakub Mazurkiewicz }
144