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// constexpr sentinel(sentinel<!Const> s)
12// requires Const && convertible_to<sentinel_t<V>, sentinel_t<Base>>;
13
14#include <cassert>
15#include <ranges>
16#include <tuple>
17
18#include "../types.h"
19
20struct Sent {
21 int i;
22 constexpr Sent() = default;
23 constexpr Sent(int ii) : i(ii) {}
24 friend constexpr bool operator==(std::tuple<int>*, const Sent&) { return true; }
25};
26
27struct ConstSent {
28 int i;
29 constexpr ConstSent() = default;
30 constexpr ConstSent(int ii) : i(ii) {}
31 constexpr ConstSent(const Sent& s) : i(s.i) {}
32 friend constexpr bool operator==(std::tuple<int>*, const ConstSent&) { return true; }
33};
34
35struct Range : std::ranges::view_base {
36 std::tuple<int>* begin() const;
37 Sent end();
38 ConstSent end() const;
39};
40
41struct NonConvertConstSent {
42 int i;
43 constexpr NonConvertConstSent() = default;
44 constexpr NonConvertConstSent(int ii) : i(ii) {}
45 friend constexpr bool operator==(std::tuple<int>*, const NonConvertConstSent&) { return true; }
46};
47
48struct NonConvertConstSentRange : std::ranges::view_base {
49 std::tuple<int>* begin() const;
50 Sent end();
51 NonConvertConstSent end() const;
52};
53
54// Test Constraint
55static_assert(std::is_constructible_v<std::ranges::sentinel_t<const std::ranges::elements_view<Range, 0>>,
56 std::ranges::sentinel_t<std::ranges::elements_view<Range, 0>>>);
57
58// !Const
59static_assert(!std::is_constructible_v<std::ranges::sentinel_t<std::ranges::elements_view<Range, 0>>,
60 std::ranges::sentinel_t<const std::ranges::elements_view<Range, 0>>>);
61
62// !convertible_to<sentinel_t<V>, sentinel_t<Base>>
63static_assert(!std::is_constructible_v<
64 std::ranges::sentinel_t<const std::ranges::elements_view<NonConvertConstSentRange, 0>>,
65 std::ranges::sentinel_t<std::ranges::elements_view<NonConvertConstSentRange, 0>>>);
66
67constexpr bool test() {
68 // base is init correctly
69 {
70 using R = std::ranges::elements_view<Range, 0>;
71 using Sentinel = std::ranges::sentinel_t<R>;
72 using ConstSentinel = std::ranges::sentinel_t<const R>;
73 static_assert(!std::same_as<Sentinel, ConstSentinel>);
74
75 Sentinel s1(Sent{5});
76 ConstSentinel s2 = s1;
77 assert(s2.base().i == 5);
78 }
79
80 return true;
81}
82
83int main(int, char**) {
84 test();
85 static_assert(test());
86
87 return 0;
88}
89

source code of libcxx/test/std/ranges/range.adaptors/range.elements/sentinel/ctor.convert.pass.cpp