• Class / Function / Type

      std::
    • Header file

      <>
    • Other / All

    最終更新日時(UTC):
    が更新

    履歴 編集

    function template
    <algorithm>

    std::partition_point

    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 の引数型へ変換可能であること

    事前条件

    • イテレータ範囲[first,last)pred によって区分化されていなければならない。つまり、pred を満たす全ての要素が、pred を満たさない全ての要素より前に出現してなければならない

    戻り値

    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

    処理系

    参照