brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.4 KiB · cf74609 Raw
128 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// template<class I2>12//   requires assignable_from<I&, const I2&>13//     constexpr counted_iterator& operator=(const counted_iterator<I2>& x);14 15#include <iterator>16 17#include "test_macros.h"18#include "test_iterators.h"19 20class AssignableFromIter21{22    int *it_;23 24public:25    typedef          std::input_iterator_tag                      iterator_category;26    typedef int                                                   value_type;27    typedef typename std::iterator_traits<int *>::difference_type difference_type;28    typedef int *                                                 pointer;29    typedef int &                                                 reference;30 31    friend constexpr int *base(const AssignableFromIter& i) {return i.it_;}32 33    AssignableFromIter() = default;34    explicit constexpr AssignableFromIter(int *it) : it_(it) {}35    constexpr AssignableFromIter(const forward_iterator<int*>& it) : it_(base(it)) {}36 37    constexpr AssignableFromIter& operator=(const forward_iterator<int*> &other) {38      it_ = base(other);39      return *this;40    }41 42    constexpr reference operator*() const {return *it_;}43 44    constexpr AssignableFromIter& operator++() {++it_; return *this;}45    constexpr AssignableFromIter operator++(int)46        {AssignableFromIter tmp(*this); ++(*this); return tmp;}47};48 49struct InputOrOutputArchetype {50  using difference_type = int;51 52  int *ptr;53 54  int operator*() { return *ptr; }55  void operator++(int) { ++ptr; }56  InputOrOutputArchetype& operator++() { ++ptr; return *this; }57};58 59constexpr bool test() {60  int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8};61 62  {63    static_assert( std::is_assignable_v<std::counted_iterator<forward_iterator<int*>>,64                                        std::counted_iterator<forward_iterator<int*>>>);65    static_assert(!std::is_assignable_v<std::counted_iterator<forward_iterator<int*>>,66                                        std::counted_iterator<random_access_iterator<int*>>>);67  }68 69  {70    std::counted_iterator iter1(AssignableFromIter{buffer}, 8);71    std::counted_iterator iter2(forward_iterator<int*>{buffer + 2}, 6);72    assert(base(iter1.base()) == buffer);73    assert(iter1.count() == 8);74    std::counted_iterator<AssignableFromIter>& result = (iter1 = iter2);75    assert(&result == &iter1);76    assert(base(iter1.base()) == buffer + 2);77    assert(iter1.count() == 6);78 79    ASSERT_SAME_TYPE(decltype(iter1 = iter2), std::counted_iterator<AssignableFromIter>&);80  }81  {82    std::counted_iterator iter1(AssignableFromIter{buffer}, 8);83    const std::counted_iterator iter2(forward_iterator<int*>{buffer + 2}, 6);84    assert(base(iter1.base()) == buffer);85    assert(iter1.count() == 8);86    std::counted_iterator<AssignableFromIter>& result = (iter1 = iter2);87    assert(&result == &iter1);88    assert(base(iter1.base()) == buffer + 2);89    assert(iter1.count() == 6);90 91    ASSERT_SAME_TYPE(decltype(iter1 = iter2), std::counted_iterator<AssignableFromIter>&);92  }93 94  {95    std::counted_iterator iter1(InputOrOutputArchetype{buffer}, 8);96    std::counted_iterator iter2(InputOrOutputArchetype{buffer + 2}, 6);97    assert(iter1.base().ptr == buffer);98    assert(iter1.count() == 8);99    std::counted_iterator<InputOrOutputArchetype>& result = (iter1 = iter2);100    assert(&result == &iter1);101    assert(iter1.base().ptr == buffer + 2);102    assert(iter1.count() == 6);103 104    ASSERT_SAME_TYPE(decltype(iter1 = iter2), std::counted_iterator<InputOrOutputArchetype>&);105  }106  {107    std::counted_iterator iter1(InputOrOutputArchetype{buffer}, 8);108    const std::counted_iterator iter2(InputOrOutputArchetype{buffer + 2}, 6);109    assert(iter1.base().ptr == buffer);110    assert(iter1.count() == 8);111    std::counted_iterator<InputOrOutputArchetype>& result = (iter1 = iter2);112    assert(&result == &iter1);113    assert(iter1.base().ptr == buffer + 2);114    assert(iter1.count() == 6);115 116    ASSERT_SAME_TYPE(decltype(iter1 = iter2), std::counted_iterator<InputOrOutputArchetype>&);117  }118 119  return true;120}121 122int main(int, char**) {123  test();124  static_assert(test());125 126  return 0;127}128