112 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// constexpr explicit join_with_view(V base, Pattern pattern);14 15#include <ranges>16 17#include <algorithm>18#include <array>19#include <cassert>20#include <utility>21 22#include "../types.h"23 24class View : public std::ranges::view_base {25 using OuterRange = std::array<std::array<int, 2>, 3>;26 27 static constexpr OuterRange default_range = {{{1, 2}, {3, 4}, {5, 6}}};28 static constexpr OuterRange range_on_move = {{{6, 5}, {4, 3}, {2, 1}}};29 30 const OuterRange* r_ = &default_range;31 32public:33 View() = default;34 constexpr View(const View&) : r_(&default_range) {}35 constexpr View(View&&) : r_(&range_on_move) {}36 37 constexpr View& operator=(View) {38 r_ = &default_range;39 return *this;40 }41 42 constexpr auto begin() { return r_->begin(); }43 constexpr auto end() { return r_->end(); }44};45 46class Pattern : public std::ranges::view_base {47 using PatternRange = std::array<int, 2>;48 49 static constexpr PatternRange default_range = {0, 0};50 static constexpr PatternRange range_on_move = {7, 7};51 52 const PatternRange* val_ = &default_range;53 54public:55 Pattern() = default;56 constexpr Pattern(const Pattern&) : val_(&default_range) {}57 constexpr Pattern(Pattern&&) : val_(&range_on_move) {}58 59 constexpr Pattern& operator=(Pattern) {60 val_ = &default_range;61 return *this;62 }63 64 constexpr auto begin() { return val_->begin(); }65 constexpr auto end() { return val_->end(); }66};67 68constexpr bool test() {69 { // Check construction from `view` and `pattern`70 { // `view` and `pattern` are glvalues71 View v;72 Pattern p;73 std::ranges::join_with_view<View, Pattern> jwv(v, p);74 assert(std::ranges::equal(jwv, std::array{6, 5, 7, 7, 4, 3, 7, 7, 2, 1}));75 }76 77 { // `view` and `pattern` are const glvalues78 const View v;79 const Pattern p;80 std::ranges::join_with_view<View, Pattern> jwv(v, p);81 assert(std::ranges::equal(jwv, std::array{6, 5, 7, 7, 4, 3, 7, 7, 2, 1}));82 }83 84 { // `view` and `pattern` are prvalues85 std::ranges::join_with_view<View, Pattern> jwv(View{}, Pattern{});86 assert(std::ranges::equal(jwv, std::array{6, 5, 7, 7, 4, 3, 7, 7, 2, 1}));87 }88 89 { // `view` and `pattern` are xvalues90 View v;91 Pattern p;92 std::ranges::join_with_view<View, Pattern> jwv(std::move(v), std::move(p));93 assert(std::ranges::equal(jwv, std::array{6, 5, 7, 7, 4, 3, 7, 7, 2, 1}));94 }95 }96 97 // Check explicitness98 static_assert(ConstructionIsExplicit<std::ranges::join_with_view<View, Pattern>, View, Pattern>);99 static_assert(ConstructionIsExplicit<std::ranges::join_with_view<View, Pattern>, View&, Pattern&>);100 static_assert(ConstructionIsExplicit<std::ranges::join_with_view<View, Pattern>, const View, const Pattern>);101 static_assert(ConstructionIsExplicit<std::ranges::join_with_view<View, Pattern>, const View&, const Pattern&>);102 103 return true;104}105 106int main(int, char**) {107 test();108 static_assert(test());109 110 return 0;111}112