194461822SHui Xie //===----------------------------------------------------------------------===// 294461822SHui Xie // 394461822SHui Xie // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 494461822SHui Xie // See https://llvm.org/LICENSE.txt for license information. 594461822SHui Xie // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 694461822SHui Xie // 794461822SHui Xie //===----------------------------------------------------------------------===// 894461822SHui Xie 994461822SHui Xie // UNSUPPORTED: c++03, c++11, c++14, c++17 1094461822SHui Xie 1194461822SHui Xie // concept checking 1294461822SHui Xie // 1394461822SHui Xie // template<class T, size_t N> 1494461822SHui Xie // concept has-tuple-element = 1594461822SHui Xie // tuple-like<T> && N < tuple_size_v<T>; 1694461822SHui Xie // 1794461822SHui Xie // template<class T, size_t N> 1894461822SHui Xie // concept returnable-element = 1994461822SHui Xie // is_reference_v<T> || move_constructible<tuple_element_t<N, T>>; 2094461822SHui Xie // 2194461822SHui Xie // template<input_range V, size_t N> 2294461822SHui Xie // requires view<V> && has-tuple-element<range_value_t<V>, N> && 2394461822SHui Xie // has-tuple-element<remove_reference_t<range_reference_t<V>>, N> && 2494461822SHui Xie // returnable-element<range_reference_t<V>, N> 2594461822SHui Xie // class elements_view; 2694461822SHui Xie 2794461822SHui Xie #include <array> 2894461822SHui Xie #include <concepts> 2994461822SHui Xie #include <tuple> 3094461822SHui Xie #include <ranges> 3194461822SHui Xie #include <utility> 3294461822SHui Xie 3394461822SHui Xie #include "test_iterators.h" 3494461822SHui Xie 3594461822SHui Xie template <class It> 3694461822SHui Xie using Range = std::ranges::subrange<It, sentinel_wrapper<It>>; 3794461822SHui Xie 38*fb855eb9SMark de Wever template <class V, std::size_t N> 3994461822SHui Xie concept HasElementsView = requires { typename std::ranges::elements_view<V, N>; }; 4094461822SHui Xie 4194461822SHui Xie static_assert(HasElementsView<Range<std::ranges::subrange<int*>*>, 0>); 4294461822SHui Xie static_assert(HasElementsView<Range<std::pair<int, int>*>, 1>); 4394461822SHui Xie static_assert(HasElementsView<Range<std::tuple<int, int, int>*>, 2>); 4494461822SHui Xie static_assert(HasElementsView<Range<std::array<int, 4>*>, 3>); 4594461822SHui Xie 4694461822SHui Xie // !view<V> 4794461822SHui Xie static_assert(!std::ranges::view<std::array<std::tuple<int>, 1>>); 4894461822SHui Xie static_assert(!HasElementsView<std::array<std::tuple<int>, 1>, 0>); 4994461822SHui Xie 5094461822SHui Xie // !input_range 5194461822SHui Xie static_assert(!std::ranges::input_range<Range<cpp20_output_iterator<std::tuple<int>*>>>); 5294461822SHui Xie static_assert(!HasElementsView<Range<cpp20_output_iterator<std::tuple<int>*>>, 0>); 5394461822SHui Xie 5494461822SHui Xie // !tuple-like 5594461822SHui Xie static_assert(!HasElementsView<Range<int*>, 1>); 5694461822SHui Xie 5794461822SHui Xie // !(N < tuple_size_v<T>) 5894461822SHui Xie static_assert(!(2 < std::tuple_size_v< std::pair<int, int>>)); 5994461822SHui Xie static_assert(!HasElementsView<Range<std::pair<int, int>*>, 2>); 6094461822SHui Xie 6194461822SHui Xie // ! (is_reference_v<T> || move_constructible<tuple_element_t<N, T>>) 6294461822SHui Xie struct NonMovable { NonMovableNonMovable6394461822SHui Xie NonMovable(int) {} 6494461822SHui Xie NonMovable(NonMovable&&) = delete; 6594461822SHui Xie }; 6694461822SHui Xie static_assert(!std::move_constructible<NonMovable>); 6794461822SHui Xie 6894461822SHui Xie using NonMovableGenerator = __anonac528cf60102(int) 6994461822SHui Xie decltype(std::views::iota(0, 1) | std::views::transform([](int) { 7094461822SHui Xie return std::pair<NonMovable, int>{1, 1}; 7194461822SHui Xie })); 7294461822SHui Xie 7394461822SHui Xie static_assert(!HasElementsView<NonMovableGenerator, 0>); 7494461822SHui Xie static_assert(HasElementsView<NonMovableGenerator, 1>); 75