//===----------------------------------------------------------------------===// // // 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, c++20 // ADDITIONAL_COMPILE_FLAGS(gcc-style-warnings): -Wno-sign-compare // MSVC warning C4242: 'argument': conversion from 'const _Ty' to 'ElementT', possible loss of data // MSVC warning C4244: 'argument': conversion from 'const _Ty' to 'ElementT', possible loss of data // ADDITIONAL_COMPILE_FLAGS(cl-style-warnings): /wd4242 /wd4244 // template S, class T, class Proj = identity> // requires indirect_binary_predicate, const T*> // constexpr subrange ranges::find_last(I first, S last, const T& value, Proj proj = {}); // template // requires indirect_binary_predicate, Proj>, const T*> // constexpr borrowed_subrange_t ranges::find_last(R&& r, const T& value, Proj proj = {}); #include #include #include #include #include #include #include "almost_satisfies_types.h" #include "test_iterators.h" struct NotEqualityComparable {}; template concept HasFindLastIt = requires(It it, Sent sent) { std::ranges::find_last(it, sent, *it); }; static_assert(HasFindLastIt); static_assert(HasFindLastIt>); static_assert(!HasFindLastIt>); static_assert(!HasFindLastIt); static_assert(!HasFindLastIt); static_assert(!HasFindLastIt); static_assert(!HasFindLastIt, SentinelForNotSemiregular>); static_assert(!HasFindLastIt, InputRangeNotSentinelEqualityComparableWith>); static_assert(!HasFindLastIt); static_assert(!HasFindLastIt); template concept HasFindLastR = requires(Range r) { std::ranges::find_last(r, ValT{}); }; static_assert(HasFindLastR, int>); static_assert(!HasFindLastR); static_assert(!HasFindLastR, NotEqualityComparable>); static_assert(!HasFindLastR); static_assert(!HasFindLastR); static_assert(!HasFindLastR); static_assert(!HasFindLastR); template constexpr void test_iterators() { using ValueT = std::iter_value_t; auto make_range = [](auto& a) { return std::ranges::subrange( It(std::to_address(std::ranges::begin(a))), Sent(It(std::to_address(std::ranges::end(a))))); }; { // simple test { ValueT a[] = {1, 2, 3, 4}; std::same_as> auto ret = std::ranges::find_last(It(a), Sent(It(a + 4)), 2); assert(base(ret.begin()) == a + 1); assert(*ret.begin() == 2); } { ValueT a[] = {1, 2, 3, 4}; std::same_as> auto ret = std::ranges::find_last(make_range(a), 2); assert(base(ret.begin()) == a + 1); assert(*ret.begin() == 2); } } { // check that an empty range works { std::array a = {}; auto ret = std::ranges::find_last(It(a.data()), Sent(It(a.data())), 1).begin(); assert(ret == It(a.data())); } { std::array a = {}; auto ret = std::ranges::find_last(make_range(a), 1).begin(); assert(ret == It(a.data())); } } { // check that last is returned with no match { ValueT a[] = {1, 1, 1}; auto ret = std::ranges::find_last(It(a), Sent(It(a + 3)), 0).begin(); assert(ret == It(a + 3)); } { ValueT a[] = {1, 1, 1}; auto ret = std::ranges::find_last(make_range(a), 0).begin(); assert(ret == It(a + 3)); } } } template