75 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710 11// concept checking12//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 35template <class It>36using Range = std::ranges::subrange<It, sentinel_wrapper<It>>;37 38template <class V, std::size_t N>39concept HasElementsView = requires { typename std::ranges::elements_view<V, N>; };40 41static_assert(HasElementsView<Range<std::ranges::subrange<int*>*>, 0>);42static_assert(HasElementsView<Range<std::pair<int, int>*>, 1>);43static_assert(HasElementsView<Range<std::tuple<int, int, int>*>, 2>);44static_assert(HasElementsView<Range<std::array<int, 4>*>, 3>);45 46// !view<V>47static_assert(!std::ranges::view<std::array<std::tuple<int>, 1>>);48static_assert(!HasElementsView<std::array<std::tuple<int>, 1>, 0>);49 50// !input_range51static_assert(!std::ranges::input_range<Range<cpp20_output_iterator<std::tuple<int>*>>>);52static_assert(!HasElementsView<Range<cpp20_output_iterator<std::tuple<int>*>>, 0>);53 54// !tuple-like55static_assert(!HasElementsView<Range<int*>, 1>);56 57// !(N < tuple_size_v<T>)58static_assert(!(2 < std::tuple_size_v< std::pair<int, int>>));59static_assert(!HasElementsView<Range<std::pair<int, int>*>, 2>);60 61// ! (is_reference_v<T> || move_constructible<tuple_element_t<N, T>>)62struct NonMovable {63 NonMovable(int) {}64 NonMovable(NonMovable&&) = delete;65};66static_assert(!std::move_constructible<NonMovable>);67 68using NonMovableGenerator =69 decltype(std::views::iota(0, 1) | std::views::transform([](int) {70 return std::pair<NonMovable, int>{1, 1};71 }));72 73static_assert(!HasElementsView<NonMovableGenerator, 0>);74static_assert(HasElementsView<NonMovableGenerator, 1>);75