std::ranges...copy_result(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ‘‘ std::ranges...copy_result(3) β€” C++ Standard Libary era

okay so welcome to the manual page for std::ranges...copy_result(3) from the C++ Standard Libary manual (yes, that’s literally how it’s spelled in the header β€” iconic typo behavior πŸ’…). This is your group-chat explainer for std::ranges::rotate_copy and std::ranges::rotate_copy_result, and no cap, every single detail is staying.


✨ NAME ✨

std::ranges::rotate_copy,std::ranges::rotate_copy_result - std::ranges::rotate_copy,std::ranges::rotate_copy_result


🌸 Synopsis 🌸

Defined in header <algorithm>

Call signature

template< std::forward_iterator I, std::sentinel_for<I> S,

          std::weakly_incrementable O >
requires std::indirectly_copyable<I, O>                           (1)
(since C++20)
constexpr rotate_copy_result<I, O>

    rotate_copy( I first, I middle, S last, O result );
template< ranges::forward_range R, std::weakly_incrementable O >

requires std::indirectly_copyable<ranges::iterator_t<R>, O>       (2)
(since C++20)
constexpr rotate_copy_result<ranges::borrowed_iterator_t<R>, O>

    rotate_copy( R&& r, ranges::iterator_t<R> middle, O result );

Helper types

template< class I, class O >                                      (3)
(since C++20)
    using rotate_copy_result = in_out_result<I, O>;
  1. Copies the elements from the source range [first, last), to the destination range beginning at result in such a way, that the element *middle becomes the first element of the destination range and *(middle - 1) becomes the last element. The result is that the destination range contains a left rotated copy of the source range. The behavior is undefined if either [first, middle) or [middle, last) is not a valid range, or the source and destination ranges overlap.
  2. Same as (1), but uses r as the source range, as if using ranges::begin(r) as first and ranges::end(r) as last.

The function-like entities described on this page are niebloids, that is:

  • Explicit template argument lists cannot be specified when calling any of them.
  • None of them are visible to argument-dependent lookup.
  • When any of them are found by normal unqualified lookup as the name to the left of the function-call operator, argument-dependent lookup is inhibited.

In practice, they may be implemented as function objects, or with special compiler extensions.


πŸŽ€ Parameters πŸŽ€

  • first, last β€” the source range of elements to copy from
  • r β€” the source range of elements to copy from
  • middle β€” the iterator to the element that should appear at the beginning of the destination range
  • result β€” beginning of the destination range

πŸ¦‹ Return value πŸ¦‹

{last, result + N}, where N = ranges::distance(first, last).


⭐ Complexity ⭐

Linear: exactly N assignments.


πŸ’œ Notes πŸ’œ

If the value type is TriviallyCopyable and the iterator types satisfy contiguous_iterator, implementations of ranges::rotate_copy usually avoid multiple assignments by using a "bulk copy" function such as std::memmove.


πŸ”₯ Possible implementation πŸ”₯

See also the implementations in libstdc++ and MSVC STL.

       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 {};

🌈 Example 🌈

       // Run this code

        #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';
        }

πŸ“ Output πŸ“

        3 4 5 1 2
        1 2 3 4 5

🧚 See also 🧚

The original listing is a little table-shaped chaos, so here’s every reference and tag exactly as it appears:

  • ranges::rotate β€” rotates the order of elements in a range β€” (C++20) β€” (niebloid)
  • ranges::copy
  • ranges::copy_if β€” copies a range of elements to a new location β€” (C++20) β€” (niebloid) β€” (C++20)
  • rotate_copy β€” copies and rotate a range of elements β€” (function template)

that’s the page, bestie! source/version vibes: http://cppreference.com Β· date: 2024.06.10 Β· page: std::ranges...copy_result(3) β€” mwah, bye πŸŽ€πŸ’–

πŸ“¦ where this page comes from