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 decltype(auto) operator*(); 12 // constexpr decltype(auto) operator*() const 13 // requires dereferenceable<const I>; 14 15 #include <iterator> 16 17 #include "test_macros.h" 18 #include "test_iterators.h" 19 20 struct InputOrOutputArchetype { 21 using difference_type = int; 22 23 int *ptr; 24 25 constexpr int operator*() const { return *ptr; } 26 constexpr void operator++(int) { ++ptr; } 27 constexpr InputOrOutputArchetype& operator++() { ++ptr; return *this; } 28 }; 29 30 struct NonConstDeref { 31 using difference_type = int; 32 33 int *ptr; 34 35 constexpr int operator*() { return *ptr; } 36 constexpr void operator++(int) { ++ptr; } 37 constexpr NonConstDeref& operator++() { ++ptr; return *this; } 38 }; 39 40 template<class T> 41 concept IsDereferenceable = requires(T& i) { 42 *i; 43 }; 44 45 constexpr bool test() { 46 int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 47 48 { 49 static_assert( IsDereferenceable<std::counted_iterator<InputOrOutputArchetype>>); 50 static_assert( IsDereferenceable<const std::counted_iterator<InputOrOutputArchetype>>); 51 static_assert( IsDereferenceable<std::counted_iterator<NonConstDeref>>); 52 static_assert(!IsDereferenceable<const std::counted_iterator<NonConstDeref>>); 53 } 54 55 { 56 std::counted_iterator iter(cpp20_input_iterator<int*>{buffer}, 8); 57 for (int i = 1; i < 9; ++i, ++iter) 58 assert(*iter == i); 59 } 60 61 { 62 std::counted_iterator iter(forward_iterator<int*>{buffer}, 8); 63 for (int i = 1; i < 9; ++i, ++iter) 64 assert(*iter == i); 65 } 66 67 { 68 std::counted_iterator iter(contiguous_iterator<int*>{buffer}, 8); 69 for (int i = 1; i < 9; ++i, ++iter) 70 assert(*iter == i); 71 } 72 73 { 74 std::counted_iterator iter(InputOrOutputArchetype{buffer}, 8); 75 for (int i = 1; i < 9; ++i, ++iter) 76 assert(*iter == i); 77 } 78 79 { 80 const std::counted_iterator iter(cpp20_input_iterator<int*>{buffer}, 8); 81 assert(*iter == 1); 82 } 83 84 { 85 const std::counted_iterator iter(forward_iterator<int*>{buffer + 1}, 7); 86 assert(*iter == 2); 87 } 88 89 { 90 const std::counted_iterator iter(contiguous_iterator<int*>{buffer + 2}, 6); 91 assert(*iter == 3); 92 } 93 94 { 95 const std::counted_iterator iter(InputOrOutputArchetype{buffer + 2}, 6); 96 assert(*iter == 3); 97 } 98 99 return true; 100 } 101 102 int main(int, char**) { 103 test(); 104 static_assert(test()); 105 106 return 0; 107 } 108