std::inplace_merge() algorithm
- since C++17
- until C++17
- since C++26
// (1)
template< class BidirIt >
void inplace_merge( BidirIt first, BidirIt middle, BidirIt last );
// (2)
template< class BidirIt, class Compare >
void inplace_merge( BidirIt first, BidirIt middle, BidirIt last, Compare comp );
// (3)
template< class ExecutionPolicy, class BidirIt >
void inplace_merge( ExecutionPolicy&& policy, BidirIt first, BidirIt middle, BidirIt last );
// (4)
template< class ExecutionPolicy, class BidirIt, class Compare >
void inplace_merge( ExecutionPolicy&& policy,
BidirIt first, BidirIt middle, BidirIt last, Compare comp )
// (1)
template< class BidirIt >
void inplace_merge( BidirIt first, BidirIt middle, BidirIt last );
// (2)
template< class BidirIt, class Compare >
void inplace_merge( BidirIt first, BidirIt middle, BidirIt last, Compare comp );
// (1)
template< class BidirIt >
constexpr void inplace_merge( BidirIt first, BidirIt middle, BidirIt last );
// (2)
template< class BidirIt, class Compare >
constexpr void inplace_merge( BidirIt first, BidirIt middle, BidirIt last, Compare comp );
// (3)
template< class ExecutionPolicy, class BidirIt >
void inplace_merge( ExecutionPolicy&& policy, BidirIt first, BidirIt middle, BidirIt last );
// (4)
template< class ExecutionPolicy, class BidirIt, class Compare >
void inplace_merge( ExecutionPolicy&& policy,
BidirIt first, BidirIt middle, BidirIt last, Compare comp )
Merges two consecutive sorted ranges [first
; middle
) and [middle
; last
) into one sorted range [first
; last
).
A sequence is said to be sorted with respect to a comparator comp
if for any iterator it
pointing to the sequence
and any non-negative integer n
such that it + n
is a valid iterator pointing to an element of the sequence,
comp(*(it + n), *it)
evaluates to false
.
-
(1) Elements are compared using
operator<
. The ranges must be sorted with respect to this operator as well. -
(2) Elements are compared using the given binary comparison function
comp
. The ranges must be sorted with respect to this comparator as well. -
(3 - 4) Same as (1) and (2), but executed according to policy.
Overload ResolutionThese overloads participate in overload resolution only if
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>
istrue
. (until C++20)std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>
istrue
. (since C++20)
This function is stable, which means that for equivalent elements in the original two ranges, the elements from the first range precede the elements from the second range, preserving their original order.
Parameters
first | The first range of elements to inplace_merge. |
middle | The end of the first sorted range and the beginning of the second. |
last | The end of the second sorted range. |
policy | The execution policy to use. See execution policy for details. |
comp | Comparison function object (i.e. an object that satisfies the requirements of Compare). The signature of the comparison function should be equivalent to the following:
|
Type requirements
BidirIt | LegacyBidirectionalIterator ValuSwappable |
Type of dereferenced BidirIt | MoveAssignable MoveConstructible |
Return value
(none)
Complexity
Given N
as std::distance(first, last)
:
- (1 - 2) Exactly
N - 1
comparisons if enough additional memory is available. If the memory is insufficient, O(N * log(N)) comparisons. - (3 - 4) O(N * log(N)) comparisons.
Exceptions
The overloads with a template parameter named ExecutionPolicy
report 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 otherExecutionPolicy
, the behavior is implementation-defined. - If the algorithm fails to allocate memory,
std::bad_alloc
is thrown.
Possible implementation
Vendor implementations: GCC (libstdc++) ⏺ LLVM Clang (libc++)
Notes
This function attempts to allocate a temporary buffer. If the allocation fails, the less efficient algorithm is chosen.
Examples
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <random>
#include <vector>
auto print = [](auto const rem, auto const& v)
{
std::cout << rem;
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
};
int main()
{
// fill the vectors with random numbers
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_int_distribution<> dis(0, 9);
std::vector<int> v1(10), v2(10);
std::generate(v1.begin(), v1.end(), std::bind(dis, std::ref(mt)));
std::generate(v2.begin(), v2.end(), std::bind(dis, std::ref(mt)));
print("Originally:\nv1: ", v1);
print("v2: ", v2);
std::sort(v1.begin(), v1.end());
std::sort(v2.begin(), v2.end());
print("After sorting:\nv1: ", v1);
print("v2: ", v2);
// inplace_merge
std::vector<int> dst;
std::inplace_merge(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(dst));
print("After merging:\ndst: ", dst);
}
Originally:
v1: 2 6 5 7 4 2 2 6 7 0
v2: 8 3 2 5 0 1 9 6 5 0
After sorting:
v1: 0 2 2 2 4 5 6 6 7 7
v2: 0 0 1 2 3 5 5 6 8 9
After merging:
dst: 0 0 0 1 2 2 2 2 3 4 5 5 5 6 6 6 7 7 8 9
Hover to see the original license.