Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/algorithm/swap ranges"

From cppreference.com
< cpp‎ | algorithm
m (Text replace - "{{params}}" to "===Parameters===")
(Wording update.)
 
(40 intermediate revisions by 13 users not shown)
Line 1: Line 1:
 
{{cpp/title|swap_ranges}}
 
{{cpp/title|swap_ranges}}
{{cpp/algorithm/sidebar}}
+
{{cpp/algorithm/navbar}}
{{ddcl list begin}}
+
{{dcl begin}}
{{ddcl list header | algorithm}}
+
{{dcl header|algorithm}}
{{ddcl list item |
+
{{dcl|num=1|notes={{mark constexpr since c++20}}|
template< class ForwardIterator1, class ForwardIterator2 >
+
template< class ForwardIt1, class ForwardIt2 >
ForwardIterator2 swap_ranges( ForwardIterator1 first1,
+
ForwardIt2 swap_ranges( ForwardIt1 first1, ForwardIt1 last1,
                              ForwardIterator1 last1,  
+
                        ForwardIt2 first2 );
                              ForwardIterator2 first2 )
+
 
}}
 
}}
{{ddcl list end}}
+
{{dcl|num=2|since=c++17|
 +
template< class ExecutionPolicy,
 +
          class ForwardIt1, class ForwardIt2 >
 +
ForwardIt2 swap_ranges( ExecutionPolicy&& policy,
 +
                        ForwardIt1 first1, ForwardIt1 last1,
 +
                        ForwardIt2 first2 );
 +
}}
 +
{{dcl end}}
 +
 
 +
@1@ Exchanges elements between range {{range|first1|last1}} and another range of {{c|std::distance(first1, last1)}} elements starting at {{c|first2}}.
 +
 
 +
@2@ Same as {{v|1}}, but executed according to {{c|policy}}.
 +
@@ {{cpp/algorithm/parallel overload precondition}}
  
Exchanges elements between range {{tt|[first1, last1)}} and another range starting at {{tt|first2}}.  
+
If any of the following conditions is satisfied, the behavior is undefined:
 +
* The two ranges overlap.
 +
* There exists a pair of corresponding iterators {{c|iter1}} and {{c|iter2}} in the two ranges such that {{c|*iter1}} is not {{named req|Swappable}} with {{c|*iter2}}.
  
<!-- ======== -->
 
 
===Parameters===
 
===Parameters===
{{param list begin}}
+
{{par begin}}
{{param list item | first1, last1 | the first range of elements to swap}}
+
{{par|first1, last1|the first range of elements to swap}}
{{param list item | first2 | beginning of the second range of elements to swap}}
+
{{par|first2|beginning of the second range of elements to swap}}
{{param list end}}
+
{{par exec pol}}
 +
{{par hreq}}
 +
{{par req named|ForwardIt1, ForwardIt2|ForwardIterator}}
 +
{{par end}}
  
<!-- ======== -->
+
===Return value===
{{returns}}
+
Iterator to the element past the last element exchanged in the range beginning with {{c|first2}}.
  
iterator to the element past the last element exchanged in the range beginning with {{tt|first2}}.
+
===Complexity===
 +
Exactly {{c|std::distance(first1, last1)}} swaps.
  
 +
===Exceptions===
 +
{{cpp/algorithm/parallel exceptions reporting behavior|singular=yes}}
  
<!-- ======== -->
+
===Notes===
{{eq fun}}
+
{{cpp/algorithm/notes swap vectorization}}
{{eq fun cpp | 1=
+
 
template<class ForwardIterator1, class ForwardIterator2>
+
===Possible implementation===
ForwardIterator1 swap_ranges(ForwardIterator1 first1,  
+
{{eq fun|1=
                            ForwardIterator1 last1,  
+
template<class ForwardIt1, class ForwardIt2>
                            ForwardIterator2 first2)
+
constexpr //< since C++20
 +
ForwardIt2 swap_ranges(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2)
 
{
 
{
     while (first1 != last1) {
+
     for (; first1 != last1; ++first1, ++first2)
         std::iter_swap(first1++, first2++);
+
         std::iter_swap(first1, first2);
     }
+
      
 
     return first2;
 
     return first2;
 
}
 
}
 
}}
 
}}
  
<!-- ======== -->
+
===Example===
{{example}}
+
{{example
{{example cpp
+
|Demonstrates swapping of subranges from different containers.
|
+
|code=
| code=
+
#include <algorithm>
 +
#include <iostream>
 +
#include <list>
 +
#include <vector>
  
| output=
+
auto print = [](auto comment, auto const& seq)
 +
{
 +
    std::cout << comment;
 +
    for (const auto& e : seq)
 +
        std::cout << e << ' ';
 +
    std::cout << '\n';
 +
};
  
 +
int main()
 +
{
 +
    std::vector<char> v{'a', 'b', 'c', 'd', 'e'};
 +
    std::list<char> l{'1', '2', '3', '4', '5'};
 +
   
 +
    print("Before swap_ranges:\n" "v: ", v);
 +
    print("l: ", l);
 +
   
 +
    std::swap_ranges(v.begin(), v.begin() + 3, l.begin());
 +
   
 +
    print("After swap_ranges:\n" "v: ", v);
 +
    print("l: ", l);
 +
}
 +
|output=
 +
Before swap_ranges:
 +
v: a b c d e
 +
l: 1 2 3 4 5
 +
After swap_ranges:
 +
v: 1 2 3 d e
 +
l: a b c 4 5
 
}}
 
}}
  
