namespace std {
template <class ForwardIterator, class Predicate>
ForwardIterator
partition_point(ForwardIterator first,
ForwardIterator last,
Predicate pred); // C++11
template <class ForwardIterator, class Predicate>
constexpr ForwardIterator
partition_point(ForwardIterator first,
ForwardIterator last,
Predicate pred); // C++20
}
概要
イテレータ範囲[first, last)
から条件によって区分化されている位置を得る。
テンプレートパラメータ制約
ForwardIterator
の value type はPredicate
の引数型へ変換可能であること
事前条件
戻り値
all_of(first, mid, pred)
と none_of(mid, last, pred)
が true
であるようなイテレータ mid
を返す。
計算量
pred
が O(log(last - first
)) 回適用される。
例
#include <iostream>
#include <vector>
#include <algorithm>
void print(const char* name, const std::vector<int>& v)
{
std::cout << name << " : ";
std::for_each(v.begin(), v.end(), [](int x) {
std::cout << x << ",";
});
std::cout << std::endl;
}
bool is_even(int x) { return x % 2 == 0; }
int main()
{
std::vector<int> v = {1, 2, 3, 4, 5};
std::partition(v.begin(), v.end(), is_even);
// 偶数グループと奇数グループに分かれた位置を得る
decltype(v)::iterator it = std::partition_point(v.begin(), v.end(), is_even);
print("v", v);
std::cout << *it << std::endl;
}
出力
v : 4,2,3,1,5,
3
実装例
template<class ForwardIterator, class Predicate>
ForwardIterator
partition_point(ForwardIterator first, ForwardIterator last, Predicate pred)
{
for (auto len = std::distance(first, last); len != 0; ) {
auto half = len / 2;
auto mid = std::next(first, half);
if (pred(*mid)) {
len -= half + 1;
first = std::next(mid);
} else {
len = half;
}
}
return first;
}
バージョン
言語
- C++11
処理系
- Clang: ??
- GCC: 4.7.0 ✅
- ICC: ??
- Visual C++: 2010 ✅, 2012 ✅, 2013 ✅, 2015 ✅