Skip to main content

std::inplace_merge() algorithm

// (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 )

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 Resolution

    These overloads participate 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)

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:

bool cmp(const Type1 &a, const Type2 &b);
  • The signature does not need to have const&, but must not modify arguments.
  • Must accept all values of type (possibly const) Type and Type2, regardless of value category (so Type1& is not allowed, nor is Type1 unless for Type1 a move is equivalent to a copy (since C++11))
  • The types Type1 and Type2 must be such that an object of type RandomIt can be implicitly converted to both of them.

Type requirements

BidirItLegacyBidirectionalIterator
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 other ExecutionPolicy, 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

Main.cpp
#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);
}
Possible Output
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
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.

std::inplace_merge() algorithm

// (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 )

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 Resolution

    These overloads participate 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)

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:

bool cmp(const Type1 &a, const Type2 &b);
  • The signature does not need to have const&, but must not modify arguments.
  • Must accept all values of type (possibly const) Type and Type2, regardless of value category (so Type1& is not allowed, nor is Type1 unless for Type1 a move is equivalent to a copy (since C++11))
  • The types Type1 and Type2 must be such that an object of type RandomIt can be implicitly converted to both of them.

Type requirements

BidirItLegacyBidirectionalIterator
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 other ExecutionPolicy, 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

Main.cpp
#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);
}
Possible Output
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
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.