跳到主要内容

std::ranges::rotate_copy() 算法

// (1)
constexpr rotate_copy_result<I, O>
rotate_copy( I first, I middle, S last, O result );

// (2)
constexpr rotate_copy_result<ranges::borrowed_iterator_t<R>, O>
rotate_copy( R&& r, ranges::iterator_t<R> middle, O result );

参数类型是泛型的,并具有以下约束

  • I - std::forward_iterator
  • S - std::sentinel_for<I>
  • O - std::weakly_incrementable
  • R - std::forward_range

此外,每个重载都有以下约束

  • (1) - std::indirectly_copyable<I, O>
  • (2) - std::indirectly_copyable<ranges::iterator_t<R>, O>

辅助类型定义如下:

template< class I, class O >
using rotate_copy_result = in_out_result<I, O>;
  • (1) 将源范围 [first; last) 中的元素复制到从 result 开始的目标范围,使得元素 *middle 成为目标范围的第一个元素,*(middle - 1) 成为最后一个元素。

    结果是目标范围包含源范围的左旋转副本。

  • (2)(1) 相同,但使用 r 作为源范围,如同使用 ranges::begin(r) 作为 firstranges::end(r) 作为 last

未定义行为

行为未定义

如果 [first; middle) 或 [middle; last) 不是有效范围,或者源范围和目标范围重叠。

本页描述的函数类实体是niebloids

参数

first
last

要复制的元素范围。

r

要复制的元素范围。

result

目标范围的开头。

middle

指向应出现在目标范围开头的元素的迭代器。

返回值

{
last,
result + N
}

其中 N 是 ranges::distance(first, last)

复杂度

恰好 ranges::distance(first, last) 次赋值。

异常

(无)

可能的实现

rotate_copy(1) 和 rotate_copy(2)
struct rotate_copy_fn
{
template<std::forward_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O>
requires std::indirectly_copyable<I, O>
constexpr ranges::rotate_copy_result<I, O>
operator()(I first, I middle, S last, O result) const
{
auto c1 {ranges::copy(middle, std::move(last), std::move(result))};
auto c2 {ranges::copy(std::move(first), std::move(middle), std::move(c1.out))};
return {std::move(c1.in), std::move(c2.out)};
}

template<ranges::forward_range R, std::weakly_incrementable O>
requires std::indirectly_copyable<ranges::iterator_t<R>, O>
constexpr ranges::rotate_copy_result<ranges::borrowed_iterator_t<R>, O>
operator()(R&& r, ranges::iterator_t<R> middle, O result) const
{
return (*this)(ranges::begin(r), std::move(middle),
ranges::end(r), std::move(result));
}
};

inline constexpr rotate_copy_fn rotate_copy {};

备注

如果值类型是 TriviallyCopyable 且迭代器类型满足 contiguous_iterator,则 ranges::rotate_copy 的实现通常通过使用“批量复制”函数(例如 std::memmove)来避免多次赋值。

示例

Main.cpp
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

int main()
{
std::vector<int> src {1, 2, 3, 4, 5};
std::vector<int> dest(src.size());
auto pivot = std::ranges::find(src, 3);

std::ranges::rotate_copy(src, pivot, dest.begin());
for (int i : dest)
std::cout << i << ' ';
std::cout << '\n';

// copy the rotation result directly to the std::cout
pivot = std::ranges::find(dest, 1);
std::ranges::rotate_copy(dest, pivot, std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
}
输出
3 4 5 1 2
1 2 3 4 5
本文来源于 此 CppReference 页面。它可能为了改进或编辑者偏好而进行了修改。点击“编辑此页面”可查看对此文档所做的所有更改。
悬停查看原始许可证。

std::ranges::rotate_copy() 算法

// (1)
constexpr rotate_copy_result<I, O>
rotate_copy( I first, I middle, S last, O result );

// (2)
constexpr rotate_copy_result<ranges::borrowed_iterator_t<R>, O>
rotate_copy( R&& r, ranges::iterator_t<R> middle, O result );

参数类型是泛型的,并具有以下约束

  • I - std::forward_iterator
  • S - std::sentinel_for<I>
  • O - std::weakly_incrementable
  • R - std::forward_range

此外,每个重载都有以下约束

  • (1) - std::indirectly_copyable<I, O>
  • (2) - std::indirectly_copyable<ranges::iterator_t<R>, O>

辅助类型定义如下:

template< class I, class O >
using rotate_copy_result = in_out_result<I, O>;
  • (1) 将源范围 [first; last) 中的元素复制到从 result 开始的目标范围,使得元素 *middle 成为目标范围的第一个元素,*(middle - 1) 成为最后一个元素。

    结果是目标范围包含源范围的左旋转副本。

  • (2)(1) 相同,但使用 r 作为源范围,如同使用 ranges::begin(r) 作为 firstranges::end(r) 作为 last

未定义行为

行为未定义

如果 [first; middle) 或 [middle; last) 不是有效范围,或者源范围和目标范围重叠。

本页描述的函数类实体是niebloids

参数

first
last

要复制的元素范围。

r

要复制的元素范围。

result

目标范围的开头。

middle

指向应出现在目标范围开头的元素的迭代器。

返回值

{
last,
result + N
}

其中 N 是 ranges::distance(first, last)

复杂度

恰好 ranges::distance(first, last) 次赋值。

异常

(无)

可能的实现

rotate_copy(1) 和 rotate_copy(2)
struct rotate_copy_fn
{
template<std::forward_iterator I, std::sentinel_for<I> S, std::weakly_incrementable O>
requires std::indirectly_copyable<I, O>
constexpr ranges::rotate_copy_result<I, O>
operator()(I first, I middle, S last, O result) const
{
auto c1 {ranges::copy(middle, std::move(last), std::move(result))};
auto c2 {ranges::copy(std::move(first), std::move(middle), std::move(c1.out))};
return {std::move(c1.in), std::move(c2.out)};
}

template<ranges::forward_range R, std::weakly_incrementable O>
requires std::indirectly_copyable<ranges::iterator_t<R>, O>
constexpr ranges::rotate_copy_result<ranges::borrowed_iterator_t<R>, O>
operator()(R&& r, ranges::iterator_t<R> middle, O result) const
{
return (*this)(ranges::begin(r), std::move(middle),
ranges::end(r), std::move(result));
}
};

inline constexpr rotate_copy_fn rotate_copy {};

备注

如果值类型是 TriviallyCopyable 且迭代器类型满足 contiguous_iterator,则 ranges::rotate_copy 的实现通常通过使用“批量复制”函数(例如 std::memmove)来避免多次赋值。

示例

Main.cpp
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

int main()
{
std::vector<int> src {1, 2, 3, 4, 5};
std::vector<int> dest(src.size());
auto pivot = std::ranges::find(src, 3);

std::ranges::rotate_copy(src, pivot, dest.begin());
for (int i : dest)
std::cout << i << ' ';
std::cout << '\n';

// copy the rotation result directly to the std::cout
pivot = std::ranges::find(dest, 1);
std::ranges::rotate_copy(dest, pivot, std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
}
输出
3 4 5 1 2
1 2 3 4 5
本文来源于 此 CppReference 页面。它可能为了改进或编辑者偏好而进行了修改。点击“编辑此页面”可查看对此文档所做的所有更改。
悬停查看原始许可证。