Namespaces
Variants
Views
Actions

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

From cppreference.com
< cpp‎ | algorithm
m (seealso par)
(Wording update.)
 
(17 intermediate revisions by 7 users not shown)
Line 2: Line 2:
 
{{cpp/algorithm/navbar}}
 
{{cpp/algorithm/navbar}}
 
{{dcl begin}}
 
{{dcl begin}}
{{dcl header | algorithm}}
+
{{dcl header|algorithm}}
{{dcl |
+
{{dcl|num=1|notes={{mark constexpr since c++20}}|
 
template< class ForwardIt1, class ForwardIt2 >
 
template< class ForwardIt1, class ForwardIt2 >
ForwardIt2 swap_ranges( ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2 );
+
ForwardIt2 swap_ranges( ForwardIt1 first1, ForwardIt1 last1,
 +
                        ForwardIt2 first2 );
 +
}}
 +
{{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}}
 
{{dcl end}}
  
Exchanges elements between range {{tt|[first1, last1)}} and another range starting at {{tt|first2}}.  
+
@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}}
 +
 
 +
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===
 
{{par begin}}
 
{{par begin}}
{{par | first1, last1 | the first range of elements to swap}}
+
{{par|first1, last1|the first range of elements to swap}}
{{par | first2 | beginning of the second range of elements to swap}}
+
{{par|first2|beginning of the second range of elements to swap}}
 +
{{par exec pol}}
 
{{par hreq}}
 
{{par hreq}}
{{par req concept | ForwardIt1, ForwardIt2 | ForwardIterator}}
+
{{par req named|ForwardIt1, ForwardIt2|ForwardIterator}}
{{par req | The types of dereferenced {{tt|ForwardIt1}} and {{tt|ForwardIt2}} must meet the requirements of {{concept|Swappable}}}}
+
 
{{par end}}
 
{{par end}}
  
 
===Return value===
 
===Return value===
Iterator to the element past the last element exchanged in the range beginning with {{tt|first2}}.
+
Iterator to the element past the last element exchanged in the range beginning with {{c|first2}}.
 +
 
 +
===Complexity===
 +
Exactly {{c|std::distance(first1, last1)}} swaps.
 +
 
 +
===Exceptions===
 +
{{cpp/algorithm/parallel exceptions reporting behavior|singular=yes}}
 +
 
 +
===Notes===
 +
{{cpp/algorithm/notes swap vectorization}}
  
 
===Possible implementation===
 
===Possible implementation===
{{eq fun | 1=
+
{{eq fun|1=
 
template<class ForwardIt1, class ForwardIt2>
 
template<class ForwardIt1, class ForwardIt2>
ForwardIt2 swap_ranges(ForwardIt1 first1,  
+
constexpr //< since C++20
                            ForwardIt1 last1,  
+
ForwardIt2 swap_ranges(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2)
                            ForwardIt2 first2)
+
 
{
 
{
     while (first1 != last1) {
+
     for (; first1 != last1; ++first1, ++first2)
         std::iter_swap(first1++, first2++);
+
         std::iter_swap(first1, first2);
     }
+
      
 
     return first2;
 
     return first2;
 
}
 
}
Line 39: Line 62:
 
===Example===
 
===Example===
 
{{example
 
{{example
| Demonstrates swapping of subranges from different containers
+
|Demonstrates swapping of subranges from different containers.
| code=
+
|code=
 
#include <algorithm>
 
#include <algorithm>
 +
#include <iostream>
 
#include <list>
 
#include <list>
 
#include <vector>
 
#include <vector>
#include <iostream>
 
int main()
 
{
 
    std::vector<int> v = {1, 2, 3, 4, 5};
 
    std::list<int> l = {-1, -2, -3, -4, -5};
 
  
    std::swap_ranges(v.begin(), v.begin()+3, l.begin());
+
auto print = [](auto comment, auto const& seq)
 
+
{
    for(int n : v)
+
     std::cout << comment;
      std::cout << n << ' ';
+
     for (const auto& e : seq)
     std::cout << '\n';
+
        std::cout << e << ' ';
     for(int n : l)
+
      std::cout << n << ' ';
+
 
     std::cout << '\n';
 
     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=
+
|output=
-1 -2 -3 4 5
+
Before swap_ranges:
1 2 3 -4 -5
+
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
 
}}
 
}}
 
===Complexity===
 
 
linear in the distance between {{tt|first}} and {{tt|last}}
 
  
 
===See also===
 
===See also===
 
{{dsc begin}}
 
{{dsc begin}}
{{dsc inc | cpp/algorithm/dsc iter_swap}}
+
{{dsc inc|cpp/algorithm/dsc iter_swap}}
{{dsc inc | cpp/algorithm/dsc swap}}
+
{{dsc inc|cpp/algorithm/dsc swap}}
{{dsc inc | cpp/experimental/parallelism/dsc algorithm | swap_ranges}}
+
{{dsc inc|cpp/algorithm/ranges/dsc swap_ranges}}
 
{{dsc end}}
 
{{dsc end}}
  
[[de:cpp/algorithm/swap ranges]]
+
{{langlinks|de|es|fr|it|ja|pt|ru|zh}}
[[es:cpp/algorithm/swap ranges]]
+
[[fr:cpp/algorithm/swap ranges]]
+
[[it:cpp/algorithm/swap ranges]]
+
[[ja:cpp/algorithm/swap ranges]]
+
[[pt:cpp/algorithm/swap ranges]]
+
[[ru:cpp/algorithm/swap ranges]]
+
[[zh:cpp/algorithm/swap ranges]]
+

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]