100 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++1410 11// UNSUPPORTED: libcpp-has-no-incomplete-pstl12 13// <algorithm>14 15// template<class ExecutionPolicy, class ForwardIterator1, class ForwardIterator2>16// ForwardIterator217// rotate_copy(ExecutionPolicy&& exec,18// ForwardIterator1 first, ForwardIterator1 middle, ForwardIterator1 last,19// ForwardIterator2 result);20 21#include <algorithm>22#include <array>23#include <cassert>24#include <numeric>25#include <vector>26 27#include "test_macros.h"28#include "test_execution_policies.h"29#include "test_iterators.h"30#include "type_algorithms.h"31 32template <class Iter>33struct Test {34 template <class Policy>35 void operator()(Policy&& policy) {36 { // simple test37 int in[] = {1, 2, 3, 4};38 int out[std::size(in)];39 40 decltype(auto) ret = std::rotate_copy(policy, Iter(in), Iter(in + 2), Iter(in + 4), Iter(out));41 static_assert(std::is_same_v<decltype(ret), Iter>);42 assert(base(ret) == out + 4);43 44 int expected[] = {3, 4, 1, 2};45 assert(std::equal(out, out + 4, expected));46 }47 { // rotating an empty range works48 std::array<int, 0> in = {};49 std::array<int, 0> out = {};50 51 decltype(auto) ret =52 std::rotate_copy(policy, Iter(in.data()), Iter(in.data()), Iter(in.data()), Iter(out.data()));53 static_assert(std::is_same_v<decltype(ret), Iter>);54 assert(base(ret) == out.data());55 }56 { // rotating an single-element range works57 int in[] = {1};58 int out[std::size(in)];59 60 decltype(auto) ret = std::rotate_copy(policy, Iter(in), Iter(in), Iter(in + 1), Iter(out));61 static_assert(std::is_same_v<decltype(ret), Iter>);62 assert(base(ret) == out + 1);63 64 int expected[] = {1};65 assert(std::equal(out, out + 1, expected));66 }67 { // rotating a two-element range works68 int in[] = {1, 2};69 int out[std::size(in)];70 71 decltype(auto) ret = std::rotate_copy(policy, Iter(in), Iter(in + 1), Iter(in + 2), Iter(out));72 static_assert(std::is_same_v<decltype(ret), Iter>);73 assert(base(ret) == out + 2);74 75 int expected[] = {2, 1};76 assert(std::equal(out, out + 2, expected));77 }78 { // rotating a large range works79 std::vector<int> data(100);80 std::iota(data.begin(), data.end(), 0);81 for (int i = 0; i != 100; ++i) { // check all permutations82 auto copy = data;83 std::vector<int> out(100);84 std::rotate_copy(Iter(data.data()), Iter(data.data() + i), Iter(data.data() + data.size()), Iter(out.data()));85 assert(out[0] == i);86 assert(std::adjacent_find(out.begin(), out.end(), [](int lhs, int rhs) {87 return lhs == 99 ? rhs != 0 : lhs != rhs - 1;88 }) == out.end());89 assert(copy == data);90 }91 }92 }93};94 95int main(int, char**) {96 types::for_each(types::forward_iterator_list<int*>{}, TestIteratorWithPolicies<Test>{});97 98 return 0;99}100