231 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// REQUIRES: std-at-least-c++2310 11// <ranges>12 13// template<class R, class P>14// join_with_view(R&&, P&&) -> join_with_view<views::all_t<R>, views::all_t<P>>;15//16// template<input_range R>17// join_with_view(R&&, range_value_t<range_reference_t<R>>)18// -> join_with_view<views::all_t<R>, single_view<range_value_t<range_reference_t<R>>>>;19 20#include <ranges>21 22#include <deque>23#include <type_traits>24 25#include "test_iterators.h"26 27struct View : std::ranges::view_base {28 using It = cpp20_input_iterator<std::deque<int>*>;29 30 View() = default;31 It begin() const;32 sentinel_wrapper<It> end() const;33};34 35static_assert(std::ranges::input_range<View>);36static_assert(std::ranges::view<View>);37 38struct Pattern : std::ranges::view_base {39 Pattern() = default;40 forward_iterator<int*> begin();41 forward_iterator<int*> end();42};43 44static_assert(std::ranges::forward_range<Pattern>);45static_assert(std::ranges::view<Pattern>);46 47// A range that is not a view48struct Range {49 using It = cpp20_input_iterator<std::deque<int>*>;50 51 Range() = default;52 It begin() const;53 sentinel_wrapper<It> end() const;54};55 56static_assert(std::ranges::input_range<Range>);57static_assert(!std::ranges::view<Range>);58 59// A pattern that is not a view60struct RangePattern {61 RangePattern() = default;62 forward_iterator<int*> begin();63 forward_iterator<int*> end();64};65 66static_assert(std::ranges::forward_range<RangePattern>);67static_assert(!std::ranges::view<RangePattern>);68 69void test_range_and_pattern_deduction_guide() {70 { // Both `v` and `pat` model `std::ranges::view`.71 {72 View v;73 Pattern pat;74 std::ranges::join_with_view view(v, pat);75 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<View, Pattern>>);76 }77 {78 View v;79 std::ranges::join_with_view view(v, Pattern{});80 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<View, Pattern>>);81 }82 {83 Pattern pat;84 std::ranges::join_with_view view(View{}, pat);85 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<View, Pattern>>);86 }87 {88 std::ranges::join_with_view view(View{}, Pattern{});89 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<View, Pattern>>);90 }91 }92 93 { // Only `pat` models `std::ranges::view`.94 {95 Range v;96 Pattern pat;97 std::ranges::join_with_view view(v, pat);98 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<std::ranges::ref_view<Range>, Pattern>>);99 }100 {101 Range v;102 std::ranges::join_with_view view(v, Pattern{});103 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<std::ranges::ref_view<Range>, Pattern>>);104 }105 {106 Pattern pat;107 std::ranges::join_with_view view(Range{}, pat);108 static_assert(109 std::is_same_v<decltype(view), std::ranges::join_with_view<std::ranges::owning_view<Range>, Pattern>>);110 }111 {112 std::ranges::join_with_view view(Range{}, Pattern{});113 static_assert(114 std::is_same_v<decltype(view), std::ranges::join_with_view<std::ranges::owning_view<Range>, Pattern>>);115 }116 }117 118 { // Only `v` models `std::ranges::view`.119 {120 View v;121 RangePattern pat;122 std::ranges::join_with_view view(v, pat);123 static_assert(124 std::is_same_v<decltype(view), std::ranges::join_with_view<View, std::ranges::ref_view<RangePattern>>>);125 }126 {127 View v;128 std::ranges::join_with_view view(v, RangePattern{});129 static_assert(130 std::is_same_v<decltype(view), std::ranges::join_with_view<View, std::ranges::owning_view<RangePattern>>>);131 }132 {133 RangePattern pat;134 std::ranges::join_with_view view(View{}, pat);135 static_assert(136 std::is_same_v<decltype(view), std::ranges::join_with_view<View, std::ranges::ref_view<RangePattern>>>);137 }138 {139 std::ranges::join_with_view view(View{}, RangePattern{});140 static_assert(141 std::is_same_v<decltype(view), std::ranges::join_with_view<View, std::ranges::owning_view<RangePattern>>>);142 }143 }144 145 { // Both `v` and `pat` don't model `std::ranges::view`.146 {147 Range r;148 RangePattern pat;149 std::ranges::join_with_view view(r, pat);150 static_assert(std::is_same_v<151 decltype(view),152 std::ranges::join_with_view<std::ranges::ref_view<Range>, std::ranges::ref_view<RangePattern>>>);153 }154 {155 Range r;156 std::ranges::join_with_view view(r, RangePattern{});157 static_assert(std::is_same_v<158 decltype(view),159 std::ranges::join_with_view<std::ranges::ref_view<Range>, std::ranges::owning_view<RangePattern>>>);160 }161 {162 RangePattern pat;163 std::ranges::join_with_view view(Range{}, pat);164 static_assert(std::is_same_v<165 decltype(view),166 std::ranges::join_with_view<std::ranges::owning_view<Range>, std::ranges::ref_view<RangePattern>>>);167 }168 {169 std::ranges::join_with_view view(Range{}, RangePattern{});170 static_assert(171 std::is_same_v<172 decltype(view),173 std::ranges::join_with_view<std::ranges::owning_view<Range>, std::ranges::owning_view<RangePattern>>>);174 }175 }176}177 178void test_range_and_element_deduction_guide() {179 { // Element is lvalue180 int elem = 0;181 182 {183 View v;184 std::ranges::join_with_view view(v, elem);185 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<View, std::ranges::single_view<int>>>);186 }187 {188 std::ranges::join_with_view view(View{}, elem);189 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<View, std::ranges::single_view<int>>>);190 }191 {192 Range r;193 std::ranges::join_with_view view(r, elem);194 static_assert(195 std::is_same_v<decltype(view),196 std::ranges::join_with_view<std::ranges::ref_view<Range>, std::ranges::single_view<int>>>);197 }198 {199 std::ranges::join_with_view view(Range{}, elem);200 static_assert(201 std::is_same_v<decltype(view),202 std::ranges::join_with_view<std::ranges::owning_view<Range>, std::ranges::single_view<int>>>);203 }204 }205 206 { // Element is rvalue207 {208 View v;209 std::ranges::join_with_view view(v, 1);210 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<View, std::ranges::single_view<int>>>);211 }212 {213 std::ranges::join_with_view view(View{}, 1);214 static_assert(std::is_same_v<decltype(view), std::ranges::join_with_view<View, std::ranges::single_view<int>>>);215 }216 {217 Range r;218 std::ranges::join_with_view view(r, 1);219 static_assert(220 std::is_same_v<decltype(view),221 std::ranges::join_with_view<std::ranges::ref_view<Range>, std::ranges::single_view<int>>>);222 }223 {224 std::ranges::join_with_view view(Range{}, 1);225 static_assert(226 std::is_same_v<decltype(view),227 std::ranges::join_with_view<std::ranges::owning_view<Range>, std::ranges::single_view<int>>>);228 }229 }230}231