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// REQUIRES: std-at-least-c++23
10
11// <ranges>
12
13// constexpr iterator(iterator<!Const> i)
14// requires Const && convertible_to<iterator_t<V>, OuterIter> &&
15// convertible_to<iterator_t<InnerRng>, InnerIter> &&
16// convertible_to<iterator_t<Pattern>, PatternIter>;
17
18#include <ranges>
19
20#include <cassert>
21#include <vector>
22
23#include "../types.h"
24
25constexpr bool test() {
26 { // Regular conversion from `!Const` to `Const` iterator
27 std::vector<std::vector<int>> vec = {{1, 2}, {3, 4}, {5, 6}};
28 int pattern = 0;
29 std::ranges::join_with_view jwv(vec, pattern);
30
31 using JWV = decltype(jwv);
32 using Iter = std::ranges::iterator_t<JWV>;
33 using CIter = std::ranges::iterator_t<const JWV>;
34 static_assert(!std::same_as<Iter, CIter>);
35 static_assert(std::convertible_to<Iter, CIter>);
36 static_assert(std::constructible_from<CIter, Iter>);
37
38 Iter it = jwv.begin();
39 assert(*it == 1);
40
41 const CIter cit1 = it; // `cit1` points to element of `V`; this constructor should not be explicit
42 assert(*cit1 == 1);
43 assert(cit1 == it);
44
45 std::ranges::advance(it, 2);
46 assert(*it == 0);
47 CIter cit2 = it; // `cit2` points to element of `Pattern`
48 assert(*cit2 == 0);
49 assert(cit2 == it);
50
51 ++it;
52 assert(*it == 3);
53 CIter cit3 = it;
54 assert(*cit3 == 3);
55 assert(cit3 == it);
56
57 --cit3;
58 assert(cit2 == cit3);
59 }
60
61 { // Test conversion from `Const` to `!Const` (should be invalid)
62 using V = std::vector<std::vector<int>>;
63 using Pattern = std::ranges::single_view<int>;
64 using JWV = std::ranges::join_with_view<std::views::all_t<V>, Pattern>;
65 using Iter = std::ranges::iterator_t<JWV>;
66 using CIter = std::ranges::iterator_t<const JWV>;
67 static_assert(!std::convertible_to<CIter, Iter>);
68 static_assert(!std::constructible_from<Iter, CIter>);
69 }
70
71 { // When `convertible_to<iterator_t<V>, OuterIter>` is not modeled
72 using Inner = std::vector<short>;
73 using V = ConstOppositeView<Inner>;
74 using Pattern = std::ranges::single_view<short>;
75 using JWV = std::ranges::join_with_view<V, Pattern>;
76 using Iter = std::ranges::iterator_t<JWV>;
77 using CIter = std::ranges::iterator_t<const JWV>;
78 static_assert(!std::convertible_to<CIter, Iter>);
79 static_assert(!std::constructible_from<Iter, CIter>);
80 }
81
82 { // When `convertible_to<iterator_t<InnerRng>, InnerIter>` is not modeled
83 using Inner = ConstOppositeView<long>;
84 using V = std::vector<Inner>;
85 using Pattern = std::ranges::single_view<long>;
86 using JWV = std::ranges::join_with_view<std::views::all_t<V>, Pattern>;
87 using Iter = std::ranges::iterator_t<JWV>;
88 using CIter = std::ranges::iterator_t<const JWV>;
89 static_assert(!std::convertible_to<CIter, Iter>);
90 static_assert(!std::constructible_from<Iter, CIter>);
91 }
92
93 { // When `convertible_to<iterator_t<Pattern>, PatternIter>` is not modeled
94 using V = std::vector<std::vector<long long>>;
95 using Pattern = ConstOppositeView<long long>;
96 using JWV = std::ranges::join_with_view<std::views::all_t<V>, Pattern>;
97 using Iter = std::ranges::iterator_t<JWV>;
98 using CIter = std::ranges::iterator_t<const JWV>;
99 static_assert(!std::convertible_to<CIter, Iter>);
100 static_assert(!std::constructible_from<Iter, CIter>);
101 }
102
103 return true;
104}
105
106int main(int, char**) {
107 test();
108 static_assert(test());
109
110 return 0;
111}
112

source code of libcxx/test/std/ranges/range.adaptors/range.join.with/range.join.with.iterator/ctor.not_const.pass.cpp