File: views_repeat.pass.cpp

package info (click to toggle)
llvm-toolchain-20 1%3A20.1.6-1~exp1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 2,111,304 kB
  • sloc: cpp: 7,438,677; ansic: 1,393,822; asm: 1,012,926; python: 241,650; f90: 86,635; objc: 75,479; lisp: 42,144; pascal: 17,286; sh: 10,027; ml: 5,082; perl: 4,730; awk: 3,523; makefile: 3,349; javascript: 2,251; xml: 892; fortran: 672
file content (134 lines) | stat: -rw-r--r-- 4,461 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20

// template <class T>
// views::repeat(T &&) requires constructible_from<ranges::repeat_view<T>, T>;

// template <class T, class Bound>
// views::repeat(T &&, Bound &&) requires constructible_from<ranges::repeat_view<T, Bound>, T, Bound>;

#include <cassert>
#include <concepts>
#include <ranges>
#include <tuple>
#include <type_traits>

#include "MoveOnly.h"

struct NonCopyable {
  NonCopyable(NonCopyable&) = delete;
};

struct NonDefaultCtor {
  NonDefaultCtor(int) {}
};

struct Empty {};

struct LessThan3 {
  constexpr bool operator()(int i) const { return i < 3; }
};

struct EqualTo33 {
  constexpr bool operator()(int i) const { return i == 33; }
};

struct Add3 {
  constexpr int operator()(int i) const { return i + 3; }
};

// Tp is_object
static_assert(std::is_invocable_v<decltype(std::views::repeat), int>);
static_assert(!std::is_invocable_v<decltype(std::views::repeat), void>);

// _Bound is semiregular, integer like or std::unreachable_sentinel_t
static_assert(!std::is_invocable_v<decltype(std::views::repeat), int, Empty>);
static_assert(!std::is_invocable_v<decltype(std::views::repeat), int, NonCopyable>);
static_assert(!std::is_invocable_v<decltype(std::views::repeat), int, NonDefaultCtor>);
static_assert(std::is_invocable_v<decltype(std::views::repeat), int, std::unreachable_sentinel_t>);

// Tp is copy_constructible
static_assert(!std::is_invocable_v<decltype(std::views::repeat), NonCopyable>);

// Tp is move_constructible
static_assert(std::is_invocable_v<decltype(std::views::repeat), MoveOnly>);

// Test LWG4054 "Repeating a repeat_view should repeat the view"
static_assert(std::is_same_v<decltype(std::views::repeat(std::views::repeat(42))),
                             std::ranges::repeat_view<std::ranges::repeat_view<int>>>);

// These cases are from LWG4053, but they are actually covered by the resolution of LWG4054,
// and the resolution of LWG4053 only affects CTAD.
using RPV = std::ranges::repeat_view<const char*>;
static_assert(std::same_as<decltype(std::views::repeat("foo", std::unreachable_sentinel)), RPV>);  // OK
static_assert(std::same_as<decltype(std::views::repeat(+"foo", std::unreachable_sentinel)), RPV>); // OK
static_assert(std::same_as<decltype(std::views::repeat("foo")), RPV>);                             // OK since LWG4054
static_assert(std::same_as<decltype(std::views::repeat(+"foo")), RPV>);                            // OK

constexpr bool test() {
  assert(*std::views::repeat(33).begin() == 33);
  assert(*std::views::repeat(33, 10).begin() == 33);
  static_assert(std::same_as<decltype(std::views::repeat(42)), std::ranges::repeat_view<int>>);
  static_assert(std::same_as<decltype(std::views::repeat(42, 3)), std::ranges::repeat_view<int, int>>);
  static_assert(std::same_as<decltype(std::views::repeat), decltype(std::ranges::views::repeat)>);

  // unbound && drop_view
  {
    auto r = std::views::repeat(33) | std::views::drop(3);
    static_assert(!std::ranges::sized_range<decltype(r)>);
    assert(*r.begin() == 33);
  }

  // bound && drop_view
  {
    auto r = std::views::repeat(33, 8) | std::views::drop(3);
    static_assert(std::ranges::sized_range<decltype(r)>);
    assert(*r.begin() == 33);
    assert(r.size() == 5);
  }

  // unbound && take_view
  {
    auto r = std::views::repeat(33) | std::views::take(3);
    static_assert(std::ranges::sized_range<decltype(r)>);
    assert(*r.begin() == 33);
    assert(r.size() == 3);
  }

  // bound && take_view
  {
    auto r = std::views::repeat(33, 8) | std::views::take(3);
    static_assert(std::ranges::sized_range<decltype(r)>);
    assert(*r.begin() == 33);
    assert(r.size() == 3);
  }

  // bound && transform_view
  {
    auto r = std::views::repeat(33, 8) | std::views::transform(Add3{});
    assert(*r.begin() == 36);
    assert(r.size() == 8);
  }

  // unbound && transform_view
  {
    auto r = std::views::repeat(33) | std::views::transform(Add3{});
    assert(*r.begin() == 36);
  }

  return true;
}

int main(int, char**) {
  test();
  static_assert(test());

  return 0;
}