//===----------------------------------------------------------------------===// // // 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() requires (!(simple-view && ...)); // constexpr auto begin() const requires (range && ...); #include #include #include #include #include #include "types.h" template concept HasConstBegin = requires(const T& ct) { ct.begin(); }; template concept HasBegin = requires(T& t) { t.begin(); }; template concept HasConstAndNonConstBegin = HasConstBegin && requires(T& t, const T& ct) { requires !std::same_as; }; template concept HasOnlyNonConstBegin = HasBegin && ! HasConstBegin; template concept HasOnlyConstBegin = HasConstBegin && ! HasConstAndNonConstBegin; struct NoConstBeginView : std::ranges::view_base { int* begin(); int* end(); }; constexpr bool test() { int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8}; { // all underlying iterators should be at the begin position std::ranges::zip_view v(SizedRandomAccessView{buffer}, std::views::iota(0), std::ranges::single_view(2.)); std::same_as> decltype(auto) val = *v.begin(); assert(val == std::make_tuple(1, 0, 2.0)); assert(&(std::get<0>(val)) == &buffer[0]); } { // with empty range std::ranges::zip_view v(SizedRandomAccessView{buffer}, std::ranges::empty_view()); assert(v.begin() == v.end()); } { // underlying ranges all model simple-view std::ranges::zip_view v(SimpleCommon{buffer}, SimpleCommon{buffer}); static_assert(std::is_same_v); assert(v.begin() == std::as_const(v).begin()); auto [x, y] = *std::as_const(v).begin(); assert(&x == &buffer[0]); assert(&y == &buffer[0]); using View = decltype(v); static_assert(HasOnlyConstBegin); static_assert(!HasOnlyNonConstBegin); static_assert(!HasConstAndNonConstBegin); } { // not all underlying ranges model simple-view std::ranges::zip_view v(SimpleCommon{buffer}, NonSimpleNonCommon{buffer}); static_assert(!std::is_same_v); assert(v.begin() == std::as_const(v).begin()); auto [x, y] = *std::as_const(v).begin(); assert(&x == &buffer[0]); assert(&y == &buffer[0]); using View = decltype(v); static_assert(!HasOnlyConstBegin); static_assert(!HasOnlyNonConstBegin); static_assert(HasConstAndNonConstBegin); } { // underlying const R is not a range using View = std::ranges::zip_view; static_assert(!HasOnlyConstBegin); static_assert(HasOnlyNonConstBegin); static_assert(!HasConstAndNonConstBegin); } return true; } int main(int, char**) { test(); static_assert(test()); return 0; }