1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // UNSUPPORTED: c++03, c++11, c++14, c++17 10 11 // concept checking 12 // 13 // template<class T, size_t N> 14 // concept has-tuple-element = 15 // tuple-like<T> && N < tuple_size_v<T>; 16 // 17 // template<class T, size_t N> 18 // concept returnable-element = 19 // is_reference_v<T> || move_constructible<tuple_element_t<N, T>>; 20 // 21 // template<input_range V, size_t N> 22 // requires view<V> && has-tuple-element<range_value_t<V>, N> && 23 // has-tuple-element<remove_reference_t<range_reference_t<V>>, N> && 24 // returnable-element<range_reference_t<V>, N> 25 // class elements_view; 26 27 #include <array> 28 #include <concepts> 29 #include <tuple> 30 #include <ranges> 31 #include <utility> 32 33 #include "test_iterators.h" 34 35 template <class It> 36 using Range = std::ranges::subrange<It, sentinel_wrapper<It>>; 37 38 template <class V, std::size_t N> 39 concept HasElementsView = requires { typename std::ranges::elements_view<V, N>; }; 40 41 static_assert(HasElementsView<Range<std::ranges::subrange<int*>*>, 0>); 42 static_assert(HasElementsView<Range<std::pair<int, int>*>, 1>); 43 static_assert(HasElementsView<Range<std::tuple<int, int, int>*>, 2>); 44 static_assert(HasElementsView<Range<std::array<int, 4>*>, 3>); 45 46 // !view<V> 47 static_assert(!std::ranges::view<std::array<std::tuple<int>, 1>>); 48 static_assert(!HasElementsView<std::array<std::tuple<int>, 1>, 0>); 49 50 // !input_range 51 static_assert(!std::ranges::input_range<Range<cpp20_output_iterator<std::tuple<int>*>>>); 52 static_assert(!HasElementsView<Range<cpp20_output_iterator<std::tuple<int>*>>, 0>); 53 54 // !tuple-like 55 static_assert(!HasElementsView<Range<int*>, 1>); 56 57 // !(N < tuple_size_v<T>) 58 static_assert(!(2 < std::tuple_size_v< std::pair<int, int>>)); 59 static_assert(!HasElementsView<Range<std::pair<int, int>*>, 2>); 60 61 // ! (is_reference_v<T> || move_constructible<tuple_element_t<N, T>>) 62 struct NonMovable { NonMovableNonMovable63 NonMovable(int) {} 64 NonMovable(NonMovable&&) = delete; 65 }; 66 static_assert(!std::move_constructible<NonMovable>); 67 68 using NonMovableGenerator = __anonac528cf60102(int) 69 decltype(std::views::iota(0, 1) | std::views::transform([](int) { 70 return std::pair<NonMovable, int>{1, 1}; 71 })); 72 73 static_assert(!HasElementsView<NonMovableGenerator, 0>); 74 static_assert(HasElementsView<NonMovableGenerator, 1>); 75