<!-- ======== -->
 
{{complex}}
 
 
linear in the distance between {{tt|first}} and {{tt|last}}
 
 
<!-- ======== -->
 
 
===See also===
 
===See also===
{{dcl list begin}}
+
{{dsc begin}}
{{dcl list template | cpp/algorithm/dcl list iter_swap}}
+
{{dsc inc|cpp/algorithm/dsc iter_swap}}
{{dcl list template | cpp/algorithm/dcl list swap}}
+
{{dsc inc|cpp/algorithm/dsc swap}}
{{dcl list end}}
+
{{dsc inc|cpp/algorithm/ranges/dsc swap_ranges}}
 +
{{dsc end}}
 +
 
 +
{{langlinks|de|es|fr|it|ja|pt|ru|zh}}

Latest revision as of 23:42, 25 March 2024

 
 
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy, ranges::sort, ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
(C++11)                (C++11)(C++11)

Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
swap_ranges

Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17)(C++11)
(C++20)(C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
(C++11)
(C++17)
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
 
Defined in header <algorithm>
template< class ForwardIt1, class ForwardIt2 >

ForwardIt2 swap_ranges( ForwardIt1 first1, ForwardIt1 last1,

                        ForwardIt2 first2 );
(1) (constexpr since C++20)
template< class ExecutionPolicy,

          class ForwardIt1, class ForwardIt2 >
ForwardIt2 swap_ranges( ExecutionPolicy&& policy,
                        ForwardIt1 first1, ForwardIt1 last1,

                        ForwardIt2 first2 );
(2) (since C++17)
1) Exchanges elements between range [first1last1) and another range of std::distance(first1, last1) elements starting at first2.
2) Same as (1), but executed according to policy.
This overload participates in overload resolution only if

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> is true.

(until C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> is true.

(since C++20)

If any of the following conditions is satisfied, the behavior is undefined:

  • The two ranges overlap.
  • There exists a pair of corresponding iterators iter1 and iter2 in the two ranges such that *iter1 is not Swappable with *iter2.

Contents

[edit] Parameters

first1, last1 - the first range of elements to swap
first2 - beginning of the second range of elements to swap
policy - the execution policy to use. See execution policy for details.
Type requirements
-
ForwardIt1, ForwardIt2 must meet the requirements of LegacyForwardIterator.

[edit] Return value

Iterator to the element past the last element exchanged in the range beginning with first2.

[edit] Complexity

Exactly std::distance(first1, last1) swaps.

[edit] Exceptions

The overload with a template parameter named ExecutionPolicy reports errors as follows:

  • If execution of a function invoked as part of the algorithm throws an exception and ExecutionPolicy is one of the standard policies, std::terminate is called. For any other ExecutionPolicy, the behavior is implementation-defined.
  • If the algorithm fails to allocate memory, std::bad_alloc is thrown.

[edit] Notes

Implementations (e.g. MSVC STL) may enable vectorization when the iterator type satisfies LegacyContiguousIterator and swapping its value type calls neither non-trivial special member function nor ADL-found swap.

[edit] Possible implementation

template<class ForwardIt1, class ForwardIt2>
constexpr //< since C++20
ForwardIt2 swap_ranges(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2)
{
    for (; first1 != last1; ++first1, ++first2)
        std::iter_swap(first1, first2);
 
    return first2;
}

[edit] Example

Demonstrates swapping of subranges from different containers.

#include <algorithm>
#include <iostream>
#include <list>
#include <vector>
 
auto print = [](auto comment, auto const& seq)
{
    std::cout << comment;
    for (const auto& e : seq)
        std::cout << e << ' ';
    std::cout << '\n';
};
 
int main()
{
    std::vector<char> v{'a', 'b', 'c', 'd', 'e'};
    std::list<char> l{'1', '2', '3', '4', '5'};
 
    print("Before swap_ranges:\n" "v: ", v);
    print("l: ", l);
 
    std::swap_ranges(v.begin(), v.begin() + 3, l.begin());
 
    print("After swap_ranges:\n" "v: ", v);
    print("l: ", l);
}

Output:

Before swap_ranges:
v: a b c d e
l: 1 2 3 4 5
After swap_ranges:
v: 1 2 3 d e
l: a b c 4 5

[edit] See also

swaps the elements pointed to by two iterators
(function template) [edit]
swaps the values of two objects
(function template) [edit]
swaps two ranges of elements
(niebloid)[edit]