108 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++1710 11// constexpr decltype(auto) operator*();12// constexpr decltype(auto) operator*() const13// requires dereferenceable<const I>;14 15#include <iterator>16 17#include "test_macros.h"18#include "test_iterators.h"19 20struct 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 30struct 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 40template<class T>41concept IsDereferenceable = requires(T& i) {42 *i;43};44 45constexpr 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 102int main(int, char**) {103 test();104 static_assert(test());105 106 return 0;107}108