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 // <iterator> 10 11 // move_iterator 12 13 // template <class U> 14 // requires HasAssign<Iter, const U&> 15 // move_iterator& 16 // operator=(const move_iterator<U>& u); 17 // 18 // constexpr in C++17 19 20 #include <iterator> 21 #include <cassert> 22 23 #include "test_macros.h" 24 #include "test_iterators.h" 25 26 template <class It, class U> 27 void test(U u)28test(U u) 29 { 30 const std::move_iterator<U> r2(u); 31 std::move_iterator<It> r1(It(nullptr)); 32 std::move_iterator<It>& rr = (r1 = r2); 33 assert(base(r1.base()) == base(u)); 34 assert(&rr == &r1); 35 } 36 37 struct Base {}; 38 struct Derived : Base {}; 39 40 struct ToIter { 41 typedef std::forward_iterator_tag iterator_category; 42 typedef char *pointer; 43 typedef char &reference; 44 typedef char value_type; 45 typedef signed char difference_type; 46 ToIterToIter47 explicit TEST_CONSTEXPR_CXX17 ToIter() : m_value(0) {} ToIterToIter48 TEST_CONSTEXPR_CXX17 ToIter(const ToIter &src) : m_value(src.m_value) {} 49 // Intentionally not defined, must not be called. 50 ToIter(char *src); operator =ToIter51 TEST_CONSTEXPR_CXX17 ToIter &operator=(char *src) { 52 m_value = src; 53 return *this; 54 } operator =ToIter55 TEST_CONSTEXPR_CXX17 ToIter &operator=(const ToIter &src) { 56 m_value = src.m_value; 57 return *this; 58 } 59 char *m_value; 60 61 reference operator*() const; 62 }; 63 test_conv_assign()64TEST_CONSTEXPR_CXX17 bool test_conv_assign() 65 { 66 char c = '\0'; 67 char *fi = &c; 68 const std::move_iterator<char *> move_fi(fi); 69 std::move_iterator<ToIter> move_ti; 70 move_ti = move_fi; 71 assert(move_ti.base().m_value == fi); 72 return true; 73 } 74 main(int,char **)75int main(int, char**) 76 { 77 Derived d; 78 79 test<cpp17_input_iterator<Base*> >(cpp17_input_iterator<Derived*>(&d)); 80 test<forward_iterator<Base*> >(forward_iterator<Derived*>(&d)); 81 test<bidirectional_iterator<Base*> >(bidirectional_iterator<Derived*>(&d)); 82 test<random_access_iterator<const Base*> >(random_access_iterator<Derived*>(&d)); 83 test<Base*>(&d); 84 test_conv_assign(); 85 #if TEST_STD_VER > 14 86 { 87 using BaseIter = std::move_iterator<const Base *>; 88 using DerivedIter = std::move_iterator<const Derived *>; 89 constexpr const Derived *p = nullptr; 90 constexpr DerivedIter it1 = std::make_move_iterator(p); 91 constexpr BaseIter it2 = (BaseIter{nullptr} = it1); 92 static_assert(it2.base() == p, ""); 93 static_assert(test_conv_assign(), ""); 94 } 95 #endif 96 97 return 0; 98 } 99