brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · 577328d Raw
134 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// <algorithm>10 11// UNSUPPORTED: c++03, c++11, c++14, c++1712 13// template<input_iterator I, weakly_incrementable O>14//   requires indirectly_copyable<I, O>15//   constexpr ranges::copy_n_result<I, O>16//     ranges::copy_n(I first, iter_difference_t<I> n, O result);17 18#include <algorithm>19#include <array>20#include <cassert>21#include <ranges>22#include <vector>23 24#include "almost_satisfies_types.h"25#include "test_macros.h"26#include "test_iterators.h"27 28template <class In, class Out = In, class Count = std::size_t>29concept HasCopyNIt = requires(In in, Count count, Out out) { std::ranges::copy_n(in, count, out); };30 31static_assert(HasCopyNIt<int*>);32static_assert(!HasCopyNIt<InputIteratorNotDerivedFrom>);33static_assert(!HasCopyNIt<InputIteratorNotIndirectlyReadable>);34static_assert(!HasCopyNIt<InputIteratorNotInputOrOutputIterator>);35static_assert(!HasCopyNIt<int*, WeaklyIncrementableNotMovable>);36struct NotIndirectlyCopyable {};37static_assert(!HasCopyNIt<int*, NotIndirectlyCopyable*>);38static_assert(!HasCopyNIt<int*, int*, SentinelForNotSemiregular>);39static_assert(!HasCopyNIt<int*, int*, SentinelForNotWeaklyEqualityComparableWith>);40 41static_assert(std::is_same_v<std::ranges::copy_result<int, long>, std::ranges::in_out_result<int, long>>);42 43template <class In, class Out>44constexpr void test_iterators() {45  { // simple test46    std::array in{1, 2, 3, 4};47    std::array<int, 4> out;48    std::same_as<std::ranges::in_out_result<In, Out>> auto ret =49        std::ranges::copy_n(In(in.data()), in.size(), Out(out.data()));50    assert(in == out);51    assert(base(ret.in) == in.data() + in.size());52    assert(base(ret.out) == out.data() + out.size());53  }54 55  { // check that an empty range works56    std::array<int, 0> in;57    std::array<int, 0> out;58    auto ret = std::ranges::copy_n(In(in.data()), in.size(), Out(out.data()));59    assert(base(ret.in) == in.data());60    assert(base(ret.out) == out.data());61  }62}63 64#if TEST_STD_VER >= 2365constexpr bool test_vector_bool(std::size_t N) {66  std::vector<bool> in(N, false);67  for (std::size_t i = 0; i < N; i += 2)68    in[i] = true;69 70  { // Test copy with aligned bytes71    std::vector<bool> out(N);72    std::ranges::copy_n(in.begin(), N, out.begin());73    assert(in == out);74  }75  { // Test copy with unaligned bytes76    std::vector<bool> out(N + 8);77    std::ranges::copy_n(in.begin(), N, out.begin() + 4);78    for (std::size_t i = 0; i < N; ++i)79      assert(out[i + 4] == in[i]);80  }81 82  return true;83};84#endif85 86constexpr bool test() {87  types::for_each(types::cpp20_input_iterator_list<int*>{}, []<class Out>() {88    types::for_each(types::cpp20_input_iterator_list<int*>{}, []<class In>() {89      test_iterators<In, Out>();90      test_iterators<ProxyIterator<In>, ProxyIterator<Out>>();91    });92  });93 94  { // check that every element is copied exactly once95    struct CopyOnce {96      bool copied                               = false;97      constexpr CopyOnce()                      = default;98      constexpr CopyOnce(const CopyOnce& other) = delete;99      constexpr CopyOnce& operator=(const CopyOnce& other) {100        assert(!other.copied);101        copied = true;102        return *this;103      }104    };105    std::array<CopyOnce, 4> in{};106    std::array<CopyOnce, 4> out{};107    auto ret = std::ranges::copy_n(in.begin(), in.size(), out.begin());108    assert(ret.in == in.end());109    assert(ret.out == out.end());110    assert(std::all_of(out.begin(), out.end(), [](const auto& e) { return e.copied; }));111  }112 113#if TEST_STD_VER >= 23114  { // Test vector<bool>::iterator optimization115    assert(test_vector_bool(8));116    assert(test_vector_bool(19));117    assert(test_vector_bool(32));118    assert(test_vector_bool(49));119    assert(test_vector_bool(64));120    assert(test_vector_bool(199));121    assert(test_vector_bool(256));122  }123#endif124 125  return true;126}127 128int main(int, char**) {129  test();130  static_assert(test());131 132  return 0;133}134