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 iterator(iterator<!Const> i)
12// requires Const && convertible_to<iterator_t<V>, iterator_t<Base>>;
13
14#include <cassert>
15#include <ranges>
16#include <tuple>
17
18#include "../types.h"
19
20template <bool Const>
21struct ConvertibleIter : IterBase<ConvertibleIter<Const>> {
22 using iterator_category = std::random_access_iterator_tag;
23 using value_type = std::tuple<int>;
24 using difference_type = std::intptr_t;
25
26 bool movedFromOtherConst = false;
27 int i = 0;
28
29 constexpr ConvertibleIter() = default;
30 constexpr ConvertibleIter(int ii) : i(ii) {}
31 template <bool otherConst>
32 requires(Const != otherConst)
33 constexpr ConvertibleIter(ConvertibleIter<otherConst> it) : movedFromOtherConst(true), i(it.i) {}
34};
35
36template <class Iter, class ConstIter>
37struct BasicView : std::ranges::view_base {
38 Iter begin();
39 Iter end();
40
41 ConstIter begin() const;
42 ConstIter end() const;
43};
44
45template <class View>
46using ElemIter = std::ranges::iterator_t<std::ranges::elements_view<View, 0>>;
47
48template <class View>
49using ConstElemIter = std::ranges::iterator_t<const std::ranges::elements_view<View, 0>>;
50
51using ConvertibleView = BasicView<ConvertibleIter<false>, ConvertibleIter<true>>;
52using NonConvertibleView = BasicView<forward_iterator<std::tuple<int>*>, bidirectional_iterator<std::tuple<int>*>>;
53
54static_assert(std::is_constructible_v<ConstElemIter<ConvertibleView>, ElemIter<ConvertibleView>>);
55static_assert(!std::is_constructible_v<ElemIter<ConvertibleView>, ConstElemIter<ConvertibleView>>);
56static_assert(!std::is_constructible_v<ConstElemIter<NonConvertibleView>, ElemIter<NonConvertibleView>>);
57static_assert(!std::is_constructible_v<ElemIter<NonConvertibleView>, ConstElemIter<NonConvertibleView>>);
58
59constexpr bool test() {
60 ElemIter<ConvertibleView> iter{ConvertibleIter<false>{5}};
61 ConstElemIter<ConvertibleView> constIter = iter; // implicit
62 assert(constIter.base().movedFromOtherConst);
63 assert(constIter.base().i == 5);
64
65 return true;
66}
67
68int main(int, char**) {
69 test();
70 static_assert(test());
71
72 return 0;
73}
74

source code of libcxx/test/std/ranges/range.adaptors/range.elements/iterator/ctor.other.pass.cpp