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 // UNSUPPORTED: libcpp-no-concepts 11 12 // decltype(auto) operator->() const 13 // requires see below; 14 15 #include <iterator> 16 #include <cassert> 17 #include <concepts> 18 19 #include "test_iterators.h" 20 #include "test_macros.h" 21 #include "types.h" 22 23 void test() { 24 // Case 1: http://eel.is/c++draft/iterators.common#common.iter.access-5.1 25 { 26 auto check = []<class Iterator>() { 27 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 28 Iterator iter(buffer); 29 using Common = std::common_iterator<Iterator, sentinel_wrapper<Iterator>>; 30 31 Common common(iter); 32 std::same_as<Iterator> auto result = common.operator->(); 33 assert(base(result) == buffer); 34 35 Common const ccommon(iter); 36 std::same_as<Iterator> auto cresult = ccommon.operator->(); 37 assert(base(cresult) == buffer); 38 }; 39 40 check.operator()<contiguous_iterator<int*>>(); 41 check.operator()<int*>(); 42 } 43 44 // Case 2: http://eel.is/c++draft/iterators.common#common.iter.access-5.2 45 { 46 auto check = []<class Iterator>() { 47 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 48 Iterator iter(buffer); 49 using Common = std::common_iterator<Iterator, sentinel_type<int*>>; 50 51 Common common(iter); 52 std::same_as<int*> auto result = common.operator->(); 53 assert(result == buffer); 54 55 Common const ccommon(iter); 56 std::same_as<int*> auto cresult = ccommon.operator->(); 57 assert(cresult == buffer); 58 }; 59 60 check.operator()<simple_iterator<int*>>(); 61 check.operator()<cpp17_input_iterator<int*>>(); 62 // cpp20_input_iterator can't be used with common_iterator because it's not copyable 63 check.operator()<forward_iterator<int*>>(); 64 check.operator()<bidirectional_iterator<int*>>(); 65 check.operator()<random_access_iterator<int*>>(); 66 } 67 68 // Case 3: http://eel.is/c++draft/iterators.common#common.iter.access-5.3 69 { 70 auto check = []<class Iterator>() { 71 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 72 Iterator iter(buffer); 73 using Common = std::common_iterator<Iterator, sentinel_type<int*>>; 74 75 Common common(iter); 76 auto proxy = common.operator->(); 77 std::same_as<int const*> auto result = proxy.operator->(); 78 assert(result != buffer); // we copied to a temporary proxy 79 assert(*result == *buffer); 80 81 Common const ccommon(iter); 82 auto cproxy = ccommon.operator->(); 83 std::same_as<int const*> auto cresult = cproxy.operator->(); 84 assert(cresult != buffer); // we copied to a temporary proxy 85 assert(*cresult == *buffer); 86 }; 87 88 check.operator()<value_iterator<int*>>(); 89 check.operator()<void_plus_plus_iterator<int*>>(); 90 } 91 } 92 93 int main(int, char**) { 94 test(); 95 96 return 0; 97 } 98