//===----------------------------------------------------------------------===// // // 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 // constexpr auto begin() // constexpr auto begin() const #include #include #include #include #include "test_iterators.h" struct SimpleView : std::ranges::view_base { int* begin() const; int* end() const; }; struct NonSimpleView : std::ranges::view_base { char* begin(); char* end(); int* begin() const; int* end() const; }; struct NonConstView : std::ranges::view_base { char* begin(); char* end(); }; template concept HasBegin = requires(T t) { t.begin(); }; static_assert(HasBegin>); static_assert(HasBegin>); static_assert(HasBegin>); static_assert(HasBegin>); static_assert(HasBegin>); static_assert(!HasBegin>); template constexpr void test_range() { int a[] = {1, 2}; std::ranges::subrange range(Iter(std::begin(a)), Sent(Iter(std::end(a)))); std::ranges::as_rvalue_view view(std::move(range)); std::same_as> decltype(auto) iter = view.begin(); assert(base(iter.base()) == std::begin(a)); } template class WrapRange { Iter iter_; Sent sent_; public: constexpr WrapRange(Iter iter, Sent sent) : iter_(std::move(iter)), sent_(std::move(sent)) {} constexpr Iter begin() const { return iter_; } constexpr Sent end() const { return sent_; } }; template WrapRange(Iter, Sent) -> WrapRange; template constexpr void test_const_range() { int a[] = {1, 2}; auto range = WrapRange{Iter(a), Sent(Iter(a + 2))}; const std::ranges::as_rvalue_view view(std::views::all(range)); std::same_as> decltype(auto) iter = view.begin(); assert(base(iter.base()) == std::begin(a)); } struct move_iterator_view : std::ranges::view_base { constexpr std::move_iterator begin() const { return {}; } constexpr std::move_iterator end() const { return {}; } }; constexpr bool test() { types::for_each(types::cpp20_input_iterator_list{}, [] { if constexpr (std::sentinel_for) test_range(); test_range>(); test_range>(); }); types::for_each(types::forward_iterator_list{}, [] { test_const_range(); test_const_range>(); test_const_range>(); }); { // check that with a std::move_iterator begin() doesn't return move_iterator> std::ranges::as_rvalue_view view{move_iterator_view{}}; std::same_as> decltype(auto) it = view.begin(); assert(it == std::move_iterator{}); } return true; } int main(int, char**) { test(); static_assert(test()); return 0; }