diff --git a/libcxx/include/pstl/internal/algorithm_fwd.h b/libcxx/include/pstl/internal/algorithm_fwd.h --- a/libcxx/include/pstl/internal/algorithm_fwd.h +++ b/libcxx/include/pstl/internal/algorithm_fwd.h @@ -18,32 +18,31 @@ _PSTL_HIDE_FROM_ABI_PUSH -namespace __pstl -{ -namespace __internal -{ +namespace __pstl { +namespace __internal { //------------------------------------------------------------------------ // any_of //------------------------------------------------------------------------ template -bool -__brick_any_of(const _ForwardIterator, const _ForwardIterator, _Pred, - /*__is_vector=*/std::false_type) noexcept; +bool __brick_any_of(const _ForwardIterator, + const _ForwardIterator, + _Pred, + /*__is_vector=*/std::false_type) noexcept; template -bool -__brick_any_of(const _RandomAccessIterator, const _RandomAccessIterator, _Pred, - /*__is_vector=*/std::true_type) noexcept; +bool __brick_any_of(const _RandomAccessIterator, + const _RandomAccessIterator, + _Pred, + /*__is_vector=*/std::true_type) noexcept; template -bool -__pattern_any_of(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Pred) noexcept; +bool __pattern_any_of(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Pred) noexcept; template -bool -__pattern_any_of(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Pred); +bool __pattern_any_of( + __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Pred); //------------------------------------------------------------------------ // walk1 (pseudo) @@ -52,53 +51,58 @@ //------------------------------------------------------------------------ template -void __brick_walk1(_ForwardIterator, _ForwardIterator, _Function, +void __brick_walk1(_ForwardIterator, + _ForwardIterator, + _Function, /*vector=*/std::false_type) noexcept; template -void __brick_walk1(_RandomAccessIterator, _RandomAccessIterator, _Function, +void __brick_walk1(_RandomAccessIterator, + _RandomAccessIterator, + _Function, /*vector=*/std::true_type) noexcept; template -void -__pattern_walk1(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Function) noexcept; +void __pattern_walk1(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Function) noexcept; template -void -__pattern_walk1(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Function); +void __pattern_walk1( + __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Function); template -void -__pattern_walk_brick(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Brick) noexcept; +void __pattern_walk_brick(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Brick) noexcept; template -void -__pattern_walk_brick(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _Brick); +void __pattern_walk_brick( + __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Brick); //------------------------------------------------------------------------ // walk1_n //------------------------------------------------------------------------ template -_ForwardIterator __brick_walk1_n(_ForwardIterator, _Size, _Function, - /*_IsVectorTag=*/std::false_type); +_ForwardIterator __brick_walk1_n( + _ForwardIterator, + _Size, + _Function, + /*_IsVectorTag=*/std::false_type); template -_RandomAccessIterator __brick_walk1_n(_RandomAccessIterator, _DifferenceType, _Function, - /*vectorTag=*/std::true_type) noexcept; +_RandomAccessIterator __brick_walk1_n( + _RandomAccessIterator, + _DifferenceType, + _Function, + /*vectorTag=*/std::true_type) noexcept; template -_ForwardIterator -__pattern_walk1_n(_Tag, _ExecutionPolicy&&, _ForwardIterator, _Size, _Function) noexcept; +_ForwardIterator __pattern_walk1_n(_Tag, _ExecutionPolicy&&, _ForwardIterator, _Size, _Function) noexcept; template _RandomAccessIterator __pattern_walk1_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _Size, _Function); template -_ForwardIterator -__pattern_walk_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator, _Size, _Brick) noexcept; +_ForwardIterator __pattern_walk_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator, _Size, _Brick) noexcept; template _RandomAccessIterator @@ -111,63 +115,106 @@ //------------------------------------------------------------------------ template -_ForwardIterator2 __brick_walk2(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function, - /*vector=*/std::false_type) noexcept; +_ForwardIterator2 __brick_walk2( + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _Function, + /*vector=*/std::false_type) noexcept; template -_RandomAccessIterator2 __brick_walk2(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, _Function, - /*vector=*/std::true_type) noexcept; +_RandomAccessIterator2 __brick_walk2( + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _Function, + /*vector=*/std::true_type) noexcept; template -_ForwardIterator2 __brick_walk2_n(_ForwardIterator1, _Size, _ForwardIterator2, _Function, - /*vector=*/std::false_type) noexcept; +_ForwardIterator2 __brick_walk2_n( + _ForwardIterator1, + _Size, + _ForwardIterator2, + _Function, + /*vector=*/std::false_type) noexcept; template -_RandomAccessIterator2 __brick_walk2_n(_RandomAccessIterator1, _Size, _RandomAccessIterator2, _Function, - /*vector=*/std::true_type) noexcept; +_RandomAccessIterator2 __brick_walk2_n( + _RandomAccessIterator1, + _Size, + _RandomAccessIterator2, + _Function, + /*vector=*/std::true_type) noexcept; template _ForwardIterator2 __pattern_walk2(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function) noexcept; -template -_RandomAccessIterator2 -__pattern_walk2(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, - _RandomAccessIterator2, _Function); - -template , + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _Function); + +template _ForwardIterator2 __pattern_walk2_n(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Function) noexcept; -template -_RandomAccessIterator2 -__pattern_walk2_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _Size, _RandomAccessIterator2, - _Function); +template +_RandomAccessIterator2 __pattern_walk2_n( + __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _Size, _RandomAccessIterator2, _Function); template -_ForwardIterator2 -__pattern_walk2_brick(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _Brick) noexcept; +_ForwardIterator2 __pattern_walk2_brick( + _Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Brick) noexcept; -template -_RandomAccessIterator2 -__pattern_walk2_brick(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, - _RandomAccessIterator2, _Brick); - -template , + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _Brick); + +template _ForwardIterator2 __pattern_walk2_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Brick) noexcept; -template -_RandomAccessIterator2 -__pattern_walk2_brick_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _Size, - _RandomAccessIterator2, _Brick); +template +_RandomAccessIterator2 __pattern_walk2_brick_n( + __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _Size, _RandomAccessIterator2, _Brick); //------------------------------------------------------------------------ // walk3 (pseudo) @@ -176,199 +223,346 @@ //------------------------------------------------------------------------ template -_ForwardIterator3 __brick_walk3(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator3, _Function, - /*vector=*/std::false_type) noexcept; +_ForwardIterator3 __brick_walk3( + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator3, + _Function, + /*vector=*/std::false_type) noexcept; template -_RandomAccessIterator3 __brick_walk3(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator3, _Function, - /*vector=*/std::true_type) noexcept; - -template -_ForwardIterator3 -__pattern_walk3(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator3, - _Function) noexcept; - -template -_RandomAccessIterator3 -__pattern_walk3(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, - _RandomAccessIterator2, _RandomAccessIterator3, _Function); +_ForwardIterator3 __pattern_walk3( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator3, + _Function) noexcept; + +template +_RandomAccessIterator3 __pattern_walk3( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator3, + _Function); //------------------------------------------------------------------------ // equal //------------------------------------------------------------------------ template -bool __brick_equal(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _BinaryPredicate, +bool __brick_equal(_ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _BinaryPredicate, /* is_vector = */ std::false_type) noexcept; template -bool __brick_equal(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, _BinaryPredicate, +bool __brick_equal(_RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _BinaryPredicate, /* is_vector = */ std::true_type) noexcept; template -bool -__pattern_equal(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _BinaryPredicate) noexcept; +bool __pattern_equal( + _Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _BinaryPredicate) noexcept; -template -bool -__pattern_equal(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, - _RandomAccessIterator2, _BinaryPredicate); +bool __pattern_equal( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _BinaryPredicate); template -bool __brick_equal(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, _BinaryPredicate, +bool __brick_equal(_ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator2, + _BinaryPredicate, /* is_vector = */ std::false_type) noexcept; template -bool __brick_equal(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator2, - _BinaryPredicate, /* is_vector = */ std::true_type) noexcept; +bool __brick_equal(_RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _BinaryPredicate, + /* is_vector = */ std::true_type) noexcept; template -bool -__pattern_equal(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate) noexcept; - -template -bool -__pattern_equal(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, - _RandomAccessIterator2, _RandomAccessIterator2, _BinaryPredicate); +bool __pattern_equal( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _BinaryPredicate); //------------------------------------------------------------------------ // find_if //------------------------------------------------------------------------ template -_ForwardIterator __brick_find_if(_ForwardIterator, _ForwardIterator, _Predicate, - /*is_vector=*/std::false_type) noexcept; +_ForwardIterator __brick_find_if( + _ForwardIterator, + _ForwardIterator, + _Predicate, + /*is_vector=*/std::false_type) noexcept; template -_RandomAccessIterator __brick_find_if(_RandomAccessIterator, _RandomAccessIterator, _Predicate, - /*is_vector=*/std::true_type) noexcept; +_RandomAccessIterator __brick_find_if( + _RandomAccessIterator, + _RandomAccessIterator, + _Predicate, + /*is_vector=*/std::true_type) noexcept; template -_ForwardIterator -__pattern_find_if(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate) noexcept; +_ForwardIterator __pattern_find_if(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate) noexcept; template -_RandomAccessIterator -__pattern_find_if(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _Predicate); +_RandomAccessIterator __pattern_find_if( + __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Predicate); //------------------------------------------------------------------------ // find_end //------------------------------------------------------------------------ template -_ForwardIterator1 __brick_find_end(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate, - /*__is_vector=*/std::false_type) noexcept; +_ForwardIterator1 __brick_find_end( + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator2, + _BinaryPredicate, + /*__is_vector=*/std::false_type) noexcept; template -_RandomAccessIterator1 __brick_find_end(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _BinaryPredicate, - /*__is_vector=*/std::true_type) noexcept; +_RandomAccessIterator1 __brick_find_end( + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _BinaryPredicate, + /*__is_vector=*/std::true_type) noexcept; template -_ForwardIterator1 -__pattern_find_end(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate) noexcept; - -template -_RandomAccessIterator1 -__pattern_find_end(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, - _RandomAccessIterator2, _RandomAccessIterator2, _BinaryPredicate) noexcept; +_RandomAccessIterator1 __pattern_find_end( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _BinaryPredicate) noexcept; //------------------------------------------------------------------------ // find_first_of //------------------------------------------------------------------------ template -_ForwardIterator1 __brick_find_first_of(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate, - /*__is_vector=*/std::false_type) noexcept; +_ForwardIterator1 __brick_find_first_of( + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator2, + _BinaryPredicate, + /*__is_vector=*/std::false_type) noexcept; template -_RandomAccessIterator1 __brick_find_first_of(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _BinaryPredicate, - /*__is_vector=*/std::true_type) noexcept; +_RandomAccessIterator1 __brick_find_first_of( + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _BinaryPredicate, + /*__is_vector=*/std::true_type) noexcept; template -_ForwardIterator1 -__pattern_find_first_of(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator2, _BinaryPredicate) noexcept; - -template -_RandomAccessIterator1 -__pattern_find_first_of(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, - _RandomAccessIterator2, _RandomAccessIterator2, _BinaryPredicate) noexcept; +_RandomAccessIterator1 __pattern_find_first_of( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _BinaryPredicate) noexcept; //------------------------------------------------------------------------ // search //------------------------------------------------------------------------ template -_ForwardIterator1 __brick_search(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate, - /*vector=*/std::false_type) noexcept; +_ForwardIterator1 __brick_search( + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator2, + _BinaryPredicate, + /*vector=*/std::false_type) noexcept; template -_RandomAccessIterator1 __brick_search(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _BinaryPredicate, - /*vector=*/std::true_type) noexcept; +_RandomAccessIterator1 __brick_search( + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _BinaryPredicate, + /*vector=*/std::true_type) noexcept; template -_ForwardIterator1 -__pattern_search(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _BinaryPredicate) noexcept; - -template -_RandomAccessIterator1 -__pattern_search(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, - _RandomAccessIterator2, _RandomAccessIterator2, _BinaryPredicate) noexcept; +_RandomAccessIterator1 __pattern_search( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _BinaryPredicate) noexcept; //------------------------------------------------------------------------ // search_n //------------------------------------------------------------------------ template -_ForwardIterator -__brick_search_n(_ForwardIterator, _ForwardIterator, _Size, const _Tp&, _BinaryPredicate, - /*vector=*/std::false_type) noexcept; +_ForwardIterator __brick_search_n( + _ForwardIterator, + _ForwardIterator, + _Size, + const _Tp&, + _BinaryPredicate, + /*vector=*/std::false_type) noexcept; template -_RandomAccessIterator -__brick_search_n(_RandomAccessIterator, _RandomAccessIterator, _Size, const _Tp&, _BinaryPredicate, - /*vector=*/std::true_type) noexcept; +_RandomAccessIterator __brick_search_n( + _RandomAccessIterator, + _RandomAccessIterator, + _Size, + const _Tp&, + _BinaryPredicate, + /*vector=*/std::true_type) noexcept; template -_ForwardIterator -__pattern_search_n(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Size, const _Tp&, - _BinaryPredicate) noexcept; - -template -_RandomAccessIterator -__pattern_search_n(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Size, - const _Tp&, _BinaryPredicate) noexcept; +_RandomAccessIterator __pattern_search_n( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator, + _RandomAccessIterator, + _Size, + const _Tp&, + _BinaryPredicate) noexcept; //------------------------------------------------------------------------ // copy_n //------------------------------------------------------------------------ template -_OutputIterator __brick_copy_n(_ForwardIterator, _Size, _OutputIterator, +_OutputIterator __brick_copy_n(_ForwardIterator, + _Size, + _OutputIterator, /*vector=*/std::false_type) noexcept; template -_OutputIterator __brick_copy_n(_RandomAccessIterator, _Size, _OutputIterator, +_OutputIterator __brick_copy_n(_RandomAccessIterator, + _Size, + _OutputIterator, /*vector=*/std::true_type) noexcept; //------------------------------------------------------------------------ @@ -376,11 +570,15 @@ //------------------------------------------------------------------------ template -_OutputIterator __brick_copy(_ForwardIterator, _ForwardIterator, _OutputIterator, +_OutputIterator __brick_copy(_ForwardIterator, + _ForwardIterator, + _OutputIterator, /*vector=*/std::false_type) noexcept; template -_OutputIterator __brick_copy(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, +_OutputIterator __brick_copy(_RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator, /*vector=*/std::true_type) noexcept; //------------------------------------------------------------------------ @@ -388,447 +586,619 @@ //------------------------------------------------------------------------ template -_OutputIterator __brick_move(_ForwardIterator, _ForwardIterator, _OutputIterator, +_OutputIterator __brick_move(_ForwardIterator, + _ForwardIterator, + _OutputIterator, /*vector=*/std::false_type) noexcept; template -_OutputIterator __brick_move(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, +_OutputIterator __brick_move(_RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator, /*vector=*/std::true_type) noexcept; //------------------------------------------------------------------------ // swap_ranges //------------------------------------------------------------------------ template -_OutputIterator __brick_swap_ranges(_ForwardIterator, _ForwardIterator, _OutputIterator, - /*vector=*/std::false_type) noexcept; +_OutputIterator __brick_swap_ranges( + _ForwardIterator, + _ForwardIterator, + _OutputIterator, + /*vector=*/std::false_type) noexcept; template -_OutputIterator __brick_swap_ranges(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, - /*vector=*/std::true_type) noexcept; +_OutputIterator __brick_swap_ranges( + _RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator, + /*vector=*/std::true_type) noexcept; //------------------------------------------------------------------------ // copy_if //------------------------------------------------------------------------ template -_OutputIterator __brick_copy_if(_ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryPredicate, - /*vector=*/std::false_type) noexcept; +_OutputIterator __brick_copy_if( + _ForwardIterator, + _ForwardIterator, + _OutputIterator, + _UnaryPredicate, + /*vector=*/std::false_type) noexcept; template -_OutputIterator __brick_copy_if(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, _UnaryPredicate, - /*vector=*/std::true_type) noexcept; +_OutputIterator __brick_copy_if( + _RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator, + _UnaryPredicate, + /*vector=*/std::true_type) noexcept; template -std::pair<_DifferenceType, _DifferenceType> -__brick_calc_mask_1(_ForwardIterator, _ForwardIterator, bool* __restrict, _UnaryPredicate, - /*vector=*/std::false_type) noexcept; +std::pair<_DifferenceType, _DifferenceType> __brick_calc_mask_1( + _ForwardIterator, + _ForwardIterator, + bool* __restrict, + _UnaryPredicate, + /*vector=*/std::false_type) noexcept; template -std::pair<_DifferenceType, _DifferenceType> -__brick_calc_mask_1(_RandomAccessIterator, _RandomAccessIterator, bool* __restrict, _UnaryPredicate, - /*vector=*/std::true_type) noexcept; +std::pair<_DifferenceType, _DifferenceType> __brick_calc_mask_1( + _RandomAccessIterator, + _RandomAccessIterator, + bool* __restrict, + _UnaryPredicate, + /*vector=*/std::true_type) noexcept; template -void -__brick_copy_by_mask(_ForwardIterator, _ForwardIterator, _OutputIterator, bool*, - /*vector=*/std::false_type) noexcept; +void __brick_copy_by_mask( + _ForwardIterator, + _ForwardIterator, + _OutputIterator, + bool*, + /*vector=*/std::false_type) noexcept; template -void -__brick_copy_by_mask(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, bool* __restrict, - /*vector=*/std::true_type) noexcept; +void __brick_copy_by_mask( + _RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator, + bool* __restrict, + /*vector=*/std::true_type) noexcept; template -void -__brick_partition_by_mask(_ForwardIterator, _ForwardIterator, _OutputIterator1, _OutputIterator2, bool*, - /*vector=*/std::false_type) noexcept; +void __brick_partition_by_mask( + _ForwardIterator, + _ForwardIterator, + _OutputIterator1, + _OutputIterator2, + bool*, + /*vector=*/std::false_type) noexcept; template -void -__brick_partition_by_mask(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator1, _OutputIterator2, bool*, - /*vector=*/std::true_type) noexcept; +void __brick_partition_by_mask( + _RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator1, + _OutputIterator2, + bool*, + /*vector=*/std::true_type) noexcept; template -_OutputIterator -__pattern_copy_if(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, - _UnaryPredicate) noexcept; +_OutputIterator __pattern_copy_if( + _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryPredicate) noexcept; -template -_OutputIterator -__pattern_copy_if(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _OutputIterator, _UnaryPredicate); +_OutputIterator __pattern_copy_if( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator, + _UnaryPredicate); //------------------------------------------------------------------------ // count //------------------------------------------------------------------------ template -typename std::iterator_traits<_RandomAccessIterator>::difference_type - __brick_count(_RandomAccessIterator, _RandomAccessIterator, _Predicate, - /* is_vector = */ std::true_type) noexcept; +typename std::iterator_traits<_RandomAccessIterator>::difference_type __brick_count( + _RandomAccessIterator, + _RandomAccessIterator, + _Predicate, + /* is_vector = */ std::true_type) noexcept; template -typename std::iterator_traits<_ForwardIterator>::difference_type - __brick_count(_ForwardIterator, _ForwardIterator, _Predicate, - /* is_vector = */ std::false_type) noexcept; +typename std::iterator_traits<_ForwardIterator>::difference_type __brick_count( + _ForwardIterator, + _ForwardIterator, + _Predicate, + /* is_vector = */ std::false_type) noexcept; template typename std::iterator_traits<_ForwardIterator>::difference_type __pattern_count(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate) noexcept; template -typename std::iterator_traits<_RandomAccessIterator>::difference_type -__pattern_count(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _Predicate); +typename std::iterator_traits<_RandomAccessIterator>::difference_type __pattern_count( + __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Predicate); //------------------------------------------------------------------------ // unique //------------------------------------------------------------------------ template -_ForwardIterator __brick_unique(_ForwardIterator, _ForwardIterator, _BinaryPredicate, - /*is_vector=*/std::false_type) noexcept; +_ForwardIterator __brick_unique( + _ForwardIterator, + _ForwardIterator, + _BinaryPredicate, + /*is_vector=*/std::false_type) noexcept; template -_RandomAccessIterator __brick_unique(_RandomAccessIterator, _RandomAccessIterator, _BinaryPredicate, - /*is_vector=*/std::true_type) noexcept; +_RandomAccessIterator __brick_unique( + _RandomAccessIterator, + _RandomAccessIterator, + _BinaryPredicate, + /*is_vector=*/std::true_type) noexcept; template _ForwardIterator __pattern_unique(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate) noexcept; template -_RandomAccessIterator -__pattern_unique(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _BinaryPredicate) noexcept; +_RandomAccessIterator __pattern_unique( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator, + _RandomAccessIterator, + _BinaryPredicate) noexcept; //------------------------------------------------------------------------ // unique_copy //------------------------------------------------------------------------ template -OutputIterator __brick_unique_copy(_ForwardIterator, _ForwardIterator, OutputIterator, _BinaryPredicate, - /*vector=*/std::false_type) noexcept; +OutputIterator __brick_unique_copy( + _ForwardIterator, + _ForwardIterator, + OutputIterator, + _BinaryPredicate, + /*vector=*/std::false_type) noexcept; template -_OutputIterator __brick_unique_copy(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, _BinaryPredicate, - /*vector=*/std::true_type) noexcept; +_OutputIterator __brick_unique_copy( + _RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator, + _BinaryPredicate, + /*vector=*/std::true_type) noexcept; template -_OutputIterator -__pattern_unique_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, - _BinaryPredicate) noexcept; +_OutputIterator __pattern_unique_copy( + _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryPredicate) noexcept; template -_DifferenceType -__brick_calc_mask_2(_RandomAccessIterator, _RandomAccessIterator, bool* __restrict, _BinaryPredicate, - /*vector=*/std::false_type) noexcept; +_DifferenceType __brick_calc_mask_2( + _RandomAccessIterator, + _RandomAccessIterator, + bool* __restrict, + _BinaryPredicate, + /*vector=*/std::false_type) noexcept; template -_DifferenceType -__brick_calc_mask_2(_RandomAccessIterator, _RandomAccessIterator, bool* __restrict, _BinaryPredicate, - /*vector=*/std::true_type) noexcept; - -template -_OutputIterator -__pattern_unique_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _OutputIterator, _BinaryPredicate); +_OutputIterator __pattern_unique_copy( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator, + _BinaryPredicate); //------------------------------------------------------------------------ // reverse //------------------------------------------------------------------------ template -void __brick_reverse(_BidirectionalIterator, _BidirectionalIterator, +void __brick_reverse(_BidirectionalIterator, + _BidirectionalIterator, /*__is_vector=*/std::false_type) noexcept; template -void __brick_reverse(_RandomAccessIterator, _RandomAccessIterator, +void __brick_reverse(_RandomAccessIterator, + _RandomAccessIterator, /*__is_vector=*/std::true_type) noexcept; template -void __brick_reverse(_BidirectionalIterator, _BidirectionalIterator, _BidirectionalIterator, +void __brick_reverse(_BidirectionalIterator, + _BidirectionalIterator, + _BidirectionalIterator, /*is_vector=*/std::false_type) noexcept; template -void __brick_reverse(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, +void __brick_reverse(_RandomAccessIterator, + _RandomAccessIterator, + _RandomAccessIterator, /*is_vector=*/std::true_type) noexcept; template -void -__pattern_reverse(_Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator) noexcept; +void __pattern_reverse(_Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator) noexcept; template -void -__pattern_reverse(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator); +void __pattern_reverse(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator); //------------------------------------------------------------------------ // reverse_copy //------------------------------------------------------------------------ template -_OutputIterator __brick_reverse_copy(_BidirectionalIterator, _BidirectionalIterator, _OutputIterator, - /*is_vector=*/std::false_type) noexcept; +_OutputIterator __brick_reverse_copy( + _BidirectionalIterator, + _BidirectionalIterator, + _OutputIterator, + /*is_vector=*/std::false_type) noexcept; template -_OutputIterator __brick_reverse_copy(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, - /*is_vector=*/std::true_type) noexcept; +_OutputIterator __brick_reverse_copy( + _RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator, + /*is_vector=*/std::true_type) noexcept; template -_OutputIterator -__pattern_reverse_copy(_Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, - _OutputIterator) noexcept; +_OutputIterator __pattern_reverse_copy( + _Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _OutputIterator) noexcept; template -_OutputIterator -__pattern_reverse_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _OutputIterator); +_OutputIterator __pattern_reverse_copy( + __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator); //------------------------------------------------------------------------ // rotate //------------------------------------------------------------------------ template -_ForwardIterator __brick_rotate(_ForwardIterator, _ForwardIterator, _ForwardIterator, - /*is_vector=*/std::false_type) noexcept; +_ForwardIterator __brick_rotate( + _ForwardIterator, + _ForwardIterator, + _ForwardIterator, + /*is_vector=*/std::false_type) noexcept; template -_RandomAccessIterator __brick_rotate(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, - /*is_vector=*/std::true_type) noexcept; +_RandomAccessIterator __brick_rotate( + _RandomAccessIterator, + _RandomAccessIterator, + _RandomAccessIterator, + /*is_vector=*/std::true_type) noexcept; template _ForwardIterator __pattern_rotate(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator) noexcept; template -_RandomAccessIterator -__pattern_rotate(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _RandomAccessIterator); +_RandomAccessIterator __pattern_rotate( + __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator); //------------------------------------------------------------------------ // rotate_copy //------------------------------------------------------------------------ template -_OutputIterator __brick_rotate_copy(_ForwardIterator, _ForwardIterator, _ForwardIterator, _OutputIterator, - /*__is_vector=*/std::false_type) noexcept; +_OutputIterator __brick_rotate_copy( + _ForwardIterator, + _ForwardIterator, + _ForwardIterator, + _OutputIterator, + /*__is_vector=*/std::false_type) noexcept; template -_OutputIterator __brick_rotate_copy(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, - _OutputIterator, - /*__is_vector=*/std::true_type) noexcept; +_OutputIterator __brick_rotate_copy( + _RandomAccessIterator, + _RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator, + /*__is_vector=*/std::true_type) noexcept; template -_OutputIterator -__pattern_rotate_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator, - _OutputIterator) noexcept; +_OutputIterator __pattern_rotate_copy( + _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator, _OutputIterator) noexcept; template -_OutputIterator -__pattern_rotate_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _RandomAccessIterator, _OutputIterator); +_OutputIterator __pattern_rotate_copy( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator, + _RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator); //------------------------------------------------------------------------ // is_partitioned //------------------------------------------------------------------------ template -bool __brick_is_partitioned(_ForwardIterator, _ForwardIterator, _UnaryPredicate, +bool __brick_is_partitioned(_ForwardIterator, + _ForwardIterator, + _UnaryPredicate, /*is_vector=*/std::false_type) noexcept; template -bool __brick_is_partitioned(_RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate, +bool __brick_is_partitioned(_RandomAccessIterator, + _RandomAccessIterator, + _UnaryPredicate, /*is_vector=*/std::true_type) noexcept; template -bool -__pattern_is_partitioned(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept; +bool __pattern_is_partitioned(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept; template -bool -__pattern_is_partitioned(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _UnaryPredicate); +bool __pattern_is_partitioned( + __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate); //------------------------------------------------------------------------ // partition //------------------------------------------------------------------------ template -_ForwardIterator __brick_partition(_ForwardIterator, _ForwardIterator, _UnaryPredicate, - /*is_vector=*/std::false_type) noexcept; +_ForwardIterator __brick_partition( + _ForwardIterator, + _ForwardIterator, + _UnaryPredicate, + /*is_vector=*/std::false_type) noexcept; template -_RandomAccessIterator __brick_partition(_RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate, - /*is_vector=*/std::true_type) noexcept; +_RandomAccessIterator __brick_partition( + _RandomAccessIterator, + _RandomAccessIterator, + _UnaryPredicate, + /*is_vector=*/std::true_type) noexcept; template _ForwardIterator __pattern_partition(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept; template -_RandomAccessIterator -__pattern_partition(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _UnaryPredicate); +_RandomAccessIterator __pattern_partition( + __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate); //------------------------------------------------------------------------ // stable_partition //------------------------------------------------------------------------ template -_BidirectionalIterator __brick_stable_partition(_BidirectionalIterator, _BidirectionalIterator, _UnaryPredicate, - /*__is_vector=*/std::false_type) noexcept; +_BidirectionalIterator __brick_stable_partition( + _BidirectionalIterator, + _BidirectionalIterator, + _UnaryPredicate, + /*__is_vector=*/std::false_type) noexcept; template -_RandomAccessIterator __brick_stable_partition(_RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate, - /*__is_vector=*/std::true_type) noexcept; +_RandomAccessIterator __brick_stable_partition( + _RandomAccessIterator, + _RandomAccessIterator, + _UnaryPredicate, + /*__is_vector=*/std::true_type) noexcept; template -_BidirectionalIterator -__pattern_stable_partition(_Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, - _UnaryPredicate) noexcept; +_BidirectionalIterator __pattern_stable_partition( + _Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _UnaryPredicate) noexcept; template -_RandomAccessIterator -__pattern_stable_partition(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _UnaryPredicate) noexcept; +_RandomAccessIterator __pattern_stable_partition( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator, + _RandomAccessIterator, + _UnaryPredicate) noexcept; //------------------------------------------------------------------------ // partition_copy //------------------------------------------------------------------------ template -std::pair<_OutputIterator1, _OutputIterator2> - __brick_partition_copy(_ForwardIterator, _ForwardIterator, _OutputIterator1, _OutputIterator2, _UnaryPredicate, - /*is_vector=*/std::false_type) noexcept; +std::pair<_OutputIterator1, _OutputIterator2> __brick_partition_copy( + _ForwardIterator, + _ForwardIterator, + _OutputIterator1, + _OutputIterator2, + _UnaryPredicate, + /*is_vector=*/std::false_type) noexcept; template -std::pair<_OutputIterator1, _OutputIterator2> __brick_partition_copy(_RandomAccessIterator, _RandomAccessIterator, - _OutputIterator1, _OutputIterator2, - _UnaryPredicate, - /*is_vector=*/std::true_type) noexcept; - -template __brick_partition_copy( + _RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator1, + _OutputIterator2, + _UnaryPredicate, + /*is_vector=*/std::true_type) noexcept; + +template -std::pair<_OutputIterator1, _OutputIterator2> -__pattern_partition_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator1, - _OutputIterator2, _UnaryPredicate) noexcept; - -template -std::pair<_OutputIterator1, _OutputIterator2> -__pattern_partition_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _OutputIterator1, _OutputIterator2, _UnaryPredicate); +std::pair<_OutputIterator1, _OutputIterator2> __pattern_partition_copy( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator, + _ForwardIterator, + _OutputIterator1, + _OutputIterator2, + _UnaryPredicate) noexcept; + +template +std::pair<_OutputIterator1, _OutputIterator2> __pattern_partition_copy( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator1, + _OutputIterator2, + _UnaryPredicate); //------------------------------------------------------------------------ // sort //------------------------------------------------------------------------ template -void -__pattern_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, - _IsMoveConstructible) noexcept; +void __pattern_sort( + _Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsMoveConstructible) noexcept; template -void -__pattern_sort(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, - /*is_move_constructible=*/std::true_type); +void __pattern_sort(__parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator, + _RandomAccessIterator, + _Compare, + /*is_move_constructible=*/std::true_type); //------------------------------------------------------------------------ // stable_sort //------------------------------------------------------------------------ template -void -__pattern_stable_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept; +void __pattern_stable_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept; template -void -__pattern_stable_sort(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _Compare); +void __pattern_stable_sort( + __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare); //------------------------------------------------------------------------ // partial_sort //------------------------------------------------------------------------ template -void -__pattern_partial_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, - _Compare) noexcept; +void __pattern_partial_sort( + _Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept; template -void -__pattern_partial_sort(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _RandomAccessIterator, _Compare); +void __pattern_partial_sort( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator, + _RandomAccessIterator, + _RandomAccessIterator, + _Compare); //------------------------------------------------------------------------ // partial_sort_copy //------------------------------------------------------------------------ -template -_RandomAccessIterator2 -__pattern_partial_sort_copy(_Tag, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, - _RandomAccessIterator2, _RandomAccessIterator2, _Compare) noexcept; - -template -_RandomAccessIterator2 -__pattern_partial_sort_copy(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, - _RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator2, _Compare); +_RandomAccessIterator2 __pattern_partial_sort_copy( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _Compare); //------------------------------------------------------------------------ // adjacent_find //------------------------------------------------------------------------ template -_RandomAccessIterator -__brick_adjacent_find(_RandomAccessIterator, _RandomAccessIterator, _BinaryPredicate, - /* IsVector = */ std::true_type, bool) noexcept; +_RandomAccessIterator __brick_adjacent_find( + _RandomAccessIterator, + _RandomAccessIterator, + _BinaryPredicate, + /* IsVector = */ std::true_type, + bool) noexcept; template -_ForwardIterator -__brick_adjacent_find(_ForwardIterator, _ForwardIterator, _BinaryPredicate, - /* IsVector = */ std::false_type, bool) noexcept; +_ForwardIterator __brick_adjacent_find( + _ForwardIterator, + _ForwardIterator, + _BinaryPredicate, + /* IsVector = */ std::false_type, + bool) noexcept; template _ForwardIterator __pattern_adjacent_find(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate, bool) noexcept; template -_RandomAccessIterator -__pattern_adjacent_find(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _BinaryPredicate, bool); +_RandomAccessIterator __pattern_adjacent_find( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator, + _RandomAccessIterator, + _BinaryPredicate, + bool); //------------------------------------------------------------------------ // nth_element //------------------------------------------------------------------------ template -void -__pattern_nth_element(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, - _Compare) noexcept; +void __pattern_nth_element( + _Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept; template -void -__pattern_nth_element(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _RandomAccessIterator, _Compare) noexcept; +void __pattern_nth_element( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator, + _RandomAccessIterator, + _RandomAccessIterator, + _Compare) noexcept; //------------------------------------------------------------------------ // fill, fill_n //------------------------------------------------------------------------ template -void -__brick_fill(_RandomAccessIterator, _RandomAccessIterator, const _Tp&, - /* __is_vector = */ std::true_type) noexcept; +void __brick_fill(_RandomAccessIterator, + _RandomAccessIterator, + const _Tp&, + /* __is_vector = */ std::true_type) noexcept; template -void -__brick_fill(_ForwardIterator, _ForwardIterator, const _Tp&, - /* __is_vector = */ std::false_type) noexcept; +void __brick_fill(_ForwardIterator, + _ForwardIterator, + const _Tp&, + /* __is_vector = */ std::false_type) noexcept; template -void -__pattern_fill(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, const _Tp&) noexcept; +void __pattern_fill(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, const _Tp&) noexcept; template _RandomAccessIterator @@ -836,17 +1206,20 @@ template _RandomAccessIterator -__brick_fill_n(_RandomAccessIterator, _Size, const _Tp&, +__brick_fill_n(_RandomAccessIterator, + _Size, + const _Tp&, /* __is_vector = */ std::true_type) noexcept; template _OutputIterator -__brick_fill_n(_OutputIterator, _Size, const _Tp&, +__brick_fill_n(_OutputIterator, + _Size, + const _Tp&, /* __is_vector = */ std::false_type) noexcept; template -_OutputIterator -__pattern_fill_n(_Tag, _ExecutionPolicy&&, _OutputIterator, _Size, const _Tp&) noexcept; +_OutputIterator __pattern_fill_n(_Tag, _ExecutionPolicy&&, _OutputIterator, _Size, const _Tp&) noexcept; template _RandomAccessIterator @@ -857,33 +1230,40 @@ //------------------------------------------------------------------------ template -void __brick_generate(_RandomAccessIterator, _RandomAccessIterator, _Generator, +void __brick_generate(_RandomAccessIterator, + _RandomAccessIterator, + _Generator, /* is_vector = */ std::true_type) noexcept; template -void __brick_generate(_ForwardIterator, _ForwardIterator, _Generator, +void __brick_generate(_ForwardIterator, + _ForwardIterator, + _Generator, /* is_vector = */ std::false_type) noexcept; template -void -__pattern_generate(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Generator) noexcept; +void __pattern_generate(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Generator) noexcept; template -_RandomAccessIterator -__pattern_generate(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _Generator); +_RandomAccessIterator __pattern_generate( + __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Generator); template -_RandomAccessIterator __brick_generate_n(_RandomAccessIterator, Size, _Generator, - /* is_vector = */ std::true_type) noexcept; +_RandomAccessIterator __brick_generate_n( + _RandomAccessIterator, + Size, + _Generator, + /* is_vector = */ std::true_type) noexcept; template -OutputIterator __brick_generate_n(OutputIterator, Size, _Generator, - /* is_vector = */ std::false_type) noexcept; +OutputIterator __brick_generate_n( + OutputIterator, + Size, + _Generator, + /* is_vector = */ std::false_type) noexcept; template -OutputIterator -__pattern_generate_n(_Tag, _ExecutionPolicy&&, OutputIterator, Size, _Generator) noexcept; +OutputIterator __pattern_generate_n(_Tag, _ExecutionPolicy&&, OutputIterator, Size, _Generator) noexcept; template _RandomAccessIterator @@ -893,306 +1273,545 @@ // remove //------------------------------------------------------------------------ template -_ForwardIterator __brick_remove_if(_ForwardIterator, _ForwardIterator, _UnaryPredicate, - /* __is_vector = */ std::false_type) noexcept; +_ForwardIterator __brick_remove_if( + _ForwardIterator, + _ForwardIterator, + _UnaryPredicate, + /* __is_vector = */ std::false_type) noexcept; template -_RandomAccessIterator __brick_remove_if(_RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate, - /* __is_vector = */ std::true_type) noexcept; +_RandomAccessIterator __brick_remove_if( + _RandomAccessIterator, + _RandomAccessIterator, + _UnaryPredicate, + /* __is_vector = */ std::true_type) noexcept; template _ForwardIterator __pattern_remove_if(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate) noexcept; template -_RandomAccessIterator -__pattern_remove_if(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _UnaryPredicate) noexcept; +_RandomAccessIterator __pattern_remove_if( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator, + _RandomAccessIterator, + _UnaryPredicate) noexcept; //------------------------------------------------------------------------ // merge //------------------------------------------------------------------------ template -_OutputIterator __brick_merge(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _OutputIterator, _Compare, - /* __is_vector = */ std::false_type) noexcept; +_OutputIterator __brick_merge( + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator2, + _OutputIterator, + _Compare, + /* __is_vector = */ std::false_type) noexcept; template -_OutputIterator __brick_merge(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _OutputIterator, _Compare, - /* __is_vector = */ std::true_type) noexcept; - -template -_OutputIterator -__pattern_merge(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _OutputIterator, _Compare) noexcept; - -template -_OutputIterator -__pattern_merge(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, - _RandomAccessIterator2, _RandomAccessIterator2, _OutputIterator, _Compare); +_OutputIterator __pattern_merge( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator2, + _OutputIterator, + _Compare) noexcept; + +template +_OutputIterator __pattern_merge( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _OutputIterator, + _Compare); //------------------------------------------------------------------------ // inplace_merge //------------------------------------------------------------------------ template -void __brick_inplace_merge(_BidirectionalIterator, _BidirectionalIterator, _BidirectionalIterator, _Compare, - /* __is_vector = */ std::false_type) noexcept; +void __brick_inplace_merge( + _BidirectionalIterator, + _BidirectionalIterator, + _BidirectionalIterator, + _Compare, + /* __is_vector = */ std::false_type) noexcept; template -void __brick_inplace_merge(_RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare, - /* __is_vector = */ std::true_type) noexcept; +void __brick_inplace_merge( + _RandomAccessIterator, + _RandomAccessIterator, + _RandomAccessIterator, + _Compare, + /* __is_vector = */ std::true_type) noexcept; template -void -__pattern_inplace_merge(_Tag, _ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, - _BidirectionalIterator, _Compare) noexcept; +void __pattern_inplace_merge( + _Tag, + _ExecutionPolicy&&, + _BidirectionalIterator, + _BidirectionalIterator, + _BidirectionalIterator, + _Compare) noexcept; template -void -__pattern_inplace_merge(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _RandomAccessIterator, _Compare); +void __pattern_inplace_merge( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator, + _RandomAccessIterator, + _RandomAccessIterator, + _Compare); //------------------------------------------------------------------------ // includes //------------------------------------------------------------------------ template -bool -__pattern_includes(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _Compare) noexcept; - -template -bool -__pattern_includes(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, - _RandomAccessIterator2, _RandomAccessIterator2, _Compare); +bool __pattern_includes( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _Compare); //------------------------------------------------------------------------ // set_union //------------------------------------------------------------------------ template -_OutputIterator __brick_set_union(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _OutputIterator, _Compare, - /*__is_vector=*/std::false_type) noexcept; +_OutputIterator __brick_set_union( + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator2, + _OutputIterator, + _Compare, + /*__is_vector=*/std::false_type) noexcept; template -_OutputIterator __brick_set_union(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _OutputIterator, _Compare, - /*__is_vector=*/std::true_type) noexcept; - -template -_OutputIterator -__pattern_set_union(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator2, _OutputIterator, _Compare) noexcept; - -template -_OutputIterator -__pattern_set_union(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, - _RandomAccessIterator2, _RandomAccessIterator2, _OutputIterator, _Compare); +_OutputIterator __pattern_set_union( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator2, + _OutputIterator, + _Compare) noexcept; + +template +_OutputIterator __pattern_set_union( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _OutputIterator, + _Compare); //------------------------------------------------------------------------ // set_intersection //------------------------------------------------------------------------ template -_OutputIterator __brick_set_intersection(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _OutputIterator, _Compare, - /*__is_vector=*/std::false_type) noexcept; +_OutputIterator __brick_set_intersection( + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator2, + _OutputIterator, + _Compare, + /*__is_vector=*/std::false_type) noexcept; template -_OutputIterator __brick_set_intersection(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _OutputIterator, _Compare, - /*__is_vector=*/std::true_type) noexcept; - -template -_OutputIterator -__pattern_set_intersection(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator2, _OutputIterator, _Compare) noexcept; - -template -_OutputIterator -__pattern_set_intersection(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, - _RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator2, _OutputIterator, - _Compare); +_OutputIterator __pattern_set_intersection( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator2, + _OutputIterator, + _Compare) noexcept; + +template +_OutputIterator __pattern_set_intersection( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _OutputIterator, + _Compare); //------------------------------------------------------------------------ // set_difference //------------------------------------------------------------------------ template -_OutputIterator __brick_set_difference(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _OutputIterator, _Compare, - /*__is_vector=*/std::false_type) noexcept; +_OutputIterator __brick_set_difference( + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator2, + _OutputIterator, + _Compare, + /*__is_vector=*/std::false_type) noexcept; template -_OutputIterator __brick_set_difference(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _OutputIterator, _Compare, - /*__is_vector=*/std::true_type) noexcept; - -template -_OutputIterator -__pattern_set_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator2, _OutputIterator, _Compare) noexcept; - -template -_OutputIterator -__pattern_set_difference(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, - _RandomAccessIterator2, _RandomAccessIterator2, _OutputIterator, _Compare); +_OutputIterator __pattern_set_difference( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator2, + _OutputIterator, + _Compare) noexcept; + +template +_OutputIterator __pattern_set_difference( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _OutputIterator, + _Compare); //------------------------------------------------------------------------ // set_symmetric_difference //------------------------------------------------------------------------ template -_OutputIterator __brick_set_symmetric_difference(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator2, _OutputIterator, _Compare, - /*__is_vector=*/std::false_type) noexcept; +_OutputIterator __brick_set_symmetric_difference( + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator2, + _OutputIterator, + _Compare, + /*__is_vector=*/std::false_type) noexcept; template -_OutputIterator __brick_set_symmetric_difference(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _OutputIterator, _Compare, - /*__is_vector=*/std::true_type) noexcept; - -template -_OutputIterator -__pattern_set_symmetric_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator2, _OutputIterator, _Compare) noexcept; - -template -_OutputIterator -__pattern_set_symmetric_difference(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, - _RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator2, - _OutputIterator, _Compare); +_OutputIterator __pattern_set_symmetric_difference( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator2, + _OutputIterator, + _Compare) noexcept; + +template +_OutputIterator __pattern_set_symmetric_difference( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _OutputIterator, + _Compare); //------------------------------------------------------------------------ // is_heap_until //------------------------------------------------------------------------ template -_RandomAccessIterator __brick_is_heap_until(_RandomAccessIterator, _RandomAccessIterator, _Compare, - /* __is_vector = */ std::false_type) noexcept; +_RandomAccessIterator __brick_is_heap_until( + _RandomAccessIterator, + _RandomAccessIterator, + _Compare, + /* __is_vector = */ std::false_type) noexcept; template -_RandomAccessIterator __brick_is_heap_until(_RandomAccessIterator, _RandomAccessIterator, _Compare, - /* __is_vector = */ std::true_type) noexcept; +_RandomAccessIterator __brick_is_heap_until( + _RandomAccessIterator, + _RandomAccessIterator, + _Compare, + /* __is_vector = */ std::true_type) noexcept; template _RandomAccessIterator __pattern_is_heap_until(_Tag, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept; template -_RandomAccessIterator -__pattern_is_heap_until(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _Compare) noexcept; +_RandomAccessIterator __pattern_is_heap_until( + __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare) noexcept; //------------------------------------------------------------------------ // min_element //------------------------------------------------------------------------ template -_ForwardIterator __brick_min_element(_ForwardIterator, _ForwardIterator, _Compare, - /* __is_vector = */ std::false_type) noexcept; +_ForwardIterator __brick_min_element( + _ForwardIterator, + _ForwardIterator, + _Compare, + /* __is_vector = */ std::false_type) noexcept; template -_RandomAccessIterator __brick_min_element(_RandomAccessIterator, _RandomAccessIterator, _Compare, - /* __is_vector = */ std::true_type) noexcept; +_RandomAccessIterator __brick_min_element( + _RandomAccessIterator, + _RandomAccessIterator, + _Compare, + /* __is_vector = */ std::true_type) noexcept; template -_ForwardIterator -__pattern_min_element(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare) noexcept; +_ForwardIterator __pattern_min_element(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare) noexcept; template -_RandomAccessIterator -__pattern_min_element(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _Compare); +_RandomAccessIterator __pattern_min_element( + __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare); //------------------------------------------------------------------------ // minmax_element //------------------------------------------------------------------------ template -std::pair<_ForwardIterator, _ForwardIterator> __brick_minmax_element(_ForwardIterator, _ForwardIterator, _Compare, - /* __is_vector = */ std::false_type) noexcept; +std::pair<_ForwardIterator, _ForwardIterator> __brick_minmax_element( + _ForwardIterator, + _ForwardIterator, + _Compare, + /* __is_vector = */ std::false_type) noexcept; template -std::pair<_RandomAccessIterator, _RandomAccessIterator> - __brick_minmax_element(_RandomAccessIterator, _RandomAccessIterator, _Compare, - /* __is_vector = */ std::true_type) noexcept; +std::pair<_RandomAccessIterator, _RandomAccessIterator> __brick_minmax_element( + _RandomAccessIterator, + _RandomAccessIterator, + _Compare, + /* __is_vector = */ std::true_type) noexcept; template std::pair<_ForwardIterator, _ForwardIterator> __pattern_minmax_element(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare) noexcept; template -std::pair<_RandomAccessIterator, _RandomAccessIterator> -__pattern_minmax_element(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _Compare); +std::pair<_RandomAccessIterator, _RandomAccessIterator> __pattern_minmax_element( + __parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare); //------------------------------------------------------------------------ // mismatch //------------------------------------------------------------------------ template -std::pair<_ForwardIterator1, _ForwardIterator2> __brick_mismatch(_ForwardIterator1, _ForwardIterator1, - _ForwardIterator2, _ForwardIterator2, _Predicate, - /* __is_vector = */ std::false_type) noexcept; +std::pair<_ForwardIterator1, _ForwardIterator2> __brick_mismatch( + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator2, + _Predicate, + /* __is_vector = */ std::false_type) noexcept; template -std::pair<_RandomAccessIterator1, _RandomAccessIterator2> - __brick_mismatch(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator2, - _Predicate, - /* __is_vector = */ std::true_type) noexcept; +std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __brick_mismatch( + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _Predicate, + /* __is_vector = */ std::true_type) noexcept; template -std::pair<_ForwardIterator1, _ForwardIterator2> -__pattern_mismatch(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _Predicate) noexcept; - -template __pattern_mismatch( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator2, + _Predicate) noexcept; + +template -std::pair<_RandomAccessIterator1, _RandomAccessIterator2> -__pattern_mismatch(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, - _RandomAccessIterator2, _RandomAccessIterator2, _Predicate) noexcept; +std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __pattern_mismatch( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _Predicate) noexcept; //------------------------------------------------------------------------ // lexicographical_compare //------------------------------------------------------------------------ template -bool __brick_lexicographical_compare(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, - _Compare, - /* __is_vector = */ std::false_type) noexcept; +bool __brick_lexicographical_compare( + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _ForwardIterator2, + _Compare, + /* __is_vector = */ std::false_type) noexcept; template -bool __brick_lexicographical_compare(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, - _RandomAccessIterator2, _Compare, - /* __is_vector = */ std::true_type) noexcept; +bool __brick_lexicographical_compare( + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _Compare, + /* __is_vector = */ std::true_type) noexcept; template -bool -__pattern_lexicographical_compare(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, - _ForwardIterator2, _Compare) noexcept; - -template -bool -__pattern_lexicographical_compare(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, - _RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator2, - _Compare) noexcept; +bool __pattern_lexicographical_compare( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _RandomAccessIterator2, + _Compare) noexcept; } // namespace __internal } // namespace __pstl diff --git a/libcxx/include/pstl/internal/algorithm_impl.h b/libcxx/include/pstl/internal/algorithm_impl.h --- a/libcxx/include/pstl/internal/algorithm_impl.h +++ b/libcxx/include/pstl/internal/algorithm_impl.h @@ -10,11 +10,11 @@ #ifndef _PSTL_ALGORITHM_IMPL_H #define _PSTL_ALGORITHM_IMPL_H +#include +#include #include #include #include -#include -#include #include "execution_impl.h" #include "memory_impl.h" @@ -26,64 +26,63 @@ _PSTL_HIDE_FROM_ABI_PUSH -namespace __pstl -{ -namespace __internal -{ +namespace __pstl { +namespace __internal { //------------------------------------------------------------------------ // any_of //------------------------------------------------------------------------ template -bool -__brick_any_of(const _ForwardIterator __first, const _ForwardIterator __last, _Pred __pred, - /*__is_vector=*/std::false_type) noexcept -{ - return std::any_of(__first, __last, __pred); +bool __brick_any_of(const _ForwardIterator __first, + const _ForwardIterator __last, + _Pred __pred, + /*__is_vector=*/std::false_type) noexcept { + return std::any_of(__first, __last, __pred); }; template -bool -__brick_any_of(const _RandomAccessIterator __first, const _RandomAccessIterator __last, _Pred __pred, - /*__is_vector=*/std::true_type) noexcept -{ - return __unseq_backend::__simd_or(__first, __last - __first, __pred); +bool __brick_any_of(const _RandomAccessIterator __first, + const _RandomAccessIterator __last, + _Pred __pred, + /*__is_vector=*/std::true_type) noexcept { + return __unseq_backend::__simd_or(__first, __last - __first, __pred); }; template -bool -__pattern_any_of(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) noexcept -{ - return __internal::__brick_any_of(__first, __last, __pred, typename _Tag::__is_vector{}); +bool __pattern_any_of( + _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) noexcept { + return __internal::__brick_any_of(__first, __last, __pred, typename _Tag::__is_vector{}); } template -bool -__pattern_any_of(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _Pred __pred) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - return __internal::__except_handler( - [&]() - { - return __internal::__parallel_or(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__pred](_RandomAccessIterator __i, _RandomAccessIterator __j) - { return __internal::__brick_any_of(__i, __j, __pred, _IsVector{}); }); +bool __pattern_any_of(__parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Pred __pred) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&]() { + return __internal::__parallel_or( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [__pred](_RandomAccessIterator __i, _RandomAccessIterator __j) { + return __internal::__brick_any_of(__i, __j, __pred, _IsVector{}); }); + }); } // [alg.foreach] // for_each_n with no policy template -_ForwardIterator -__for_each_n_it_serial(_ForwardIterator __first, _Size __n, _Function __f) -{ - for (; __n > 0; ++__first, --__n) - __f(__first); - return __first; +_ForwardIterator __for_each_n_it_serial(_ForwardIterator __first, _Size __n, _Function __f) { + for (; __n > 0; ++__first, --__n) + __f(__first); + return __first; } //------------------------------------------------------------------------ @@ -92,125 +91,131 @@ // walk1 evaluates f(x) for each dereferenced value x drawn from [first,last) //------------------------------------------------------------------------ template -void -__brick_walk1(_ForwardIterator __first, _ForwardIterator __last, _Function __f, /*vector=*/std::false_type) noexcept -{ - std::for_each(__first, __last, __f); +void __brick_walk1( + _ForwardIterator __first, _ForwardIterator __last, _Function __f, /*vector=*/std::false_type) noexcept { + std::for_each(__first, __last, __f); } template -void -__brick_walk1(_RandomAccessIterator __first, _RandomAccessIterator __last, _Function __f, - /*vector=*/std::true_type) noexcept -{ - __unseq_backend::__simd_walk_1(__first, __last - __first, __f); +void __brick_walk1(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Function __f, + /*vector=*/std::true_type) noexcept { + __unseq_backend::__simd_walk_1(__first, __last - __first, __f); } template -void -__pattern_walk1(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __f) noexcept -{ - __internal::__brick_walk1(__first, __last, __f, typename _Tag::__is_vector{}); +void __pattern_walk1( + _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __f) noexcept { + __internal::__brick_walk1(__first, __last, __f, typename _Tag::__is_vector{}); } template -void -__pattern_walk1(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _Function __f) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - __internal::__except_handler( - [&]() - { - __par_backend::__parallel_for(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__f](_RandomAccessIterator __i, _RandomAccessIterator __j) - { __internal::__brick_walk1(__i, __j, __f, _IsVector{}); }); +void __pattern_walk1(__parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Function __f) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + __internal::__except_handler([&]() { + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [__f](_RandomAccessIterator __i, _RandomAccessIterator __j) { + __internal::__brick_walk1(__i, __j, __f, _IsVector{}); }); + }); } template -void -__pattern_walk_brick(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _Brick __brick) noexcept -{ - __brick(__first, __last); +void __pattern_walk_brick( + _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Brick __brick) noexcept { + __brick(__first, __last); } template -void -__pattern_walk_brick(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _Brick __brick) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - __internal::__except_handler( - [&]() - { - __par_backend::__parallel_for(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__brick](_RandomAccessIterator __i, _RandomAccessIterator __j) - { __brick(__i, __j); }); - }); +void __pattern_walk_brick( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Brick __brick) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + __internal::__except_handler([&]() { + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [__brick](_RandomAccessIterator __i, _RandomAccessIterator __j) { __brick(__i, __j); }); + }); } //------------------------------------------------------------------------ // walk1_n //------------------------------------------------------------------------ template -_ForwardIterator -__brick_walk1_n(_ForwardIterator __first, _Size __n, _Function __f, /*_IsVectorTag=*/std::false_type) -{ - return __internal::__for_each_n_it_serial(__first, __n, - [&__f](_ForwardIterator __it) { __f(*__it); }); // calling serial version +_ForwardIterator __brick_walk1_n(_ForwardIterator __first, _Size __n, _Function __f, /*_IsVectorTag=*/std::false_type) { + return __internal::__for_each_n_it_serial(__first, __n, [&__f](_ForwardIterator __it) { + __f(*__it); + }); // calling serial version } template _RandomAccessIterator -__brick_walk1_n(_RandomAccessIterator __first, _DifferenceType __n, _Function __f, - /*vectorTag=*/std::true_type) noexcept -{ - return __unseq_backend::__simd_walk_1(__first, __n, __f); +__brick_walk1_n(_RandomAccessIterator __first, + _DifferenceType __n, + _Function __f, + /*vectorTag=*/std::true_type) noexcept { + return __unseq_backend::__simd_walk_1(__first, __n, __f); } template _ForwardIterator -__pattern_walk1_n(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Function __f) noexcept -{ - return __internal::__brick_walk1_n(__first, __n, __f, typename _Tag::__is_vector{}); +__pattern_walk1_n(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Function __f) noexcept { + return __internal::__brick_walk1_n(__first, __n, __f, typename _Tag::__is_vector{}); } template -_RandomAccessIterator -__pattern_walk1_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Size __n, - _Function __f) -{ - __internal::__pattern_walk1(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __first + __n, __f); +_RandomAccessIterator __pattern_walk1_n( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _Size __n, + _Function __f) { + __internal::__pattern_walk1(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __first + __n, __f); - return __first + __n; + return __first + __n; } template _ForwardIterator -__pattern_walk_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Brick __brick) noexcept -{ - return __brick(__first, __n); +__pattern_walk_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Brick __brick) noexcept { + return __brick(__first, __n); } template -_RandomAccessIterator -__pattern_walk_brick_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _Size __n, _Brick __brick) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - return __internal::__except_handler( - [&]() - { - __par_backend::__parallel_for( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __first + __n, - [__brick](_RandomAccessIterator __i, _RandomAccessIterator __j) { __brick(__i, __j - __i); }); - return __first + __n; - }); +_RandomAccessIterator __pattern_walk_brick_n( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _Size __n, + _Brick __brick) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&]() { + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __first + __n, + [__brick](_RandomAccessIterator __i, _RandomAccessIterator __j) { __brick(__i, __j - __i); }); + return __first + __n; + }); } //------------------------------------------------------------------------ @@ -220,140 +225,199 @@ //------------------------------------------------------------------------ template _ForwardIterator2 -__brick_walk2(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Function __f, - /*vector=*/std::false_type) noexcept -{ - for (; __first1 != __last1; ++__first1, ++__first2) - __f(*__first1, *__first2); - return __first2; +__brick_walk2(_ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _Function __f, + /*vector=*/std::false_type) noexcept { + for (; __first1 != __last1; ++__first1, ++__first2) + __f(*__first1, *__first2); + return __first2; } template _RandomAccessIterator2 -__brick_walk2(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, +__brick_walk2(_RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, _Function __f, - /*vector=*/std::true_type) noexcept -{ - return __unseq_backend::__simd_walk_2(__first1, __last1 - __first1, __first2, __f); + /*vector=*/std::true_type) noexcept { + return __unseq_backend::__simd_walk_2(__first1, __last1 - __first1, __first2, __f); } template -_ForwardIterator2 -__brick_walk2_n(_ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2, _Function __f, - /*vector=*/std::false_type) noexcept -{ - for (; __n > 0; --__n, ++__first1, ++__first2) - __f(*__first1, *__first2); - return __first2; +_ForwardIterator2 __brick_walk2_n( + _ForwardIterator1 __first1, + _Size __n, + _ForwardIterator2 __first2, + _Function __f, + /*vector=*/std::false_type) noexcept { + for (; __n > 0; --__n, ++__first1, ++__first2) + __f(*__first1, *__first2); + return __first2; } template -_RandomAccessIterator2 -__brick_walk2_n(_RandomAccessIterator1 __first1, _Size __n, _RandomAccessIterator2 __first2, _Function __f, - /*vector=*/std::true_type) noexcept -{ - return __unseq_backend::__simd_walk_2(__first1, __n, __first2, __f); +_RandomAccessIterator2 __brick_walk2_n( + _RandomAccessIterator1 __first1, + _Size __n, + _RandomAccessIterator2 __first2, + _Function __f, + /*vector=*/std::true_type) noexcept { + return __unseq_backend::__simd_walk_2(__first1, __n, __first2, __f); } template -_ForwardIterator2 -__pattern_walk2(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Function __f) noexcept -{ - return __internal::__brick_walk2(__first1, __last1, __first2, __f, typename _Tag::__is_vector{}); -} - -template -_RandomAccessIterator2 -__pattern_walk2(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, - _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _Function __f) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - return __internal::__except_handler( - [&]() - { - __par_backend::__parallel_for( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - [__f, __first1, __first2](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) - { __internal::__brick_walk2(__i, __j, __first2 + (__i - __first1), __f, _IsVector{}); }); - return __first2 + (__last1 - __first1); +_RandomAccessIterator2 __pattern_walk2( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _Function __f) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&]() { + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + [__f, __first1, __first2](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + __internal::__brick_walk2(__i, __j, __first2 + (__i - __first1), __f, _IsVector{}); }); + return __first2 + (__last1 - __first1); + }); } -template -_ForwardIterator2 -__pattern_walk2_n(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2, - _Function __f) noexcept -{ - return __internal::__brick_walk2_n(__first1, __n, __first2, __f, typename _Tag::__is_vector{}); -} - -template -_RandomAccessIterator2 -__pattern_walk2_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, - _Size __n, _RandomAccessIterator2 __first2, _Function __f) -{ - return __internal::__pattern_walk2(__tag, std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, - __first2, __f); +_ForwardIterator2 __pattern_walk2_n( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1 __first1, + _Size __n, + _ForwardIterator2 __first2, + _Function __f) noexcept { + return __internal::__brick_walk2_n(__first1, __n, __first2, __f, typename _Tag::__is_vector{}); +} + +template +_RandomAccessIterator2 __pattern_walk2_n( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, + _Size __n, + _RandomAccessIterator2 __first2, + _Function __f) { + return __internal::__pattern_walk2( + __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, __first2, __f); } template -_ForwardIterator2 -__pattern_walk2_brick(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Brick __brick) noexcept -{ - return __brick(__first1, __last1, __first2); -} - -template -_RandomAccessIterator2 -__pattern_walk2_brick(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, - _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _Brick __brick) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - return __internal::__except_handler( - [&]() - { - __par_backend::__parallel_for( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) - { __brick(__i, __j, __first2 + (__i - __first1)); }); - return __first2 + (__last1 - __first1); +_RandomAccessIterator2 __pattern_walk2_brick( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _Brick __brick) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&]() { + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + __brick(__i, __j, __first2 + (__i - __first1)); }); + return __first2 + (__last1 - __first1); + }); } -template -_ForwardIterator2 -__pattern_walk2_brick_n(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2, - _Brick __brick) noexcept -{ - return __brick(__first1, __n, __first2); -} - -template -_RandomAccessIterator2 -__pattern_walk2_brick_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, - _Size __n, _RandomAccessIterator2 __first2, _Brick __brick) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - return __internal::__except_handler( - [&]() - { - __par_backend::__parallel_for( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, - [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) - { __brick(__i, __j - __i, __first2 + (__i - __first1)); }); - return __first2 + __n; +_ForwardIterator2 __pattern_walk2_brick_n( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1 __first1, + _Size __n, + _ForwardIterator2 __first2, + _Brick __brick) noexcept { + return __brick(__first1, __n, __first2); +} + +template +_RandomAccessIterator2 __pattern_walk2_brick_n( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, + _Size __n, + _RandomAccessIterator2 __first2, + _Brick __brick) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&]() { + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __first1 + __n, + [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + __brick(__i, __j - __i, __first2 + (__i - __first1)); }); + return __first2 + __n; + }); } //------------------------------------------------------------------------ @@ -362,52 +426,74 @@ // walk3 evaluates f(x,y,z) for (x,y,z) drawn from [first1,last1), [first2,...), [first3,...) //------------------------------------------------------------------------ template -_ForwardIterator3 -__brick_walk3(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator3 __first3, _Function __f, /*vector=*/std::false_type) noexcept -{ - for (; __first1 != __last1; ++__first1, ++__first2, ++__first3) - __f(*__first1, *__first2, *__first3); - return __first3; +_ForwardIterator3 __brick_walk3( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator3 __first3, + _Function __f, + /*vector=*/std::false_type) noexcept { + for (; __first1 != __last1; ++__first1, ++__first2, ++__first3) + __f(*__first1, *__first2, *__first3); + return __first3; } template -_RandomAccessIterator3 -__brick_walk3(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator3 __first3, _Function __f, /*vector=*/std::true_type) noexcept -{ - return __unseq_backend::__simd_walk_3(__first1, __last1 - __first1, __first2, __first3, __f); -} - -template -_ForwardIterator3 -__pattern_walk3(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator3 __first3, _Function __f) noexcept -{ - return __internal::__brick_walk3(__first1, __last1, __first2, __first3, __f, typename _Tag::__is_vector{}); -} - -template -_RandomAccessIterator3 -__pattern_walk3(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, - _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator3 __first3, - _Function __f) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - return __internal::__except_handler( - [&]() - { - __par_backend::__parallel_for( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - [__f, __first1, __first2, __first3](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { - __internal::__brick_walk3(__i, __j, __first2 + (__i - __first1), __first3 + (__i - __first1), __f, - _IsVector{}); - }); - return __first3 + (__last1 - __first1); +_ForwardIterator3 __pattern_walk3( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator3 __first3, + _Function __f) noexcept { + return __internal::__brick_walk3(__first1, __last1, __first2, __first3, __f, typename _Tag::__is_vector{}); +} + +template +_RandomAccessIterator3 __pattern_walk3( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator3 __first3, + _Function __f) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&]() { + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + [__f, __first1, __first2, __first3](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + __internal::__brick_walk3( + __i, __j, __first2 + (__i - __first1), __first3 + (__i - __first1), __f, _IsVector{}); }); + return __first3 + (__last1 - __first1); + }); } //------------------------------------------------------------------------ @@ -415,55 +501,69 @@ //------------------------------------------------------------------------ template -bool -__brick_equal(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _BinaryPredicate __p, /* IsVector = */ std::false_type) noexcept -{ - return std::equal(__first1, __last1, __first2, __last2, __p); +bool __brick_equal(_ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate __p, + /* IsVector = */ std::false_type) noexcept { + return std::equal(__first1, __last1, __first2, __last2, __p); } template -bool -__brick_equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _BinaryPredicate __p, /* is_vector = */ std::true_type) noexcept -{ - if (__last1 - __first1 != __last2 - __first2) - return false; +bool __brick_equal(_RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _BinaryPredicate __p, + /* is_vector = */ std::true_type) noexcept { + if (__last1 - __first1 != __last2 - __first2) + return false; - return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1; + return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1; } template -bool -__pattern_equal(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __p) noexcept -{ - return __internal::__brick_equal(__first1, __last1, __first2, __last2, __p, typename _Tag::__is_vector{}); -} - -template -bool -__pattern_equal(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, - _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, - _BinaryPredicate __p) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - if (__last1 - __first1 != __last2 - __first2) - return false; - - return __internal::__except_handler( - [&]() - { - return !__internal::__parallel_or( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - [__first1, __first2, __p](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) - { - return !__internal::__brick_equal(__i, __j, __first2 + (__i - __first1), - __first2 + (__j - __first1), __p, _IsVector{}); - }); +bool __pattern_equal( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _BinaryPredicate __p) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + if (__last1 - __first1 != __last2 - __first2) + return false; + + return __internal::__except_handler([&]() { + return !__internal::__parallel_or( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + [__first1, __first2, __p](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + return !__internal::__brick_equal( + __i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), __p, _IsVector{}); }); + }); } //------------------------------------------------------------------------ @@ -471,45 +571,58 @@ //------------------------------------------------------------------------ template -bool -__brick_equal(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __p, - /* IsVector = */ std::false_type) noexcept -{ - return std::equal(__first1, __last1, __first2, __p); +bool __brick_equal(_ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _BinaryPredicate __p, + /* IsVector = */ std::false_type) noexcept { + return std::equal(__first1, __last1, __first2, __p); } template -bool -__brick_equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _BinaryPredicate __p, /* is_vector = */ std::true_type) noexcept -{ - return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1; +bool __brick_equal(_RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _BinaryPredicate __p, + /* is_vector = */ std::true_type) noexcept { + return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1; } template -bool -__pattern_equal(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _BinaryPredicate __p) noexcept -{ - return __internal::__brick_equal(__first1, __last1, __first2, __p, typename _Tag::__is_vector{}); -} - -template -bool -__pattern_equal(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, - _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _BinaryPredicate __p) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - return __internal::__except_handler( - [&]() - { - return !__internal::__parallel_or( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - [__first1, __first2, __p](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) - { return !__internal::__brick_equal(__i, __j, __first2 + (__i - __first1), __p, _IsVector{}); }); +bool __pattern_equal( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _BinaryPredicate __p) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&]() { + return !__internal::__parallel_or( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + [__first1, __first2, __p](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + return !__internal::__brick_equal(__i, __j, __first2 + (__i - __first1), __p, _IsVector{}); }); + }); } //------------------------------------------------------------------------ @@ -517,48 +630,53 @@ //------------------------------------------------------------------------ template _ForwardIterator -__brick_find_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, - /*is_vector=*/std::false_type) noexcept -{ - return std::find_if(__first, __last, __pred); +__brick_find_if(_ForwardIterator __first, + _ForwardIterator __last, + _Predicate __pred, + /*is_vector=*/std::false_type) noexcept { + return std::find_if(__first, __last, __pred); } template _RandomAccessIterator -__brick_find_if(_RandomAccessIterator __first, _RandomAccessIterator __last, _Predicate __pred, - /*is_vector=*/std::true_type) noexcept -{ - typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType; - return __unseq_backend::__simd_first( - __first, _SizeType(0), __last - __first, - [&__pred](_RandomAccessIterator __it, _SizeType __i) { return __pred(__it[__i]); }); +__brick_find_if(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Predicate __pred, + /*is_vector=*/std::true_type) noexcept { + typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType; + return __unseq_backend::__simd_first( + __first, _SizeType(0), __last - __first, [&__pred](_RandomAccessIterator __it, _SizeType __i) { + return __pred(__it[__i]); + }); } template -_ForwardIterator -__pattern_find_if(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _Predicate __pred) noexcept -{ - return __internal::__brick_find_if(__first, __last, __pred, typename _Tag::__is_vector{}); +_ForwardIterator __pattern_find_if( + _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) noexcept { + return __internal::__brick_find_if(__first, __last, __pred, typename _Tag::__is_vector{}); } template -_RandomAccessIterator -__pattern_find_if(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _Predicate __pred) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - return __internal::__except_handler( - [&]() - { - return __internal::__parallel_find( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__pred](_RandomAccessIterator __i, _RandomAccessIterator __j) - { return __internal::__brick_find_if(__i, __j, __pred, _IsVector{}); }, - std::less::difference_type>(), - /*is_first=*/true); - }); +_RandomAccessIterator __pattern_find_if( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Predicate __pred) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&]() { + return __internal::__parallel_find( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [__pred](_RandomAccessIterator __i, _RandomAccessIterator __j) { + return __internal::__brick_find_if(__i, __j, __pred, _IsVector{}); + }, + std::less::difference_type>(), + /*is_first=*/true); + }); } //------------------------------------------------------------------------ @@ -569,312 +687,364 @@ // or the last occurrence of the subsequence in the range [first, last) // b_first determines what occurrence we want to find (first or last) template -_RandomAccessIterator1 -__find_subrange(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator1 __global_last, - _RandomAccessIterator2 __s_first, _RandomAccessIterator2 __s_last, _BinaryPredicate __pred, - bool __b_first, _IsVector __is_vector) noexcept -{ - typedef typename std::iterator_traits<_RandomAccessIterator2>::value_type _ValueType; - auto __n2 = __s_last - __s_first; - if (__n2 < 1) - { - return __b_first ? __first : __last; - } - - auto __n1 = __global_last - __first; - if (__n1 < __n2) - { - return __last; +_RandomAccessIterator1 __find_subrange( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator1 __global_last, + _RandomAccessIterator2 __s_first, + _RandomAccessIterator2 __s_last, + _BinaryPredicate __pred, + bool __b_first, + _IsVector __is_vector) noexcept { + typedef typename std::iterator_traits<_RandomAccessIterator2>::value_type _ValueType; + auto __n2 = __s_last - __s_first; + if (__n2 < 1) { + return __b_first ? __first : __last; + } + + auto __n1 = __global_last - __first; + if (__n1 < __n2) { + return __last; + } + + auto __cur = __last; + while (__first != __last && (__global_last - __first >= __n2)) { + // find position of *s_first in [first, last) (it can be start of subsequence) + __first = __internal::__brick_find_if( + __first, __last, __equal_value_by_pred<_ValueType, _BinaryPredicate>(*__s_first, __pred), __is_vector); + + // if position that was found previously is the start of subsequence + // then we can exit the loop (b_first == true) or keep the position + // (b_first == false) + if (__first != __last && (__global_last - __first >= __n2) && + __internal::__brick_equal(__s_first + 1, __s_last, __first + 1, __pred, __is_vector)) { + if (__b_first) { + return __first; + } else { + __cur = __first; + } + } else if (__first == __last) { + break; + } else { } - auto __cur = __last; - while (__first != __last && (__global_last - __first >= __n2)) - { - // find position of *s_first in [first, last) (it can be start of subsequence) - __first = __internal::__brick_find_if( - __first, __last, __equal_value_by_pred<_ValueType, _BinaryPredicate>(*__s_first, __pred), __is_vector); - - // if position that was found previously is the start of subsequence - // then we can exit the loop (b_first == true) or keep the position - // (b_first == false) - if (__first != __last && (__global_last - __first >= __n2) && - __internal::__brick_equal(__s_first + 1, __s_last, __first + 1, __pred, __is_vector)) - { - if (__b_first) - { - return __first; - } - else - { - __cur = __first; - } - } - else if (__first == __last) - { - break; - } - else - { - } - - // in case of b_first == false we try to find new start position - // for the next subsequence - ++__first; - } - return __cur; + // in case of b_first == false we try to find new start position + // for the next subsequence + ++__first; + } + return __cur; } template -_RandomAccessIterator -__find_subrange(_RandomAccessIterator __first, _RandomAccessIterator __last, _RandomAccessIterator __global_last, - _Size __count, const _Tp& __value, _BinaryPredicate __pred, _IsVector __is_vector) noexcept -{ - if (static_cast<_Size>(__global_last - __first) < __count || __count < 1) - { - return __last; // According to the standard last shall be returned when count < 1 - } - - auto __unary_pred = __equal_value_by_pred<_Tp, _BinaryPredicate>(__value, __pred); - while (__first != __last && (static_cast<_Size>(__global_last - __first) >= __count)) - { - __first = __internal::__brick_find_if(__first, __last, __unary_pred, __is_vector); - - // check that all of elements in [first+1, first+count) equal to value - if (__first != __last && (static_cast<_Size>(__global_last - __first) >= __count) && - !__internal::__brick_any_of(__first + 1, __first + __count, std::not_fn(__unary_pred), __is_vector)) - { - return __first; - } - else if (__first == __last) - { - break; - } - else - { - ++__first; - } +_RandomAccessIterator __find_subrange( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _RandomAccessIterator __global_last, + _Size __count, + const _Tp& __value, + _BinaryPredicate __pred, + _IsVector __is_vector) noexcept { + if (static_cast<_Size>(__global_last - __first) < __count || __count < 1) { + return __last; // According to the standard last shall be returned when count < 1 + } + + auto __unary_pred = __equal_value_by_pred<_Tp, _BinaryPredicate>(__value, __pred); + while (__first != __last && (static_cast<_Size>(__global_last - __first) >= __count)) { + __first = __internal::__brick_find_if(__first, __last, __unary_pred, __is_vector); + + // check that all of elements in [first+1, first+count) equal to value + if (__first != __last && (static_cast<_Size>(__global_last - __first) >= __count) && + !__internal::__brick_any_of(__first + 1, __first + __count, std::not_fn(__unary_pred), __is_vector)) { + return __first; + } else if (__first == __last) { + break; + } else { + ++__first; } - return __last; + } + return __last; } template -_ForwardIterator1 -__brick_find_end(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, - _ForwardIterator2 __s_last, _BinaryPredicate __pred, /*__is_vector=*/std::false_type) noexcept -{ - return std::find_end(__first, __last, __s_first, __s_last, __pred); +_ForwardIterator1 __brick_find_end( + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __s_first, + _ForwardIterator2 __s_last, + _BinaryPredicate __pred, + /*__is_vector=*/std::false_type) noexcept { + return std::find_end(__first, __last, __s_first, __s_last, __pred); } template -_RandomAccessIterator1 -__brick_find_end(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __s_first, - _RandomAccessIterator2 __s_last, _BinaryPredicate __pred, /*__is_vector=*/std::true_type) noexcept -{ - return __find_subrange(__first, __last, __last, __s_first, __s_last, __pred, false, std::true_type()); +_RandomAccessIterator1 __brick_find_end( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __s_first, + _RandomAccessIterator2 __s_last, + _BinaryPredicate __pred, + /*__is_vector=*/std::true_type) noexcept { + return __find_subrange(__first, __last, __last, __s_first, __s_last, __pred, false, std::true_type()); } template -_ForwardIterator1 -__pattern_find_end(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred) noexcept -{ - return __internal::__brick_find_end(__first, __last, __s_first, __s_last, __pred, typename _Tag::__is_vector{}); -} - -template -_RandomAccessIterator1 -__pattern_find_end(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, - _RandomAccessIterator1 __last, _RandomAccessIterator2 __s_first, _RandomAccessIterator2 __s_last, - _BinaryPredicate __pred) noexcept -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - if (__last - __first == __s_last - __s_first) - { - const bool __res = __internal::__pattern_equal(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - __s_first, __pred); - return __res ? __first : __last; - } - else - { - return __internal::__except_handler( - [&]() - { - return __internal::__parallel_find( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__last, __s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { - return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, false, - _IsVector{}); - }, - std::greater::difference_type>(), - /*is_first=*/false); - }); - } +_RandomAccessIterator1 __pattern_find_end( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __s_first, + _RandomAccessIterator2 __s_last, + _BinaryPredicate __pred) noexcept { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + if (__last - __first == __s_last - __s_first) { + const bool __res = + __internal::__pattern_equal(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __pred); + return __res ? __first : __last; + } else { + return __internal::__except_handler([&]() { + return __internal::__parallel_find( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [__last, __s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, false, _IsVector{}); + }, + std::greater::difference_type>(), + /*is_first=*/false); + }); + } } //------------------------------------------------------------------------ // find_first_of //------------------------------------------------------------------------ template -_ForwardIterator1 -__brick_find_first_of(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, - _ForwardIterator2 __s_last, _BinaryPredicate __pred, /*__is_vector=*/std::false_type) noexcept -{ - return std::find_first_of(__first, __last, __s_first, __s_last, __pred); +_ForwardIterator1 __brick_find_first_of( + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __s_first, + _ForwardIterator2 __s_last, + _BinaryPredicate __pred, + /*__is_vector=*/std::false_type) noexcept { + return std::find_first_of(__first, __last, __s_first, __s_last, __pred); } template -_RandomAccessIterator1 -__brick_find_first_of(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __s_first, - _RandomAccessIterator2 __s_last, _BinaryPredicate __pred, /*__is_vector=*/std::true_type) noexcept -{ - return __unseq_backend::__simd_find_first_of(__first, __last, __s_first, __s_last, __pred); +_RandomAccessIterator1 __brick_find_first_of( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __s_first, + _RandomAccessIterator2 __s_last, + _BinaryPredicate __pred, + /*__is_vector=*/std::true_type) noexcept { + return __unseq_backend::__simd_find_first_of(__first, __last, __s_first, __s_last, __pred); } template -_ForwardIterator1 -__pattern_find_first_of(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred) noexcept -{ - return __internal::__brick_find_first_of(__first, __last, __s_first, __s_last, __pred, - typename _Tag::__is_vector{}); -} - -template -_RandomAccessIterator1 -__pattern_find_first_of(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, - _RandomAccessIterator1 __last, _RandomAccessIterator2 __s_first, - _RandomAccessIterator2 __s_last, _BinaryPredicate __pred) noexcept -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - return __internal::__except_handler( - [&]() - { - return __internal::__parallel_find( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) - { return __internal::__brick_find_first_of(__i, __j, __s_first, __s_last, __pred, _IsVector{}); }, - std::less::difference_type>(), /*is_first=*/true); - }); +_RandomAccessIterator1 __pattern_find_first_of( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __s_first, + _RandomAccessIterator2 __s_last, + _BinaryPredicate __pred) noexcept { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&]() { + return __internal::__parallel_find( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [__s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + return __internal::__brick_find_first_of(__i, __j, __s_first, __s_last, __pred, _IsVector{}); + }, + std::less::difference_type>(), + /*is_first=*/true); + }); } //------------------------------------------------------------------------ // search //------------------------------------------------------------------------ template -_RandomAccessIterator1 -__brick_search(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __s_first, - _RandomAccessIterator2 __s_last, _BinaryPredicate __pred, /*vector=*/std::false_type) noexcept -{ - return std::search(__first, __last, __s_first, __s_last, __pred); +_RandomAccessIterator1 __brick_search( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __s_first, + _RandomAccessIterator2 __s_last, + _BinaryPredicate __pred, + /*vector=*/std::false_type) noexcept { + return std::search(__first, __last, __s_first, __s_last, __pred); } template -_RandomAccessIterator1 -__brick_search(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __s_first, - _RandomAccessIterator2 __s_last, _BinaryPredicate __pred, /*vector=*/std::true_type) noexcept -{ - return __internal::__find_subrange(__first, __last, __last, __s_first, __s_last, __pred, true, std::true_type()); +_RandomAccessIterator1 __brick_search( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __s_first, + _RandomAccessIterator2 __s_last, + _BinaryPredicate __pred, + /*vector=*/std::true_type) noexcept { + return __internal::__find_subrange(__first, __last, __last, __s_first, __s_last, __pred, true, std::true_type()); } template -_ForwardIterator1 -__pattern_search(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred) noexcept -{ - return __internal::__brick_search(__first, __last, __s_first, __s_last, __pred, typename _Tag::__is_vector{}); -} - -template -_RandomAccessIterator1 -__pattern_search(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, - _RandomAccessIterator1 __last, _RandomAccessIterator2 __s_first, _RandomAccessIterator2 __s_last, - _BinaryPredicate __pred) noexcept -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - if (__last - __first == __s_last - __s_first) - { - const bool __res = __internal::__pattern_equal(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - __s_first, __pred); - return __res ? __first : __last; - } - else - { - return __internal::__except_handler( - [&]() - { - return __internal::__parallel_find( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__last, __s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { - return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, true, - _IsVector{}); - }, - std::less::difference_type>(), - /*is_first=*/true); - }); - } +_RandomAccessIterator1 __pattern_search( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __s_first, + _RandomAccessIterator2 __s_last, + _BinaryPredicate __pred) noexcept { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + if (__last - __first == __s_last - __s_first) { + const bool __res = + __internal::__pattern_equal(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __pred); + return __res ? __first : __last; + } else { + return __internal::__except_handler([&]() { + return __internal::__parallel_find( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [__last, __s_first, __s_last, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, true, _IsVector{}); + }, + std::less::difference_type>(), + /*is_first=*/true); + }); + } } //------------------------------------------------------------------------ // search_n //------------------------------------------------------------------------ template -_ForwardIterator -__brick_search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value, - _BinaryPredicate __pred, /*vector=*/std::false_type) noexcept -{ - return std::search_n(__first, __last, __count, __value, __pred); +_ForwardIterator __brick_search_n( + _ForwardIterator __first, + _ForwardIterator __last, + _Size __count, + const _Tp& __value, + _BinaryPredicate __pred, + /*vector=*/std::false_type) noexcept { + return std::search_n(__first, __last, __count, __value, __pred); } template -_RandomAccessIterator -__brick_search_n(_RandomAccessIterator __first, _RandomAccessIterator __last, _Size __count, const _Tp& __value, - _BinaryPredicate __pred, /*vector=*/std::true_type) noexcept -{ - return __internal::__find_subrange(__first, __last, __last, __count, __value, __pred, std::true_type()); +_RandomAccessIterator __brick_search_n( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Size __count, + const _Tp& __value, + _BinaryPredicate __pred, + /*vector=*/std::true_type) noexcept { + return __internal::__find_subrange(__first, __last, __last, __count, __value, __pred, std::true_type()); } template -_ForwardIterator -__pattern_search_n(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Size __count, - const _Tp& __value, _BinaryPredicate __pred) noexcept -{ - return __internal::__brick_search_n(__first, __last, __count, __value, __pred, typename _Tag::__is_vector{}); -} - -template -_RandomAccessIterator -__pattern_search_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _Size __count, const _Tp& __value, _BinaryPredicate __pred) noexcept -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - if (static_cast<_Size>(__last - __first) == __count) - { - const bool __result = - !__internal::__pattern_any_of(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [&__value, &__pred](const _Tp& __val) { return !__pred(__val, __value); }); - return __result ? __first : __last; - } - else - { - return __internal::__except_handler( - [&__exec, __first, __last, __count, &__value, __pred]() - { - return __internal::__parallel_find( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__last, __count, &__value, __pred](_RandomAccessIterator __i, _RandomAccessIterator __j) - { return __internal::__find_subrange(__i, __j, __last, __count, __value, __pred, _IsVector{}); }, - std::less::difference_type>(), - /*is_first=*/true); - }); - } +_RandomAccessIterator __pattern_search_n( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Size __count, + const _Tp& __value, + _BinaryPredicate __pred) noexcept { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + if (static_cast<_Size>(__last - __first) == __count) { + const bool __result = !__internal::__pattern_any_of( + __tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [&__value, &__pred](const _Tp& __val) { + return !__pred(__val, __value); + }); + return __result ? __first : __last; + } else { + return __internal::__except_handler([&__exec, __first, __last, __count, &__value, __pred]() { + return __internal::__parallel_find( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [__last, __count, &__value, __pred](_RandomAccessIterator __i, _RandomAccessIterator __j) { + return __internal::__find_subrange(__i, __j, __last, __count, __value, __pred, _IsVector{}); + }, + std::less::difference_type>(), + /*is_first=*/true); + }); + } } //------------------------------------------------------------------------ @@ -883,19 +1053,20 @@ template _OutputIterator -__brick_copy_n(_ForwardIterator __first, _Size __n, _OutputIterator __result, /*vector=*/std::false_type) noexcept -{ - return std::copy_n(__first, __n, __result); +__brick_copy_n(_ForwardIterator __first, _Size __n, _OutputIterator __result, /*vector=*/std::false_type) noexcept { + return std::copy_n(__first, __n, __result); } template _RandomAccessIterator2 -__brick_copy_n(_RandomAccessIterator1 __first, _Size __n, _RandomAccessIterator2 __result, - /*vector=*/std::true_type) noexcept -{ - return __unseq_backend::__simd_assign( - __first, __n, __result, - [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) { *__result = *__first; }); +__brick_copy_n(_RandomAccessIterator1 __first, + _Size __n, + _RandomAccessIterator2 __result, + /*vector=*/std::true_type) noexcept { + return __unseq_backend::__simd_assign( + __first, __n, __result, [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) { + *__result = *__first; + }); } //------------------------------------------------------------------------ @@ -903,20 +1074,23 @@ //------------------------------------------------------------------------ template _OutputIterator -__brick_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, - /*vector=*/std::false_type) noexcept -{ - return std::copy(__first, __last, __result); +__brick_copy(_ForwardIterator __first, + _ForwardIterator __last, + _OutputIterator __result, + /*vector=*/std::false_type) noexcept { + return std::copy(__first, __last, __result); } template _RandomAccessIterator2 -__brick_copy(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, - /*vector=*/std::true_type) noexcept -{ - return __unseq_backend::__simd_assign( - __first, __last - __first, __result, - [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) { *__result = *__first; }); +__brick_copy(_RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, + /*vector=*/std::true_type) noexcept { + return __unseq_backend::__simd_assign( + __first, __last - __first, __result, [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) { + *__result = *__first; + }); } //------------------------------------------------------------------------ @@ -924,236 +1098,264 @@ //------------------------------------------------------------------------ template _OutputIterator -__brick_move(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, - /*vector=*/std::false_type) noexcept -{ - return std::move(__first, __last, __result); +__brick_move(_ForwardIterator __first, + _ForwardIterator __last, + _OutputIterator __result, + /*vector=*/std::false_type) noexcept { + return std::move(__first, __last, __result); } template _RandomAccessIterator2 -__brick_move(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, - /*vector=*/std::true_type) noexcept -{ - return __unseq_backend::__simd_assign( - __first, __last - __first, __result, - [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) { *__result = std::move(*__first); }); -} - -struct __brick_move_destroy -{ - template - _RandomAccessIterator2 - operator()(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, - /*vec*/ std::true_type) const - { - using _IteratorValueType = typename std::iterator_traits<_RandomAccessIterator1>::value_type; - - return __unseq_backend::__simd_assign(__first, __last - __first, __result, - [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) { - *__result = std::move(*__first); - (*__first).~_IteratorValueType(); - }); - } +__brick_move(_RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, + /*vector=*/std::true_type) noexcept { + return __unseq_backend::__simd_assign( + __first, __last - __first, __result, [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) { + *__result = std::move(*__first); + }); +} + +struct __brick_move_destroy { + template + _RandomAccessIterator2 + operator()(_RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, + /*vec*/ std::true_type) const { + using _IteratorValueType = typename std::iterator_traits<_RandomAccessIterator1>::value_type; - template - _RandomAccessIterator2 - operator()(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, - /*vec*/ std::false_type) const - { - using _IteratorValueType = typename std::iterator_traits<_RandomAccessIterator1>::value_type; - - for (; __first != __last; ++__first, ++__result) - { - *__result = std::move(*__first); - (*__first).~_IteratorValueType(); - } - return __result; + return __unseq_backend::__simd_assign( + __first, __last - __first, __result, [](_RandomAccessIterator1 __first, _RandomAccessIterator2 __result) { + *__result = std::move(*__first); + (*__first).~_IteratorValueType(); + }); + } + + template + _RandomAccessIterator2 + operator()(_RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, + /*vec*/ std::false_type) const { + using _IteratorValueType = typename std::iterator_traits<_RandomAccessIterator1>::value_type; + + for (; __first != __last; ++__first, ++__result) { + *__result = std::move(*__first); + (*__first).~_IteratorValueType(); } + return __result; + } }; //------------------------------------------------------------------------ // swap_ranges //------------------------------------------------------------------------ template -_OutputIterator -__brick_swap_ranges(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, - /*vector=*/std::false_type) noexcept -{ - return std::swap_ranges(__first, __last, __result); +_OutputIterator __brick_swap_ranges( + _ForwardIterator __first, + _ForwardIterator __last, + _OutputIterator __result, + /*vector=*/std::false_type) noexcept { + return std::swap_ranges(__first, __last, __result); } template -_RandomAccessIterator2 -__brick_swap_ranges(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, - /*vector=*/std::true_type) noexcept -{ - using std::iter_swap; - return __unseq_backend::__simd_assign(__first, __last - __first, __result, - iter_swap<_RandomAccessIterator1, _RandomAccessIterator2>); +_RandomAccessIterator2 __brick_swap_ranges( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, + /*vector=*/std::true_type) noexcept { + using std::iter_swap; + return __unseq_backend::__simd_assign( + __first, __last - __first, __result, iter_swap<_RandomAccessIterator1, _RandomAccessIterator2>); } //------------------------------------------------------------------------ // copy_if //------------------------------------------------------------------------ template -_OutputIterator -__brick_copy_if(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _UnaryPredicate __pred, - /*vector=*/std::false_type) noexcept -{ - return std::copy_if(__first, __last, __result, __pred); +_OutputIterator __brick_copy_if( + _ForwardIterator __first, + _ForwardIterator __last, + _OutputIterator __result, + _UnaryPredicate __pred, + /*vector=*/std::false_type) noexcept { + return std::copy_if(__first, __last, __result, __pred); } template -_RandomAccessIterator2 -__brick_copy_if(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, - _UnaryPredicate __pred, - /*vector=*/std::true_type) noexcept -{ +_RandomAccessIterator2 __brick_copy_if( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, + _UnaryPredicate __pred, + /*vector=*/std::true_type) noexcept { #if defined(_PSTL_MONOTONIC_PRESENT) - return __unseq_backend::__simd_copy_if(__first, __last - __first, __result, __pred); + return __unseq_backend::__simd_copy_if(__first, __last - __first, __result, __pred); #else - return std::copy_if(__first, __last, __result, __pred); + return std::copy_if(__first, __last, __result, __pred); #endif } // TODO: Try to use transform_reduce for combining __brick_copy_if_phase1 on IsVector. template -std::pair<_DifferenceType, _DifferenceType> -__brick_calc_mask_1(_ForwardIterator __first, _ForwardIterator __last, bool* __restrict __mask, _UnaryPredicate __pred, - /*vector=*/std::false_type) noexcept -{ - auto __count_true = _DifferenceType(0); - auto __size = __last - __first; - - static_assert(__are_random_access_iterators<_ForwardIterator>::value, - "Pattern-brick error. Should be a random access iterator."); - - for (; __first != __last; ++__first, ++__mask) - { - *__mask = __pred(*__first); - if (*__mask) - { - ++__count_true; - } +std::pair<_DifferenceType, _DifferenceType> __brick_calc_mask_1( + _ForwardIterator __first, + _ForwardIterator __last, + bool* __restrict __mask, + _UnaryPredicate __pred, + /*vector=*/std::false_type) noexcept { + auto __count_true = _DifferenceType(0); + auto __size = __last - __first; + + static_assert(__are_random_access_iterators<_ForwardIterator>::value, + "Pattern-brick error. Should be a random access iterator."); + + for (; __first != __last; ++__first, ++__mask) { + *__mask = __pred(*__first); + if (*__mask) { + ++__count_true; } - return std::make_pair(__count_true, __size - __count_true); + } + return std::make_pair(__count_true, __size - __count_true); } template -std::pair<_DifferenceType, _DifferenceType> -__brick_calc_mask_1(_RandomAccessIterator __first, _RandomAccessIterator __last, bool* __mask, _UnaryPredicate __pred, - /*vector=*/std::true_type) noexcept -{ - auto __result = __unseq_backend::__simd_calc_mask_1(__first, __last - __first, __mask, __pred); - return std::make_pair(__result, (__last - __first) - __result); +std::pair<_DifferenceType, _DifferenceType> __brick_calc_mask_1( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + bool* __mask, + _UnaryPredicate __pred, + /*vector=*/std::true_type) noexcept { + auto __result = __unseq_backend::__simd_calc_mask_1(__first, __last - __first, __mask, __pred); + return std::make_pair(__result, (__last - __first) - __result); } template -void -__brick_copy_by_mask(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, bool* __mask, - _Assigner __assigner, /*vector=*/std::false_type) noexcept -{ - for (; __first != __last; ++__first, ++__mask) - { - if (*__mask) - { - __assigner(__first, __result); - ++__result; - } +void __brick_copy_by_mask( + _ForwardIterator __first, + _ForwardIterator __last, + _OutputIterator __result, + bool* __mask, + _Assigner __assigner, + /*vector=*/std::false_type) noexcept { + for (; __first != __last; ++__first, ++__mask) { + if (*__mask) { + __assigner(__first, __result); + ++__result; } + } } template -void -__brick_copy_by_mask(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, - bool* __restrict __mask, _Assigner __assigner, /*vector=*/std::true_type) noexcept -{ +void __brick_copy_by_mask( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, + bool* __restrict __mask, + _Assigner __assigner, + /*vector=*/std::true_type) noexcept { #if defined(_PSTL_MONOTONIC_PRESENT) - __unseq_backend::__simd_copy_by_mask(__first, __last - __first, __result, __mask, __assigner); + __unseq_backend::__simd_copy_by_mask(__first, __last - __first, __result, __mask, __assigner); #else - __internal::__brick_copy_by_mask(__first, __last, __result, __mask, __assigner, std::false_type()); + __internal::__brick_copy_by_mask(__first, __last, __result, __mask, __assigner, std::false_type()); #endif } template -void -__brick_partition_by_mask(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator1 __out_true, - _OutputIterator2 __out_false, bool* __mask, /*vector=*/std::false_type) noexcept -{ - for (; __first != __last; ++__first, ++__mask) - { - if (*__mask) - { - *__out_true = *__first; - ++__out_true; - } - else - { - *__out_false = *__first; - ++__out_false; - } +void __brick_partition_by_mask( + _ForwardIterator __first, + _ForwardIterator __last, + _OutputIterator1 __out_true, + _OutputIterator2 __out_false, + bool* __mask, + /*vector=*/std::false_type) noexcept { + for (; __first != __last; ++__first, ++__mask) { + if (*__mask) { + *__out_true = *__first; + ++__out_true; + } else { + *__out_false = *__first; + ++__out_false; } + } } template -void -__brick_partition_by_mask(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, - _RandomAccessIterator2 __out_true, _RandomAccessIterator3 __out_false, bool* __mask, - /*vector=*/std::true_type) noexcept -{ +void __brick_partition_by_mask( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __out_true, + _RandomAccessIterator3 __out_false, + bool* __mask, + /*vector=*/std::true_type) noexcept { #if defined(_PSTL_MONOTONIC_PRESENT) - __unseq_backend::__simd_partition_by_mask(__first, __last - __first, __out_true, __out_false, __mask); + __unseq_backend::__simd_partition_by_mask(__first, __last - __first, __out_true, __out_false, __mask); #else - __internal::__brick_partition_by_mask(__first, __last, __out_true, __out_false, __mask, std::false_type()); + __internal::__brick_partition_by_mask(__first, __last, __out_true, __out_false, __mask, std::false_type()); #endif } template -_OutputIterator -__pattern_copy_if(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, - _UnaryPredicate __pred) noexcept -{ - return __internal::__brick_copy_if(__first, __last, __result, __pred, typename _Tag::__is_vector{}); -} - -template -_RandomAccessIterator2 -__pattern_copy_if(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, - _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, _UnaryPredicate __pred) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; - const _DifferenceType __n = __last - __first; - if (_DifferenceType(1) < __n) - { - __par_backend::__buffer __mask_buf(__n); - return __internal::__except_handler( - [&__exec, __n, __first, __result, __pred, &__mask_buf]() - { - bool* __mask = __mask_buf.get(); - _DifferenceType __m{}; - __par_backend::__parallel_strict_scan( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0), - [=](_DifferenceType __i, _DifferenceType __len) { // Reduce - return __internal::__brick_calc_mask_1<_DifferenceType>(__first + __i, __first + (__i + __len), - __mask + __i, __pred, _IsVector{}) - .first; - }, - std::plus<_DifferenceType>(), // Combine - [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { // Scan - __internal::__brick_copy_by_mask( - __first + __i, __first + (__i + __len), __result + __initial, __mask + __i, - [](_RandomAccessIterator1 __x, _RandomAccessIterator2 __z) { *__z = *__x; }, _IsVector{}); - }, - [&__m](_DifferenceType __total) { __m = __total; }); - return __result + __m; - }); - } - // trivial sequence - use serial algorithm - return __internal::__brick_copy_if(__first, __last, __result, __pred, _IsVector{}); +_RandomAccessIterator2 __pattern_copy_if( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, + _UnaryPredicate __pred) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; + const _DifferenceType __n = __last - __first; + if (_DifferenceType(1) < __n) { + __par_backend::__buffer __mask_buf(__n); + return __internal::__except_handler([&__exec, __n, __first, __result, __pred, &__mask_buf]() { + bool* __mask = __mask_buf.get(); + _DifferenceType __m{}; + __par_backend::__parallel_strict_scan( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __n, + _DifferenceType(0), + [=](_DifferenceType __i, _DifferenceType __len) { // Reduce + return __internal::__brick_calc_mask_1<_DifferenceType>( + __first + __i, __first + (__i + __len), __mask + __i, __pred, _IsVector{}) + .first; + }, + std::plus<_DifferenceType>(), // Combine + [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { // Scan + __internal::__brick_copy_by_mask( + __first + __i, + __first + (__i + __len), + __result + __initial, + __mask + __i, + [](_RandomAccessIterator1 __x, _RandomAccessIterator2 __z) { *__z = *__x; }, + _IsVector{}); + }, + [&__m](_DifferenceType __total) { __m = __total; }); + return __result + __m; + }); + } + // trivial sequence - use serial algorithm + return __internal::__brick_copy_if(__first, __last, __result, __pred, _IsVector{}); } //------------------------------------------------------------------------ @@ -1161,44 +1363,50 @@ //------------------------------------------------------------------------ template typename std::iterator_traits<_RandomAccessIterator>::difference_type -__brick_count(_RandomAccessIterator __first, _RandomAccessIterator __last, _Predicate __pred, - /* is_vector = */ std::true_type) noexcept -{ - return __unseq_backend::__simd_count(__first, __last - __first, __pred); +__brick_count(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Predicate __pred, + /* is_vector = */ std::true_type) noexcept { + return __unseq_backend::__simd_count(__first, __last - __first, __pred); } template typename std::iterator_traits<_ForwardIterator>::difference_type -__brick_count(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, - /* is_vector = */ std::false_type) noexcept -{ - return std::count_if(__first, __last, __pred); +__brick_count(_ForwardIterator __first, + _ForwardIterator __last, + _Predicate __pred, + /* is_vector = */ std::false_type) noexcept { + return std::count_if(__first, __last, __pred); } template -typename std::iterator_traits<_ForwardIterator>::difference_type -__pattern_count(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) noexcept -{ - return __internal::__brick_count(__first, __last, __pred, typename _Tag::__is_vector{}); +typename std::iterator_traits<_ForwardIterator>::difference_type __pattern_count( + _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) noexcept { + return __internal::__brick_count(__first, __last, __pred, typename _Tag::__is_vector{}); } template -typename std::iterator_traits<_RandomAccessIterator>::difference_type -__pattern_count(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _Predicate __pred) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType; - return __internal::__except_handler( - [&]() - { - return __par_backend::__parallel_reduce( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, _SizeType(0), - [__pred](_RandomAccessIterator __begin, _RandomAccessIterator __end, _SizeType __value) -> _SizeType - { return __value + __internal::__brick_count(__begin, __end, __pred, _IsVector{}); }, - std::plus<_SizeType>()); - }); +typename std::iterator_traits<_RandomAccessIterator>::difference_type __pattern_count( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Predicate __pred) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType; + return __internal::__except_handler([&]() { + return __par_backend::__parallel_reduce( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + _SizeType(0), + [__pred](_RandomAccessIterator __begin, _RandomAccessIterator __end, _SizeType __value) -> _SizeType { + return __value + __internal::__brick_count(__begin, __end, __pred, _IsVector{}); + }, + std::plus<_SizeType>()); + }); } //------------------------------------------------------------------------ @@ -1207,142 +1415,158 @@ template _RandomAccessIterator -__brick_unique(_RandomAccessIterator __first, _RandomAccessIterator __last, _BinaryPredicate __pred, - /*is_vector=*/std::false_type) noexcept -{ - return std::unique(__first, __last, __pred); +__brick_unique(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _BinaryPredicate __pred, + /*is_vector=*/std::false_type) noexcept { + return std::unique(__first, __last, __pred); } template _RandomAccessIterator -__brick_unique(_RandomAccessIterator __first, _RandomAccessIterator __last, _BinaryPredicate __pred, - /*is_vector=*/std::true_type) noexcept -{ - _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); - return std::unique(__first, __last, __pred); +__brick_unique(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _BinaryPredicate __pred, + /*is_vector=*/std::true_type) noexcept { + _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); + return std::unique(__first, __last, __pred); } template -_ForwardIterator -__pattern_unique(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _BinaryPredicate __pred) noexcept -{ - return __internal::__brick_unique(__first, __last, __pred, typename _Tag::__is_vector{}); +_ForwardIterator __pattern_unique( + _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) noexcept { + return __internal::__brick_unique(__first, __last, __pred, typename _Tag::__is_vector{}); } -// That function is shared between two algorithms - remove_if (__pattern_remove_if) and unique (pattern unique). But a mask calculation is different. -// So, a caller passes _CalcMask brick into remove_elements. +// That function is shared between two algorithms - remove_if (__pattern_remove_if) and unique (pattern unique). But a +// mask calculation is different. So, a caller passes _CalcMask brick into remove_elements. template -_ForwardIterator -__remove_elements(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _ForwardIterator __first, - _ForwardIterator __last, _CalcMask __calc_mask) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - typedef typename std::iterator_traits<_ForwardIterator>::difference_type _DifferenceType; - typedef typename std::iterator_traits<_ForwardIterator>::value_type _Tp; - _DifferenceType __n = __last - __first; - __par_backend::__buffer __mask_buf(__n); - // 1. find a first iterator that should be removed - return __internal::__except_handler([&]() { - bool* __mask = __mask_buf.get(); - _DifferenceType __min = __par_backend::__parallel_reduce( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), _DifferenceType(0), __n, __n, - [__first, __mask, &__calc_mask](_DifferenceType __i, _DifferenceType __j, - _DifferenceType __local_min) -> _DifferenceType - { - // Create mask - __calc_mask(__mask + __i, __mask + __j, __first + __i); - - // if minimum was found in a previous range we shouldn't do anymore - if (__local_min < __i) - { - return __local_min; - } - // find first iterator that should be removed - bool* __result = __internal::__brick_find_if( - __mask + __i, __mask + __j, [](bool __val) { return !__val; }, _IsVector{}); - if (__result - __mask == __j) - { - return __local_min; - } - return std::min(__local_min, _DifferenceType(__result - __mask)); - }, - [](_DifferenceType __local_min1, _DifferenceType __local_min2) -> _DifferenceType - { return std::min(__local_min1, __local_min2); }); +_ForwardIterator __remove_elements( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _ForwardIterator __first, + _ForwardIterator __last, + _CalcMask __calc_mask) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + typedef typename std::iterator_traits<_ForwardIterator>::difference_type _DifferenceType; + typedef typename std::iterator_traits<_ForwardIterator>::value_type _Tp; + _DifferenceType __n = __last - __first; + __par_backend::__buffer __mask_buf(__n); + // 1. find a first iterator that should be removed + return __internal::__except_handler([&]() { + bool* __mask = __mask_buf.get(); + _DifferenceType __min = __par_backend::__parallel_reduce( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + _DifferenceType(0), + __n, + __n, + [__first, __mask, &__calc_mask]( + _DifferenceType __i, _DifferenceType __j, _DifferenceType __local_min) -> _DifferenceType { + // Create mask + __calc_mask(__mask + __i, __mask + __j, __first + __i); + + // if minimum was found in a previous range we shouldn't do anymore + if (__local_min < __i) { + return __local_min; + } + // find first iterator that should be removed + bool* __result = __internal::__brick_find_if( + __mask + __i, __mask + __j, [](bool __val) { return !__val; }, _IsVector{}); + if (__result - __mask == __j) { + return __local_min; + } + return std::min(__local_min, _DifferenceType(__result - __mask)); + }, + [](_DifferenceType __local_min1, _DifferenceType __local_min2) -> _DifferenceType { + return std::min(__local_min1, __local_min2); + }); - // No elements to remove - exit - if (__min == __n) - { - return __last; - } - __n -= __min; - __first += __min; + // No elements to remove - exit + if (__min == __n) { + return __last; + } + __n -= __min; + __first += __min; - __par_backend::__buffer<_Tp> __buf(__n); - _Tp* __result = __buf.get(); - __mask += __min; - _DifferenceType __m{}; - // 2. Elements that doesn't satisfy pred are moved to result - __par_backend::__parallel_strict_scan( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0), - [__mask](_DifferenceType __i, _DifferenceType __len) - { - return __internal::__brick_count( - __mask + __i, __mask + __i + __len, [](bool __val) { return __val; }, _IsVector{}); - }, - std::plus<_DifferenceType>(), - [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) - { - __internal::__brick_copy_by_mask( - __first + __i, __first + __i + __len, __result + __initial, __mask + __i, - [](_ForwardIterator __x, _Tp* __z) - { - __internal::__invoke_if_else( - std::is_trivial<_Tp>(), [&]() { *__z = std::move(*__x); }, - [&]() { ::new (std::addressof(*__z)) _Tp(std::move(*__x)); }); - }, - _IsVector{}); - }, - [&__m](_DifferenceType __total) { __m = __total; }); + __par_backend::__buffer<_Tp> __buf(__n); + _Tp* __result = __buf.get(); + __mask += __min; + _DifferenceType __m{}; + // 2. Elements that doesn't satisfy pred are moved to result + __par_backend::__parallel_strict_scan( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __n, + _DifferenceType(0), + [__mask](_DifferenceType __i, _DifferenceType __len) { + return __internal::__brick_count( + __mask + __i, __mask + __i + __len, [](bool __val) { return __val; }, _IsVector{}); + }, + std::plus<_DifferenceType>(), + [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { + __internal::__brick_copy_by_mask( + __first + __i, + __first + __i + __len, + __result + __initial, + __mask + __i, + [](_ForwardIterator __x, _Tp* __z) { + __internal::__invoke_if_else( + std::is_trivial<_Tp>(), + [&]() { *__z = std::move(*__x); }, + [&]() { ::new (std::addressof(*__z)) _Tp(std::move(*__x)); }); + }, + _IsVector{}); + }, + [&__m](_DifferenceType __total) { __m = __total; }); - // 3. Elements from result are moved to [first, last) - __par_backend::__parallel_for( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __result, __result + __m, - [__result, __first](_Tp* __i, _Tp* __j) - { - __invoke_if_else( - std::is_trivial<_Tp>(), [&]() { __brick_move(__i, __j, __first + (__i - __result), _IsVector{}); }, - [&]() { __brick_move_destroy()(__i, __j, __first + (__i - __result), _IsVector{}); }); - }); - return __first + __m; - }); + // 3. Elements from result are moved to [first, last) + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __result, + __result + __m, + [__result, __first](_Tp* __i, _Tp* __j) { + __invoke_if_else( + std::is_trivial<_Tp>(), + [&]() { __brick_move(__i, __j, __first + (__i - __result), _IsVector{}); }, + [&]() { __brick_move_destroy()(__i, __j, __first + (__i - __result), _IsVector{}); }); + }); + return __first + __m; + }); } template -_RandomAccessIterator -__pattern_unique(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _BinaryPredicate __pred) noexcept -{ - typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; - - if (__first == __last) - { - return __last; - } - if (__first + 1 == __last || __first + 2 == __last) - { - // Trivial sequence - use serial algorithm - return __internal::__brick_unique(__first, __last, __pred, _IsVector{}); - } - return __internal::__remove_elements( - __tag, std::forward<_ExecutionPolicy>(__exec), ++__first, __last, - [&__pred](bool* __b, bool* __e, _RandomAccessIterator __it) - { - __internal::__brick_walk3( - __b, __e, __it - 1, __it, - [&__pred](bool& __x, _ReferenceType __y, _ReferenceType __z) { __x = !__pred(__y, __z); }, _IsVector{}); - }); +_RandomAccessIterator __pattern_unique( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _BinaryPredicate __pred) noexcept { + typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; + + if (__first == __last) { + return __last; + } + if (__first + 1 == __last || __first + 2 == __last) { + // Trivial sequence - use serial algorithm + return __internal::__brick_unique(__first, __last, __pred, _IsVector{}); + } + return __internal::__remove_elements( + __tag, + std::forward<_ExecutionPolicy>(__exec), + ++__first, + __last, + [&__pred](bool* __b, bool* __e, _RandomAccessIterator __it) { + __internal::__brick_walk3( + __b, + __e, + __it - 1, + __it, + [&__pred](bool& __x, _ReferenceType __y, _ReferenceType __z) { __x = !__pred(__y, __z); }, + _IsVector{}); + }); } //------------------------------------------------------------------------ @@ -1350,179 +1574,199 @@ //------------------------------------------------------------------------ template -OutputIterator -__brick_unique_copy(_ForwardIterator __first, _ForwardIterator __last, OutputIterator __result, _BinaryPredicate __pred, - /*vector=*/std::false_type) noexcept -{ - return std::unique_copy(__first, __last, __result, __pred); +OutputIterator __brick_unique_copy( + _ForwardIterator __first, + _ForwardIterator __last, + OutputIterator __result, + _BinaryPredicate __pred, + /*vector=*/std::false_type) noexcept { + return std::unique_copy(__first, __last, __result, __pred); } template -_RandomAccessIterator2 -__brick_unique_copy(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, - _BinaryPredicate __pred, /*vector=*/std::true_type) noexcept -{ +_RandomAccessIterator2 __brick_unique_copy( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, + _BinaryPredicate __pred, + /*vector=*/std::true_type) noexcept { #if defined(_PSTL_MONOTONIC_PRESENT) - return __unseq_backend::__simd_unique_copy(__first, __last - __first, __result, __pred); + return __unseq_backend::__simd_unique_copy(__first, __last - __first, __result, __pred); #else - return std::unique_copy(__first, __last, __result, __pred); + return std::unique_copy(__first, __last, __result, __pred); #endif } template -_OutputIterator -__pattern_unique_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _OutputIterator __result, _BinaryPredicate __pred) noexcept -{ - return __internal::__brick_unique_copy(__first, __last, __result, __pred, typename _Tag::__is_vector{}); +_OutputIterator __pattern_unique_copy( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator __first, + _ForwardIterator __last, + _OutputIterator __result, + _BinaryPredicate __pred) noexcept { + return __internal::__brick_unique_copy(__first, __last, __result, __pred, typename _Tag::__is_vector{}); } template -_DifferenceType -__brick_calc_mask_2(_RandomAccessIterator __first, _RandomAccessIterator __last, bool* __restrict __mask, - _BinaryPredicate __pred, /*vector=*/std::false_type) noexcept -{ - _DifferenceType __count = 0; - for (; __first != __last; ++__first, ++__mask) - { - *__mask = !__pred(*__first, *(__first - 1)); - __count += *__mask; - } - return __count; +_DifferenceType __brick_calc_mask_2( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + bool* __restrict __mask, + _BinaryPredicate __pred, + /*vector=*/std::false_type) noexcept { + _DifferenceType __count = 0; + for (; __first != __last; ++__first, ++__mask) { + *__mask = !__pred(*__first, *(__first - 1)); + __count += *__mask; + } + return __count; } template -_DifferenceType -__brick_calc_mask_2(_RandomAccessIterator __first, _RandomAccessIterator __last, bool* __restrict __mask, - _BinaryPredicate __pred, /*vector=*/std::true_type) noexcept -{ - return __unseq_backend::__simd_calc_mask_2(__first, __last - __first, __mask, __pred); -} - -template -_RandomAccessIterator2 -__pattern_unique_copy(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, - _RandomAccessIterator1 __last, _RandomAccessIterator2 __result, _BinaryPredicate __pred) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; - const _DifferenceType __n = __last - __first; - if (_DifferenceType(2) < __n) - { - __par_backend::__buffer __mask_buf(__n); - if (_DifferenceType(2) < __n) - { - return __internal::__except_handler( - [&__exec, __n, __first, __result, __pred, &__mask_buf]() - { - bool* __mask = __mask_buf.get(); - _DifferenceType __m{}; - __par_backend::__parallel_strict_scan( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0), - [=](_DifferenceType __i, _DifferenceType __len) -> _DifferenceType { // Reduce - _DifferenceType __extra = 0; - if (__i == 0) - { - // Special boundary case - __mask[__i] = true; - if (--__len == 0) - return 1; - ++__i; - ++__extra; - } - return __internal::__brick_calc_mask_2<_DifferenceType>( - __first + __i, __first + (__i + __len), __mask + __i, __pred, _IsVector{}) + - __extra; - }, - std::plus<_DifferenceType>(), // Combine - [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { // Scan - // Phase 2 is same as for __pattern_copy_if - __internal::__brick_copy_by_mask( - __first + __i, __first + (__i + __len), __result + __initial, __mask + __i, - [](_RandomAccessIterator1 __x, _RandomAccessIterator2 __z) { *__z = *__x; }, - _IsVector{}); - }, - [&__m](_DifferenceType __total) { __m = __total; }); - return __result + __m; - }); - } +_RandomAccessIterator2 __pattern_unique_copy( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, + _BinaryPredicate __pred) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; + const _DifferenceType __n = __last - __first; + if (_DifferenceType(2) < __n) { + __par_backend::__buffer __mask_buf(__n); + if (_DifferenceType(2) < __n) { + return __internal::__except_handler([&__exec, __n, __first, __result, __pred, &__mask_buf]() { + bool* __mask = __mask_buf.get(); + _DifferenceType __m{}; + __par_backend::__parallel_strict_scan( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __n, + _DifferenceType(0), + [=](_DifferenceType __i, _DifferenceType __len) -> _DifferenceType { // Reduce + _DifferenceType __extra = 0; + if (__i == 0) { + // Special boundary case + __mask[__i] = true; + if (--__len == 0) + return 1; + ++__i; + ++__extra; + } + return __internal::__brick_calc_mask_2<_DifferenceType>( + __first + __i, __first + (__i + __len), __mask + __i, __pred, _IsVector{}) + + __extra; + }, + std::plus<_DifferenceType>(), // Combine + [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { // Scan + // Phase 2 is same as for __pattern_copy_if + __internal::__brick_copy_by_mask( + __first + __i, + __first + (__i + __len), + __result + __initial, + __mask + __i, + [](_RandomAccessIterator1 __x, _RandomAccessIterator2 __z) { *__z = *__x; }, + _IsVector{}); + }, + [&__m](_DifferenceType __total) { __m = __total; }); + return __result + __m; + }); } - // trivial sequence - use serial algorithm - return __internal::__brick_unique_copy(__first, __last, __result, __pred, _IsVector{}); + } + // trivial sequence - use serial algorithm + return __internal::__brick_unique_copy(__first, __last, __result, __pred, _IsVector{}); } //------------------------------------------------------------------------ // reverse //------------------------------------------------------------------------ template -void -__brick_reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, /*__is_vector=*/std::false_type) noexcept -{ - std::reverse(__first, __last); +void __brick_reverse( + _BidirectionalIterator __first, _BidirectionalIterator __last, /*__is_vector=*/std::false_type) noexcept { + std::reverse(__first, __last); } template -void -__brick_reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, /*__is_vector=*/std::true_type) noexcept -{ - typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; +void __brick_reverse( + _RandomAccessIterator __first, _RandomAccessIterator __last, /*__is_vector=*/std::true_type) noexcept { + typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; - const auto __n = (__last - __first) / 2; - __unseq_backend::__simd_walk_2(__first, __n, std::reverse_iterator<_RandomAccessIterator>(__last), - [](_ReferenceType __x, _ReferenceType __y) { - using std::swap; - swap(__x, __y); - }); + const auto __n = (__last - __first) / 2; + __unseq_backend::__simd_walk_2( + __first, __n, std::reverse_iterator<_RandomAccessIterator>(__last), [](_ReferenceType __x, _ReferenceType __y) { + using std::swap; + swap(__x, __y); + }); } // this brick is called in parallel version, so we can use iterator arithmetic template -void -__brick_reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, _BidirectionalIterator __d_last, - /*is_vector=*/std::false_type) noexcept -{ - for (--__d_last; __first != __last; ++__first, --__d_last) - { - using std::iter_swap; - iter_swap(__first, __d_last); - } +void __brick_reverse(_BidirectionalIterator __first, + _BidirectionalIterator __last, + _BidirectionalIterator __d_last, + /*is_vector=*/std::false_type) noexcept { + for (--__d_last; __first != __last; ++__first, --__d_last) { + using std::iter_swap; + iter_swap(__first, __d_last); + } } // this brick is called in parallel version, so we can use iterator arithmetic template -void -__brick_reverse(_RandomAccessIterator __first, _RandomAccessIterator __last, _RandomAccessIterator __d_last, - /*is_vector=*/std::true_type) noexcept -{ - typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; - - __unseq_backend::__simd_walk_2(__first, __last - __first, std::reverse_iterator<_RandomAccessIterator>(__d_last), - [](_ReferenceType __x, _ReferenceType __y) { - using std::swap; - swap(__x, __y); - }); +void __brick_reverse(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _RandomAccessIterator __d_last, + /*is_vector=*/std::true_type) noexcept { + typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; + + __unseq_backend::__simd_walk_2( + __first, + __last - __first, + std::reverse_iterator<_RandomAccessIterator>(__d_last), + [](_ReferenceType __x, _ReferenceType __y) { + using std::swap; + swap(__x, __y); + }); } template -void -__pattern_reverse(_Tag, _ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last) noexcept -{ - __internal::__brick_reverse(__first, __last, typename _Tag::__is_vector{}); +void __pattern_reverse( + _Tag, _ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last) noexcept { + __internal::__brick_reverse(__first, __last, typename _Tag::__is_vector{}); } template -void -__pattern_reverse(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - __par_backend::__parallel_for( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __first + (__last - __first) / 2, - [__first, __last](_RandomAccessIterator __inner_first, _RandomAccessIterator __inner_last) - { __internal::__brick_reverse(__inner_first, __inner_last, __last - (__inner_first - __first), _IsVector{}); }); +void __pattern_reverse(__parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __first + (__last - __first) / 2, + [__first, __last](_RandomAccessIterator __inner_first, _RandomAccessIterator __inner_last) { + __internal::__brick_reverse(__inner_first, __inner_last, __last - (__inner_first - __first), _IsVector{}); + }); } //------------------------------------------------------------------------ @@ -1530,49 +1774,60 @@ //------------------------------------------------------------------------ template -_OutputIterator -__brick_reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __d_first, - /*is_vector=*/std::false_type) noexcept -{ - return std::reverse_copy(__first, __last, __d_first); +_OutputIterator __brick_reverse_copy( + _BidirectionalIterator __first, + _BidirectionalIterator __last, + _OutputIterator __d_first, + /*is_vector=*/std::false_type) noexcept { + return std::reverse_copy(__first, __last, __d_first); } template -_RandomAccessIterator2 -__brick_reverse_copy(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __d_first, - /*is_vector=*/std::true_type) noexcept -{ - typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1; - typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2; +_RandomAccessIterator2 __brick_reverse_copy( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __d_first, + /*is_vector=*/std::true_type) noexcept { + typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1; + typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2; - return __unseq_backend::__simd_walk_2(std::reverse_iterator<_RandomAccessIterator1>(__last), __last - __first, - __d_first, [](_ReferenceType1 __x, _ReferenceType2 __y) { __y = __x; }); + return __unseq_backend::__simd_walk_2( + std::reverse_iterator<_RandomAccessIterator1>(__last), + __last - __first, + __d_first, + [](_ReferenceType1 __x, _ReferenceType2 __y) { __y = __x; }); } template -_OutputIterator -__pattern_reverse_copy(_Tag, _ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last, - _OutputIterator __d_first) noexcept -{ - return __internal::__brick_reverse_copy(__first, __last, __d_first, typename _Tag::__is_vector{}); +_OutputIterator __pattern_reverse_copy( + _Tag, + _ExecutionPolicy&&, + _BidirectionalIterator __first, + _BidirectionalIterator __last, + _OutputIterator __d_first) noexcept { + return __internal::__brick_reverse_copy(__first, __last, __d_first, typename _Tag::__is_vector{}); } template -_RandomAccessIterator2 -__pattern_reverse_copy(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, - _RandomAccessIterator1 __last, _RandomAccessIterator2 __d_first) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - auto __len = __last - __first; - __par_backend::__parallel_for( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__first, __len, __d_first](_RandomAccessIterator1 __inner_first, _RandomAccessIterator1 __inner_last) - { - __internal::__brick_reverse_copy(__inner_first, __inner_last, - __d_first + (__len - (__inner_last - __first)), _IsVector{}); - }); - return __d_first + __len; +_RandomAccessIterator2 __pattern_reverse_copy( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __d_first) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + auto __len = __last - __first; + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [__first, __len, __d_first](_RandomAccessIterator1 __inner_first, _RandomAccessIterator1 __inner_last) { + __internal::__brick_reverse_copy( + __inner_first, __inner_last, __d_first + (__len - (__inner_last - __first)), _IsVector{}); + }); + return __d_first + __len; } //------------------------------------------------------------------------ @@ -1580,126 +1835,139 @@ //------------------------------------------------------------------------ template _ForwardIterator -__brick_rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, - /*is_vector=*/std::false_type) noexcept -{ +__brick_rotate(_ForwardIterator __first, + _ForwardIterator __middle, + _ForwardIterator __last, + /*is_vector=*/std::false_type) noexcept { #if defined(_PSTL_CPP11_STD_ROTATE_BROKEN) - std::rotate(__first, __middle, __last); - return std::next(__first, std::distance(__middle, __last)); + std::rotate(__first, __middle, __last); + return std::next(__first, std::distance(__middle, __last)); #else - return std::rotate(__first, __middle, __last); + return std::rotate(__first, __middle, __last); #endif } template _RandomAccessIterator -__brick_rotate(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, - /*is_vector=*/std::true_type) noexcept -{ - auto __n = __last - __first; - auto __m = __middle - __first; - const _RandomAccessIterator __ret = __first + (__last - __middle); - - bool __is_left = (__m <= __n / 2); - if (!__is_left) - __m = __n - __m; - - while (__n > 1 && __m > 0) - { - using std::iter_swap; - const auto __m_2 = __m * 2; - if (__is_left) - { - for (; __last - __first >= __m_2; __first += __m) - { - __unseq_backend::__simd_assign(__first, __m, __first + __m, - iter_swap<_RandomAccessIterator, _RandomAccessIterator>); - } - } - else - { - for (; __last - __first >= __m_2; __last -= __m) - { - __unseq_backend::__simd_assign(__last - __m, __m, __last - __m_2, - iter_swap<_RandomAccessIterator, _RandomAccessIterator>); - } - } - __is_left = !__is_left; - __m = __n % __m; - __n = __last - __first; +__brick_rotate(_RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, + /*is_vector=*/std::true_type) noexcept { + auto __n = __last - __first; + auto __m = __middle - __first; + const _RandomAccessIterator __ret = __first + (__last - __middle); + + bool __is_left = (__m <= __n / 2); + if (!__is_left) + __m = __n - __m; + + while (__n > 1 && __m > 0) { + using std::iter_swap; + const auto __m_2 = __m * 2; + if (__is_left) { + for (; __last - __first >= __m_2; __first += __m) { + __unseq_backend::__simd_assign( + __first, __m, __first + __m, iter_swap<_RandomAccessIterator, _RandomAccessIterator>); + } + } else { + for (; __last - __first >= __m_2; __last -= __m) { + __unseq_backend::__simd_assign( + __last - __m, __m, __last - __m_2, iter_swap<_RandomAccessIterator, _RandomAccessIterator>); + } } + __is_left = !__is_left; + __m = __n % __m; + __n = __last - __first; + } - return __ret; + return __ret; } template -_ForwardIterator -__pattern_rotate(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __middle, - _ForwardIterator __last) noexcept -{ - return __internal::__brick_rotate(__first, __middle, __last, typename _Tag::__is_vector{}); +_ForwardIterator __pattern_rotate( + _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) noexcept { + return __internal::__brick_rotate(__first, __middle, __last, typename _Tag::__is_vector{}); } template -_RandomAccessIterator -__pattern_rotate(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __middle, _RandomAccessIterator __last) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp; - auto __n = __last - __first; - auto __m = __middle - __first; - if (__m <= __n / 2) - { - __par_backend::__buffer<_Tp> __buf(__n - __m); - return __internal::__except_handler( - [&__exec, __n, __m, __first, __middle, __last, &__buf]() - { - _Tp* __result = __buf.get(); - __par_backend::__parallel_for( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __middle, __last, - [__middle, __result](_RandomAccessIterator __b, _RandomAccessIterator __e) - { __internal::__brick_uninitialized_move(__b, __e, __result + (__b - __middle), _IsVector{}); }); - - __par_backend::__parallel_for( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __middle, - [__last, __middle](_RandomAccessIterator __b, _RandomAccessIterator __e) - { __internal::__brick_move(__b, __e, __b + (__last - __middle), _IsVector{}); }); - - __par_backend::__parallel_for( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __result, __result + (__n - __m), - [__first, __result](_Tp* __b, _Tp* __e) - { __brick_move_destroy()(__b, __e, __first + (__b - __result), _IsVector{}); }); - - return __first + (__last - __middle); - }); - } - else - { - __par_backend::__buffer<_Tp> __buf(__m); - return __internal::__except_handler( - [&__exec, __n, __m, __first, __middle, __last, &__buf]() - { - _Tp* __result = __buf.get(); - __par_backend::__parallel_for( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __middle, - [__first, __result](_RandomAccessIterator __b, _RandomAccessIterator __e) - { __internal::__brick_uninitialized_move(__b, __e, __result + (__b - __first), _IsVector{}); }); - - __par_backend::__parallel_for( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __middle, __last, - [__first, __middle](_RandomAccessIterator __b, _RandomAccessIterator __e) - { __internal::__brick_move(__b, __e, __first + (__b - __middle), _IsVector{}); }); - - __par_backend::__parallel_for( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __result, __result + __m, - [__n, __m, __first, __result](_Tp* __b, _Tp* __e) - { __brick_move_destroy()(__b, __e, __first + ((__n - __m) + (__b - __result)), _IsVector{}); }); - - return __first + (__last - __middle); - }); - } +_RandomAccessIterator __pattern_rotate( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp; + auto __n = __last - __first; + auto __m = __middle - __first; + if (__m <= __n / 2) { + __par_backend::__buffer<_Tp> __buf(__n - __m); + return __internal::__except_handler([&__exec, __n, __m, __first, __middle, __last, &__buf]() { + _Tp* __result = __buf.get(); + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __middle, + __last, + [__middle, __result](_RandomAccessIterator __b, _RandomAccessIterator __e) { + __internal::__brick_uninitialized_move(__b, __e, __result + (__b - __middle), _IsVector{}); + }); + + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __middle, + [__last, __middle](_RandomAccessIterator __b, _RandomAccessIterator __e) { + __internal::__brick_move(__b, __e, __b + (__last - __middle), _IsVector{}); + }); + + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __result, + __result + (__n - __m), + [__first, __result](_Tp* __b, _Tp* __e) { + __brick_move_destroy()(__b, __e, __first + (__b - __result), _IsVector{}); + }); + + return __first + (__last - __middle); + }); + } else { + __par_backend::__buffer<_Tp> __buf(__m); + return __internal::__except_handler([&__exec, __n, __m, __first, __middle, __last, &__buf]() { + _Tp* __result = __buf.get(); + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __middle, + [__first, __result](_RandomAccessIterator __b, _RandomAccessIterator __e) { + __internal::__brick_uninitialized_move(__b, __e, __result + (__b - __first), _IsVector{}); + }); + + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __middle, + __last, + [__first, __middle](_RandomAccessIterator __b, _RandomAccessIterator __e) { + __internal::__brick_move(__b, __e, __first + (__b - __middle), _IsVector{}); + }); + + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __result, + __result + __m, + [__n, __m, __first, __result](_Tp* __b, _Tp* __e) { + __brick_move_destroy()(__b, __e, __first + ((__n - __m) + (__b - __result)), _IsVector{}); + }); + + return __first + (__last - __middle); + }); + } } //------------------------------------------------------------------------ @@ -1707,60 +1975,66 @@ //------------------------------------------------------------------------ template -_OutputIterator -__brick_rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, - _OutputIterator __result, /*__is_vector=*/std::false_type) noexcept -{ - return std::rotate_copy(__first, __middle, __last, __result); +_OutputIterator __brick_rotate_copy( + _ForwardIterator __first, + _ForwardIterator __middle, + _ForwardIterator __last, + _OutputIterator __result, + /*__is_vector=*/std::false_type) noexcept { + return std::rotate_copy(__first, __middle, __last, __result); } template -_RandomAccessIterator2 -__brick_rotate_copy(_RandomAccessIterator1 __first, _RandomAccessIterator1 __middle, _RandomAccessIterator1 __last, - _RandomAccessIterator2 __result, /*__is_vector=*/std::true_type) noexcept -{ - _RandomAccessIterator2 __res = __internal::__brick_copy(__middle, __last, __result, std::true_type()); - return __internal::__brick_copy(__first, __middle, __res, std::true_type()); +_RandomAccessIterator2 __brick_rotate_copy( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __middle, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result, + /*__is_vector=*/std::true_type) noexcept { + _RandomAccessIterator2 __res = __internal::__brick_copy(__middle, __last, __result, std::true_type()); + return __internal::__brick_copy(__first, __middle, __res, std::true_type()); } template -_OutputIterator -__pattern_rotate_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __middle, - _ForwardIterator __last, _OutputIterator __result) noexcept -{ - return __internal::__brick_rotate_copy(__first, __middle, __last, __result, typename _Tag::__is_vector{}); +_OutputIterator __pattern_rotate_copy( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator __first, + _ForwardIterator __middle, + _ForwardIterator __last, + _OutputIterator __result) noexcept { + return __internal::__brick_rotate_copy(__first, __middle, __last, __result, typename _Tag::__is_vector{}); } template -_RandomAccessIterator2 -__pattern_rotate_copy(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, - _RandomAccessIterator1 __middle, _RandomAccessIterator1 __last, _RandomAccessIterator2 __result) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - __par_backend::__parallel_for( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__first, __last, __middle, __result](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e) - { - if (__b > __middle) - { - __internal::__brick_copy(__b, __e, __result + (__b - __middle), _IsVector{}); - } - else - { - _RandomAccessIterator2 __new_result = __result + ((__last - __middle) + (__b - __first)); - if (__e < __middle) - { - __internal::__brick_copy(__b, __e, __new_result, _IsVector{}); - } - else - { - __internal::__brick_copy(__b, __middle, __new_result, _IsVector{}); - __internal::__brick_copy(__middle, __e, __result, _IsVector{}); - } - } - }); - return __result + (__last - __first); +_RandomAccessIterator2 __pattern_rotate_copy( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __middle, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __result) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [__first, __last, __middle, __result](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e) { + if (__b > __middle) { + __internal::__brick_copy(__b, __e, __result + (__b - __middle), _IsVector{}); + } else { + _RandomAccessIterator2 __new_result = __result + ((__last - __middle) + (__b - __first)); + if (__e < __middle) { + __internal::__brick_copy(__b, __e, __new_result, _IsVector{}); + } else { + __internal::__brick_copy(__b, __middle, __new_result, _IsVector{}); + __internal::__brick_copy(__middle, __e, __result, _IsVector{}); + } + } + }); + return __result + (__last - __first); } //------------------------------------------------------------------------ @@ -1768,147 +2042,133 @@ //------------------------------------------------------------------------ template -bool -__brick_is_partitioned(_ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred, - /*is_vector=*/std::false_type) noexcept -{ - return std::is_partitioned(__first, __last, __pred); +bool __brick_is_partitioned(_ForwardIterator __first, + _ForwardIterator __last, + _UnaryPredicate __pred, + /*is_vector=*/std::false_type) noexcept { + return std::is_partitioned(__first, __last, __pred); } template -bool -__brick_is_partitioned(_RandomAccessIterator __first, _RandomAccessIterator __last, _UnaryPredicate __pred, - /*is_vector=*/std::true_type) noexcept -{ - typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType; - if (__first == __last) - { - return true; - } - else - { - _RandomAccessIterator __result = __unseq_backend::__simd_first( - __first, _SizeType(0), __last - __first, - [&__pred](_RandomAccessIterator __it, _SizeType __i) { return !__pred(__it[__i]); }); - if (__result == __last) - { - return true; - } - else - { - ++__result; - return !__unseq_backend::__simd_or(__result, __last - __result, __pred); - } +bool __brick_is_partitioned(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _UnaryPredicate __pred, + /*is_vector=*/std::true_type) noexcept { + typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType; + if (__first == __last) { + return true; + } else { + _RandomAccessIterator __result = __unseq_backend::__simd_first( + __first, _SizeType(0), __last - __first, [&__pred](_RandomAccessIterator __it, _SizeType __i) { + return !__pred(__it[__i]); + }); + if (__result == __last) { + return true; + } else { + ++__result; + return !__unseq_backend::__simd_or(__result, __last - __result, __pred); } + } } template -bool -__pattern_is_partitioned(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _UnaryPredicate __pred) noexcept -{ - return __internal::__brick_is_partitioned(__first, __last, __pred, typename _Tag::__is_vector{}); +bool __pattern_is_partitioned( + _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) noexcept { + return __internal::__brick_is_partitioned(__first, __last, __pred, typename _Tag::__is_vector{}); } template -bool -__pattern_is_partitioned(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _UnaryPredicate __pred) -{ - if (__first == __last) - { - return true; - } - else - { - using __backend_tag = typename decltype(__tag)::__backend_tag; - - return __internal::__except_handler([&]() { - // State of current range: - // broken - current range is not partitioned by pred - // all_true - all elements in current range satisfy pred - // all_false - all elements in current range don't satisfy pred - // true_false - elements satisfy pred are placed before elements that don't satisfy pred - enum _ReduceType - { - __not_init = -1, - __broken, - __all_true, - __all_false, - __true_false - }; - _ReduceType __init = __not_init; - - // Array with states that we'll have when state from the left branch is merged with state from the right branch. - // State is calculated by formula: new_state = table[left_state * 4 + right_state] - _ReduceType __table[] = {__broken, __broken, __broken, __broken, __broken, __all_true, - __true_false, __true_false, __broken, __broken, __all_false, __broken, - __broken, __broken, __true_false, __broken}; - - __init = __par_backend::__parallel_reduce( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, - [&__pred, &__table](_RandomAccessIterator __i, _RandomAccessIterator __j, - _ReduceType __value) -> _ReduceType - { - if (__value == __broken) - { - return __broken; - } - _ReduceType __res = __not_init; - // if first element satisfy pred - if (__pred(*__i)) - { - // find first element that don't satisfy pred - _RandomAccessIterator __x = - __internal::__brick_find_if(__i + 1, __j, std::not_fn(__pred), _IsVector{}); - if (__x != __j) - { - // find first element after "x" that satisfy pred - _RandomAccessIterator __y = __internal::__brick_find_if(__x + 1, __j, __pred, _IsVector{}); - // if it was found then range isn't partitioned by pred - if (__y != __j) - { - return __broken; - } - else - { - __res = __true_false; - } - } - else - { - __res = __all_true; - } - } - else - { // if first element doesn't satisfy pred - // then we should find the first element that satisfy pred. - // If we found it then range isn't partitioned by pred - if (__internal::__brick_find_if(__i + 1, __j, __pred, _IsVector{}) != __j) - { - return __broken; - } - else - { - __res = __all_false; - } - } - // if we have value from left range then we should calculate the result - return (__value == -1) ? __res : __table[__value * 4 + __res]; - }, - - [&__table](_ReduceType __val1, _ReduceType __val2) -> _ReduceType - { - if (__val1 == __broken || __val2 == __broken) - { - return __broken; - } - // calculate the result for new big range - return __table[__val1 * 4 + __val2]; - }); - return __init != __broken; - }); - } +bool __pattern_is_partitioned( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _UnaryPredicate __pred) { + if (__first == __last) { + return true; + } else { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&]() { + // State of current range: + // broken - current range is not partitioned by pred + // all_true - all elements in current range satisfy pred + // all_false - all elements in current range don't satisfy pred + // true_false - elements satisfy pred are placed before elements that don't satisfy pred + enum _ReduceType { __not_init = -1, __broken, __all_true, __all_false, __true_false }; + _ReduceType __init = __not_init; + + // Array with states that we'll have when state from the left branch is merged with state from the right branch. + // State is calculated by formula: new_state = table[left_state * 4 + right_state] + _ReduceType __table[] = { + __broken, + __broken, + __broken, + __broken, + __broken, + __all_true, + __true_false, + __true_false, + __broken, + __broken, + __all_false, + __broken, + __broken, + __broken, + __true_false, + __broken}; + + __init = __par_backend::__parallel_reduce( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __init, + [&__pred, + &__table](_RandomAccessIterator __i, _RandomAccessIterator __j, _ReduceType __value) -> _ReduceType { + if (__value == __broken) { + return __broken; + } + _ReduceType __res = __not_init; + // if first element satisfy pred + if (__pred(*__i)) { + // find first element that don't satisfy pred + _RandomAccessIterator __x = __internal::__brick_find_if(__i + 1, __j, std::not_fn(__pred), _IsVector{}); + if (__x != __j) { + // find first element after "x" that satisfy pred + _RandomAccessIterator __y = __internal::__brick_find_if(__x + 1, __j, __pred, _IsVector{}); + // if it was found then range isn't partitioned by pred + if (__y != __j) { + return __broken; + } else { + __res = __true_false; + } + } else { + __res = __all_true; + } + } else { // if first element doesn't satisfy pred + // then we should find the first element that satisfy pred. + // If we found it then range isn't partitioned by pred + if (__internal::__brick_find_if(__i + 1, __j, __pred, _IsVector{}) != __j) { + return __broken; + } else { + __res = __all_false; + } + } + // if we have value from left range then we should calculate the result + return (__value == -1) ? __res : __table[__value * 4 + __res]; + }, + + [&__table](_ReduceType __val1, _ReduceType __val2) -> _ReduceType { + if (__val1 == __broken || __val2 == __broken) { + return __broken; + } + // calculate the result for new big range + return __table[__val1 * 4 + __val2]; + }); + return __init != __broken; + }); + } } //------------------------------------------------------------------------ @@ -1916,99 +2176,105 @@ //------------------------------------------------------------------------ template -_ForwardIterator -__brick_partition(_ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred, - /*is_vector=*/std::false_type) noexcept -{ - return std::partition(__first, __last, __pred); +_ForwardIterator __brick_partition( + _ForwardIterator __first, + _ForwardIterator __last, + _UnaryPredicate __pred, + /*is_vector=*/std::false_type) noexcept { + return std::partition(__first, __last, __pred); } template -_RandomAccessIterator -__brick_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, _UnaryPredicate __pred, - /*is_vector=*/std::true_type) noexcept -{ - _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); - return std::partition(__first, __last, __pred); +_RandomAccessIterator __brick_partition( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _UnaryPredicate __pred, + /*is_vector=*/std::true_type) noexcept { + _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); + return std::partition(__first, __last, __pred); } template -_ForwardIterator -__pattern_partition(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _UnaryPredicate __pred) noexcept -{ - return __internal::__brick_partition(__first, __last, __pred, typename _Tag::__is_vector{}); +_ForwardIterator __pattern_partition( + _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) noexcept { + return __internal::__brick_partition(__first, __last, __pred, typename _Tag::__is_vector{}); } template -_RandomAccessIterator -__pattern_partition(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _UnaryPredicate __pred) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - // partitioned range: elements before pivot satisfy pred (true part), - // elements after pivot don't satisfy pred (false part) - struct _PartitionRange - { - _RandomAccessIterator __begin; - _RandomAccessIterator __pivot; - _RandomAccessIterator __end; +_RandomAccessIterator __pattern_partition( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _UnaryPredicate __pred) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + // partitioned range: elements before pivot satisfy pred (true part), + // elements after pivot don't satisfy pred (false part) + struct _PartitionRange { + _RandomAccessIterator __begin; + _RandomAccessIterator __pivot; + _RandomAccessIterator __end; + }; + + return __internal::__except_handler([&]() { + _PartitionRange __init{__last, __last, __last}; + + // lambda for merging two partitioned ranges to one partitioned range + auto __reductor = [&__exec](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange { + auto __size1 = __val1.__end - __val1.__pivot; + auto __size2 = __val2.__pivot - __val2.__begin; + auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin); + + // if all elements in left range satisfy pred then we can move new pivot to pivot of right range + if (__val1.__end == __val1.__pivot) { + return {__new_begin, __val2.__pivot, __val2.__end}; + } + // if true part of right range greater than false part of left range + // then we should swap the false part of left range and last part of true part of right range + else if (__size2 > __size1) { + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __val1.__pivot, + __val1.__pivot + __size1, + [__val1, __val2, __size1](_RandomAccessIterator __i, _RandomAccessIterator __j) { + __internal::__brick_swap_ranges( + __i, __j, (__val2.__pivot - __size1) + (__i - __val1.__pivot), _IsVector{}); + }); + return {__new_begin, __val2.__pivot - __size1, __val2.__end}; + } + // else we should swap the first part of false part of left range and true part of right range + else { + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __val1.__pivot, + __val1.__pivot + __size2, + [__val1, __val2](_RandomAccessIterator __i, _RandomAccessIterator __j) { + __internal::__brick_swap_ranges(__i, __j, __val2.__begin + (__i - __val1.__pivot), _IsVector{}); + }); + return {__new_begin, __val1.__pivot + __size2, __val2.__end}; + } }; - return __internal::__except_handler([&]() { - _PartitionRange __init{__last, __last, __last}; - - // lambda for merging two partitioned ranges to one partitioned range - auto __reductor = [&__exec](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange - { - auto __size1 = __val1.__end - __val1.__pivot; - auto __size2 = __val2.__pivot - __val2.__begin; - auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin); - - // if all elements in left range satisfy pred then we can move new pivot to pivot of right range - if (__val1.__end == __val1.__pivot) - { - return {__new_begin, __val2.__pivot, __val2.__end}; - } - // if true part of right range greater than false part of left range - // then we should swap the false part of left range and last part of true part of right range - else if (__size2 > __size1) - { - __par_backend::__parallel_for( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __val1.__pivot, __val1.__pivot + __size1, - [__val1, __val2, __size1](_RandomAccessIterator __i, _RandomAccessIterator __j) { - __internal::__brick_swap_ranges(__i, __j, (__val2.__pivot - __size1) + (__i - __val1.__pivot), - _IsVector{}); - }); - return {__new_begin, __val2.__pivot - __size1, __val2.__end}; - } - // else we should swap the first part of false part of left range and true part of right range - else - { - __par_backend::__parallel_for( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __val1.__pivot, __val1.__pivot + __size2, - [__val1, __val2](_RandomAccessIterator __i, _RandomAccessIterator __j) { - __internal::__brick_swap_ranges(__i, __j, __val2.__begin + (__i - __val1.__pivot), _IsVector{}); - }); - return {__new_begin, __val1.__pivot + __size2, __val2.__end}; - } - }; - - _PartitionRange __result = __par_backend::__parallel_reduce( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, - [__pred, __reductor](_RandomAccessIterator __i, _RandomAccessIterator __j, - _PartitionRange __value) -> _PartitionRange - { - //1. serial partition - _RandomAccessIterator __pivot = __internal::__brick_partition(__i, __j, __pred, _IsVector{}); - - // 2. merging of two ranges (left and right respectively) - return __reductor(__value, {__i, __pivot, __j}); - }, - __reductor); - return __result.__pivot; - }); + _PartitionRange __result = __par_backend::__parallel_reduce( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __init, + [__pred, + __reductor](_RandomAccessIterator __i, _RandomAccessIterator __j, _PartitionRange __value) -> _PartitionRange { + // 1. serial partition + _RandomAccessIterator __pivot = __internal::__brick_partition(__i, __j, __pred, _IsVector{}); + + // 2. merging of two ranges (left and right respectively) + return __reductor(__value, {__i, __pivot, __j}); + }, + __reductor); + return __result.__pivot; + }); } //------------------------------------------------------------------------ @@ -2016,83 +2282,88 @@ //------------------------------------------------------------------------ template -_BidirectionalIterator -__brick_stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _UnaryPredicate __pred, - /*__is_vector=*/std::false_type) noexcept -{ - return std::stable_partition(__first, __last, __pred); +_BidirectionalIterator __brick_stable_partition( + _BidirectionalIterator __first, + _BidirectionalIterator __last, + _UnaryPredicate __pred, + /*__is_vector=*/std::false_type) noexcept { + return std::stable_partition(__first, __last, __pred); } template -_RandomAccessIterator -__brick_stable_partition(_RandomAccessIterator __first, _RandomAccessIterator __last, _UnaryPredicate __pred, - /*__is_vector=*/std::true_type) noexcept -{ - _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); - return std::stable_partition(__first, __last, __pred); +_RandomAccessIterator __brick_stable_partition( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _UnaryPredicate __pred, + /*__is_vector=*/std::true_type) noexcept { + _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); + return std::stable_partition(__first, __last, __pred); } template -_BidirectionalIterator -__pattern_stable_partition(_Tag, _ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last, - _UnaryPredicate __pred) noexcept -{ - return __internal::__brick_stable_partition(__first, __last, __pred, typename _Tag::__is_vector{}); +_BidirectionalIterator __pattern_stable_partition( + _Tag, + _ExecutionPolicy&&, + _BidirectionalIterator __first, + _BidirectionalIterator __last, + _UnaryPredicate __pred) noexcept { + return __internal::__brick_stable_partition(__first, __last, __pred, typename _Tag::__is_vector{}); } template -_RandomAccessIterator -__pattern_stable_partition(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _UnaryPredicate __pred) noexcept -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - // partitioned range: elements before pivot satisfy pred (true part), - // elements after pivot don't satisfy pred (false part) - struct _PartitionRange - { - _RandomAccessIterator __begin; - _RandomAccessIterator __pivot; - _RandomAccessIterator __end; +_RandomAccessIterator __pattern_stable_partition( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _UnaryPredicate __pred) noexcept { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + // partitioned range: elements before pivot satisfy pred (true part), + // elements after pivot don't satisfy pred (false part) + struct _PartitionRange { + _RandomAccessIterator __begin; + _RandomAccessIterator __pivot; + _RandomAccessIterator __end; + }; + + return __internal::__except_handler([&]() { + _PartitionRange __init{__last, __last, __last}; + + // lambda for merging two partitioned ranges to one partitioned range + auto __reductor = [](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange { + auto __size1 = __val1.__end - __val1.__pivot; + auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin); + + // if all elements in left range satisfy pred then we can move new pivot to pivot of right range + if (__val1.__end == __val1.__pivot) { + return {__new_begin, __val2.__pivot, __val2.__end}; + } + // if true part of right range greater than false part of left range + // then we should swap the false part of left range and last part of true part of right range + else { + __internal::__brick_rotate(__val1.__pivot, __val2.__begin, __val2.__pivot, _IsVector{}); + return {__new_begin, __val2.__pivot - __size1, __val2.__end}; + } }; - return __internal::__except_handler([&]() { - _PartitionRange __init{__last, __last, __last}; - - // lambda for merging two partitioned ranges to one partitioned range - auto __reductor = [](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange - { - auto __size1 = __val1.__end - __val1.__pivot; - auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin); - - // if all elements in left range satisfy pred then we can move new pivot to pivot of right range - if (__val1.__end == __val1.__pivot) - { - return {__new_begin, __val2.__pivot, __val2.__end}; - } - // if true part of right range greater than false part of left range - // then we should swap the false part of left range and last part of true part of right range - else - { - __internal::__brick_rotate(__val1.__pivot, __val2.__begin, __val2.__pivot, _IsVector{}); - return {__new_begin, __val2.__pivot - __size1, __val2.__end}; - } - }; - - _PartitionRange __result = __par_backend::__parallel_reduce( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, - [&__pred, __reductor](_RandomAccessIterator __i, _RandomAccessIterator __j, - _PartitionRange __value) -> _PartitionRange - { - //1. serial stable_partition - _RandomAccessIterator __pivot = __internal::__brick_stable_partition(__i, __j, __pred, _IsVector{}); - - // 2. merging of two ranges (left and right respectively) - return __reductor(__value, {__i, __pivot, __j}); - }, - __reductor); - return __result.__pivot; - }); + _PartitionRange __result = __par_backend::__parallel_reduce( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __init, + [&__pred, + __reductor](_RandomAccessIterator __i, _RandomAccessIterator __j, _PartitionRange __value) -> _PartitionRange { + // 1. serial stable_partition + _RandomAccessIterator __pivot = __internal::__brick_stable_partition(__i, __j, __pred, _IsVector{}); + + // 2. merging of two ranges (left and right respectively) + return __reductor(__value, {__i, __pivot, __j}); + }, + __reductor); + return __result.__pivot; + }); } //------------------------------------------------------------------------ @@ -2100,77 +2371,103 @@ //------------------------------------------------------------------------ template -std::pair<_OutputIterator1, _OutputIterator2> -__brick_partition_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator1 __out_true, - _OutputIterator2 __out_false, _UnaryPredicate __pred, /*is_vector=*/std::false_type) noexcept -{ - return std::partition_copy(__first, __last, __out_true, __out_false, __pred); -} - -template __brick_partition_copy( + _ForwardIterator __first, + _ForwardIterator __last, + _OutputIterator1 __out_true, + _OutputIterator2 __out_false, + _UnaryPredicate __pred, + /*is_vector=*/std::false_type) noexcept { + return std::partition_copy(__first, __last, __out_true, __out_false, __pred); +} + +template -std::pair<_RandomAccessIterator2, _RandomAccessIterator3> -__brick_partition_copy(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator2 __out_true, - _RandomAccessIterator3 __out_false, _UnaryPredicate __pred, - /*is_vector=*/std::true_type) noexcept -{ +std::pair<_RandomAccessIterator2, _RandomAccessIterator3> __brick_partition_copy( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __out_true, + _RandomAccessIterator3 __out_false, + _UnaryPredicate __pred, + /*is_vector=*/std::true_type) noexcept { #if defined(_PSTL_MONOTONIC_PRESENT) - return __unseq_backend::__simd_partition_copy(__first, __last - __first, __out_true, __out_false, __pred); + return __unseq_backend::__simd_partition_copy(__first, __last - __first, __out_true, __out_false, __pred); #else - return std::partition_copy(__first, __last, __out_true, __out_false, __pred); + return std::partition_copy(__first, __last, __out_true, __out_false, __pred); #endif } -template -std::pair<_OutputIterator1, _OutputIterator2> -__pattern_partition_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _OutputIterator1 __out_true, _OutputIterator2 __out_false, _UnaryPredicate __pred) noexcept -{ - return __internal::__brick_partition_copy(__first, __last, __out_true, __out_false, __pred, - typename _Tag::__is_vector{}); -} - -template -std::pair<_RandomAccessIterator2, _RandomAccessIterator3> -__pattern_partition_copy(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, - _RandomAccessIterator1 __last, _RandomAccessIterator2 __out_true, - _RandomAccessIterator3 __out_false, _UnaryPredicate __pred) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; - typedef std::pair<_DifferenceType, _DifferenceType> _ReturnType; - const _DifferenceType __n = __last - __first; - if (_DifferenceType(1) < __n) - { - __par_backend::__buffer __mask_buf(__n); - return __internal::__except_handler( - [&__exec, __n, __first, __out_true, __out_false, __pred, &__mask_buf]() - { - bool* __mask = __mask_buf.get(); - _ReturnType __m{}; - __par_backend::__parallel_strict_scan( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __n, - std::make_pair(_DifferenceType(0), _DifferenceType(0)), - [=](_DifferenceType __i, _DifferenceType __len) { // Reduce - return __internal::__brick_calc_mask_1<_DifferenceType>(__first + __i, __first + (__i + __len), - __mask + __i, __pred, _IsVector{}); - }, - [](const _ReturnType& __x, const _ReturnType& __y) -> _ReturnType - { return std::make_pair(__x.first + __y.first, __x.second + __y.second); }, // Combine - [=](_DifferenceType __i, _DifferenceType __len, _ReturnType __initial) { // Scan - __internal::__brick_partition_by_mask( - __first + __i, __first + (__i + __len), __out_true + __initial.first, - __out_false + __initial.second, __mask + __i, _IsVector{}); - }, - [&__m](_ReturnType __total) { __m = __total; }); - return std::make_pair(__out_true + __m.first, __out_false + __m.second); - }); - } - // trivial sequence - use serial algorithm - return __internal::__brick_partition_copy(__first, __last, __out_true, __out_false, __pred, _IsVector{}); +std::pair<_OutputIterator1, _OutputIterator2> __pattern_partition_copy( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator __first, + _ForwardIterator __last, + _OutputIterator1 __out_true, + _OutputIterator2 __out_false, + _UnaryPredicate __pred) noexcept { + return __internal::__brick_partition_copy( + __first, __last, __out_true, __out_false, __pred, typename _Tag::__is_vector{}); +} + +template +std::pair<_RandomAccessIterator2, _RandomAccessIterator3> __pattern_partition_copy( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __out_true, + _RandomAccessIterator3 __out_false, + _UnaryPredicate __pred) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; + typedef std::pair<_DifferenceType, _DifferenceType> _ReturnType; + const _DifferenceType __n = __last - __first; + if (_DifferenceType(1) < __n) { + __par_backend::__buffer __mask_buf(__n); + return __internal::__except_handler([&__exec, __n, __first, __out_true, __out_false, __pred, &__mask_buf]() { + bool* __mask = __mask_buf.get(); + _ReturnType __m{}; + __par_backend::__parallel_strict_scan( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __n, + std::make_pair(_DifferenceType(0), _DifferenceType(0)), + [=](_DifferenceType __i, _DifferenceType __len) { // Reduce + return __internal::__brick_calc_mask_1<_DifferenceType>( + __first + __i, __first + (__i + __len), __mask + __i, __pred, _IsVector{}); + }, + [](const _ReturnType& __x, const _ReturnType& __y) -> _ReturnType { + return std::make_pair(__x.first + __y.first, __x.second + __y.second); + }, // Combine + [=](_DifferenceType __i, _DifferenceType __len, _ReturnType __initial) { // Scan + __internal::__brick_partition_by_mask( + __first + __i, + __first + (__i + __len), + __out_true + __initial.first, + __out_false + __initial.second, + __mask + __i, + _IsVector{}); + }, + [&__m](_ReturnType __total) { __m = __total; }); + return std::make_pair(__out_true + __m.first, __out_false + __m.second); + }); + } + // trivial sequence - use serial algorithm + return __internal::__brick_partition_copy(__first, __last, __out_true, __out_false, __pred, _IsVector{}); } //------------------------------------------------------------------------ @@ -2178,28 +2475,35 @@ //------------------------------------------------------------------------ template -void -__pattern_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - _IsMoveConstructible) noexcept -{ - std::sort(__first, __last, __comp); +void __pattern_sort(_Tag, + _ExecutionPolicy&&, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare __comp, + _IsMoveConstructible) noexcept { + std::sort(__first, __last, __comp); } template -void -__pattern_sort(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _Compare __comp, /*is_move_constructible=*/std::true_type) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - __internal::__except_handler( - [&]() - { - __par_backend::__parallel_stable_sort( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, - [](_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) - { std::sort(__first, __last, __comp); }); +void __pattern_sort(__parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare __comp, + /*is_move_constructible=*/std::true_type) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + __internal::__except_handler([&]() { + __par_backend::__parallel_stable_sort( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __comp, + [](_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + std::sort(__first, __last, __comp); }); + }); } //------------------------------------------------------------------------ @@ -2207,28 +2511,31 @@ //------------------------------------------------------------------------ template -void -__pattern_stable_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp) noexcept -{ - std::stable_sort(__first, __last, __comp); +void __pattern_stable_sort( + _Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) noexcept { + std::stable_sort(__first, __last, __comp); } template -void -__pattern_stable_sort(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _Compare __comp) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - __internal::__except_handler( - [&]() - { - __par_backend::__parallel_stable_sort( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, - [](_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) - { std::stable_sort(__first, __last, __comp); }); +void __pattern_stable_sort( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare __comp) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + __internal::__except_handler([&]() { + __par_backend::__parallel_stable_sort( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __comp, + [](_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + std::stable_sort(__first, __last, __comp); }); + }); } //------------------------------------------------------------------------ @@ -2236,38 +2543,45 @@ //------------------------------------------------------------------------ template -void -__pattern_partial_sort(_Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __middle, - _RandomAccessIterator __last, _Compare __comp) noexcept -{ - std::partial_sort(__first, __middle, __last, __comp); +void __pattern_partial_sort( + _Tag, + _ExecutionPolicy&&, + _RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, + _Compare __comp) noexcept { + std::partial_sort(__first, __middle, __last, __comp); } template -void -__pattern_partial_sort(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - const auto __n = __middle - __first; - if (__n == 0) - return; - - __internal::__except_handler( - [&]() - { - __par_backend::__parallel_stable_sort( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, - [__n](_RandomAccessIterator __begin, _RandomAccessIterator __end, _Compare __comp) - { - if (__n < __end - __begin) - std::partial_sort(__begin, __begin + __n, __end, __comp); - else - std::sort(__begin, __end, __comp); - }, - __n); - }); +void __pattern_partial_sort( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, + _Compare __comp) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + const auto __n = __middle - __first; + if (__n == 0) + return; + + __internal::__except_handler([&]() { + __par_backend::__parallel_stable_sort( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __comp, + [__n](_RandomAccessIterator __begin, _RandomAccessIterator __end, _Compare __comp) { + if (__n < __end - __begin) + std::partial_sort(__begin, __begin + __n, __end, __comp); + else + std::sort(__begin, __end, __comp); + }, + __n); + }); } //------------------------------------------------------------------------ @@ -2275,164 +2589,192 @@ //------------------------------------------------------------------------ template -_RandomAccessIterator -__pattern_partial_sort_copy(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _RandomAccessIterator __d_first, _RandomAccessIterator __d_last, _Compare __comp) noexcept -{ - return std::partial_sort_copy(__first, __last, __d_first, __d_last, __comp); -} - -template -_RandomAccessIterator2 -__pattern_partial_sort_copy(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first, - _RandomAccessIterator1 __last, _RandomAccessIterator2 __d_first, - _RandomAccessIterator2 __d_last, _Compare __comp) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - if (__last == __first || __d_last == __d_first) - { - return __d_first; - } - auto __n1 = __last - __first; - auto __n2 = __d_last - __d_first; - return __internal::__except_handler([&]() { - if (__n2 >= __n1) - { - __par_backend::__parallel_stable_sort( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __d_first, __d_first + __n1, __comp, - [__first, __d_first](_RandomAccessIterator2 __i, _RandomAccessIterator2 __j, _Compare __comp) - { - _RandomAccessIterator1 __i1 = __first + (__i - __d_first); - _RandomAccessIterator1 __j1 = __first + (__j - __d_first); - - // 1. Copy elements from input to output +_RandomAccessIterator2 __pattern_partial_sort_copy( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __d_first, + _RandomAccessIterator2 __d_last, + _Compare __comp) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + if (__last == __first || __d_last == __d_first) { + return __d_first; + } + auto __n1 = __last - __first; + auto __n2 = __d_last - __d_first; + return __internal::__except_handler([&]() { + if (__n2 >= __n1) { + __par_backend::__parallel_stable_sort( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __d_first, + __d_first + __n1, + __comp, + [__first, __d_first](_RandomAccessIterator2 __i, _RandomAccessIterator2 __j, _Compare __comp) { + _RandomAccessIterator1 __i1 = __first + (__i - __d_first); + _RandomAccessIterator1 __j1 = __first + (__j - __d_first); + + // 1. Copy elements from input to output #if !defined(_PSTL_ICC_18_OMP_SIMD_BROKEN) - __internal::__brick_copy(__i1, __j1, __i, _IsVector{}); + __internal::__brick_copy(__i1, __j1, __i, _IsVector{}); #else - std::copy(__i1, __j1, __i); + std::copy(__i1, __j1, __i); #endif - // 2. Sort elements in output sequence - std::sort(__i, __j, __comp); - }, - __n1); - return __d_first + __n1; - } - else - { - typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type _T1; - typedef typename std::iterator_traits<_RandomAccessIterator2>::value_type _T2; - __par_backend::__buffer<_T1> __buf(__n1); - _T1* __r = __buf.get(); - - __par_backend::__parallel_stable_sort( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __r, __r + __n1, __comp, - [__n2, __first, __r](_T1* __i, _T1* __j, _Compare __comp) - { - _RandomAccessIterator1 __it = __first + (__i - __r); - - // 1. Copy elements from input to raw memory - for (_T1* __k = __i; __k != __j; ++__k, ++__it) - { - ::new (__k) _T2(*__it); - } - - // 2. Sort elements in temporary __buffer - if (__n2 < __j - __i) - std::partial_sort(__i, __i + __n2, __j, __comp); - else - std::sort(__i, __j, __comp); - }, - __n2); - - // 3. Move elements from temporary __buffer to output - __par_backend::__parallel_for(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __r, __r + __n2, - [__r, __d_first](_T1* __i, _T1* __j) - { __brick_move_destroy()(__i, __j, __d_first + (__i - __r), _IsVector{}); }); - __par_backend::__parallel_for(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __r + __n2, - __r + __n1, - [](_T1* __i, _T1* __j) { __brick_destroy(__i, __j, _IsVector{}); }); - - return __d_first + __n2; - } - }); + // 2. Sort elements in output sequence + std::sort(__i, __j, __comp); + }, + __n1); + return __d_first + __n1; + } else { + typedef typename std::iterator_traits<_RandomAccessIterator1>::value_type _T1; + typedef typename std::iterator_traits<_RandomAccessIterator2>::value_type _T2; + __par_backend::__buffer<_T1> __buf(__n1); + _T1* __r = __buf.get(); + + __par_backend::__parallel_stable_sort( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __r, + __r + __n1, + __comp, + [__n2, __first, __r](_T1* __i, _T1* __j, _Compare __comp) { + _RandomAccessIterator1 __it = __first + (__i - __r); + + // 1. Copy elements from input to raw memory + for (_T1* __k = __i; __k != __j; ++__k, ++__it) { + ::new (__k) _T2(*__it); + } + + // 2. Sort elements in temporary __buffer + if (__n2 < __j - __i) + std::partial_sort(__i, __i + __n2, __j, __comp); + else + std::sort(__i, __j, __comp); + }, + __n2); + + // 3. Move elements from temporary __buffer to output + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __r, + __r + __n2, + [__r, __d_first](_T1* __i, _T1* __j) { + __brick_move_destroy()(__i, __j, __d_first + (__i - __r), _IsVector{}); + }); + __par_backend::__parallel_for( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __r + __n2, __r + __n1, [](_T1* __i, _T1* __j) { + __brick_destroy(__i, __j, _IsVector{}); + }); + + return __d_first + __n2; + } + }); } //------------------------------------------------------------------------ // adjacent_find //------------------------------------------------------------------------ template -_RandomAccessIterator -__brick_adjacent_find(_RandomAccessIterator __first, _RandomAccessIterator __last, _BinaryPredicate __pred, - /* IsVector = */ std::true_type, bool __or_semantic) noexcept -{ - return __unseq_backend::__simd_adjacent_find(__first, __last, __pred, __or_semantic); +_RandomAccessIterator __brick_adjacent_find( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _BinaryPredicate __pred, + /* IsVector = */ std::true_type, + bool __or_semantic) noexcept { + return __unseq_backend::__simd_adjacent_find(__first, __last, __pred, __or_semantic); } template -_ForwardIterator -__brick_adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred, - /* IsVector = */ std::false_type, bool) noexcept -{ - return std::adjacent_find(__first, __last, __pred); +_ForwardIterator __brick_adjacent_find( + _ForwardIterator __first, + _ForwardIterator __last, + _BinaryPredicate __pred, + /* IsVector = */ std::false_type, + bool) noexcept { + return std::adjacent_find(__first, __last, __pred); } template -_ForwardIterator -__pattern_adjacent_find(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _BinaryPredicate __pred, bool __or_semantic) noexcept -{ - return __internal::__brick_adjacent_find(__first, __last, __pred, typename _Tag::__is_vector{}, __or_semantic); +_ForwardIterator __pattern_adjacent_find( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator __first, + _ForwardIterator __last, + _BinaryPredicate __pred, + bool __or_semantic) noexcept { + return __internal::__brick_adjacent_find(__first, __last, __pred, typename _Tag::__is_vector{}, __or_semantic); } template -_RandomAccessIterator -__pattern_adjacent_find(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _BinaryPredicate __pred, bool __or_semantic) -{ - if (__last - __first < 2) - return __last; - - using __backend_tag = typename decltype(__tag)::__backend_tag; +_RandomAccessIterator __pattern_adjacent_find( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _BinaryPredicate __pred, + bool __or_semantic) { + if (__last - __first < 2) + return __last; - return __internal::__except_handler( - [&]() - { - return __par_backend::__parallel_reduce( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, __last, - [__last, __pred, __or_semantic](_RandomAccessIterator __begin, _RandomAccessIterator __end, - _RandomAccessIterator __value) -> _RandomAccessIterator - { - // TODO: investigate performance benefits from the use of shared variable for the result, - // checking (compare_and_swap idiom) its __value at __first. - if (__or_semantic && __value < __last) - { //found - __par_backend::__cancel_execution(); - return __value; - } - - if (__value > __begin) - { - // modify __end to check the predicate on the boundary __values; - // TODO: to use a custom range with boundaries overlapping - // TODO: investigate what if we remove "if" below and run algorithm on range [__first, __last-1) - // then check the pair [__last-1, __last) - if (__end != __last) - ++__end; - - //correct the global result iterator if the "brick" returns a local "__last" - const _RandomAccessIterator __res = - __internal::__brick_adjacent_find(__begin, __end, __pred, _IsVector{}, __or_semantic); - if (__res < __end) - __value = __res; - } - return __value; - }, - [](_RandomAccessIterator __x, _RandomAccessIterator __y) -> _RandomAccessIterator - { return __x < __y ? __x : __y; } //reduce a __value - ); - }); + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&]() { + return __par_backend::__parallel_reduce( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __last, + [__last, __pred, __or_semantic]( + _RandomAccessIterator __begin, _RandomAccessIterator __end, _RandomAccessIterator __value) + -> _RandomAccessIterator { + // TODO: investigate performance benefits from the use of shared variable for the result, + // checking (compare_and_swap idiom) its __value at __first. + if (__or_semantic && __value < __last) { // found + __par_backend::__cancel_execution(); + return __value; + } + + if (__value > __begin) { + // modify __end to check the predicate on the boundary __values; + // TODO: to use a custom range with boundaries overlapping + // TODO: investigate what if we remove "if" below and run algorithm on range [__first, __last-1) + // then check the pair [__last-1, __last) + if (__end != __last) + ++__end; + + // correct the global result iterator if the "brick" returns a local "__last" + const _RandomAccessIterator __res = + __internal::__brick_adjacent_find(__begin, __end, __pred, _IsVector{}, __or_semantic); + if (__res < __end) + __value = __res; + } + return __value; + }, + [](_RandomAccessIterator __x, _RandomAccessIterator __y) -> _RandomAccessIterator { + return __x < __y ? __x : __y; + } // reduce a __value + ); + }); } //------------------------------------------------------------------------ @@ -2440,205 +2782,213 @@ //------------------------------------------------------------------------ template -void -__pattern_nth_element(_Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __nth, - _RandomAccessIterator __last, _Compare __comp) noexcept -{ - std::nth_element(__first, __nth, __last, __comp); +void __pattern_nth_element( + _Tag, + _ExecutionPolicy&&, + _RandomAccessIterator __first, + _RandomAccessIterator __nth, + _RandomAccessIterator __last, + _Compare __comp) noexcept { + std::nth_element(__first, __nth, __last, __comp); } template -void -__pattern_nth_element(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) noexcept -{ - if (__first == __last || __nth == __last) - { - return; +void __pattern_nth_element( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __nth, + _RandomAccessIterator __last, + _Compare __comp) noexcept { + if (__first == __last || __nth == __last) { + return; + } + + using std::iter_swap; + typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp; + _RandomAccessIterator __x; + do { + __x = __internal::__pattern_partition( + __tag, std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, [&__comp, __first](const _Tp& __x) { + return __comp(__x, *__first); + }); + --__x; + if (__x != __first) { + iter_swap(__first, __x); } - - using std::iter_swap; - typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp; - _RandomAccessIterator __x; - do - { - __x = __internal::__pattern_partition(__tag, std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, - [&__comp, __first](const _Tp& __x) { return __comp(__x, *__first); }); - --__x; - if (__x != __first) - { - iter_swap(__first, __x); - } - // if x > nth then our new range for partition is [first, x) - if (__x - __nth > 0) - { - __last = __x; - } - // if x < nth then our new range for partition is [x, last) - else if (__x - __nth < 0) - { - // if *x == *nth then we can start new partition with x+1 - if (!__comp(*__nth, *__x) && !__comp(*__x, *__nth)) - { - ++__x; - } - else - { - iter_swap(__nth, __x); - } - __first = __x; - } - } while (__x != __nth); + // if x > nth then our new range for partition is [first, x) + if (__x - __nth > 0) { + __last = __x; + } + // if x < nth then our new range for partition is [x, last) + else if (__x - __nth < 0) { + // if *x == *nth then we can start new partition with x+1 + if (!__comp(*__nth, *__x) && !__comp(*__x, *__nth)) { + ++__x; + } else { + iter_swap(__nth, __x); + } + __first = __x; + } + } while (__x != __nth); } //------------------------------------------------------------------------ // fill, fill_n //------------------------------------------------------------------------ template -void -__brick_fill(_RandomAccessIterator __first, _RandomAccessIterator __last, const _Tp& __value, - /* __is_vector = */ std::true_type) noexcept -{ - __unseq_backend::__simd_fill_n(__first, __last - __first, __value); +void __brick_fill(_RandomAccessIterator __first, + _RandomAccessIterator __last, + const _Tp& __value, + /* __is_vector = */ std::true_type) noexcept { + __unseq_backend::__simd_fill_n(__first, __last - __first, __value); } template -void -__brick_fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, - /* __is_vector = */ std::false_type) noexcept -{ - std::fill(__first, __last, __value); +void __brick_fill(_ForwardIterator __first, + _ForwardIterator __last, + const _Tp& __value, + /* __is_vector = */ std::false_type) noexcept { + std::fill(__first, __last, __value); } template -void -__pattern_fill(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) noexcept -{ - __internal::__brick_fill(__first, __last, __value, typename _Tag::__is_vector{}); +void __pattern_fill( + _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) noexcept { + __internal::__brick_fill(__first, __last, __value, typename _Tag::__is_vector{}); } template -_RandomAccessIterator -__pattern_fill(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, const _Tp& __value) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - return __internal::__except_handler( - [&__exec, __first, __last, &__value]() - { - __par_backend::__parallel_for(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [&__value](_RandomAccessIterator __begin, _RandomAccessIterator __end) - { __internal::__brick_fill(__begin, __end, __value, _IsVector{}); }); - return __last; +_RandomAccessIterator __pattern_fill( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + const _Tp& __value) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&__exec, __first, __last, &__value]() { + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [&__value](_RandomAccessIterator __begin, _RandomAccessIterator __end) { + __internal::__brick_fill(__begin, __end, __value, _IsVector{}); }); + return __last; + }); } template _RandomAccessIterator -__brick_fill_n(_RandomAccessIterator __first, _Size __count, const _Tp& __value, - /* __is_vector = */ std::true_type) noexcept -{ - return __unseq_backend::__simd_fill_n(__first, __count, __value); +__brick_fill_n(_RandomAccessIterator __first, + _Size __count, + const _Tp& __value, + /* __is_vector = */ std::true_type) noexcept { + return __unseq_backend::__simd_fill_n(__first, __count, __value); } template -_OutputIterator -__brick_fill_n(_OutputIterator __first, _Size __count, const _Tp& __value, /* __is_vector = */ std::false_type) noexcept -{ - return std::fill_n(__first, __count, __value); +_OutputIterator __brick_fill_n( + _OutputIterator __first, _Size __count, const _Tp& __value, /* __is_vector = */ std::false_type) noexcept { + return std::fill_n(__first, __count, __value); } template _OutputIterator -__pattern_fill_n(_Tag, _ExecutionPolicy&&, _OutputIterator __first, _Size __count, const _Tp& __value) noexcept -{ - return __internal::__brick_fill_n(__first, __count, __value, typename _Tag::__is_vector{}); +__pattern_fill_n(_Tag, _ExecutionPolicy&&, _OutputIterator __first, _Size __count, const _Tp& __value) noexcept { + return __internal::__brick_fill_n(__first, __count, __value, typename _Tag::__is_vector{}); } template -_RandomAccessIterator -__pattern_fill_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _Size __count, const _Tp& __value) -{ - return __internal::__pattern_fill(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, - __value); +_RandomAccessIterator __pattern_fill_n( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _Size __count, + const _Tp& __value) { + return __internal::__pattern_fill(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, __value); } //------------------------------------------------------------------------ // generate, generate_n //------------------------------------------------------------------------ template -void -__brick_generate(_RandomAccessIterator __first, _RandomAccessIterator __last, _Generator __g, - /* is_vector = */ std::true_type) noexcept -{ - __unseq_backend::__simd_generate_n(__first, __last - __first, __g); +void __brick_generate(_RandomAccessIterator __first, + _RandomAccessIterator __last, + _Generator __g, + /* is_vector = */ std::true_type) noexcept { + __unseq_backend::__simd_generate_n(__first, __last - __first, __g); } template -void -__brick_generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __g, - /* is_vector = */ std::false_type) noexcept -{ - std::generate(__first, __last, __g); +void __brick_generate(_ForwardIterator __first, + _ForwardIterator __last, + _Generator __g, + /* is_vector = */ std::false_type) noexcept { + std::generate(__first, __last, __g); } template -void -__pattern_generate(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Generator __g) noexcept -{ - __internal::__brick_generate(__first, __last, __g, typename _Tag::__is_vector{}); +void __pattern_generate( + _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Generator __g) noexcept { + __internal::__brick_generate(__first, __last, __g, typename _Tag::__is_vector{}); } template -_RandomAccessIterator -__pattern_generate(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _Generator __g) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - return __internal::__except_handler( - [&]() - { - __par_backend::__parallel_for(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__g](_RandomAccessIterator __begin, _RandomAccessIterator __end) - { __internal::__brick_generate(__begin, __end, __g, _IsVector{}); }); - return __last; +_RandomAccessIterator __pattern_generate( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Generator __g) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&]() { + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [__g](_RandomAccessIterator __begin, _RandomAccessIterator __end) { + __internal::__brick_generate(__begin, __end, __g, _IsVector{}); }); + return __last; + }); } template -_RandomAccessIterator -__brick_generate_n(_RandomAccessIterator __first, Size __count, _Generator __g, - /* is_vector = */ std::true_type) noexcept -{ - return __unseq_backend::__simd_generate_n(__first, __count, __g); +_RandomAccessIterator __brick_generate_n( + _RandomAccessIterator __first, + Size __count, + _Generator __g, + /* is_vector = */ std::true_type) noexcept { + return __unseq_backend::__simd_generate_n(__first, __count, __g); } template OutputIterator -__brick_generate_n(OutputIterator __first, Size __count, _Generator __g, /* is_vector = */ std::false_type) noexcept -{ - return std::generate_n(__first, __count, __g); +__brick_generate_n(OutputIterator __first, Size __count, _Generator __g, /* is_vector = */ std::false_type) noexcept { + return std::generate_n(__first, __count, __g); } template _OutputIterator -__pattern_generate_n(_Tag, _ExecutionPolicy&&, _OutputIterator __first, _Size __count, _Generator __g) noexcept -{ - return __internal::__brick_generate_n(__first, __count, __g, typename _Tag::__is_vector{}); +__pattern_generate_n(_Tag, _ExecutionPolicy&&, _OutputIterator __first, _Size __count, _Generator __g) noexcept { + return __internal::__brick_generate_n(__first, __count, __g, typename _Tag::__is_vector{}); } template -_RandomAccessIterator -__pattern_generate_n(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _Size __count, _Generator __g) -{ - static_assert(__are_random_access_iterators<_RandomAccessIterator>::value, - "Pattern-brick error. Should be a random access iterator."); - return __internal::__pattern_generate(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, - __g); +_RandomAccessIterator __pattern_generate_n( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _Size __count, + _Generator __g) { + static_assert(__are_random_access_iterators<_RandomAccessIterator>::value, + "Pattern-brick error. Should be a random access iterator."); + return __internal::__pattern_generate(__tag, std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, __g); } //------------------------------------------------------------------------ @@ -2646,53 +2996,56 @@ //------------------------------------------------------------------------ template -_ForwardIterator -__brick_remove_if(_ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred, - /* __is_vector = */ std::false_type) noexcept -{ - return std::remove_if(__first, __last, __pred); +_ForwardIterator __brick_remove_if( + _ForwardIterator __first, + _ForwardIterator __last, + _UnaryPredicate __pred, + /* __is_vector = */ std::false_type) noexcept { + return std::remove_if(__first, __last, __pred); } template -_RandomAccessIterator -__brick_remove_if(_RandomAccessIterator __first, _RandomAccessIterator __last, _UnaryPredicate __pred, - /* __is_vector = */ std::true_type) noexcept -{ +_RandomAccessIterator __brick_remove_if( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _UnaryPredicate __pred, + /* __is_vector = */ std::true_type) noexcept { #if defined(_PSTL_MONOTONIC_PRESENT) - return __unseq_backend::__simd_remove_if(__first, __last - __first, __pred); + return __unseq_backend::__simd_remove_if(__first, __last - __first, __pred); #else - return std::remove_if(__first, __last, __pred); + return std::remove_if(__first, __last, __pred); #endif } template -_ForwardIterator -__pattern_remove_if(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _UnaryPredicate __pred) noexcept -{ - return __internal::__brick_remove_if(__first, __last, __pred, typename _Tag::__is_vector{}); +_ForwardIterator __pattern_remove_if( + _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) noexcept { + return __internal::__brick_remove_if(__first, __last, __pred, typename _Tag::__is_vector{}); } template -_RandomAccessIterator -__pattern_remove_if(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _UnaryPredicate __pred) noexcept -{ - typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; - - if (__first == __last || __first + 1 == __last) - { - // Trivial sequence - use serial algorithm - return __internal::__brick_remove_if(__first, __last, __pred, _IsVector{}); - } - - return __internal::__remove_elements( - __tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [&__pred](bool* __b, bool* __e, _RandomAccessIterator __it) - { - __internal::__brick_walk2( - __b, __e, __it, [&__pred](bool& __x, _ReferenceType __y) { __x = !__pred(__y); }, _IsVector{}); - }); +_RandomAccessIterator __pattern_remove_if( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _UnaryPredicate __pred) noexcept { + typedef typename std::iterator_traits<_RandomAccessIterator>::reference _ReferenceType; + + if (__first == __last || __first + 1 == __last) { + // Trivial sequence - use serial algorithm + return __internal::__brick_remove_if(__first, __last, __pred, _IsVector{}); + } + + return __internal::__remove_elements( + __tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [&__pred](bool* __b, bool* __e, _RandomAccessIterator __it) { + __internal::__brick_walk2( + __b, __e, __it, [&__pred](bool& __x, _ReferenceType __y) { __x = !__pred(__y); }, _IsVector{}); + }); } //------------------------------------------------------------------------ @@ -2700,124 +3053,173 @@ //------------------------------------------------------------------------ template -_OutputIterator -__brick_merge(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _OutputIterator __d_first, _Compare __comp, - /* __is_vector = */ std::false_type) noexcept -{ - return std::merge(__first1, __last1, __first2, __last2, __d_first, __comp); +_OutputIterator __brick_merge( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _OutputIterator __d_first, + _Compare __comp, + /* __is_vector = */ std::false_type) noexcept { + return std::merge(__first1, __last1, __first2, __last2, __d_first, __comp); } template -_RandomAccessIterator3 -__brick_merge(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _RandomAccessIterator3 __d_first, _Compare __comp, - /* __is_vector = */ std::true_type) noexcept -{ - _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); - return std::merge(__first1, __last1, __first2, __last2, __d_first, __comp); -} - -template -_OutputIterator -__pattern_merge(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __d_first, - _Compare __comp) noexcept -{ - return __internal::__brick_merge(__first1, __last1, __first2, __last2, __d_first, __comp, - typename _Tag::__is_vector{}); -} - -template -_RandomAccessIterator3 -__pattern_merge(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, - _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, - _RandomAccessIterator3 __d_first, _Compare __comp) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - __par_backend::__parallel_merge( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __d_first, - __comp, - [](_RandomAccessIterator1 __f1, _RandomAccessIterator1 __l1, _RandomAccessIterator2 __f2, - _RandomAccessIterator2 __l2, _RandomAccessIterator3 __f3, _Compare __comp) - { return __internal::__brick_merge(__f1, __l1, __f2, __l2, __f3, __comp, _IsVector{}); }); - return __d_first + (__last1 - __first1) + (__last2 - __first2); +_OutputIterator __pattern_merge( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _OutputIterator __d_first, + _Compare __comp) noexcept { + return __internal::__brick_merge( + __first1, __last1, __first2, __last2, __d_first, __comp, typename _Tag::__is_vector{}); +} + +template +_RandomAccessIterator3 __pattern_merge( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _RandomAccessIterator3 __d_first, + _Compare __comp) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + __par_backend::__parallel_merge( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + __first2, + __last2, + __d_first, + __comp, + [](_RandomAccessIterator1 __f1, + _RandomAccessIterator1 __l1, + _RandomAccessIterator2 __f2, + _RandomAccessIterator2 __l2, + _RandomAccessIterator3 __f3, + _Compare __comp) { return __internal::__brick_merge(__f1, __l1, __f2, __l2, __f3, __comp, _IsVector{}); }); + return __d_first + (__last1 - __first1) + (__last2 - __first2); } //------------------------------------------------------------------------ // inplace_merge //------------------------------------------------------------------------ template -void -__brick_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last, - _Compare __comp, /* __is_vector = */ std::false_type) noexcept -{ - std::inplace_merge(__first, __middle, __last, __comp); +void __brick_inplace_merge( + _BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Compare __comp, + /* __is_vector = */ std::false_type) noexcept { + std::inplace_merge(__first, __middle, __last, __comp); } template -void -__brick_inplace_merge(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, - _Compare __comp, /* __is_vector = */ std::true_type) noexcept -{ - _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial") - std::inplace_merge(__first, __middle, __last, __comp); +void __brick_inplace_merge( + _RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, + _Compare __comp, + /* __is_vector = */ std::true_type) noexcept { + _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial") + std::inplace_merge(__first, __middle, __last, __comp); } template -void -__pattern_inplace_merge(_Tag, _ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __middle, - _BidirectionalIterator __last, _Compare __comp) noexcept -{ - __internal::__brick_inplace_merge(__first, __middle, __last, __comp, typename _Tag::__is_vector{}); +void __pattern_inplace_merge( + _Tag, + _ExecutionPolicy&&, + _BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Compare __comp) noexcept { + __internal::__brick_inplace_merge(__first, __middle, __last, __comp, typename _Tag::__is_vector{}); } template -void -__pattern_inplace_merge(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; +void __pattern_inplace_merge( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, + _Compare __comp) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + if (__first == __last || __first == __middle || __middle == __last) { + return; + } + typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp; + auto __n = __last - __first; + __par_backend::__buffer<_Tp> __buf(__n); + _Tp* __r = __buf.get(); + __internal::__except_handler([&]() { + auto __move_values = [](_RandomAccessIterator __x, _Tp* __z) { + __internal::__invoke_if_else( + std::is_trivial<_Tp>(), + [&]() { *__z = std::move(*__x); }, + [&]() { ::new (std::addressof(*__z)) _Tp(std::move(*__x)); }); + }; - if (__first == __last || __first == __middle || __middle == __last) - { - return; - } - typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp; - auto __n = __last - __first; - __par_backend::__buffer<_Tp> __buf(__n); - _Tp* __r = __buf.get(); - __internal::__except_handler( - [&]() - { - auto __move_values = [](_RandomAccessIterator __x, _Tp* __z) - { - __internal::__invoke_if_else( - std::is_trivial<_Tp>(), [&]() { *__z = std::move(*__x); }, - [&]() { ::new (std::addressof(*__z)) _Tp(std::move(*__x)); }); - }; - - auto __move_sequences = [](_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Tp* __first2) - { return __internal::__brick_uninitialized_move(__first1, __last1, __first2, _IsVector()); }; - - __par_backend::__parallel_merge( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __middle, __last, __r, - __comp, - [__n, __move_values, __move_sequences](_RandomAccessIterator __f1, _RandomAccessIterator __l1, - _RandomAccessIterator __f2, _RandomAccessIterator __l2, - _Tp* __f3, _Compare __comp) - { - (__utils::__serial_move_merge(__n))(__f1, __l1, __f2, __l2, __f3, __comp, __move_values, - __move_values, __move_sequences, __move_sequences); - return __f3 + (__l1 - __f1) + (__l2 - __f2); - }); - __par_backend::__parallel_for(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __r, __r + __n, - [__r, __first](_Tp* __i, _Tp* __j) - { __brick_move_destroy()(__i, __j, __first + (__i - __r), _IsVector{}); }); + auto __move_sequences = [](_RandomAccessIterator __first1, _RandomAccessIterator __last1, _Tp* __first2) { + return __internal::__brick_uninitialized_move(__first1, __last1, __first2, _IsVector()); + }; + + __par_backend::__parallel_merge( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __middle, + __middle, + __last, + __r, + __comp, + [__n, __move_values, __move_sequences]( + _RandomAccessIterator __f1, + _RandomAccessIterator __l1, + _RandomAccessIterator __f2, + _RandomAccessIterator __l2, + _Tp* __f3, + _Compare __comp) { + (__utils::__serial_move_merge(__n))( + __f1, __l1, __f2, __l2, __f3, __comp, __move_values, __move_values, __move_sequences, __move_sequences); + return __f3 + (__l1 - __f1) + (__l2 - __f2); }); + __par_backend::__parallel_for( + __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __r, __r + __n, [__r, __first](_Tp* __i, _Tp* __j) { + __brick_move_destroy()(__i, __j, __first + (__i - __r), _IsVector{}); + }); + }); } //------------------------------------------------------------------------ @@ -2825,289 +3227,333 @@ //------------------------------------------------------------------------ template -bool -__pattern_includes(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp) noexcept -{ - return std::includes(__first1, __last1, __first2, __last2, __comp); -} - -template -bool -__pattern_includes(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, - _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, - _Compare __comp) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - if (__first2 >= __last2) - return true; - - if (__first1 >= __last1 || __comp(*__first2, *__first1) || __comp(*(__last1 - 1), *(__last2 - 1))) - return false; - - __first1 = std::lower_bound(__first1, __last1, *__first2, __comp); - if (__first1 == __last1) - return false; - - if (__last2 - __first2 == 1) - return !__comp(*__first1, *__first2) && !__comp(*__first2, *__first1); - - return __internal::__except_handler( - [&]() - { - return !__internal::__parallel_or( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, - [__first1, __last1, __first2, __last2, &__comp](_RandomAccessIterator2 __i, _RandomAccessIterator2 __j) - { - _PSTL_ASSERT(__j > __i); - //_PSTL_ASSERT(__j - __i > 1); - - //1. moving boundaries to "consume" subsequence of equal elements - auto __is_equal = [&__comp](_RandomAccessIterator2 __a, _RandomAccessIterator2 __b) -> bool - { return !__comp(*__a, *__b) && !__comp(*__b, *__a); }; - - //1.1 left bound, case "aaa[aaaxyz...]" - searching "x" - if (__i > __first2 && __is_equal(__i, __i - 1)) - { - //whole subrange continues to content equal elements - return "no op" - if (__is_equal(__i, __j - 1)) - return false; - - __i = std::upper_bound(__i, __last2, *__i, __comp); - } - - //1.2 right bound, case "[...aaa]aaaxyz" - searching "x" - if (__j < __last2 && __is_equal(__j - 1, __j)) - __j = std::upper_bound(__j, __last2, *__j, __comp); - - //2. testing is __a subsequence of the second range included into the first range - auto __b = std::lower_bound(__first1, __last1, *__i, __comp); - - _PSTL_ASSERT(!__comp(*(__last1 - 1), *__b)); - _PSTL_ASSERT(!__comp(*(__j - 1), *__i)); - return !std::includes(__b, __last1, __i, __j, __comp); - }); +bool __pattern_includes( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _Compare __comp) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + if (__first2 >= __last2) + return true; + + if (__first1 >= __last1 || __comp(*__first2, *__first1) || __comp(*(__last1 - 1), *(__last2 - 1))) + return false; + + __first1 = std::lower_bound(__first1, __last1, *__first2, __comp); + if (__first1 == __last1) + return false; + + if (__last2 - __first2 == 1) + return !__comp(*__first1, *__first2) && !__comp(*__first2, *__first1); + + return __internal::__except_handler([&]() { + return !__internal::__parallel_or( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first2, + __last2, + [__first1, __last1, __first2, __last2, &__comp](_RandomAccessIterator2 __i, _RandomAccessIterator2 __j) { + _PSTL_ASSERT(__j > __i); + //_PSTL_ASSERT(__j - __i > 1); + + // 1. moving boundaries to "consume" subsequence of equal elements + auto __is_equal = [&__comp](_RandomAccessIterator2 __a, _RandomAccessIterator2 __b) -> bool { + return !__comp(*__a, *__b) && !__comp(*__b, *__a); + }; + + // 1.1 left bound, case "aaa[aaaxyz...]" - searching "x" + if (__i > __first2 && __is_equal(__i, __i - 1)) { + // whole subrange continues to content equal elements - return "no op" + if (__is_equal(__i, __j - 1)) + return false; + + __i = std::upper_bound(__i, __last2, *__i, __comp); + } + + // 1.2 right bound, case "[...aaa]aaaxyz" - searching "x" + if (__j < __last2 && __is_equal(__j - 1, __j)) + __j = std::upper_bound(__j, __last2, *__j, __comp); + + // 2. testing is __a subsequence of the second range included into the first range + auto __b = std::lower_bound(__first1, __last1, *__i, __comp); + + _PSTL_ASSERT(!__comp(*(__last1 - 1), *__b)); + _PSTL_ASSERT(!__comp(*(__j - 1), *__i)); + return !std::includes(__b, __last1, __i, __j, __comp); }); + }); } constexpr auto __set_algo_cut_off = 1000; -template -_OutputIterator -__parallel_set_op(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, - _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, - _OutputIterator __result, _Compare __comp, _SizeFunction __size_func, _SetOP __set_op) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType; - typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp; - - struct _SetRange - { - _DifferenceType __pos, __len, __buf_pos; - bool - empty() const - { - return __len == 0; - } - }; - - const _DifferenceType __n1 = __last1 - __first1; - const _DifferenceType __n2 = __last2 - __first2; - - __par_backend::__buffer<_Tp> __buf(__size_func(__n1, __n2)); - - return __internal::__except_handler( - [&__exec, __n1, __first1, __last1, __first2, __last2, __result, __comp, __size_func, __set_op, &__buf]() - { - auto __buffer = __buf.get(); - _DifferenceType __m{}; - auto __scan = [=](_DifferenceType, _DifferenceType, const _SetRange& __s) { // Scan - if (!__s.empty()) - __brick_move_destroy()(__buffer + __s.__buf_pos, __buffer + (__s.__buf_pos + __s.__len), - __result + __s.__pos, _IsVector{}); - }; - __par_backend::__parallel_strict_scan( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __n1, _SetRange{0, 0, 0}, //-1, 0}, - [=](_DifferenceType __i, _DifferenceType __len) { // Reduce - //[__b; __e) - a subrange of the first sequence, to reduce - _ForwardIterator1 __b = __first1 + __i, __e = __first1 + (__i + __len); - - //try searching for the first element which not equal to *__b - if (__b != __first1) - __b = std::upper_bound(__b, __last1, *__b, __comp); - - //try searching for the first element which not equal to *__e - if (__e != __last1) - __e = std::upper_bound(__e, __last1, *__e, __comp); - - //check is [__b; __e) empty - if (__e - __b < 1) - { - _ForwardIterator2 __bb = __last2; - if (__b != __last1) - __bb = std::lower_bound(__first2, __last2, *__b, __comp); - - const _DifferenceType __buf_pos = __size_func((__b - __first1), (__bb - __first2)); - return _SetRange{0, 0, __buf_pos}; - } - - //try searching for "corresponding" subrange [__bb; __ee) in the second sequence - _ForwardIterator2 __bb = __first2; - if (__b != __first1) - __bb = std::lower_bound(__first2, __last2, *__b, __comp); - - _ForwardIterator2 __ee = __last2; - if (__e != __last1) - __ee = std::lower_bound(__bb, __last2, *__e, __comp); - - const _DifferenceType __buf_pos = __size_func((__b - __first1), (__bb - __first2)); - auto __buffer_b = __buffer + __buf_pos; - auto __res = __set_op(__b, __e, __bb, __ee, __buffer_b, __comp); - - return _SetRange{0, __res - __buffer_b, __buf_pos}; - }, - [](const _SetRange& __a, const _SetRange& __b) { // Combine - if (__b.__buf_pos > __a.__buf_pos || ((__b.__buf_pos == __a.__buf_pos) && !__b.empty())) - return _SetRange{__a.__pos + __a.__len + __b.__pos, __b.__len, __b.__buf_pos}; - return _SetRange{__b.__pos + __b.__len + __a.__pos, __a.__len, __a.__buf_pos}; - }, - __scan, // Scan - [&__m, &__scan](const _SetRange& __total) { // Apex - //final scan - __scan(0, 0, __total); - __m = __total.__pos + __total.__len; - }); - return __result + __m; - }); -} - -//a shared parallel pattern for '__pattern_set_union' and '__pattern_set_symmetric_difference' -template -_OutputIterator -__parallel_set_union_op(_Tag __tag, _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp, _SetUnionOp __set_union_op) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType; - - const auto __n1 = __last1 - __first1; - const auto __n2 = __last2 - __first2; - - auto copy_range1 = [](_ForwardIterator1 __begin, _ForwardIterator1 __end, _OutputIterator __res) - { return __internal::__brick_copy(__begin, __end, __res, typename _Tag::__is_vector{}); }; - auto copy_range2 = [](_ForwardIterator2 __begin, _ForwardIterator2 __end, _OutputIterator __res) - { return __internal::__brick_copy(__begin, __end, __res, typename _Tag::__is_vector{}); }; - - // {1} {}: parallel copying just first sequence - if (__n2 == 0) - return __internal::__pattern_walk2_brick(__tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - __result, copy_range1); - - // {} {2}: parallel copying justmake second sequence - if (__n1 == 0) - return __internal::__pattern_walk2_brick(__tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, - __result, copy_range2); - - // testing whether the sequences are intersected - _ForwardIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp); - - if (__left_bound_seq_1 == __last1) - { - //{1} < {2}: seq2 is wholly greater than seq1, so, do parallel copying seq1 and seq2 - __par_backend::__parallel_invoke( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), - [=] - { - __internal::__pattern_walk2_brick(__tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - __result, copy_range1); - }, - [=] - { - __internal::__pattern_walk2_brick(__tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, - __result + __n1, copy_range2); - }); - return __result + __n1 + __n2; - } - - // testing whether the sequences are intersected - _ForwardIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp); - - if (__left_bound_seq_2 == __last2) - { - //{2} < {1}: seq2 is wholly greater than seq1, so, do parallel copying seq1 and seq2 - __par_backend::__parallel_invoke( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), - [=] - { - __internal::__pattern_walk2_brick(__tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, - __result, copy_range2); +template +_OutputIterator __parallel_set_op( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _OutputIterator __result, + _Compare __comp, + _SizeFunction __size_func, + _SetOP __set_op) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType; + typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp; + + struct _SetRange { + _DifferenceType __pos, __len, __buf_pos; + bool empty() const { return __len == 0; } + }; + + const _DifferenceType __n1 = __last1 - __first1; + const _DifferenceType __n2 = __last2 - __first2; + + __par_backend::__buffer<_Tp> __buf(__size_func(__n1, __n2)); + + return __internal::__except_handler( + [&__exec, __n1, __first1, __last1, __first2, __last2, __result, __comp, __size_func, __set_op, &__buf]() { + auto __buffer = __buf.get(); + _DifferenceType __m{}; + auto __scan = [=](_DifferenceType, _DifferenceType, const _SetRange& __s) { // Scan + if (!__s.empty()) + __brick_move_destroy()( + __buffer + __s.__buf_pos, __buffer + (__s.__buf_pos + __s.__len), __result + __s.__pos, _IsVector{}); + }; + __par_backend::__parallel_strict_scan( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __n1, + _SetRange{0, 0, 0}, //-1, 0}, + [=](_DifferenceType __i, _DifferenceType __len) { // Reduce + //[__b; __e) - a subrange of the first sequence, to reduce + _ForwardIterator1 __b = __first1 + __i, __e = __first1 + (__i + __len); + + // try searching for the first element which not equal to *__b + if (__b != __first1) + __b = std::upper_bound(__b, __last1, *__b, __comp); + + // try searching for the first element which not equal to *__e + if (__e != __last1) + __e = std::upper_bound(__e, __last1, *__e, __comp); + + // check is [__b; __e) empty + if (__e - __b < 1) { + _ForwardIterator2 __bb = __last2; + if (__b != __last1) + __bb = std::lower_bound(__first2, __last2, *__b, __comp); + + const _DifferenceType __buf_pos = __size_func((__b - __first1), (__bb - __first2)); + return _SetRange{0, 0, __buf_pos}; + } + + // try searching for "corresponding" subrange [__bb; __ee) in the second sequence + _ForwardIterator2 __bb = __first2; + if (__b != __first1) + __bb = std::lower_bound(__first2, __last2, *__b, __comp); + + _ForwardIterator2 __ee = __last2; + if (__e != __last1) + __ee = std::lower_bound(__bb, __last2, *__e, __comp); + + const _DifferenceType __buf_pos = __size_func((__b - __first1), (__bb - __first2)); + auto __buffer_b = __buffer + __buf_pos; + auto __res = __set_op(__b, __e, __bb, __ee, __buffer_b, __comp); + + return _SetRange{0, __res - __buffer_b, __buf_pos}; }, - [=] - { - __internal::__pattern_walk2_brick(__tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - __result + __n2, copy_range1); - }); - return __result + __n1 + __n2; - } - - const auto __m1 = __left_bound_seq_1 - __first1; - if (__m1 > __set_algo_cut_off) - { - auto __res_or = __result; - __result += __m1; //we know proper offset due to [first1; left_bound_seq_1) < [first2; last2) - __par_backend::__parallel_invoke( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), - //do parallel copying of [first1; left_bound_seq_1) - [=] - { - __internal::__pattern_walk2_brick(__tag, std::forward<_ExecutionPolicy>(__exec), __first1, - __left_bound_seq_1, __res_or, copy_range1); + [](const _SetRange& __a, const _SetRange& __b) { // Combine + if (__b.__buf_pos > __a.__buf_pos || ((__b.__buf_pos == __a.__buf_pos) && !__b.empty())) + return _SetRange{__a.__pos + __a.__len + __b.__pos, __b.__len, __b.__buf_pos}; + return _SetRange{__b.__pos + __b.__len + __a.__pos, __a.__len, __a.__buf_pos}; }, - [=, &__result] - { - __result = __internal::__parallel_set_op( - __tag, std::forward<_ExecutionPolicy>(__exec), __left_bound_seq_1, __last1, __first2, __last2, - __result, __comp, [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, - __set_union_op); + __scan, // Scan + [&__m, &__scan](const _SetRange& __total) { // Apex + // final scan + __scan(0, 0, __total); + __m = __total.__pos + __total.__len; }); - return __result; - } - - const auto __m2 = __left_bound_seq_2 - __first2; - _PSTL_ASSERT(__m1 == 0 || __m2 == 0); - if (__m2 > __set_algo_cut_off) - { - auto __res_or = __result; - __result += __m2; //we know proper offset due to [first2; left_bound_seq_2) < [first1; last1) - __par_backend::__parallel_invoke( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), - //do parallel copying of [first2; left_bound_seq_2) - [=] - { - __internal::__pattern_walk2_brick(__tag, std::forward<_ExecutionPolicy>(__exec), __first2, - __left_bound_seq_2, __res_or, copy_range2); - }, - [=, &__result] - { - __result = __internal::__parallel_set_op( - __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __left_bound_seq_2, __last2, - __result, __comp, [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, - __set_union_op); - }); - return __result; - } - - return __internal::__parallel_set_op( - __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, - [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, __set_union_op); + return __result + __m; + }); +} + +// a shared parallel pattern for '__pattern_set_union' and '__pattern_set_symmetric_difference' +template +_OutputIterator __parallel_set_union_op( + _Tag __tag, + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _OutputIterator __result, + _Compare __comp, + _SetUnionOp __set_union_op) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType; + + const auto __n1 = __last1 - __first1; + const auto __n2 = __last2 - __first2; + + auto copy_range1 = [](_ForwardIterator1 __begin, _ForwardIterator1 __end, _OutputIterator __res) { + return __internal::__brick_copy(__begin, __end, __res, typename _Tag::__is_vector{}); + }; + auto copy_range2 = [](_ForwardIterator2 __begin, _ForwardIterator2 __end, _OutputIterator __res) { + return __internal::__brick_copy(__begin, __end, __res, typename _Tag::__is_vector{}); + }; + + // {1} {}: parallel copying just first sequence + if (__n2 == 0) + return __internal::__pattern_walk2_brick( + __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, copy_range1); + + // {} {2}: parallel copying justmake second sequence + if (__n1 == 0) + return __internal::__pattern_walk2_brick( + __tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result, copy_range2); + + // testing whether the sequences are intersected + _ForwardIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp); + + if (__left_bound_seq_1 == __last1) { + //{1} < {2}: seq2 is wholly greater than seq1, so, do parallel copying seq1 and seq2 + __par_backend::__parallel_invoke( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + [=] { + __internal::__pattern_walk2_brick( + __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, copy_range1); + }, + [=] { + __internal::__pattern_walk2_brick( + __tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result + __n1, copy_range2); + }); + return __result + __n1 + __n2; + } + + // testing whether the sequences are intersected + _ForwardIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp); + + if (__left_bound_seq_2 == __last2) { + //{2} < {1}: seq2 is wholly greater than seq1, so, do parallel copying seq1 and seq2 + __par_backend::__parallel_invoke( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + [=] { + __internal::__pattern_walk2_brick( + __tag, std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result, copy_range2); + }, + [=] { + __internal::__pattern_walk2_brick( + __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result + __n2, copy_range1); + }); + return __result + __n1 + __n2; + } + + const auto __m1 = __left_bound_seq_1 - __first1; + if (__m1 > __set_algo_cut_off) { + auto __res_or = __result; + __result += __m1; // we know proper offset due to [first1; left_bound_seq_1) < [first2; last2) + __par_backend::__parallel_invoke( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + // do parallel copying of [first1; left_bound_seq_1) + [=] { + __internal::__pattern_walk2_brick( + __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __left_bound_seq_1, __res_or, copy_range1); + }, + [=, &__result] { + __result = __internal::__parallel_set_op( + __tag, + std::forward<_ExecutionPolicy>(__exec), + __left_bound_seq_1, + __last1, + __first2, + __last2, + __result, + __comp, + [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, + __set_union_op); + }); + return __result; + } + + const auto __m2 = __left_bound_seq_2 - __first2; + _PSTL_ASSERT(__m1 == 0 || __m2 == 0); + if (__m2 > __set_algo_cut_off) { + auto __res_or = __result; + __result += __m2; // we know proper offset due to [first2; left_bound_seq_2) < [first1; last1) + __par_backend::__parallel_invoke( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + // do parallel copying of [first2; left_bound_seq_2) + [=] { + __internal::__pattern_walk2_brick( + __tag, std::forward<_ExecutionPolicy>(__exec), __first2, __left_bound_seq_2, __res_or, copy_range2); + }, + [=, &__result] { + __result = __internal::__parallel_set_op( + __tag, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + __left_bound_seq_2, + __last2, + __result, + __comp, + [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, + __set_union_op); + }); + return __result; + } + + return __internal::__parallel_set_op( + __tag, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + __first2, + __last2, + __result, + __comp, + [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, + __set_union_op); } //------------------------------------------------------------------------ @@ -3115,70 +3561,98 @@ //------------------------------------------------------------------------ template -_OutputIterator -__brick_set_union(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp, - /*__is_vector=*/std::false_type) noexcept -{ - return std::set_union(__first1, __last1, __first2, __last2, __result, __comp); +_OutputIterator __brick_set_union( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _OutputIterator __result, + _Compare __comp, + /*__is_vector=*/std::false_type) noexcept { + return std::set_union(__first1, __last1, __first2, __last2, __result, __comp); } template -struct __BrickCopyConstruct -{ - template - _OutputIterator - operator()(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result) - { - return __brick_uninitialized_copy(__first, __last, __result, _IsVector()); - } +struct __BrickCopyConstruct { + template + _OutputIterator operator()(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result) { + return __brick_uninitialized_copy(__first, __last, __result, _IsVector()); + } }; template -_OutputIterator -__brick_set_union(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _OutputIterator __result, _Compare __comp, - /*__is_vector=*/std::true_type) noexcept -{ - _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); - return std::set_union(__first1, __last1, __first2, __last2, __result, __comp); -} - -template -_OutputIterator -__pattern_set_union(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp) noexcept -{ - return __internal::__brick_set_union(__first1, __last1, __first2, __last2, __result, __comp, - typename _Tag::__is_vector{}); -} +_OutputIterator __pattern_set_union( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _OutputIterator __result, + _Compare __comp) noexcept { + return __internal::__brick_set_union( + __first1, __last1, __first2, __last2, __result, __comp, typename _Tag::__is_vector{}); +} + +template +_OutputIterator __pattern_set_union( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _OutputIterator __result, + _Compare __comp) { + const auto __n1 = __last1 - __first1; + const auto __n2 = __last2 - __first2; + + // use serial algorithm + if (__n1 + __n2 <= __set_algo_cut_off) + return std::set_union(__first1, __last1, __first2, __last2, __result, __comp); -template -_OutputIterator -__pattern_set_union(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, - _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, - _OutputIterator __result, _Compare __comp) -{ - - const auto __n1 = __last1 - __first1; - const auto __n2 = __last2 - __first2; - - // use serial algorithm - if (__n1 + __n2 <= __set_algo_cut_off) - return std::set_union(__first1, __last1, __first2, __last2, __result, __comp); - - typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp; - return __parallel_set_union_op( - __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, - [](_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _Tp* __result, _Compare __comp) - { - return __pstl::__utils::__set_union_construct(__first1, __last1, __first2, __last2, __result, __comp, - __BrickCopyConstruct<_IsVector>()); - }); + typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp; + return __parallel_set_union_op( + __tag, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + __first2, + __last2, + __result, + __comp, + [](_RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _Tp* __result, + _Compare __comp) { + return __pstl::__utils::__set_union_construct( + __first1, __last1, __first2, __last2, __result, __comp, __BrickCopyConstruct<_IsVector>()); + }); } //------------------------------------------------------------------------ @@ -3186,96 +3660,135 @@ //------------------------------------------------------------------------ template -_OutputIterator -__brick_set_intersection(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp, - /*__is_vector=*/std::false_type) noexcept -{ - return std::set_intersection(__first1, __last1, __first2, __last2, __result, __comp); +_OutputIterator __brick_set_intersection( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _OutputIterator __result, + _Compare __comp, + /*__is_vector=*/std::false_type) noexcept { + return std::set_intersection(__first1, __last1, __first2, __last2, __result, __comp); } template -_RandomAccessIterator3 -__brick_set_intersection(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, - _RandomAccessIterator3 __result, _Compare __comp, - /*__is_vector=*/std::true_type) noexcept -{ - _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); - return std::set_intersection(__first1, __last1, __first2, __last2, __result, __comp); -} - -template -_OutputIterator -__pattern_set_intersection(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp) noexcept -{ - return __internal::__brick_set_intersection(__first1, __last1, __first2, __last2, __result, __comp, - typename _Tag::__is_vector{}); -} - -template -_RandomAccessIterator3 -__pattern_set_intersection(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, - _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _RandomAccessIterator3 __result, _Compare __comp) -{ - typedef typename std::iterator_traits<_RandomAccessIterator3>::value_type _Tp; - typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; - - const auto __n1 = __last1 - __first1; - const auto __n2 = __last2 - __first2; - - // intersection is empty - if (__n1 == 0 || __n2 == 0) - return __result; - - // testing whether the sequences are intersected - _RandomAccessIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp); - //{1} < {2}: seq 2 is wholly greater than seq 1, so, the intersection is empty - if (__left_bound_seq_1 == __last1) - return __result; - - // testing whether the sequences are intersected - _RandomAccessIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp); - //{2} < {1}: seq 1 is wholly greater than seq 2, so, the intersection is empty - if (__left_bound_seq_2 == __last2) - return __result; - - const auto __m1 = __last1 - __left_bound_seq_1 + __n2; - if (__m1 > __set_algo_cut_off) - { - //we know proper offset due to [first1; left_bound_seq_1) < [first2; last2) - return __internal::__parallel_set_op( - __tag, std::forward<_ExecutionPolicy>(__exec), __left_bound_seq_1, __last1, __first2, __last2, __result, - __comp, [](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); }, - [](_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _Tp* __result, _Compare __comp) { - return __pstl::__utils::__set_intersection_construct(__first1, __last1, __first2, __last2, __result, - __comp); - }); - } - - const auto __m2 = __last2 - __left_bound_seq_2 + __n1; - if (__m2 > __set_algo_cut_off) - { - //we know proper offset due to [first2; left_bound_seq_2) < [first1; last1) - __result = __internal::__parallel_set_op( - __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __left_bound_seq_2, __last2, __result, - __comp, [](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); }, - [](_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _Tp* __result, _Compare __comp) { - return __pstl::__utils::__set_intersection_construct(__first2, __last2, __first1, __last1, __result, - __comp); - }); - return __result; - } +_OutputIterator __pattern_set_intersection( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _OutputIterator __result, + _Compare __comp) noexcept { + return __internal::__brick_set_intersection( + __first1, __last1, __first2, __last2, __result, __comp, typename _Tag::__is_vector{}); +} + +template +_RandomAccessIterator3 __pattern_set_intersection( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _RandomAccessIterator3 __result, + _Compare __comp) { + typedef typename std::iterator_traits<_RandomAccessIterator3>::value_type _Tp; + typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; + + const auto __n1 = __last1 - __first1; + const auto __n2 = __last2 - __first2; + + // intersection is empty + if (__n1 == 0 || __n2 == 0) + return __result; + + // testing whether the sequences are intersected + _RandomAccessIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp); + //{1} < {2}: seq 2 is wholly greater than seq 1, so, the intersection is empty + if (__left_bound_seq_1 == __last1) + return __result; + + // testing whether the sequences are intersected + _RandomAccessIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp); + //{2} < {1}: seq 1 is wholly greater than seq 2, so, the intersection is empty + if (__left_bound_seq_2 == __last2) + return __result; + + const auto __m1 = __last1 - __left_bound_seq_1 + __n2; + if (__m1 > __set_algo_cut_off) { + // we know proper offset due to [first1; left_bound_seq_1) < [first2; last2) + return __internal::__parallel_set_op( + __tag, + std::forward<_ExecutionPolicy>(__exec), + __left_bound_seq_1, + __last1, + __first2, + __last2, + __result, + __comp, + [](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); }, + [](_RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _Tp* __result, + _Compare __comp) { + return __pstl::__utils::__set_intersection_construct(__first1, __last1, __first2, __last2, __result, __comp); + }); + } + + const auto __m2 = __last2 - __left_bound_seq_2 + __n1; + if (__m2 > __set_algo_cut_off) { + // we know proper offset due to [first2; left_bound_seq_2) < [first1; last1) + __result = __internal::__parallel_set_op( + __tag, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + __left_bound_seq_2, + __last2, + __result, + __comp, + [](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); }, + [](_RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _Tp* __result, + _Compare __comp) { + return __pstl::__utils::__set_intersection_construct(__first2, __last2, __first1, __last1, __result, __comp); + }); + return __result; + } - // [left_bound_seq_1; last1) and [left_bound_seq_2; last2) - use serial algorithm - return std::set_intersection(__left_bound_seq_1, __last1, __left_bound_seq_2, __last2, __result, __comp); + // [left_bound_seq_1; last1) and [left_bound_seq_2; last2) - use serial algorithm + return std::set_intersection(__left_bound_seq_1, __last1, __left_bound_seq_2, __last2, __result, __comp); } //------------------------------------------------------------------------ @@ -3283,90 +3796,137 @@ //------------------------------------------------------------------------ template -_OutputIterator -__brick_set_difference(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp, - /*__is_vector=*/std::false_type) noexcept -{ - return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp); +_OutputIterator __brick_set_difference( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _OutputIterator __result, + _Compare __comp, + /*__is_vector=*/std::false_type) noexcept { + return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp); } template -_RandomAccessIterator3 -__brick_set_difference(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _RandomAccessIterator3 __result, _Compare __comp, - /*__is_vector=*/std::true_type) noexcept -{ - _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); - return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp); -} - -template -_OutputIterator -__pattern_set_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp) noexcept -{ - return __internal::__brick_set_difference(__first1, __last1, __first2, __last2, __result, __comp, - typename _Tag::__is_vector{}); -} - -template -_RandomAccessIterator3 -__pattern_set_difference(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, - _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _RandomAccessIterator3 __result, _Compare __comp) -{ - typedef typename std::iterator_traits<_RandomAccessIterator3>::value_type _Tp; - typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; - - const auto __n1 = __last1 - __first1; - const auto __n2 = __last2 - __first2; - - // {} \ {2}: the difference is empty - if (__n1 == 0) - return __result; - - // {1} \ {}: parallel copying just first sequence - if (__n2 == 0) - return __internal::__pattern_walk2_brick( - __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, - [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) - { return __internal::__brick_copy(__begin, __end, __res, _IsVector{}); }); - - // testing whether the sequences are intersected - _RandomAccessIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp); - //{1} < {2}: seq 2 is wholly greater than seq 1, so, parallel copying just first sequence - if (__left_bound_seq_1 == __last1) - return __internal::__pattern_walk2_brick( - __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, - [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) - { return __internal::__brick_copy(__begin, __end, __res, _IsVector{}); }); - - // testing whether the sequences are intersected - _RandomAccessIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp); - //{2} < {1}: seq 1 is wholly greater than seq 2, so, parallel copying just first sequence - if (__left_bound_seq_2 == __last2) - return __internal::__pattern_walk2_brick( - __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result, - [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) - { return __internal::__brick_copy(__begin, __end, __res, _IsVector{}); }); - - if (__n1 + __n2 > __set_algo_cut_off) - return __parallel_set_op( - __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, - [](_DifferenceType __n, _DifferenceType) { return __n; }, - [](_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _Tp* __result, _Compare __comp) - { - return __pstl::__utils::__set_difference_construct(__first1, __last1, __first2, __last2, __result, - __comp, __BrickCopyConstruct<_IsVector>()); - }); +_OutputIterator __pattern_set_difference( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _OutputIterator __result, + _Compare __comp) noexcept { + return __internal::__brick_set_difference( + __first1, __last1, __first2, __last2, __result, __comp, typename _Tag::__is_vector{}); +} + +template +_RandomAccessIterator3 __pattern_set_difference( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _RandomAccessIterator3 __result, + _Compare __comp) { + typedef typename std::iterator_traits<_RandomAccessIterator3>::value_type _Tp; + typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; + + const auto __n1 = __last1 - __first1; + const auto __n2 = __last2 - __first2; + + // {} \ {2}: the difference is empty + if (__n1 == 0) + return __result; + + // {1} \ {}: parallel copying just first sequence + if (__n2 == 0) + return __internal::__pattern_walk2_brick( + __tag, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + __result, + [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) { + return __internal::__brick_copy(__begin, __end, __res, _IsVector{}); + }); + + // testing whether the sequences are intersected + _RandomAccessIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp); + //{1} < {2}: seq 2 is wholly greater than seq 1, so, parallel copying just first sequence + if (__left_bound_seq_1 == __last1) + return __internal::__pattern_walk2_brick( + __tag, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + __result, + [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) { + return __internal::__brick_copy(__begin, __end, __res, _IsVector{}); + }); + + // testing whether the sequences are intersected + _RandomAccessIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp); + //{2} < {1}: seq 1 is wholly greater than seq 2, so, parallel copying just first sequence + if (__left_bound_seq_2 == __last2) + return __internal::__pattern_walk2_brick( + __tag, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + __result, + [](_RandomAccessIterator1 __begin, _RandomAccessIterator1 __end, _RandomAccessIterator3 __res) { + return __internal::__brick_copy(__begin, __end, __res, _IsVector{}); + }); + + if (__n1 + __n2 > __set_algo_cut_off) + return __parallel_set_op( + __tag, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + __first2, + __last2, + __result, + __comp, + [](_DifferenceType __n, _DifferenceType) { return __n; }, + [](_RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _Tp* __result, + _Compare __comp) { + return __pstl::__utils::__set_difference_construct( + __first1, __last1, __first2, __last2, __result, __comp, __BrickCopyConstruct<_IsVector>()); + }); - // use serial algorithm - return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp); + // use serial algorithm + return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp); } //------------------------------------------------------------------------ @@ -3374,61 +3934,90 @@ //------------------------------------------------------------------------ template -_OutputIterator -__brick_set_symmetric_difference(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp, - /*__is_vector=*/std::false_type) noexcept -{ - return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp); +_OutputIterator __brick_set_symmetric_difference( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _OutputIterator __result, + _Compare __comp, + /*__is_vector=*/std::false_type) noexcept { + return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp); } template -_RandomAccessIterator3 -__brick_set_symmetric_difference(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, - _RandomAccessIterator3 __result, _Compare __comp, - /*__is_vector=*/std::true_type) noexcept -{ - _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); +_RandomAccessIterator3 __brick_set_symmetric_difference( + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _RandomAccessIterator3 __result, + _Compare __comp, + /*__is_vector=*/std::true_type) noexcept { + _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial"); + return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp); +} + +template +_OutputIterator __pattern_set_symmetric_difference( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _OutputIterator __result, + _Compare __comp) noexcept { + return __internal::__brick_set_symmetric_difference( + __first1, __last1, __first2, __last2, __result, __comp, typename _Tag::__is_vector{}); +} + +template +_RandomAccessIterator3 __pattern_set_symmetric_difference( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _RandomAccessIterator3 __result, + _Compare __comp) { + const auto __n1 = __last1 - __first1; + const auto __n2 = __last2 - __first2; + + // use serial algorithm + if (__n1 + __n2 <= __set_algo_cut_off) return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp); -} -template -_OutputIterator -__pattern_set_symmetric_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, - _Compare __comp) noexcept -{ - return __internal::__brick_set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp, - typename _Tag::__is_vector{}); -} - -template -_RandomAccessIterator3 -__pattern_set_symmetric_difference(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, - _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, - _RandomAccessIterator3 __result, _Compare __comp) -{ - - const auto __n1 = __last1 - __first1; - const auto __n2 = __last2 - __first2; - - // use serial algorithm - if (__n1 + __n2 <= __set_algo_cut_off) - return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp); - - typedef typename std::iterator_traits<_RandomAccessIterator3>::value_type _Tp; - return __internal::__parallel_set_union_op( - __tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, - [](_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _Tp* __result, _Compare __comp) - { - return __pstl::__utils::__set_symmetric_difference_construct(__first1, __last1, __first2, __last2, __result, - __comp, __BrickCopyConstruct<_IsVector>()); - }); + typedef typename std::iterator_traits<_RandomAccessIterator3>::value_type _Tp; + return __internal::__parallel_set_union_op( + __tag, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + __first2, + __last2, + __result, + __comp, + [](_RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _Tp* __result, + _Compare __comp) { + return __pstl::__utils::__set_symmetric_difference_construct( + __first1, __last1, __first2, __last2, __result, __comp, __BrickCopyConstruct<_IsVector>()); + }); } //------------------------------------------------------------------------ @@ -3436,81 +4025,88 @@ //------------------------------------------------------------------------ template -_RandomAccessIterator -__brick_is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - /* __is_vector = */ std::false_type) noexcept -{ - return std::is_heap_until(__first, __last, __comp); +_RandomAccessIterator __brick_is_heap_until( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare __comp, + /* __is_vector = */ std::false_type) noexcept { + return std::is_heap_until(__first, __last, __comp); } template -_RandomAccessIterator -__brick_is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - /* __is_vector = */ std::true_type) noexcept -{ - if (__last - __first < 2) - return __last; - typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType; - return __unseq_backend::__simd_first( - __first, _SizeType(0), __last - __first, - [&__comp](_RandomAccessIterator __it, _SizeType __i) { return __comp(__it[(__i - 1) / 2], __it[__i]); }); +_RandomAccessIterator __brick_is_heap_until( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare __comp, + /* __is_vector = */ std::true_type) noexcept { + if (__last - __first < 2) + return __last; + typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType; + return __unseq_backend::__simd_first( + __first, _SizeType(0), __last - __first, [&__comp](_RandomAccessIterator __it, _SizeType __i) { + return __comp(__it[(__i - 1) / 2], __it[__i]); + }); } template -_RandomAccessIterator -__pattern_is_heap_until(_Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, - _Compare __comp) noexcept -{ - return __internal::__brick_is_heap_until(__first, __last, __comp, typename _Tag::__is_vector{}); +_RandomAccessIterator __pattern_is_heap_until( + _Tag, _ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) noexcept { + return __internal::__brick_is_heap_until(__first, __last, __comp, typename _Tag::__is_vector{}); } template -_RandomAccessIterator -__is_heap_until_local(_RandomAccessIterator __first, _DifferenceType __begin, _DifferenceType __end, _Compare __comp, - /* __is_vector = */ std::false_type) noexcept -{ - _DifferenceType __i = __begin; - for (; __i < __end; ++__i) - { - if (__comp(__first[(__i - 1) / 2], __first[__i])) - { - break; - } +_RandomAccessIterator __is_heap_until_local( + _RandomAccessIterator __first, + _DifferenceType __begin, + _DifferenceType __end, + _Compare __comp, + /* __is_vector = */ std::false_type) noexcept { + _DifferenceType __i = __begin; + for (; __i < __end; ++__i) { + if (__comp(__first[(__i - 1) / 2], __first[__i])) { + break; } - return __first + __i; + } + return __first + __i; } template -_RandomAccessIterator -__is_heap_until_local(_RandomAccessIterator __first, _DifferenceType __begin, _DifferenceType __end, _Compare __comp, - /* __is_vector = */ std::true_type) noexcept -{ - return __unseq_backend::__simd_first( - __first, __begin, __end, - [&__comp](_RandomAccessIterator __it, _DifferenceType __i) { return __comp(__it[(__i - 1) / 2], __it[__i]); }); +_RandomAccessIterator __is_heap_until_local( + _RandomAccessIterator __first, + _DifferenceType __begin, + _DifferenceType __end, + _Compare __comp, + /* __is_vector = */ std::true_type) noexcept { + return __unseq_backend::__simd_first( + __first, __begin, __end, [&__comp](_RandomAccessIterator __it, _DifferenceType __i) { + return __comp(__it[(__i - 1) / 2], __it[__i]); + }); } template -_RandomAccessIterator -__pattern_is_heap_until(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _Compare __comp) noexcept -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; +_RandomAccessIterator __pattern_is_heap_until( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare __comp) noexcept { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + if (__last - __first < 2) + return __last; - if (__last - __first < 2) - return __last; - - return __internal::__except_handler( - [&]() - { - return __parallel_find( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__first, __comp](_RandomAccessIterator __i, _RandomAccessIterator __j) { - return __internal::__is_heap_until_local(__first, __i - __first, __j - __first, __comp, - _IsVector{}); - }, - std::less::difference_type>(), /*is_first=*/true); - }); + return __internal::__except_handler([&]() { + return __parallel_find( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [__first, __comp](_RandomAccessIterator __i, _RandomAccessIterator __j) { + return __internal::__is_heap_until_local(__first, __i - __first, __j - __first, __comp, _IsVector{}); + }, + std::less::difference_type>(), + /*is_first=*/true); + }); } //------------------------------------------------------------------------ @@ -3518,58 +4114,61 @@ //------------------------------------------------------------------------ template -_ForwardIterator -__brick_min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp, - /* __is_vector = */ std::false_type) noexcept -{ - return std::min_element(__first, __last, __comp); +_ForwardIterator __brick_min_element( + _ForwardIterator __first, + _ForwardIterator __last, + _Compare __comp, + /* __is_vector = */ std::false_type) noexcept { + return std::min_element(__first, __last, __comp); } template -_RandomAccessIterator -__brick_min_element(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - /* __is_vector = */ std::true_type) noexcept -{ +_RandomAccessIterator __brick_min_element( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare __comp, + /* __is_vector = */ std::true_type) noexcept { #if defined(_PSTL_UDR_PRESENT) - return __unseq_backend::__simd_min_element(__first, __last - __first, __comp); + return __unseq_backend::__simd_min_element(__first, __last - __first, __comp); #else - return std::min_element(__first, __last, __comp); + return std::min_element(__first, __last, __comp); #endif } template -_ForwardIterator -__pattern_min_element(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _Compare __comp) noexcept -{ - return __internal::__brick_min_element(__first, __last, __comp, typename _Tag::__is_vector{}); +_ForwardIterator __pattern_min_element( + _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) noexcept { + return __internal::__brick_min_element(__first, __last, __comp, typename _Tag::__is_vector{}); } template -_RandomAccessIterator -__pattern_min_element(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _Compare __comp) -{ - if (__first == __last) - return __last; - - using __backend_tag = typename decltype(__tag)::__backend_tag; +_RandomAccessIterator __pattern_min_element( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare __comp) { + if (__first == __last) + return __last; - return __internal::__except_handler( - [&]() - { - return __par_backend::__parallel_reduce( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, __first, - [=](_RandomAccessIterator __begin, _RandomAccessIterator __end, - _RandomAccessIterator __init) -> _RandomAccessIterator - { - const _RandomAccessIterator subresult = - __internal::__brick_min_element(__begin, __end, __comp, _IsVector{}); - return __internal::__cmp_iterators_by_values(__init, subresult, __comp); - }, - [=](_RandomAccessIterator __it1, _RandomAccessIterator __it2) -> _RandomAccessIterator - { return __internal::__cmp_iterators_by_values(__it1, __it2, __comp); }); + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&]() { + return __par_backend::__parallel_reduce( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first + 1, + __last, + __first, + [=](_RandomAccessIterator __begin, _RandomAccessIterator __end, _RandomAccessIterator __init) + -> _RandomAccessIterator { + const _RandomAccessIterator subresult = __internal::__brick_min_element(__begin, __end, __comp, _IsVector{}); + return __internal::__cmp_iterators_by_values(__init, subresult, __comp); + }, + [=](_RandomAccessIterator __it1, _RandomAccessIterator __it2) -> _RandomAccessIterator { + return __internal::__cmp_iterators_by_values(__it1, __it2, __comp); }); + }); } //------------------------------------------------------------------------ @@ -3577,130 +4176,152 @@ //------------------------------------------------------------------------ template -std::pair<_ForwardIterator, _ForwardIterator> -__brick_minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp, - /* __is_vector = */ std::false_type) noexcept -{ - return std::minmax_element(__first, __last, __comp); +std::pair<_ForwardIterator, _ForwardIterator> __brick_minmax_element( + _ForwardIterator __first, + _ForwardIterator __last, + _Compare __comp, + /* __is_vector = */ std::false_type) noexcept { + return std::minmax_element(__first, __last, __comp); } template -std::pair<_RandomAccessIterator, _RandomAccessIterator> -__brick_minmax_element(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp, - /* __is_vector = */ std::true_type) noexcept -{ +std::pair<_RandomAccessIterator, _RandomAccessIterator> __brick_minmax_element( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare __comp, + /* __is_vector = */ std::true_type) noexcept { #if defined(_PSTL_UDR_PRESENT) - return __unseq_backend::__simd_minmax_element(__first, __last - __first, __comp); + return __unseq_backend::__simd_minmax_element(__first, __last - __first, __comp); #else - return std::minmax_element(__first, __last, __comp); + return std::minmax_element(__first, __last, __comp); #endif } template -std::pair<_ForwardIterator, _ForwardIterator> -__pattern_minmax_element(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _Compare __comp) noexcept -{ - return __internal::__brick_minmax_element(__first, __last, __comp, typename _Tag::__is_vector{}); +std::pair<_ForwardIterator, _ForwardIterator> __pattern_minmax_element( + _Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) noexcept { + return __internal::__brick_minmax_element(__first, __last, __comp, typename _Tag::__is_vector{}); } template -std::pair<_RandomAccessIterator, _RandomAccessIterator> -__pattern_minmax_element(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _Compare __comp) -{ - if (__first == __last) - return std::make_pair(__first, __first); - - using __backend_tag = typename decltype(__tag)::__backend_tag; - - return __internal::__except_handler([&]() { - typedef std::pair<_RandomAccessIterator, _RandomAccessIterator> _Result; - - return __par_backend::__parallel_reduce( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, - std::make_pair(__first, __first), - [=](_RandomAccessIterator __begin, _RandomAccessIterator __end, _Result __init) -> _Result - { - const _Result __subresult = __internal::__brick_minmax_element(__begin, __end, __comp, _IsVector{}); - return std::make_pair( - __internal::__cmp_iterators_by_values(__subresult.first, __init.first, __comp), - __internal::__cmp_iterators_by_values(__init.second, __subresult.second, std::not_fn(__comp))); - }, - [=](_Result __p1, _Result __p2) -> _Result - { - return std::make_pair( - __internal::__cmp_iterators_by_values(__p1.first, __p2.first, __comp), - __internal::__cmp_iterators_by_values(__p2.second, __p1.second, std::not_fn(__comp))); - }); - }); +std::pair<_RandomAccessIterator, _RandomAccessIterator> __pattern_minmax_element( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Compare __comp) { + if (__first == __last) + return std::make_pair(__first, __first); + + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&]() { + typedef std::pair<_RandomAccessIterator, _RandomAccessIterator> _Result; + + return __par_backend::__parallel_reduce( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first + 1, + __last, + std::make_pair(__first, __first), + [=](_RandomAccessIterator __begin, _RandomAccessIterator __end, _Result __init) -> _Result { + const _Result __subresult = __internal::__brick_minmax_element(__begin, __end, __comp, _IsVector{}); + return std::make_pair( + __internal::__cmp_iterators_by_values(__subresult.first, __init.first, __comp), + __internal::__cmp_iterators_by_values(__init.second, __subresult.second, std::not_fn(__comp))); + }, + [=](_Result __p1, _Result __p2) -> _Result { + return std::make_pair(__internal::__cmp_iterators_by_values(__p1.first, __p2.first, __comp), + __internal::__cmp_iterators_by_values(__p2.second, __p1.second, std::not_fn(__comp))); + }); + }); } //------------------------------------------------------------------------ // mismatch //------------------------------------------------------------------------ template -std::pair<_ForwardIterator1, _ForwardIterator2> -__mismatch_serial(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _BinaryPredicate __pred) -{ +std::pair<_ForwardIterator1, _ForwardIterator2> __mismatch_serial( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate __pred) { #if defined(_PSTL_CPP14_2RANGE_MISMATCH_EQUAL_PRESENT) - return std::mismatch(__first1, __last1, __first2, __last2, __pred); + return std::mismatch(__first1, __last1, __first2, __last2, __pred); #else - for (; __first1 != __last1 && __first2 != __last2 && __pred(*__first1, *__first2); ++__first1, ++__first2) - { - } - return std::make_pair(__first1, __first2); + for (; __first1 != __last1 && __first2 != __last2 && __pred(*__first1, *__first2); ++__first1, ++__first2) { + } + return std::make_pair(__first1, __first2); #endif } template -std::pair<_ForwardIterator1, _ForwardIterator2> -__brick_mismatch(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _Predicate __pred, /* __is_vector = */ std::false_type) noexcept -{ - return __mismatch_serial(__first1, __last1, __first2, __last2, __pred); +std::pair<_ForwardIterator1, _ForwardIterator2> __brick_mismatch( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _Predicate __pred, + /* __is_vector = */ std::false_type) noexcept { + return __mismatch_serial(__first1, __last1, __first2, __last2, __pred); } template -std::pair<_RandomAccessIterator1, _RandomAccessIterator2> -__brick_mismatch(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, - _RandomAccessIterator2 __last2, _Predicate __pred, /* __is_vector = */ std::true_type) noexcept -{ - auto __n = std::min(__last1 - __first1, __last2 - __first2); - return __unseq_backend::__simd_first(__first1, __n, __first2, std::not_fn(__pred)); +std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __brick_mismatch( + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _Predicate __pred, + /* __is_vector = */ std::true_type) noexcept { + auto __n = std::min(__last1 - __first1, __last2 - __first2); + return __unseq_backend::__simd_first(__first1, __n, __first2, std::not_fn(__pred)); } template -std::pair<_ForwardIterator1, _ForwardIterator2> -__pattern_mismatch(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Predicate __pred) noexcept -{ - return __internal::__brick_mismatch(__first1, __last1, __first2, __last2, __pred, typename _Tag::__is_vector{}); -} - -template __pattern_mismatch( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _Predicate __pred) noexcept { + return __internal::__brick_mismatch(__first1, __last1, __first2, __last2, __pred, typename _Tag::__is_vector{}); +} + +template -std::pair<_RandomAccessIterator1, _RandomAccessIterator2> -__pattern_mismatch(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, - _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, - _Predicate __pred) noexcept -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - return __internal::__except_handler([&]() { - auto __n = std::min(__last1 - __first1, __last2 - __first2); - auto __result = __internal::__parallel_find( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, - [__first1, __first2, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) - { - return __internal::__brick_mismatch(__i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), - __pred, _IsVector{}) - .first; - }, - std::less::difference_type>(), /*is_first=*/true); - return std::make_pair(__result, __first2 + (__result - __first1)); - }); +std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __pattern_mismatch( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _Predicate __pred) noexcept { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&]() { + auto __n = std::min(__last1 - __first1, __last2 - __first2); + auto __result = __internal::__parallel_find( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __first1 + __n, + [__first1, __first2, __pred](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + return __internal::__brick_mismatch( + __i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), __pred, _IsVector{}) + .first; + }, + std::less::difference_type>(), + /*is_first=*/true); + return std::make_pair(__result, __first2 + (__result - __first1)); + }); } //------------------------------------------------------------------------ @@ -3708,107 +4329,111 @@ //------------------------------------------------------------------------ template -bool -__brick_lexicographical_compare(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _Compare __comp, - /* __is_vector = */ std::false_type) noexcept -{ - return std::lexicographical_compare(__first1, __last1, __first2, __last2, __comp); +bool __brick_lexicographical_compare( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _Compare __comp, + /* __is_vector = */ std::false_type) noexcept { + return std::lexicographical_compare(__first1, __last1, __first2, __last2, __comp); } template -bool -__brick_lexicographical_compare(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _Compare __comp, - /* __is_vector = */ std::true_type) noexcept -{ - if (__first2 == __last2) - { // if second sequence is empty - return false; - } - else if (__first1 == __last1) - { // if first sequence is empty - return true; - } - else - { - typedef typename std::iterator_traits<_RandomAccessIterator1>::reference ref_type1; - typedef typename std::iterator_traits<_RandomAccessIterator2>::reference ref_type2; - --__last1; - --__last2; - auto __n = std::min(__last1 - __first1, __last2 - __first2); - std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __result = __unseq_backend::__simd_first( - __first1, __n, __first2, [__comp](const ref_type1 __x, const ref_type2 __y) mutable { - return __comp(__x, __y) || __comp(__y, __x); - }); +bool __brick_lexicographical_compare( + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _Compare __comp, + /* __is_vector = */ std::true_type) noexcept { + if (__first2 == __last2) { // if second sequence is empty + return false; + } else if (__first1 == __last1) { // if first sequence is empty + return true; + } else { + typedef typename std::iterator_traits<_RandomAccessIterator1>::reference ref_type1; + typedef typename std::iterator_traits<_RandomAccessIterator2>::reference ref_type2; + --__last1; + --__last2; + auto __n = std::min(__last1 - __first1, __last2 - __first2); + std::pair<_RandomAccessIterator1, _RandomAccessIterator2> __result = __unseq_backend::__simd_first( + __first1, __n, __first2, [__comp](const ref_type1 __x, const ref_type2 __y) mutable { + return __comp(__x, __y) || __comp(__y, __x); + }); - if (__result.first == __last1 && __result.second != __last2) - { // if first sequence shorter than second - return !__comp(*__result.second, *__result.first); - } - else - { // if second sequence shorter than first or both have the same number of elements - return __comp(*__result.first, *__result.second); - } + if (__result.first == __last1 && __result.second != __last2) { // if first sequence shorter than second + return !__comp(*__result.second, *__result.first); + } else { // if second sequence shorter than first or both have the same number of elements + return __comp(*__result.first, *__result.second); } + } } template -bool -__pattern_lexicographical_compare(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp) noexcept -{ - return __internal::__brick_lexicographical_compare(__first1, __last1, __first2, __last2, __comp, - typename _Tag::__is_vector{}); -} - -template -bool -__pattern_lexicographical_compare(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, - _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, - _Compare __comp) noexcept -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - if (__first2 == __last2) - { // if second sequence is empty - return false; - } - else if (__first1 == __last1) - { // if first sequence is empty - return true; - } - else - { - typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _RefType1; - typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _RefType2; - --__last1; - --__last2; - auto __n = std::min(__last1 - __first1, __last2 - __first2); - auto __result = __internal::__parallel_find( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, - [__first1, __first2, &__comp](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) - { - return __internal::__brick_mismatch( - __i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), - [&__comp](const _RefType1 __x, const _RefType2 __y) - { return !__comp(__x, __y) && !__comp(__y, __x); }, - _IsVector{}) - .first; - }, - std::less::difference_type>(), /*is_first=*/true); - - if (__result == __last1 && __first2 + (__result - __first1) != __last2) - { // if first sequence shorter than second - return !__comp(*(__first2 + (__result - __first1)), *__result); - } - else - { // if second sequence shorter than first or both have the same number of elements - return __comp(*__result, *(__first2 + (__result - __first1))); - } +bool __pattern_lexicographical_compare( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, + _Compare __comp) noexcept { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + if (__first2 == __last2) { // if second sequence is empty + return false; + } else if (__first1 == __last1) { // if first sequence is empty + return true; + } else { + typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _RefType1; + typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _RefType2; + --__last1; + --__last2; + auto __n = std::min(__last1 - __first1, __last2 - __first2); + auto __result = __internal::__parallel_find( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __first1 + __n, + [__first1, __first2, &__comp](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + return __internal::__brick_mismatch( + __i, + __j, + __first2 + (__i - __first1), + __first2 + (__j - __first1), + [&__comp](const _RefType1 __x, const _RefType2 __y) { + return !__comp(__x, __y) && !__comp(__y, __x); + }, + _IsVector{}) + .first; + }, + std::less::difference_type>(), + /*is_first=*/true); + + if (__result == __last1 && __first2 + (__result - __first1) != __last2) { // if first sequence shorter than second + return !__comp(*(__first2 + (__result - __first1)), *__result); + } else { // if second sequence shorter than first or both have the same number of elements + return __comp(*__result, *(__first2 + (__result - __first1))); } + } } } // namespace __internal diff --git a/libcxx/include/pstl/internal/execution_defs.h b/libcxx/include/pstl/internal/execution_defs.h --- a/libcxx/include/pstl/internal/execution_defs.h +++ b/libcxx/include/pstl/internal/execution_defs.h @@ -16,31 +16,20 @@ _PSTL_HIDE_FROM_ABI_PUSH -namespace __pstl -{ -namespace execution -{ -inline namespace v1 -{ +namespace __pstl { +namespace execution { +inline namespace v1 { // 2.4, Sequential execution policy -class sequenced_policy -{ -}; +class sequenced_policy {}; // 2.5, Parallel execution policy -class parallel_policy -{ -}; +class parallel_policy {}; // 2.6, Parallel+Vector execution policy -class parallel_unsequenced_policy -{ -}; +class parallel_unsequenced_policy {}; -class unsequenced_policy -{ -}; +class unsequenced_policy {}; // 2.8, Execution policy objects constexpr sequenced_policy seq{}; @@ -50,26 +39,16 @@ // 2.3, Execution policy type trait template -struct is_execution_policy : std::false_type -{ -}; +struct is_execution_policy : std::false_type {}; template <> -struct is_execution_policy<__pstl::execution::sequenced_policy> : std::true_type -{ -}; +struct is_execution_policy<__pstl::execution::sequenced_policy> : std::true_type {}; template <> -struct is_execution_policy<__pstl::execution::parallel_policy> : std::true_type -{ -}; +struct is_execution_policy<__pstl::execution::parallel_policy> : std::true_type {}; template <> -struct is_execution_policy<__pstl::execution::parallel_unsequenced_policy> : std::true_type -{ -}; +struct is_execution_policy<__pstl::execution::parallel_unsequenced_policy> : std::true_type {}; template <> -struct is_execution_policy<__pstl::execution::unsequenced_policy> : std::true_type -{ -}; +struct is_execution_policy<__pstl::execution::unsequenced_policy> : std::true_type {}; #if defined(_PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT) template @@ -79,8 +58,7 @@ } // namespace v1 } // namespace execution -namespace __internal -{ +namespace __internal { template using __enable_if_execution_policy = typename std::enable_if<__pstl::execution::is_execution_policy::type>::value, diff --git a/libcxx/include/pstl/internal/execution_impl.h b/libcxx/include/pstl/internal/execution_impl.h --- a/libcxx/include/pstl/internal/execution_impl.h +++ b/libcxx/include/pstl/internal/execution_impl.h @@ -13,15 +13,13 @@ #include #include -#include "pstl_config.h" #include "execution_defs.h" +#include "pstl_config.h" _PSTL_HIDE_FROM_ABI_PUSH -namespace __pstl -{ -namespace __internal -{ +namespace __pstl { +namespace __internal { template using __are_iterators_of = std::conjunction< @@ -30,15 +28,9 @@ template using __are_random_access_iterators = __are_iterators_of; -struct __serial_backend_tag -{ -}; -struct __tbb_backend_tag -{ -}; -struct __openmp_backend_tag -{ -}; +struct __serial_backend_tag {}; +struct __tbb_backend_tag {}; +struct __openmp_backend_tag {}; #if defined(_PSTL_PAR_BACKEND_TBB) using __par_backend_tag = __tbb_backend_tag; @@ -47,54 +39,50 @@ #elif defined(_PSTL_PAR_BACKEND_SERIAL) using __par_backend_tag = __serial_backend_tag; #else -# error "A parallel backend must be specified"; +# error "A parallel backend must be specified"; #endif template -struct __serial_tag -{ - using __is_vector = _IsVector; +struct __serial_tag { + using __is_vector = _IsVector; }; template -struct __parallel_tag -{ - using __is_vector = _IsVector; - // backend tag can be change depending on - // TBB availability in the environment - using __backend_tag = __par_backend_tag; +struct __parallel_tag { + using __is_vector = _IsVector; + // backend tag can be change depending on + // TBB availability in the environment + using __backend_tag = __par_backend_tag; }; template -using __tag_type = typename std::conditional<__internal::__are_random_access_iterators<_IteratorTypes...>::value, - __parallel_tag<_IsVector>, __serial_tag<_IsVector>>::type; +using __tag_type = + typename std::conditional<__internal::__are_random_access_iterators<_IteratorTypes...>::value, + __parallel_tag<_IsVector>, + __serial_tag<_IsVector>>::type; template __serial_tag -__select_backend(__pstl::execution::sequenced_policy, _IteratorTypes&&...) -{ - return {}; +__select_backend(__pstl::execution::sequenced_policy, _IteratorTypes&&...) { + return {}; } template __serial_tag<__internal::__are_random_access_iterators<_IteratorTypes...>> -__select_backend(__pstl::execution::unsequenced_policy, _IteratorTypes&&...) -{ - return {}; +__select_backend(__pstl::execution::unsequenced_policy, _IteratorTypes&&...) { + return {}; } template __tag_type -__select_backend(__pstl::execution::parallel_policy, _IteratorTypes&&...) -{ - return {}; +__select_backend(__pstl::execution::parallel_policy, _IteratorTypes&&...) { + return {}; } template __tag_type<__internal::__are_random_access_iterators<_IteratorTypes...>, _IteratorTypes...> -__select_backend(__pstl::execution::parallel_unsequenced_policy, _IteratorTypes&&...) -{ - return {}; +__select_backend(__pstl::execution::parallel_unsequenced_policy, _IteratorTypes&&...) { + return {}; } } // namespace __internal diff --git a/libcxx/include/pstl/internal/glue_algorithm_defs.h b/libcxx/include/pstl/internal/glue_algorithm_defs.h --- a/libcxx/include/pstl/internal/glue_algorithm_defs.h +++ b/libcxx/include/pstl/internal/glue_algorithm_defs.h @@ -18,8 +18,7 @@ _PSTL_HIDE_FROM_ABI_PUSH -namespace std -{ +namespace std { // [alg.any_of] @@ -67,25 +66,39 @@ template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> -find_end(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, - _ForwardIterator2 __s_last, _BinaryPredicate __pred); +find_end(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __s_first, + _ForwardIterator2 __s_last, + _BinaryPredicate __pred); template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> -find_end(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, +find_end(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __s_first, _ForwardIterator2 __s_last); // [alg.find_first_of] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> -find_first_of(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> find_first_of( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __s_first, + _ForwardIterator2 __s_last, + _BinaryPredicate __pred); template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> -find_first_of(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __s_first, _ForwardIterator2 __s_last); +find_first_of(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __s_first, + _ForwardIterator2 __s_last); // [alg.adjacent_find] @@ -113,23 +126,33 @@ template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> -search(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, - _ForwardIterator2 __s_last, _BinaryPredicate __pred); +search(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __s_first, + _ForwardIterator2 __s_last, + _BinaryPredicate __pred); template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> -search(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, +search(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __s_first, _ForwardIterator2 __s_last); template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -search_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count, - const _Tp& __value, _BinaryPredicate __pred); +search_n(_ExecutionPolicy&& __exec, + _ForwardIterator __first, + _ForwardIterator __last, + _Size __count, + const _Tp& __value, + _BinaryPredicate __pred); template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -search_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count, - const _Tp& __value); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> search_n( + _ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value); // [alg.copy] @@ -143,50 +166,76 @@ template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -copy_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 result, +copy_if(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 result, _Predicate __pred); // [alg.swap] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -swap_ranges(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> swap_ranges( + _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2); // [alg.transform] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, +transform(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, _UnaryOperation __op); -template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator __result, _BinaryOperation __op); +transform(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator __result, + _BinaryOperation __op); // [alg.replace] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -replace_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred, +replace_if(_ExecutionPolicy&& __exec, + _ForwardIterator __first, + _ForwardIterator __last, + _UnaryPredicate __pred, const _Tp& __new_value); template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -replace(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, +replace(_ExecutionPolicy&& __exec, + _ForwardIterator __first, + _ForwardIterator __last, + const _Tp& __old_value, const _Tp& __new_value); template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -replace_copy_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _UnaryPredicate __pred, const _Tp& __new_value); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> replace_copy_if( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _UnaryPredicate __pred, + const _Tp& __new_value); template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -replace_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, - const _Tp& __old_value, const _Tp& __new_value); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> replace_copy( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + const _Tp& __old_value, + const _Tp& __new_value); // [alg.fill] @@ -210,13 +259,19 @@ // [alg.remove] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -remove_copy_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _Predicate __pred); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> remove_copy_if( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _Predicate __pred); template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -remove_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, +remove_copy(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, const _Tp& __value); template @@ -239,7 +294,10 @@ template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -unique_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, +unique_copy(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, _BinaryPredicate __pred); template @@ -254,7 +312,9 @@ template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -reverse_copy(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, +reverse_copy(_ExecutionPolicy&& __exec, + _BidirectionalIterator __first, + _BidirectionalIterator __last, _ForwardIterator __d_first); // [alg.rotate] @@ -265,7 +325,10 @@ template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -rotate_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __middle, _ForwardIterator1 __last, +rotate_copy(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __middle, + _ForwardIterator1 __last, _ForwardIterator2 __result); // [alg.partitions] @@ -279,15 +342,21 @@ partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred); template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _BidirectionalIterator> -stable_partition(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, - _UnaryPredicate __pred); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _BidirectionalIterator> stable_partition( + _ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, _UnaryPredicate __pred); -template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> -partition_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, - _ForwardIterator1 __out_true, _ForwardIterator2 __out_false, _UnaryPredicate __pred); +partition_copy(_ExecutionPolicy&& __exec, + _ForwardIterator __first, + _ForwardIterator __last, + _ForwardIterator1 __out_true, + _ForwardIterator2 __out_false, + _UnaryPredicate __pred); // [alg.sort] @@ -313,17 +382,27 @@ template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> -mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _BinaryPredicate __pred); +mismatch(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate __pred); template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> -mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, +mismatch(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _BinaryPredicate __pred); template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> -mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, +mismatch(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2); template @@ -334,7 +413,10 @@ template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, +equal(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _BinaryPredicate __p); template @@ -343,12 +425,19 @@ template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _BinaryPredicate __p); +equal(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate __p); template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, +equal(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2); // [alg.move] @@ -360,25 +449,37 @@ template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __middle, - _RandomAccessIterator __last, _Compare __comp); +partial_sort(_ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, + _Compare __comp); template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __middle, +partial_sort(_ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __middle, _RandomAccessIterator __last); // [partial.sort.copy] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, - _RandomAccessIterator __d_first, _RandomAccessIterator __d_last, _Compare __comp); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> partial_sort_copy( + _ExecutionPolicy&& __exec, + _ForwardIterator __first, + _ForwardIterator __last, + _RandomAccessIterator __d_first, + _RandomAccessIterator __d_last, + _Compare __comp); template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, - _RandomAccessIterator __d_first, _RandomAccessIterator __d_last); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> partial_sort_copy( + _ExecutionPolicy&& __exec, + _ForwardIterator __first, + _ForwardIterator __last, + _RandomAccessIterator __d_first, + _RandomAccessIterator __d_last); // [is.sorted] template @@ -401,100 +502,176 @@ template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __nth, - _RandomAccessIterator __last, _Compare __comp); +nth_element(_ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __nth, + _RandomAccessIterator __last, + _Compare __comp); template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __nth, +nth_element(_ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __nth, _RandomAccessIterator __last); // [alg.merge] -template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -merge(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _ForwardIterator __d_first, _Compare __comp); +merge(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __d_first, + _Compare __comp); template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -merge(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _ForwardIterator __d_first); +merge(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __d_first); template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -inplace_merge(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __middle, - _BidirectionalIterator __last, _Compare __comp); +inplace_merge(_ExecutionPolicy&& __exec, + _BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Compare __comp); template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -inplace_merge(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __middle, +inplace_merge(_ExecutionPolicy&& __exec, + _BidirectionalIterator __first, + _BidirectionalIterator __middle, _BidirectionalIterator __last); // [includes] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _Compare __comp); +includes(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _Compare __comp); template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, +includes(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, _ForwardIterator2 __last2); // [set.union] -template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp); +set_union(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __result, + _Compare __comp); template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _ForwardIterator __result); +set_union(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __result); // [set.intersection] -template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_intersection( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __result, + _Compare __comp); template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_intersection( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __result); // [set.difference] -template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_difference( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __result, + _Compare __comp); template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_difference( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __result); // [set.symmetric.difference] -template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -set_symmetric_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator result, - _Compare __comp); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_symmetric_difference( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator result, + _Compare __comp); template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -set_symmetric_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_symmetric_difference( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __result); // [is.heap] template @@ -542,14 +719,21 @@ // [alg.lex.comparison] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -lexicographical_compare(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> lexicographical_compare( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _Compare __comp); template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -lexicographical_compare(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> lexicographical_compare( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2); } // namespace std diff --git a/libcxx/include/pstl/internal/glue_algorithm_impl.h b/libcxx/include/pstl/internal/glue_algorithm_impl.h --- a/libcxx/include/pstl/internal/glue_algorithm_impl.h +++ b/libcxx/include/pstl/internal/glue_algorithm_impl.h @@ -14,157 +14,160 @@ #include "pstl_config.h" -#include "execution_defs.h" -#include "utils.h" #include "algorithm_fwd.h" +#include "execution_defs.h" #include "numeric_fwd.h" /* count and count_if use __pattern_transform_reduce */ +#include "utils.h" #include "execution_impl.h" _PSTL_HIDE_FROM_ABI_PUSH -namespace std -{ +namespace std { // [alg.any_of] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -any_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +any_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_any_of(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - __pred); + return __pstl::__internal::__pattern_any_of( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); } // [alg.all_of] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -all_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) -{ - return !std::any_of(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::not_fn(__pred)); +all_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) { + return !std::any_of(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::not_fn(__pred)); } // [alg.none_of] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -none_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) -{ - return !std::any_of(std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); +none_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + return !std::any_of(std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); } // [alg.foreach] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -for_each(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Function __f) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +for_each(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Function __f) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - __pstl::__internal::__pattern_walk1(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __f); + __pstl::__internal::__pattern_walk1(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __f); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -for_each_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, _Function __f) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +for_each_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, _Function __f) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_walk1_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, - __f); + return __pstl::__internal::__pattern_walk1_n( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, __f); } // [alg.find] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -find_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +find_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_find_if(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __pred); + return __pstl::__internal::__pattern_find_if( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -find_if_not(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) -{ - return std::find_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::not_fn(__pred)); +find_if_not(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + return std::find_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::not_fn(__pred)); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) -{ - return std::find_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, - __pstl::__internal::__equal_value<_Tp>(__value)); +find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + return std::find_if( + std::forward<_ExecutionPolicy>(__exec), __first, __last, __pstl::__internal::__equal_value<_Tp>(__value)); } // [alg.find.end] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> -find_end(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, - _ForwardIterator2 __s_last, _BinaryPredicate __pred) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first); +find_end(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __s_first, + _ForwardIterator2 __s_last, + _BinaryPredicate __pred) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first); - return __pstl::__internal::__pattern_find_end(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __s_first, __s_last, __pred); + return __pstl::__internal::__pattern_find_end( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> -find_end(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, - _ForwardIterator2 __s_last) -{ - return std::find_end(std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, - std::equal_to<>()); +find_end(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __s_first, + _ForwardIterator2 __s_last) { + return std::find_end(std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, std::equal_to<>()); } // [alg.find_first_of] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> -find_first_of(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> find_first_of( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __s_first, + _ForwardIterator2 __s_last, + _BinaryPredicate __pred) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first); - return __pstl::__internal::__pattern_find_first_of(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __s_first, __s_last, __pred); + return __pstl::__internal::__pattern_find_first_of( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> -find_first_of(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __s_first, _ForwardIterator2 __s_last) -{ - return std::find_first_of(std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, - std::equal_to<>()); +find_first_of(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __s_first, + _ForwardIterator2 __s_last) { + return std::find_first_of( + std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, std::equal_to<>()); } // [alg.adjacent_find] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - return __pstl::__internal::__pattern_adjacent_find(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, std::equal_to<_ValueType>(), /*first_semantic*/ false); + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + return __pstl::__internal::__pattern_adjacent_find( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + std::equal_to<_ValueType>(), + /*first_semantic*/ false); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_adjacent_find(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __pred, /*first_semantic*/ false); +adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + return __pstl::__internal::__pattern_adjacent_find( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, /*first_semantic*/ false); } // [alg.count] @@ -175,930 +178,1085 @@ template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, typename iterator_traits<_ForwardIterator>::difference_type> -count(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +count(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - return __pstl::__internal::__pattern_count(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [&__value](const _ValueType& __x) { return __value == __x; }); + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + return __pstl::__internal::__pattern_count( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [&__value](const _ValueType& __x) { + return __value == __x; + }); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, typename iterator_traits<_ForwardIterator>::difference_type> -count_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_count(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - __pred); +count_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + return __pstl::__internal::__pattern_count( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); } // [alg.search] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> -search(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, - _ForwardIterator2 __s_last, _BinaryPredicate __pred) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first); +search(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __s_first, + _ForwardIterator2 __s_last, + _BinaryPredicate __pred) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __s_first); - return __pstl::__internal::__pattern_search(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - __s_first, __s_last, __pred); + return __pstl::__internal::__pattern_search( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> -search(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, - _ForwardIterator2 __s_last) -{ - return std::search(std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, std::equal_to<>()); +search(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __s_first, + _ForwardIterator2 __s_last) { + return std::search(std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, std::equal_to<>()); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -search_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count, - const _Tp& __value, _BinaryPredicate __pred) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +search_n(_ExecutionPolicy&& __exec, + _ForwardIterator __first, + _ForwardIterator __last, + _Size __count, + const _Tp& __value, + _BinaryPredicate __pred) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_search_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __count, __value, __pred); + return __pstl::__internal::__pattern_search_n( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __count, __value, __pred); } template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -search_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count, - const _Tp& __value) -{ - return std::search_n(std::forward<_ExecutionPolicy>(__exec), __first, __last, __count, __value, - std::equal_to::value_type>()); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> search_n( + _ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) { + return std::search_n( + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __count, + __value, + std::equal_to::value_type>()); } // [alg.copy] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); +copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); - using __is_vector = typename decltype(__dispatch_tag)::__is_vector; + using __is_vector = typename decltype(__dispatch_tag)::__is_vector; - return __pstl::__internal::__pattern_walk2_brick( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, - [](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res) - { return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{}); }); + return __pstl::__internal::__pattern_walk2_brick( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __result, + [](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res) { + return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{}); + }); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -copy_n(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _Size __n, _ForwardIterator2 __result) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); +copy_n(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _Size __n, _ForwardIterator2 __result) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); - using __is_vector = typename decltype(__dispatch_tag)::__is_vector; + using __is_vector = typename decltype(__dispatch_tag)::__is_vector; - return __pstl::__internal::__pattern_walk2_brick_n( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, - [](_ForwardIterator1 __begin, _Size __sz, _ForwardIterator2 __res) - { return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{}); }); + return __pstl::__internal::__pattern_walk2_brick_n( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __n, + __result, + [](_ForwardIterator1 __begin, _Size __sz, _ForwardIterator2 __res) { + return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{}); + }); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -copy_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, - _Predicate __pred) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); +copy_if(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _Predicate __pred) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); - return __pstl::__internal::__pattern_copy_if(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __result, __pred); + return __pstl::__internal::__pattern_copy_if( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred); } // [alg.swap] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -swap_ranges(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2) -{ - typedef typename iterator_traits<_ForwardIterator1>::reference _ReferenceType1; - typedef typename iterator_traits<_ForwardIterator2>::reference _ReferenceType2; +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> swap_ranges( + _ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { + typedef typename iterator_traits<_ForwardIterator1>::reference _ReferenceType1; + typedef typename iterator_traits<_ForwardIterator2>::reference _ReferenceType2; - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); - return __pstl::__internal::__pattern_walk2(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, - __last1, __first2, - [](_ReferenceType1 __x, _ReferenceType2 __y) - { - using std::swap; - swap(__x, __y); - }); + return __pstl::__internal::__pattern_walk2( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + __first2, + [](_ReferenceType1 __x, _ReferenceType2 __y) { + using std::swap; + swap(__x, __y); + }); } // [alg.transform] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, - _UnaryOperation __op) -{ - typedef typename iterator_traits<_ForwardIterator1>::reference _InputType; - typedef typename iterator_traits<_ForwardIterator2>::reference _OutputType; - - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); - - return __pstl::__internal::__pattern_walk2(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - __result, - [__op](_InputType __x, _OutputType __y) mutable { __y = __op(__x); }); -} - -template ::reference _InputType; + typedef typename iterator_traits<_ForwardIterator2>::reference _OutputType; + + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); + + return __pstl::__internal::__pattern_walk2( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __result, + [__op](_InputType __x, _OutputType __y) mutable { __y = __op(__x); }); +} + +template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator __result, _BinaryOperation __op) -{ - typedef typename iterator_traits<_ForwardIterator1>::reference _Input1Type; - typedef typename iterator_traits<_ForwardIterator2>::reference _Input2Type; - typedef typename iterator_traits<_ForwardIterator>::reference _OutputType; - - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result); - - return __pstl::__internal::__pattern_walk3( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __result, - [__op](_Input1Type x, _Input2Type y, _OutputType z) mutable { z = __op(x, y); }); +transform(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator __result, + _BinaryOperation __op) { + typedef typename iterator_traits<_ForwardIterator1>::reference _Input1Type; + typedef typename iterator_traits<_ForwardIterator2>::reference _Input2Type; + typedef typename iterator_traits<_ForwardIterator>::reference _OutputType; + + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result); + + return __pstl::__internal::__pattern_walk3( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + __first2, + __result, + [__op](_Input1Type x, _Input2Type y, _OutputType z) mutable { z = __op(x, y); }); } // [alg.replace] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -replace_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred, - const _Tp& __new_value) -{ - typedef typename iterator_traits<_ForwardIterator>::reference _ElementType; - - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - - __pstl::__internal::__pattern_walk1(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [&__pred, &__new_value](_ElementType __elem) - { - if (__pred(__elem)) - { - __elem = __new_value; - } - }); +replace_if(_ExecutionPolicy&& __exec, + _ForwardIterator __first, + _ForwardIterator __last, + _UnaryPredicate __pred, + const _Tp& __new_value) { + typedef typename iterator_traits<_ForwardIterator>::reference _ElementType; + + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + + __pstl::__internal::__pattern_walk1( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [&__pred, &__new_value](_ElementType __elem) { + if (__pred(__elem)) { + __elem = __new_value; + } + }); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -replace(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, - const _Tp& __new_value) -{ - std::replace_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, - __pstl::__internal::__equal_value<_Tp>(__old_value), __new_value); +replace(_ExecutionPolicy&& __exec, + _ForwardIterator __first, + _ForwardIterator __last, + const _Tp& __old_value, + const _Tp& __new_value) { + std::replace_if( + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __pstl::__internal::__equal_value<_Tp>(__old_value), + __new_value); } template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -replace_copy_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _UnaryPredicate __pred, const _Tp& __new_value) -{ - typedef typename iterator_traits<_ForwardIterator1>::reference _InputType; - typedef typename iterator_traits<_ForwardIterator2>::reference _OutputType; - - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); - - return __pstl::__internal::__pattern_walk2( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, - [__pred, &__new_value](_InputType __x, _OutputType __y) mutable { __y = __pred(__x) ? __new_value : __x; }); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> replace_copy_if( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _UnaryPredicate __pred, + const _Tp& __new_value) { + typedef typename iterator_traits<_ForwardIterator1>::reference _InputType; + typedef typename iterator_traits<_ForwardIterator2>::reference _OutputType; + + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); + + return __pstl::__internal::__pattern_walk2( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __result, + [__pred, &__new_value](_InputType __x, _OutputType __y) mutable { __y = __pred(__x) ? __new_value : __x; }); } template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -replace_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, - const _Tp& __old_value, const _Tp& __new_value) -{ - return std::replace_copy_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, - __pstl::__internal::__equal_value<_Tp>(__old_value), __new_value); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> replace_copy( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + const _Tp& __old_value, + const _Tp& __new_value) { + return std::replace_copy_if( + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __result, + __pstl::__internal::__equal_value<_Tp>(__old_value), + __new_value); } // [alg.fill] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - __pstl::__internal::__pattern_fill(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - __value); + __pstl::__internal::__pattern_fill(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __value); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __count, const _Tp& __value) -{ - if (__count <= 0) - return __first; +fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __count, const _Tp& __value) { + if (__count <= 0) + return __first; - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_fill_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __count, __value); + return __pstl::__internal::__pattern_fill_n( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __count, __value); } // [alg.generate] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -generate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Generator __g) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +generate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Generator __g) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - __pstl::__internal::__pattern_generate(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - __g); + __pstl::__internal::__pattern_generate(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __g); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -generate_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __count, _Generator __g) -{ - if (__count <= 0) - return __first; +generate_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __count, _Generator __g) { + if (__count <= 0) + return __first; - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_generate_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __count, __g); + return __pstl::__internal::__pattern_generate_n( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __count, __g); } // [alg.remove] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -remove_copy_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _Predicate __pred) -{ - return std::copy_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, std::not_fn(__pred)); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> remove_copy_if( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _Predicate __pred) { + return std::copy_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, std::not_fn(__pred)); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -remove_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, - const _Tp& __value) -{ - return std::copy_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, - __pstl::__internal::__not_equal_value<_Tp>(__value)); +remove_copy(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + const _Tp& __value) { + return std::copy_if( + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __result, + __pstl::__internal::__not_equal_value<_Tp>(__value)); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -remove_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +remove_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_remove_if(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __pred); + return __pstl::__internal::__pattern_remove_if( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -remove(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) -{ - return std::remove_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, - __pstl::__internal::__equal_value<_Tp>(__value)); +remove(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + return std::remove_if( + std::forward<_ExecutionPolicy>(__exec), __first, __last, __pstl::__internal::__equal_value<_Tp>(__value)); } // [alg.unique] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_unique(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - __pred); + return __pstl::__internal::__pattern_unique( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) -{ - return std::unique(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::equal_to<>()); +unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { + return std::unique(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::equal_to<>()); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -unique_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, - _BinaryPredicate __pred) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); +unique_copy(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _BinaryPredicate __pred) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); - return __pstl::__internal::__pattern_unique_copy(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __result, __pred); + return __pstl::__internal::__pattern_unique_copy( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred); } template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -unique_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result) -{ - return std::unique_copy(__exec, __first, __last, __result, std::equal_to<>()); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> unique_copy( + _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result) { + return std::unique_copy(__exec, __first, __last, __result, std::equal_to<>()); } // [alg.reverse] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -reverse(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +reverse(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - __pstl::__internal::__pattern_reverse(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last); + __pstl::__internal::__pattern_reverse(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -reverse_copy(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, - _ForwardIterator __d_first) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first); +reverse_copy(_ExecutionPolicy&& __exec, + _BidirectionalIterator __first, + _BidirectionalIterator __last, + _ForwardIterator __d_first) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first); - return __pstl::__internal::__pattern_reverse_copy(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __d_first); + return __pstl::__internal::__pattern_reverse_copy( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first); } // [alg.rotate] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_rotate(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __middle, __last); + return __pstl::__internal::__pattern_rotate( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -rotate_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __middle, _ForwardIterator1 __last, - _ForwardIterator2 __result) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); +rotate_copy(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __middle, + _ForwardIterator1 __last, + _ForwardIterator2 __result) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); - return __pstl::__internal::__pattern_rotate_copy(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __middle, __last, __result); + return __pstl::__internal::__pattern_rotate_copy( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __result); } // [alg.partitions] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_is_partitioned(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __pred); +is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + return __pstl::__internal::__pattern_is_partitioned( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_partition(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __pred); + return __pstl::__internal::__pattern_partition( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); } template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _BidirectionalIterator> -stable_partition(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, - _UnaryPredicate __pred) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_stable_partition(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), - __first, __last, __pred); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _BidirectionalIterator> stable_partition( + _ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, _UnaryPredicate __pred) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + return __pstl::__internal::__pattern_stable_partition( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); } -template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> -partition_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, - _ForwardIterator1 __out_true, _ForwardIterator2 __out_false, _UnaryPredicate __pred) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __out_true, __out_false); +partition_copy(_ExecutionPolicy&& __exec, + _ForwardIterator __first, + _ForwardIterator __last, + _ForwardIterator1 __out_true, + _ForwardIterator2 __out_false, + _UnaryPredicate __pred) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __out_true, __out_false); - return __pstl::__internal::__pattern_partition_copy(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __out_true, __out_false, __pred); + return __pstl::__internal::__pattern_partition_copy( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __out_true, __out_false, __pred); } // [alg.sort] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType; - return __pstl::__internal::__pattern_sort(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - __comp, typename std::is_move_constructible<_InputType>::type()); + typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType; + return __pstl::__internal::__pattern_sort( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __comp, + typename std::is_move_constructible<_InputType>::type()); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) -{ - typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType; - std::sort(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); +sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) { + typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType; + std::sort(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); } // [stable.sort] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_stable_sort(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __comp); + return __pstl::__internal::__pattern_stable_sort( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) -{ - typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType; - std::stable_sort(__exec, __first, __last, std::less<_InputType>()); +stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) { + typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType; + std::stable_sort(__exec, __first, __last, std::less<_InputType>()); } // [mismatch] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> -mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _BinaryPredicate __pred) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); +mismatch(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate __pred) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); - return __pstl::__internal::__pattern_mismatch(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, - __last1, __first2, __last2, __pred); + return __pstl::__internal::__pattern_mismatch( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __pred); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> -mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _BinaryPredicate __pred) -{ - return std::mismatch(__exec, __first1, __last1, __first2, std::next(__first2, std::distance(__first1, __last1)), - __pred); +mismatch(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _BinaryPredicate __pred) { + return std::mismatch( + __exec, __first1, __last1, __first2, std::next(__first2, std::distance(__first1, __last1)), __pred); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> -mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2) -{ - return std::mismatch(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, - std::equal_to<>()); +mismatch(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2) { + return std::mismatch(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::equal_to<>()); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> -mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) -{ - //TODO: to get rid of "distance" - return std::mismatch(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, - std::next(__first2, std::distance(__first1, __last1))); +mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { + // TODO: to get rid of "distance" + return std::mismatch( + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + __first2, + std::next(__first2, std::distance(__first1, __last1))); } // [alg.equal] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _BinaryPredicate __p) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); +equal(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _BinaryPredicate __p) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); - return __pstl::__internal::__pattern_equal(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, - __last1, __first2, __p); + return __pstl::__internal::__pattern_equal( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __p); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) -{ - return std::equal(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, std::equal_to<>()); +equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) { + return std::equal(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, std::equal_to<>()); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _BinaryPredicate __p) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); +equal(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _BinaryPredicate __p) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); - return __pstl::__internal::__pattern_equal(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, - __last1, __first2, __last2, __p); + return __pstl::__internal::__pattern_equal( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __p); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2) -{ - return equal(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::equal_to<>()); +equal(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2) { + return equal(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::equal_to<>()); } // [alg.move] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -move(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first); +move(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first); - using __is_vector = typename decltype(__dispatch_tag)::__is_vector; + using __is_vector = typename decltype(__dispatch_tag)::__is_vector; - return __pstl::__internal::__pattern_walk2_brick( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, - [](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res) - { return __pstl::__internal::__brick_move(__begin, __end, __res, __is_vector{}); }); + return __pstl::__internal::__pattern_walk2_brick( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __d_first, + [](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res) { + return __pstl::__internal::__brick_move(__begin, __end, __res, __is_vector{}); + }); } // [partial.sort] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __middle, - _RandomAccessIterator __last, _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +partial_sort(_ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last, + _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - __pstl::__internal::__pattern_partial_sort(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __middle, __last, __comp); + __pstl::__internal::__pattern_partial_sort( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __middle, - _RandomAccessIterator __last) -{ - typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType; - std::partial_sort(__exec, __first, __middle, __last, std::less<_InputType>()); +partial_sort(_ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __middle, + _RandomAccessIterator __last) { + typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType; + std::partial_sort(__exec, __first, __middle, __last, std::less<_InputType>()); } // [partial.sort.copy] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, - _RandomAccessIterator __d_first, _RandomAccessIterator __d_last, _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> partial_sort_copy( + _ExecutionPolicy&& __exec, + _ForwardIterator __first, + _ForwardIterator __last, + _RandomAccessIterator __d_first, + _RandomAccessIterator __d_last, + _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first); - return __pstl::__internal::__pattern_partial_sort_copy(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), - __first, __last, __d_first, __d_last, __comp); + return __pstl::__internal::__pattern_partial_sort_copy( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __d_last, __comp); } template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, - _RandomAccessIterator __d_first, _RandomAccessIterator __d_last) -{ - return std::partial_sort_copy(std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __d_last, - std::less<>()); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> partial_sort_copy( + _ExecutionPolicy&& __exec, + _ForwardIterator __first, + _ForwardIterator __last, + _RandomAccessIterator __d_first, + _RandomAccessIterator __d_last) { + return std::partial_sort_copy( + std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __d_last, std::less<>()); } // [is.sorted] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - const _ForwardIterator __res = - __pstl::__internal::__pattern_adjacent_find(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __pstl::__internal::__reorder_pred<_Compare>(__comp), - /*first_semantic*/ false); - return __res == __last ? __last : std::next(__res); +is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + const _ForwardIterator __res = __pstl::__internal::__pattern_adjacent_find( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __pstl::__internal::__reorder_pred<_Compare>(__comp), + /*first_semantic*/ false); + return __res == __last ? __last : std::next(__res); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) -{ - typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType; - return is_sorted_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); +is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { + typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType; + return is_sorted_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_adjacent_find(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __pstl::__internal::__reorder_pred<_Compare>(__comp), - /*or_semantic*/ true) == __last; +is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + return __pstl::__internal::__pattern_adjacent_find( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __pstl::__internal::__reorder_pred<_Compare>(__comp), + /*or_semantic*/ true) == __last; } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) -{ - typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType; - return std::is_sorted(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); +is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { + typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType; + return std::is_sorted(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); } // [alg.merge] -template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -merge(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _ForwardIterator __d_first, _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __d_first); +merge(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __d_first, + _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __d_first); - return __pstl::__internal::__pattern_merge(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, - __last1, __first2, __last2, __d_first, __comp); + return __pstl::__internal::__pattern_merge( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __d_first, __comp); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -merge(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _ForwardIterator __d_first) -{ - return std::merge(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __d_first, - std::less<>()); +merge(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __d_first) { + return std::merge( + std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __d_first, std::less<>()); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -inplace_merge(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __middle, - _BidirectionalIterator __last, _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +inplace_merge(_ExecutionPolicy&& __exec, + _BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last, + _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - __pstl::__internal::__pattern_inplace_merge(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __middle, __last, __comp); + __pstl::__internal::__pattern_inplace_merge( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -inplace_merge(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __middle, - _BidirectionalIterator __last) -{ - typedef typename std::iterator_traits<_BidirectionalIterator>::value_type _InputType; - std::inplace_merge(__exec, __first, __middle, __last, std::less<_InputType>()); +inplace_merge(_ExecutionPolicy&& __exec, + _BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last) { + typedef typename std::iterator_traits<_BidirectionalIterator>::value_type _InputType; + std::inplace_merge(__exec, __first, __middle, __last, std::less<_InputType>()); } // [includes] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); +includes(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); - return __pstl::__internal::__pattern_includes(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, - __last1, __first2, __last2, __comp); + return __pstl::__internal::__pattern_includes( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2) -{ - return std::includes(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::less<>()); +includes(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2) { + return std::includes(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::less<>()); } // [set.union] -template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result); +set_union(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __result, + _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result); - return __pstl::__internal::__pattern_set_union(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, - __last1, __first2, __last2, __result, __comp); + return __pstl::__internal::__pattern_set_union( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, - _ForwardIterator2 __last2, _ForwardIterator __result) -{ - return std::set_union(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, - std::less<>()); +set_union(_ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __result) { + return std::set_union( + std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, std::less<>()); } // [set.intersection] -template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_intersection( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __result, + _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result); - return __pstl::__internal::__pattern_set_intersection(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), - __first1, __last1, __first2, __last2, __result, __comp); + return __pstl::__internal::__pattern_set_intersection( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp); } template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result) -{ - return std::set_intersection(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, - std::less<>()); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_intersection( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __result) { + return std::set_intersection( + std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, std::less<>()); } // [set.difference] -template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_difference( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __result, + _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result); - return __pstl::__internal::__pattern_set_difference(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), - __first1, __last1, __first2, __last2, __result, __comp); + return __pstl::__internal::__pattern_set_difference( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp); } template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result) -{ - return std::set_difference(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, - std::less<>()); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_difference( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __result) { + return std::set_difference( + std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, std::less<>()); } // [set.symmetric.difference] -template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -set_symmetric_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, - _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_symmetric_difference( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __result, + _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2, __result); - return __pstl::__internal::__pattern_set_symmetric_difference( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp); + return __pstl::__internal::__pattern_set_symmetric_difference( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp); } template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -set_symmetric_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result) -{ - return std::set_symmetric_difference(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, - __result, std::less<>()); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> set_symmetric_difference( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _ForwardIterator __result) { + return std::set_symmetric_difference( + std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, std::less<>()); } // [is.heap] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_is_heap_until(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __comp); + return __pstl::__internal::__pattern_is_heap_until( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> -is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) -{ - typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType; - return std::is_heap_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); +is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) { + typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType; + return std::is_heap_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) -{ - return std::is_heap_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp) == __last; +is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { + return std::is_heap_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp) == __last; } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) -{ - typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType; - return std::is_heap(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); +is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) { + typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType; + return std::is_heap(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); } // [alg.min.max] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_min_element(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __comp); +min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + return __pstl::__internal::__pattern_min_element( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) -{ - typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType; - return std::min_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); +min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { + typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType; + return std::min_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - return min_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, - __pstl::__internal::__reorder_pred<_Compare>(__comp)); +max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + return min_element( + std::forward<_ExecutionPolicy>(__exec), __first, __last, __pstl::__internal::__reorder_pred<_Compare>(__comp)); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) -{ - typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType; - return std::min_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, - __pstl::__internal::__reorder_pred>(std::less<_InputType>())); +max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { + typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType; + return std::min_element( + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __pstl::__internal::__reorder_pred>(std::less<_InputType>())); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>> -minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_minmax_element(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __comp); +minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + return __pstl::__internal::__pattern_minmax_element( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>> -minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - return std::minmax_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_ValueType>()); +minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + return std::minmax_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_ValueType>()); } // [alg.nth.element] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __nth, - _RandomAccessIterator __last, _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); +nth_element(_ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __nth, + _RandomAccessIterator __last, + _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - __pstl::__internal::__pattern_nth_element(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __nth, - __last, __comp); + __pstl::__internal::__pattern_nth_element( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __nth, __last, __comp); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __nth, - _RandomAccessIterator __last) -{ - typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType; - std::nth_element(std::forward<_ExecutionPolicy>(__exec), __first, __nth, __last, std::less<_InputType>()); +nth_element(_ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __nth, + _RandomAccessIterator __last) { + typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType; + std::nth_element(std::forward<_ExecutionPolicy>(__exec), __first, __nth, __last, std::less<_InputType>()); } // [alg.lex.comparison] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -lexicographical_compare(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> lexicographical_compare( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2, + _Compare __comp) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); - return __pstl::__internal::__pattern_lexicographical_compare(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), - __first1, __last1, __first2, __last2, __comp); + return __pstl::__internal::__pattern_lexicographical_compare( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp); } template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> -lexicographical_compare(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _ForwardIterator2 __last2) -{ - return std::lexicographical_compare(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, - std::less<>()); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> lexicographical_compare( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _ForwardIterator2 __last2) { + return std::lexicographical_compare( + std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, std::less<>()); } } // namespace std diff --git a/libcxx/include/pstl/internal/glue_execution_defs.h b/libcxx/include/pstl/internal/glue_execution_defs.h --- a/libcxx/include/pstl/internal/glue_execution_defs.h +++ b/libcxx/include/pstl/internal/glue_execution_defs.h @@ -15,21 +15,19 @@ #include "execution_defs.h" #include "pstl_config.h" -namespace std -{ +namespace std { // Type trait using __pstl::execution::is_execution_policy; #if defined(_PSTL_CPP14_VARIABLE_TEMPLATES_PRESENT) -# if defined(__INTEL_COMPILER) +# if defined(__INTEL_COMPILER) template constexpr bool is_execution_policy_v = is_execution_policy::value; -# else +# else using __pstl::execution::is_execution_policy_v; -# endif +# endif #endif -namespace execution -{ +namespace execution { // Standard C++ policy classes using __pstl::execution::parallel_policy; using __pstl::execution::parallel_unsequenced_policy; diff --git a/libcxx/include/pstl/internal/glue_memory_defs.h b/libcxx/include/pstl/internal/glue_memory_defs.h --- a/libcxx/include/pstl/internal/glue_memory_defs.h +++ b/libcxx/include/pstl/internal/glue_memory_defs.h @@ -15,8 +15,7 @@ _PSTL_HIDE_FROM_ABI_PUSH -namespace std -{ +namespace std { // [uninitialized.copy] diff --git a/libcxx/include/pstl/internal/glue_memory_impl.h b/libcxx/include/pstl/internal/glue_memory_impl.h --- a/libcxx/include/pstl/internal/glue_memory_impl.h +++ b/libcxx/include/pstl/internal/glue_memory_impl.h @@ -12,337 +12,368 @@ #include "pstl_config.h" +#include "algorithm_fwd.h" #include "execution_defs.h" #include "utils.h" -#include "algorithm_fwd.h" #include "execution_impl.h" _PSTL_HIDE_FROM_ABI_PUSH -namespace std -{ +namespace std { // [uninitialized.copy] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -uninitialized_copy(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result) -{ - typedef typename iterator_traits<_InputIterator>::value_type _ValueType1; - typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; - typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; - typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; - - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); - - using __is_vector = typename decltype(__dispatch_tag)::__is_vector; - - return __pstl::__internal::__invoke_if_else( - std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), - [&]() - { - return __pstl::__internal::__pattern_walk2_brick( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, - [](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) - { return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{}); }); - }, - [&]() - { - return __pstl::__internal::__pattern_walk2(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __result, - [](_ReferenceType1 __val1, _ReferenceType2 __val2) - { ::new (std::addressof(__val2)) _ValueType2(__val1); }); - }); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> uninitialized_copy( + _ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result) { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType1; + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; + typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; + typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; + + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); + + using __is_vector = typename decltype(__dispatch_tag)::__is_vector; + + return __pstl::__internal::__invoke_if_else( + std::integral_constant < bool, + std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), + [&]() { + return __pstl::__internal::__pattern_walk2_brick( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __result, + [](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) { + return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{}); + }); + }, + [&]() { + return __pstl::__internal::__pattern_walk2( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __result, + [](_ReferenceType1 __val1, _ReferenceType2 __val2) { ::new (std::addressof(__val2)) _ValueType2(__val1); }); + }); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -uninitialized_copy_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result) -{ - typedef typename iterator_traits<_InputIterator>::value_type _ValueType1; - typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; - typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; - typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; - - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); - - using __is_vector = typename decltype(__dispatch_tag)::__is_vector; - - return __pstl::__internal::__invoke_if_else( - std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), - [&]() - { - return __pstl::__internal::__pattern_walk2_brick_n( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, - [](_InputIterator __begin, _Size __sz, _ForwardIterator __res) - { return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{}); }); - }, - [&]() - { - return __pstl::__internal::__pattern_walk2_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), - __first, __n, __result, - [](_ReferenceType1 __val1, _ReferenceType2 __val2) - { ::new (std::addressof(__val2)) _ValueType2(__val1); }); - }); +uninitialized_copy_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result) { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType1; + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; + typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; + typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; + + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); + + using __is_vector = typename decltype(__dispatch_tag)::__is_vector; + + return __pstl::__internal::__invoke_if_else( + std::integral_constant < bool, + std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), + [&]() { + return __pstl::__internal::__pattern_walk2_brick_n( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __n, + __result, + [](_InputIterator __begin, _Size __sz, _ForwardIterator __res) { + return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{}); + }); + }, + [&]() { + return __pstl::__internal::__pattern_walk2_n( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __n, + __result, + [](_ReferenceType1 __val1, _ReferenceType2 __val2) { ::new (std::addressof(__val2)) _ValueType2(__val1); }); + }); } // [uninitialized.move] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -uninitialized_move(_ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result) -{ - typedef typename iterator_traits<_InputIterator>::value_type _ValueType1; - typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; - typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; - typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; - - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); - - using __is_vector = typename decltype(__dispatch_tag)::__is_vector; - - return __pstl::__internal::__invoke_if_else( - std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), - [&]() - { - return __pstl::__internal::__pattern_walk2_brick( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, - [](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) - { return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{}); }); - }, - [&]() - { - return __pstl::__internal::__pattern_walk2( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, - [](_ReferenceType1 __val1, _ReferenceType2 __val2) - { ::new (std::addressof(__val2)) _ValueType2(std::move(__val1)); }); - }); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> uninitialized_move( + _ExecutionPolicy&& __exec, _InputIterator __first, _InputIterator __last, _ForwardIterator __result) { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType1; + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; + typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; + typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; + + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); + + using __is_vector = typename decltype(__dispatch_tag)::__is_vector; + + return __pstl::__internal::__invoke_if_else( + std::integral_constant < bool, + std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), + [&]() { + return __pstl::__internal::__pattern_walk2_brick( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __result, + [](_InputIterator __begin, _InputIterator __end, _ForwardIterator __res) { + return __pstl::__internal::__brick_copy(__begin, __end, __res, __is_vector{}); + }); + }, + [&]() { + return __pstl::__internal::__pattern_walk2( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __result, + [](_ReferenceType1 __val1, _ReferenceType2 __val2) { + ::new (std::addressof(__val2)) _ValueType2(std::move(__val1)); + }); + }); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result) -{ - typedef typename iterator_traits<_InputIterator>::value_type _ValueType1; - typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; - typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; - typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; - - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); - - using __is_vector = typename decltype(__dispatch_tag)::__is_vector; - - return __pstl::__internal::__invoke_if_else( - std::integral_constant < bool, std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), - [&]() - { - return __pstl::__internal::__pattern_walk2_brick_n( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, - [](_InputIterator __begin, _Size __sz, _ForwardIterator __res) - { return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{}); }); - }, - [&]() - { - return __pstl::__internal::__pattern_walk2_n( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, - [](_ReferenceType1 __val1, _ReferenceType2 __val2) - { ::new (std::addressof(__val2)) _ValueType2(std::move(__val1)); }); - }); +uninitialized_move_n(_ExecutionPolicy&& __exec, _InputIterator __first, _Size __n, _ForwardIterator __result) { + typedef typename iterator_traits<_InputIterator>::value_type _ValueType1; + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType2; + typedef typename iterator_traits<_InputIterator>::reference _ReferenceType1; + typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType2; + + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); + + using __is_vector = typename decltype(__dispatch_tag)::__is_vector; + + return __pstl::__internal::__invoke_if_else( + std::integral_constant < bool, + std::is_trivial<_ValueType1>::value&& std::is_trivial<_ValueType2>::value > (), + [&]() { + return __pstl::__internal::__pattern_walk2_brick_n( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __n, + __result, + [](_InputIterator __begin, _Size __sz, _ForwardIterator __res) { + return __pstl::__internal::__brick_copy_n(__begin, __sz, __res, __is_vector{}); + }); + }, + [&]() { + return __pstl::__internal::__pattern_walk2_n( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __n, + __result, + [](_ReferenceType1 __val1, _ReferenceType2 __val2) { + ::new (std::addressof(__val2)) _ValueType2(std::move(__val1)); + }); + }); } // [uninitialized.fill] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; - - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - - using __is_vector = typename decltype(__dispatch_tag)::__is_vector; - - __pstl::__internal::__invoke_if_else( - std::is_arithmetic<_ValueType>(), - [&]() - { - __pstl::__internal::__pattern_walk_brick( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [&__value](_ForwardIterator __begin, _ForwardIterator __end) - { __pstl::__internal::__brick_fill(__begin, __end, _ValueType(__value), __is_vector{}); }); - }, - [&]() - { - __pstl::__internal::__pattern_walk1(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [&__value](_ReferenceType __val) - { ::new (std::addressof(__val)) _ValueType(__value); }); - }); +uninitialized_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; + + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + + using __is_vector = typename decltype(__dispatch_tag)::__is_vector; + + __pstl::__internal::__invoke_if_else( + std::is_arithmetic<_ValueType>(), + [&]() { + __pstl::__internal::__pattern_walk_brick( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [&__value](_ForwardIterator __begin, _ForwardIterator __end) { + __pstl::__internal::__brick_fill(__begin, __end, _ValueType(__value), __is_vector{}); + }); + }, + [&]() { + __pstl::__internal::__pattern_walk1( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [&__value](_ReferenceType __val) { + ::new (std::addressof(__val)) _ValueType(__value); + }); + }); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -uninitialized_fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, const _Tp& __value) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; - - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - - using __is_vector = typename decltype(__dispatch_tag)::__is_vector; - - return __pstl::__internal::__invoke_if_else( - std::is_arithmetic<_ValueType>(), - [&]() - { - return __pstl::__internal::__pattern_walk_brick_n( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, - [&__value](_ForwardIterator __begin, _Size __count) - { return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(__value), __is_vector{}); }); - }, - [&]() - { - return __pstl::__internal::__pattern_walk1_n( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, - [&__value](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(__value); }); - }); +uninitialized_fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, const _Tp& __value) { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; + + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + + using __is_vector = typename decltype(__dispatch_tag)::__is_vector; + + return __pstl::__internal::__invoke_if_else( + std::is_arithmetic<_ValueType>(), + [&]() { + return __pstl::__internal::__pattern_walk_brick_n( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __n, + [&__value](_ForwardIterator __begin, _Size __count) { + return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(__value), __is_vector{}); + }); + }, + [&]() { + return __pstl::__internal::__pattern_walk1_n( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, [&__value](_ReferenceType __val) { + ::new (std::addressof(__val)) _ValueType(__value); + }); + }); } // [specialized.destroy] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -destroy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; - - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - - __pstl::__internal::__invoke_if_not(std::is_trivially_destructible<_ValueType>(), - [&]() - { - __pstl::__internal::__pattern_walk1( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [](_ReferenceType __val) { __val.~_ValueType(); }); - }); +destroy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; + + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + + __pstl::__internal::__invoke_if_not(std::is_trivially_destructible<_ValueType>(), [&]() { + __pstl::__internal::__pattern_walk1( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [](_ReferenceType __val) { + __val.~_ValueType(); + }); + }); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -destroy_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; - - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - - return __pstl::__internal::__invoke_if_else( - std::is_trivially_destructible<_ValueType>(), [&]() { return std::next(__first, __n); }, - [&]() - { - return __pstl::__internal::__pattern_walk1_n(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), - __first, __n, - [](_ReferenceType __val) { __val.~_ValueType(); }); - }); +destroy_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; + + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + + return __pstl::__internal::__invoke_if_else( + std::is_trivially_destructible<_ValueType>(), + [&]() { return std::next(__first, __n); }, + [&]() { + return __pstl::__internal::__pattern_walk1_n( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, [](_ReferenceType __val) { + __val.~_ValueType(); + }); + }); } // [uninitialized.construct.default] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -uninitialized_default_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; - - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - - __pstl::__internal::__invoke_if_not(std::is_trivial<_ValueType>(), - [&]() - { - __pstl::__internal::__pattern_walk1( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; }); - }); +uninitialized_default_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; + + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + + __pstl::__internal::__invoke_if_not(std::is_trivial<_ValueType>(), [&]() { + __pstl::__internal::__pattern_walk1( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [](_ReferenceType __val) { + ::new (std::addressof(__val)) _ValueType; + }); + }); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -uninitialized_default_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; - - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - - return __pstl::__internal::__invoke_if_else( - std::is_trivial<_ValueType>(), [&]() { return std::next(__first, __n); }, - [&]() - { - return __pstl::__internal::__pattern_walk1_n( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, - [](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType; }); - }); +uninitialized_default_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; + + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + + return __pstl::__internal::__invoke_if_else( + std::is_trivial<_ValueType>(), + [&]() { return std::next(__first, __n); }, + [&]() { + return __pstl::__internal::__pattern_walk1_n( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, [](_ReferenceType __val) { + ::new (std::addressof(__val)) _ValueType; + }); + }); } // [uninitialized.construct.value] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> -uninitialized_value_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; - - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - - using __is_vector = typename decltype(__dispatch_tag)::__is_vector; - - __pstl::__internal::__invoke_if_else( - std::is_trivial<_ValueType>(), - [&]() - { - __pstl::__internal::__pattern_walk_brick( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [](_ForwardIterator __begin, _ForwardIterator __end) - { __pstl::__internal::__brick_fill(__begin, __end, _ValueType(), __is_vector{}); }); - }, - [&]() - { - __pstl::__internal::__pattern_walk1(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [](_ReferenceType __val) - { ::new (std::addressof(__val)) _ValueType(); }); - }); +uninitialized_value_construct(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; + + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + + using __is_vector = typename decltype(__dispatch_tag)::__is_vector; + + __pstl::__internal::__invoke_if_else( + std::is_trivial<_ValueType>(), + [&]() { + __pstl::__internal::__pattern_walk_brick( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [](_ForwardIterator __begin, _ForwardIterator __end) { + __pstl::__internal::__brick_fill(__begin, __end, _ValueType(), __is_vector{}); + }); + }, + [&]() { + __pstl::__internal::__pattern_walk1( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, [](_ReferenceType __val) { + ::new (std::addressof(__val)) _ValueType(); + }); + }); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> -uninitialized_value_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; - - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - - using __is_vector = typename decltype(__dispatch_tag)::__is_vector; - - return __pstl::__internal::__invoke_if_else( - std::is_trivial<_ValueType>(), - [&]() - { - return __pstl::__internal::__pattern_walk_brick_n( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, - [](_ForwardIterator __begin, _Size __count) - { return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(), __is_vector{}); }); - }, - [&]() - { - return __pstl::__internal::__pattern_walk1_n( - __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, - [](_ReferenceType __val) { ::new (std::addressof(__val)) _ValueType(); }); - }); +uninitialized_value_construct_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n) { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + typedef typename iterator_traits<_ForwardIterator>::reference _ReferenceType; + + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + + using __is_vector = typename decltype(__dispatch_tag)::__is_vector; + + return __pstl::__internal::__invoke_if_else( + std::is_trivial<_ValueType>(), + [&]() { + return __pstl::__internal::__pattern_walk_brick_n( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __n, + [](_ForwardIterator __begin, _Size __count) { + return __pstl::__internal::__brick_fill_n(__begin, __count, _ValueType(), __is_vector{}); + }); + }, + [&]() { + return __pstl::__internal::__pattern_walk1_n( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __n, [](_ReferenceType __val) { + ::new (std::addressof(__val)) _ValueType(); + }); + }); } } // namespace std diff --git a/libcxx/include/pstl/internal/glue_numeric_defs.h b/libcxx/include/pstl/internal/glue_numeric_defs.h --- a/libcxx/include/pstl/internal/glue_numeric_defs.h +++ b/libcxx/include/pstl/internal/glue_numeric_defs.h @@ -17,13 +17,15 @@ _PSTL_HIDE_FROM_ABI_PUSH -namespace std -{ +namespace std { // [reduce] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> -reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, +reduce(_ExecutionPolicy&& __exec, + _ForwardIterator __first, + _ForwardIterator __last, + _Tp __init, _BinaryOperation __binary_op); template @@ -36,86 +38,139 @@ reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last); template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> -transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Tp __init); - -template transform_reduce( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _Tp __init); + +template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> -transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, - _BinaryOperation2 __binary_op2); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> transform_reduce( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _Tp __init, + _BinaryOperation1 __binary_op1, + _BinaryOperation2 __binary_op2); template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> -transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, - _BinaryOperation __binary_op, _UnaryOperation __unary_op); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> transform_reduce( + _ExecutionPolicy&& __exec, + _ForwardIterator __first, + _ForwardIterator __last, + _Tp __init, + _BinaryOperation __binary_op, + _UnaryOperation __unary_op); // [exclusive.scan] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _Tp __init); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _Tp __init); template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _Tp __init, + _BinaryOperation __binary_op); // [inclusive.scan] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan( + _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result); template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _BinaryOperation __binary_op); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _BinaryOperation __binary_op); template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _BinaryOperation __binary_op, _Tp __init); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _BinaryOperation __binary_op, + _Tp __init); // [transform.exclusive.scan] -template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -transform_exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op, - _UnaryOperation __unary_op); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_exclusive_scan( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _Tp __init, + _BinaryOperation __binary_op, + _UnaryOperation __unary_op); // [transform.inclusive.scan] -template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -transform_inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _BinaryOperation __binary_op, _UnaryOperation __unary_op, - _Tp __init); - -template +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _BinaryOperation __binary_op, + _UnaryOperation __unary_op, + _Tp __init); + +template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -transform_inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _BinaryOperation __binary_op, _UnaryOperation __unary_op); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _BinaryOperation __binary_op, + _UnaryOperation __unary_op); // [adjacent.difference] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __d_first, _BinaryOperation op); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __d_first, + _BinaryOperation op); template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __d_first); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference( + _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first); } // namespace std diff --git a/libcxx/include/pstl/internal/glue_numeric_impl.h b/libcxx/include/pstl/internal/glue_numeric_impl.h --- a/libcxx/include/pstl/internal/glue_numeric_impl.h +++ b/libcxx/include/pstl/internal/glue_numeric_impl.h @@ -14,215 +14,307 @@ #include "pstl_config.h" -#include "utils.h" -#include "numeric_fwd.h" #include "execution_impl.h" +#include "numeric_fwd.h" +#include "utils.h" _PSTL_HIDE_FROM_ABI_PUSH -namespace std -{ +namespace std { // [reduce] template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> -reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, - _BinaryOperation __binary_op) -{ - return transform_reduce(std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, __binary_op, - __pstl::__internal::__no_op()); +reduce(_ExecutionPolicy&& __exec, + _ForwardIterator __first, + _ForwardIterator __last, + _Tp __init, + _BinaryOperation __binary_op) { + return transform_reduce( + std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, __binary_op, __pstl::__internal::__no_op()); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> -reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init) -{ - return transform_reduce(std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, std::plus<_Tp>(), - __pstl::__internal::__no_op()); +reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init) { + return transform_reduce( + std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, std::plus<_Tp>(), __pstl::__internal::__no_op()); } template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, typename iterator_traits<_ForwardIterator>::value_type> -reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) -{ - typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; - return transform_reduce(std::forward<_ExecutionPolicy>(__exec), __first, __last, _ValueType{}, - std::plus<_ValueType>(), __pstl::__internal::__no_op()); +reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) { + typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; + return transform_reduce( + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + _ValueType{}, + std::plus<_ValueType>(), + __pstl::__internal::__no_op()); } // [transform.reduce] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> -transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Tp __init) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); - - typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType; - return __pstl::__internal::__pattern_transform_reduce(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), - __first1, __last1, __first2, __init, std::plus<_InputType>(), - std::multiplies<_InputType>()); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> transform_reduce( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _Tp __init) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); + + typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType; + return __pstl::__internal::__pattern_transform_reduce( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + __first2, + __init, + std::plus<_InputType>(), + std::multiplies<_InputType>()); } -template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> -transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); - return __pstl::__internal::__pattern_transform_reduce(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), - __first1, __last1, __first2, __init, __binary_op1, - __binary_op2); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> transform_reduce( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _Tp __init, + _BinaryOperation1 __binary_op1, + _BinaryOperation2 __binary_op2) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first1, __first2); + return __pstl::__internal::__pattern_transform_reduce( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + __first2, + __init, + __binary_op1, + __binary_op2); } template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> -transform_reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, - _BinaryOperation __binary_op, _UnaryOperation __unary_op) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); - return __pstl::__internal::__pattern_transform_reduce(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), - __first, __last, __init, __binary_op, __unary_op); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _Tp> transform_reduce( + _ExecutionPolicy&& __exec, + _ForwardIterator __first, + _ForwardIterator __last, + _Tp __init, + _BinaryOperation __binary_op, + _UnaryOperation __unary_op) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first); + return __pstl::__internal::__pattern_transform_reduce( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, __binary_op, __unary_op); } // [exclusive.scan] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _Tp __init) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); - - using namespace __pstl; - return __internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - __result, __pstl::__internal::__no_op(), __init, std::plus<_Tp>(), - /*inclusive=*/std::false_type()); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _Tp __init) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); + + using namespace __pstl; + return __internal::__pattern_transform_scan( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __result, + __pstl::__internal::__no_op(), + __init, + std::plus<_Tp>(), + /*inclusive=*/std::false_type()); } template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); - - using namespace __pstl; - return __internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, - __result, __pstl::__internal::__no_op(), __init, __binary_op, - /*inclusive=*/std::false_type()); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> exclusive_scan( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _Tp __init, + _BinaryOperation __binary_op) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); + + using namespace __pstl; + return __internal::__pattern_transform_scan( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __result, + __pstl::__internal::__no_op(), + __init, + __binary_op, + /*inclusive=*/std::false_type()); } // [inclusive.scan] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result) -{ - typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType; - return transform_inclusive_scan(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, - std::plus<_InputType>(), __pstl::__internal::__no_op()); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan( + _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result) { + typedef typename iterator_traits<_ForwardIterator1>::value_type _InputType; + return transform_inclusive_scan( + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __result, + std::plus<_InputType>(), + __pstl::__internal::__no_op()); } template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _BinaryOperation __binary_op) -{ - return transform_inclusive_scan(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __binary_op, - __pstl::__internal::__no_op()); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _BinaryOperation __binary_op) { + return transform_inclusive_scan( + std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __binary_op, __pstl::__internal::__no_op()); } template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _BinaryOperation __binary_op, _Tp __init) -{ - return transform_inclusive_scan(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __binary_op, - __pstl::__internal::__no_op(), __init); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> inclusive_scan( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _BinaryOperation __binary_op, + _Tp __init) { + return transform_inclusive_scan( + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __result, + __binary_op, + __pstl::__internal::__no_op(), + __init); } // [transform.exclusive.scan] -template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -transform_exclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _Tp __init, _BinaryOperation __binary_op, - _UnaryOperation __unary_op) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); - - return __pstl::__internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __result, __unary_op, __init, __binary_op, - /*inclusive=*/std::false_type()); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_exclusive_scan( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _Tp __init, + _BinaryOperation __binary_op, + _UnaryOperation __unary_op) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); + + return __pstl::__internal::__pattern_transform_scan( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __result, + __unary_op, + __init, + __binary_op, + /*inclusive=*/std::false_type()); } // [transform.inclusive.scan] -template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -transform_inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _BinaryOperation __binary_op, _UnaryOperation __unary_op, - _Tp __init) -{ - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); - - return __pstl::__internal::__pattern_transform_scan(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, - __last, __result, __unary_op, __init, __binary_op, - /*inclusive=*/std::true_type()); +template +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _BinaryOperation __binary_op, + _UnaryOperation __unary_op, + _Tp __init) { + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __result); + + return __pstl::__internal::__pattern_transform_scan( + __dispatch_tag, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + __result, + __unary_op, + __init, + __binary_op, + /*inclusive=*/std::true_type()); } -template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -transform_inclusive_scan(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __result, _BinaryOperation __binary_op, _UnaryOperation __unary_op) -{ - if (__first != __last) - { - auto __tmp = __unary_op(*__first); - *__result = __tmp; - return transform_inclusive_scan(std::forward<_ExecutionPolicy>(__exec), ++__first, __last, ++__result, - __binary_op, __unary_op, __tmp); - } - else - { - return __result; - } +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> transform_inclusive_scan( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __result, + _BinaryOperation __binary_op, + _UnaryOperation __unary_op) { + if (__first != __last) { + auto __tmp = __unary_op(*__first); + *__result = __tmp; + return transform_inclusive_scan( + std::forward<_ExecutionPolicy>(__exec), ++__first, __last, ++__result, __binary_op, __unary_op, __tmp); + } else { + return __result; + } } // [adjacent.difference] template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __d_first, _BinaryOperation __op) -{ - - if (__first == __last) - return __d_first; - - auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first); - - return __pstl::__internal::__pattern_adjacent_difference(__dispatch_tag, std::forward<_ExecutionPolicy>(__exec), - __first, __last, __d_first, __op); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference( + _ExecutionPolicy&& __exec, + _ForwardIterator1 __first, + _ForwardIterator1 __last, + _ForwardIterator2 __d_first, + _BinaryOperation __op) { + if (__first == __last) + return __d_first; + + auto __dispatch_tag = __pstl::__internal::__select_backend(__exec, __first, __d_first); + + return __pstl::__internal::__pattern_adjacent_difference( + __dispatch_tag, std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __op); } template -__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> -adjacent_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, - _ForwardIterator2 __d_first) -{ - typedef typename iterator_traits<_ForwardIterator1>::value_type _ValueType; - return adjacent_difference(std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, - std::minus<_ValueType>()); +__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> adjacent_difference( + _ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first) { + typedef typename iterator_traits<_ForwardIterator1>::value_type _ValueType; + return adjacent_difference( + std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, std::minus<_ValueType>()); } } // namespace std diff --git a/libcxx/include/pstl/internal/memory_impl.h b/libcxx/include/pstl/internal/memory_impl.h --- a/libcxx/include/pstl/internal/memory_impl.h +++ b/libcxx/include/pstl/internal/memory_impl.h @@ -17,60 +17,56 @@ _PSTL_HIDE_FROM_ABI_PUSH -namespace __pstl -{ -namespace __internal -{ +namespace __pstl { +namespace __internal { //------------------------------------------------------------------------ // uninitialized_move //------------------------------------------------------------------------ template -_OutputIterator -__brick_uninitialized_move(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, - /*vector=*/std::false_type) noexcept -{ - using _ValueType = typename std::iterator_traits<_OutputIterator>::value_type; - for (; __first != __last; ++__first, ++__result) - { - ::new (std::addressof(*__result)) _ValueType(std::move(*__first)); - } - return __result; +_OutputIterator __brick_uninitialized_move( + _ForwardIterator __first, + _ForwardIterator __last, + _OutputIterator __result, + /*vector=*/std::false_type) noexcept { + using _ValueType = typename std::iterator_traits<_OutputIterator>::value_type; + for (; __first != __last; ++__first, ++__result) { + ::new (std::addressof(*__result)) _ValueType(std::move(*__first)); + } + return __result; } template -_OutputIterator -__brick_uninitialized_move(_RandomAccessIterator __first, _RandomAccessIterator __last, _OutputIterator __result, - /*vector=*/std::true_type) noexcept -{ - using __ValueType = typename std::iterator_traits<_OutputIterator>::value_type; - using _ReferenceType1 = typename std::iterator_traits<_RandomAccessIterator>::reference; - using _ReferenceType2 = typename std::iterator_traits<_OutputIterator>::reference; - - return __unseq_backend::__simd_walk_2( - __first, __last - __first, __result, - [](_ReferenceType1 __x, _ReferenceType2 __y) { ::new (std::addressof(__y)) __ValueType(std::move(__x)); }); +_OutputIterator __brick_uninitialized_move( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _OutputIterator __result, + /*vector=*/std::true_type) noexcept { + using __ValueType = typename std::iterator_traits<_OutputIterator>::value_type; + using _ReferenceType1 = typename std::iterator_traits<_RandomAccessIterator>::reference; + using _ReferenceType2 = typename std::iterator_traits<_OutputIterator>::reference; + + return __unseq_backend::__simd_walk_2( + __first, __last - __first, __result, [](_ReferenceType1 __x, _ReferenceType2 __y) { + ::new (std::addressof(__y)) __ValueType(std::move(__x)); + }); } template -void -__brick_destroy(_Iterator __first, _Iterator __last, /*vector*/ std::false_type) noexcept -{ - using _ValueType = typename std::iterator_traits<_Iterator>::value_type; +void __brick_destroy(_Iterator __first, _Iterator __last, /*vector*/ std::false_type) noexcept { + using _ValueType = typename std::iterator_traits<_Iterator>::value_type; - for (; __first != __last; ++__first) - __first->~_ValueType(); + for (; __first != __last; ++__first) + __first->~_ValueType(); } template -void -__brick_destroy(_RandomAccessIterator __first, _RandomAccessIterator __last, /*vector*/ std::true_type) noexcept -{ - using _ValueType = typename std::iterator_traits<_RandomAccessIterator>::value_type; - using _ReferenceType = typename std::iterator_traits<_RandomAccessIterator>::reference; +void __brick_destroy(_RandomAccessIterator __first, _RandomAccessIterator __last, /*vector*/ std::true_type) noexcept { + using _ValueType = typename std::iterator_traits<_RandomAccessIterator>::value_type; + using _ReferenceType = typename std::iterator_traits<_RandomAccessIterator>::reference; - __unseq_backend::__simd_walk_1(__first, __last - __first, [](_ReferenceType __x) { __x.~_ValueType(); }); + __unseq_backend::__simd_walk_1(__first, __last - __first, [](_ReferenceType __x) { __x.~_ValueType(); }); } //------------------------------------------------------------------------ @@ -78,30 +74,32 @@ //------------------------------------------------------------------------ template -_OutputIterator -__brick_uninitialized_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, - /*vector=*/std::false_type) noexcept -{ - using _ValueType = typename std::iterator_traits<_OutputIterator>::value_type; - for (; __first != __last; ++__first, ++__result) - { - ::new (std::addressof(*__result)) _ValueType(*__first); - } - return __result; +_OutputIterator __brick_uninitialized_copy( + _ForwardIterator __first, + _ForwardIterator __last, + _OutputIterator __result, + /*vector=*/std::false_type) noexcept { + using _ValueType = typename std::iterator_traits<_OutputIterator>::value_type; + for (; __first != __last; ++__first, ++__result) { + ::new (std::addressof(*__result)) _ValueType(*__first); + } + return __result; } template -_OutputIterator -__brick_uninitialized_copy(_RandomAccessIterator __first, _RandomAccessIterator __last, _OutputIterator __result, - /*vector=*/std::true_type) noexcept -{ - using __ValueType = typename std::iterator_traits<_OutputIterator>::value_type; - using _ReferenceType1 = typename std::iterator_traits<_RandomAccessIterator>::reference; - using _ReferenceType2 = typename std::iterator_traits<_OutputIterator>::reference; - - return __unseq_backend::__simd_walk_2( - __first, __last - __first, __result, - [](_ReferenceType1 __x, _ReferenceType2 __y) { ::new (std::addressof(__y)) __ValueType(__x); }); +_OutputIterator __brick_uninitialized_copy( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _OutputIterator __result, + /*vector=*/std::true_type) noexcept { + using __ValueType = typename std::iterator_traits<_OutputIterator>::value_type; + using _ReferenceType1 = typename std::iterator_traits<_RandomAccessIterator>::reference; + using _ReferenceType2 = typename std::iterator_traits<_OutputIterator>::reference; + + return __unseq_backend::__simd_walk_2( + __first, __last - __first, __result, [](_ReferenceType1 __x, _ReferenceType2 __y) { + ::new (std::addressof(__y)) __ValueType(__x); + }); } } // namespace __internal diff --git a/libcxx/include/pstl/internal/numeric_fwd.h b/libcxx/include/pstl/internal/numeric_fwd.h --- a/libcxx/include/pstl/internal/numeric_fwd.h +++ b/libcxx/include/pstl/internal/numeric_fwd.h @@ -17,61 +17,116 @@ _PSTL_HIDE_FROM_ABI_PUSH -namespace __pstl -{ -namespace __internal -{ +namespace __pstl { +namespace __internal { //------------------------------------------------------------------------ // transform_reduce (version with two binary functions, according to draft N4659) //------------------------------------------------------------------------ -template -_Tp __brick_transform_reduce(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, _Tp, - _BinaryOperation1, _BinaryOperation2, - /*__is_vector=*/std::true_type) noexcept; +_Tp __brick_transform_reduce( + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _Tp, + _BinaryOperation1, + _BinaryOperation2, + /*__is_vector=*/std::true_type) noexcept; template -_Tp __brick_transform_reduce(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Tp, _BinaryOperation1, - _BinaryOperation2, - /*__is_vector=*/std::false_type) noexcept; - -template -_Tp -__pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Tp, - _BinaryOperation1, _BinaryOperation2) noexcept; - -template -_Tp -__pattern_transform_reduce(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator1, - _RandomAccessIterator1, _RandomAccessIterator2, _Tp, _BinaryOperation1, _BinaryOperation2); +_Tp __brick_transform_reduce( + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _Tp, + _BinaryOperation1, + _BinaryOperation2, + /*__is_vector=*/std::false_type) noexcept; + +template +_Tp __pattern_transform_reduce( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1, + _ForwardIterator1, + _ForwardIterator2, + _Tp, + _BinaryOperation1, + _BinaryOperation2) noexcept; + +template +_Tp __pattern_transform_reduce( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator1, + _RandomAccessIterator1, + _RandomAccessIterator2, + _Tp, + _BinaryOperation1, + _BinaryOperation2); //------------------------------------------------------------------------ // transform_reduce (version with unary and binary functions) //------------------------------------------------------------------------ template -_Tp __brick_transform_reduce(_RandomAccessIterator, _RandomAccessIterator, _Tp, _BinaryOperation, _UnaryOperation, - /*is_vector=*/std::true_type) noexcept; +_Tp __brick_transform_reduce( + _RandomAccessIterator, + _RandomAccessIterator, + _Tp, + _BinaryOperation, + _UnaryOperation, + /*is_vector=*/std::true_type) noexcept; template -_Tp __brick_transform_reduce(_ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation, _UnaryOperation, - /*is_vector=*/std::false_type) noexcept; +_Tp __brick_transform_reduce( + _ForwardIterator, + _ForwardIterator, + _Tp, + _BinaryOperation, + _UnaryOperation, + /*is_vector=*/std::false_type) noexcept; -template -_Tp -__pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation, - _UnaryOperation) noexcept; +_Tp __pattern_transform_reduce( + _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation, _UnaryOperation) noexcept; -template -_Tp -__pattern_transform_reduce(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _Tp, _BinaryOperation, _UnaryOperation); +_Tp __pattern_transform_reduce( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator, + _RandomAccessIterator, + _Tp, + _BinaryOperation, + _UnaryOperation); //------------------------------------------------------------------------ // transform_exclusive_scan @@ -80,56 +135,118 @@ //------------------------------------------------------------------------ template -std::pair<_OutputIterator, _Tp> __brick_transform_scan(_ForwardIterator, _ForwardIterator, _OutputIterator, - _UnaryOperation, _Tp, _BinaryOperation, - /*Inclusive*/ std::false_type) noexcept; +std::pair<_OutputIterator, _Tp> __brick_transform_scan( + _ForwardIterator, + _ForwardIterator, + _OutputIterator, + _UnaryOperation, + _Tp, + _BinaryOperation, + /*Inclusive*/ std::false_type) noexcept; template -std::pair<_OutputIterator, _Tp> __brick_transform_scan(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, - _UnaryOperation, _Tp, _BinaryOperation, - /*Inclusive*/ std::true_type) noexcept; - -template -_OutputIterator -__pattern_transform_scan(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryOperation, - _Tp, _BinaryOperation, _Inclusive) noexcept; - -template -typename std::enable_if::value, _OutputIterator>::type -__pattern_transform_scan(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&&, _RandomAccessIterator, - _RandomAccessIterator, _OutputIterator, _UnaryOperation, _Tp, _BinaryOperation, _Inclusive); - -template -typename std::enable_if::value, _OutputIterator>::type -__pattern_transform_scan(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, - _OutputIterator, _UnaryOperation, _Tp, _BinaryOperation, _Inclusive); +std::pair<_OutputIterator, _Tp> __brick_transform_scan( + _RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator, + _UnaryOperation, + _Tp, + _BinaryOperation, + /*Inclusive*/ std::true_type) noexcept; + +template +_OutputIterator __pattern_transform_scan( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator, + _ForwardIterator, + _OutputIterator, + _UnaryOperation, + _Tp, + _BinaryOperation, + _Inclusive) noexcept; + +template +typename std::enable_if::value, _OutputIterator>::type __pattern_transform_scan( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&&, + _RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator, + _UnaryOperation, + _Tp, + _BinaryOperation, + _Inclusive); + +template +typename std::enable_if::value, _OutputIterator>::type __pattern_transform_scan( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator, + _UnaryOperation, + _Tp, + _BinaryOperation, + _Inclusive); //------------------------------------------------------------------------ // adjacent_difference //------------------------------------------------------------------------ template -_OutputIterator __brick_adjacent_difference(_ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryOperation, - /*is_vector*/ std::false_type) noexcept; +_OutputIterator __brick_adjacent_difference( + _ForwardIterator, + _ForwardIterator, + _OutputIterator, + _BinaryOperation, + /*is_vector*/ std::false_type) noexcept; template -_OutputIterator __brick_adjacent_difference(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, - _BinaryOperation, - /*is_vector*/ std::true_type) noexcept; +_OutputIterator __brick_adjacent_difference( + _RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator, + _BinaryOperation, + /*is_vector*/ std::true_type) noexcept; template -_OutputIterator -__pattern_adjacent_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, - _BinaryOperation) noexcept; +_OutputIterator __pattern_adjacent_difference( + _Tag, _ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryOperation) noexcept; -template -_OutputIterator -__pattern_adjacent_difference(__parallel_tag<_IsVector>, _ExecutionPolicy&&, _RandomAccessIterator, - _RandomAccessIterator, _OutputIterator, _BinaryOperation); +_OutputIterator __pattern_adjacent_difference( + __parallel_tag<_IsVector>, + _ExecutionPolicy&&, + _RandomAccessIterator, + _RandomAccessIterator, + _OutputIterator, + _BinaryOperation); } // namespace __internal } // namespace __pstl diff --git a/libcxx/include/pstl/internal/numeric_impl.h b/libcxx/include/pstl/internal/numeric_impl.h --- a/libcxx/include/pstl/internal/numeric_impl.h +++ b/libcxx/include/pstl/internal/numeric_impl.h @@ -22,74 +22,100 @@ _PSTL_HIDE_FROM_ABI_PUSH -namespace __pstl -{ -namespace __internal -{ +namespace __pstl { +namespace __internal { //------------------------------------------------------------------------ // transform_reduce (version with two binary functions, according to draft N4659) //------------------------------------------------------------------------ template -_Tp -__brick_transform_reduce(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Tp __init, - _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2, - /*is_vector=*/std::false_type) noexcept -{ - return std::inner_product(__first1, __last1, __first2, __init, __binary_op1, __binary_op2); +_Tp __brick_transform_reduce( + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _Tp __init, + _BinaryOperation1 __binary_op1, + _BinaryOperation2 __binary_op2, + /*is_vector=*/std::false_type) noexcept { + return std::inner_product(__first1, __last1, __first2, __init, __binary_op1, __binary_op2); } -template -_Tp -__brick_transform_reduce(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, - _RandomAccessIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, - _BinaryOperation2 __binary_op2, - /*is_vector=*/std::true_type) noexcept -{ - typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; - return __unseq_backend::__simd_transform_reduce( - __last1 - __first1, __init, __binary_op1, - [=, &__binary_op2](_DifferenceType __i) { return __binary_op2(__first1[__i], __first2[__i]); }); +_Tp __brick_transform_reduce( + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _Tp __init, + _BinaryOperation1 __binary_op1, + _BinaryOperation2 __binary_op2, + /*is_vector=*/std::true_type) noexcept { + typedef typename std::iterator_traits<_RandomAccessIterator1>::difference_type _DifferenceType; + return __unseq_backend::__simd_transform_reduce( + __last1 - __first1, __init, __binary_op1, [=, &__binary_op2](_DifferenceType __i) { + return __binary_op2(__first1[__i], __first2[__i]); + }); } -template -_Tp -__pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, - _ForwardIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, - _BinaryOperation2 __binary_op2) noexcept -{ - return __brick_transform_reduce(__first1, __last1, __first2, __init, __binary_op1, __binary_op2, - typename _Tag::__is_vector{}); +template +_Tp __pattern_transform_reduce( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator1 __first1, + _ForwardIterator1 __last1, + _ForwardIterator2 __first2, + _Tp __init, + _BinaryOperation1 __binary_op1, + _BinaryOperation2 __binary_op2) noexcept { + return __brick_transform_reduce( + __first1, __last1, __first2, __init, __binary_op1, __binary_op2, typename _Tag::__is_vector{}); } -template -_Tp -__pattern_transform_reduce(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, - _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _Tp __init, - _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - return __internal::__except_handler( - [&]() - { - return __par_backend::__parallel_transform_reduce( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first1, __last1, - [__first1, __first2, __binary_op2](_RandomAccessIterator1 __i) mutable - { return __binary_op2(*__i, *(__first2 + (__i - __first1))); }, - __init, - __binary_op1, // Combine - [__first1, __first2, __binary_op1, __binary_op2](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j, - _Tp __init) -> _Tp - { - return __internal::__brick_transform_reduce(__i, __j, __first2 + (__i - __first1), __init, - __binary_op1, __binary_op2, _IsVector{}); - }); +template +_Tp __pattern_transform_reduce( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first1, + _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, + _Tp __init, + _BinaryOperation1 __binary_op1, + _BinaryOperation2 __binary_op2) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&]() { + return __par_backend::__parallel_transform_reduce( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first1, + __last1, + [__first1, __first2, __binary_op2](_RandomAccessIterator1 __i) mutable { + return __binary_op2(*__i, *(__first2 + (__i - __first1))); + }, + __init, + __binary_op1, // Combine + [__first1, __first2, __binary_op1, __binary_op2]( + _RandomAccessIterator1 __i, _RandomAccessIterator1 __j, _Tp __init) -> _Tp { + return __internal::__brick_transform_reduce( + __i, __j, __first2 + (__i - __first1), __init, __binary_op1, __binary_op2, _IsVector{}); }); + }); } //------------------------------------------------------------------------ @@ -97,54 +123,78 @@ //------------------------------------------------------------------------ template -_Tp -__brick_transform_reduce(_ForwardIterator __first, _ForwardIterator __last, _Tp __init, _BinaryOperation __binary_op, - _UnaryOperation __unary_op, /*is_vector=*/std::false_type) noexcept -{ - return std::transform_reduce(__first, __last, __init, __binary_op, __unary_op); +_Tp __brick_transform_reduce( + _ForwardIterator __first, + _ForwardIterator __last, + _Tp __init, + _BinaryOperation __binary_op, + _UnaryOperation __unary_op, + /*is_vector=*/std::false_type) noexcept { + return std::transform_reduce(__first, __last, __init, __binary_op, __unary_op); } template -_Tp -__brick_transform_reduce(_RandomAccessIterator __first, _RandomAccessIterator __last, _Tp __init, - _BinaryOperation __binary_op, _UnaryOperation __unary_op, - /*is_vector=*/std::true_type) noexcept -{ - typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; - return __unseq_backend::__simd_transform_reduce( - __last - __first, __init, __binary_op, - [=, &__unary_op](_DifferenceType __i) { return __unary_op(__first[__i]); }); +_Tp __brick_transform_reduce( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Tp __init, + _BinaryOperation __binary_op, + _UnaryOperation __unary_op, + /*is_vector=*/std::true_type) noexcept { + typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; + return __unseq_backend::__simd_transform_reduce( + __last - __first, __init, __binary_op, [=, &__unary_op](_DifferenceType __i) { + return __unary_op(__first[__i]); + }); } -template -_Tp -__pattern_transform_reduce(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Tp __init, - _BinaryOperation __binary_op, _UnaryOperation __unary_op) noexcept -{ - return __internal::__brick_transform_reduce(__first, __last, __init, __binary_op, __unary_op, - typename _Tag::__is_vector{}); +_Tp __pattern_transform_reduce( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator __first, + _ForwardIterator __last, + _Tp __init, + _BinaryOperation __binary_op, + _UnaryOperation __unary_op) noexcept { + return __internal::__brick_transform_reduce( + __first, __last, __init, __binary_op, __unary_op, typename _Tag::__is_vector{}); } -template -_Tp -__pattern_transform_reduce(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _Tp __init, _BinaryOperation __binary_op, - _UnaryOperation __unary_op) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - return __internal::__except_handler( - [&]() - { - return __par_backend::__parallel_transform_reduce( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__unary_op](_RandomAccessIterator __i) mutable { return __unary_op(*__i); }, __init, __binary_op, - [__unary_op, __binary_op](_RandomAccessIterator __i, _RandomAccessIterator __j, _Tp __init) { - return __internal::__brick_transform_reduce(__i, __j, __init, __binary_op, __unary_op, _IsVector{}); - }); +_Tp __pattern_transform_reduce( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _Tp __init, + _BinaryOperation __binary_op, + _UnaryOperation __unary_op) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + return __internal::__except_handler([&]() { + return __par_backend::__parallel_transform_reduce( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last, + [__unary_op](_RandomAccessIterator __i) mutable { return __unary_op(*__i); }, + __init, + __binary_op, + [__unary_op, __binary_op](_RandomAccessIterator __i, _RandomAccessIterator __j, _Tp __init) { + return __internal::__brick_transform_reduce(__i, __j, __init, __binary_op, __unary_op, _IsVector{}); }); + }); } //------------------------------------------------------------------------ @@ -155,159 +205,247 @@ // Exclusive form template -std::pair<_OutputIterator, _Tp> -__brick_transform_scan(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, - _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, - /*Inclusive*/ std::false_type, /*is_vector=*/std::false_type) noexcept -{ - for (; __first != __last; ++__first, ++__result) - { - *__result = __init; - _PSTL_PRAGMA_FORCEINLINE - __init = __binary_op(__init, __unary_op(*__first)); - } - return std::make_pair(__result, __init); +std::pair<_OutputIterator, _Tp> __brick_transform_scan( + _ForwardIterator __first, + _ForwardIterator __last, + _OutputIterator __result, + _UnaryOperation __unary_op, + _Tp __init, + _BinaryOperation __binary_op, + /*Inclusive*/ std::false_type, + /*is_vector=*/std::false_type) noexcept { + for (; __first != __last; ++__first, ++__result) { + *__result = __init; + _PSTL_PRAGMA_FORCEINLINE + __init = __binary_op(__init, __unary_op(*__first)); + } + return std::make_pair(__result, __init); } // Inclusive form template -std::pair<_OutputIterator, _Tp> -__brick_transform_scan(_RandomAccessIterator __first, _RandomAccessIterator __last, _OutputIterator __result, - _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, - /*Inclusive*/ std::true_type, /*is_vector=*/std::false_type) noexcept -{ - for (; __first != __last; ++__first, ++__result) - { - _PSTL_PRAGMA_FORCEINLINE - __init = __binary_op(__init, __unary_op(*__first)); - *__result = __init; - } - return std::make_pair(__result, __init); +std::pair<_OutputIterator, _Tp> __brick_transform_scan( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _OutputIterator __result, + _UnaryOperation __unary_op, + _Tp __init, + _BinaryOperation __binary_op, + /*Inclusive*/ std::true_type, + /*is_vector=*/std::false_type) noexcept { + for (; __first != __last; ++__first, ++__result) { + _PSTL_PRAGMA_FORCEINLINE + __init = __binary_op(__init, __unary_op(*__first)); + *__result = __init; + } + return std::make_pair(__result, __init); } // type is arithmetic and binary operation is a user defined operation. template -using is_arithmetic_udop = std::integral_constant::value && - !std::is_same<_BinaryOperation, std::plus<_Tp>>::value>; +using is_arithmetic_udop = + std::integral_constant::value && !std::is_same<_BinaryOperation, std::plus<_Tp>>::value>; // [restriction] - T shall be DefaultConstructible. // [violation] - default ctor of T shall set the identity value for binary_op. -template typename std::enable_if::value, std::pair<_OutputIterator, _Tp>>::type -__brick_transform_scan(_RandomAccessIterator __first, _RandomAccessIterator __last, _OutputIterator __result, - _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, _Inclusive, - /*is_vector=*/std::true_type) noexcept -{ +__brick_transform_scan( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _OutputIterator __result, + _UnaryOperation __unary_op, + _Tp __init, + _BinaryOperation __binary_op, + _Inclusive, + /*is_vector=*/std::true_type) noexcept { #if defined(_PSTL_UDS_PRESENT) - return __unseq_backend::__simd_scan(__first, __last - __first, __result, __unary_op, __init, __binary_op, - _Inclusive()); + return __unseq_backend::__simd_scan( + __first, __last - __first, __result, __unary_op, __init, __binary_op, _Inclusive()); #else - // We need to call serial brick here to call function for inclusive and exclusive scan that depends on _Inclusive() value - return __internal::__brick_transform_scan(__first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(), - /*is_vector=*/std::false_type()); + // We need to call serial brick here to call function for inclusive and exclusive scan that depends on _Inclusive() value + return __internal::__brick_transform_scan( + __first, + __last, + __result, + __unary_op, + __init, + __binary_op, + _Inclusive(), + /*is_vector=*/std::false_type()); #endif } -template typename std::enable_if::value, std::pair<_OutputIterator, _Tp>>::type -__brick_transform_scan(_RandomAccessIterator __first, _RandomAccessIterator __last, _OutputIterator __result, - _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, _Inclusive, - /*is_vector=*/std::true_type) noexcept -{ - return __internal::__brick_transform_scan(__first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(), - /*is_vector=*/std::false_type()); +__brick_transform_scan( + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _OutputIterator __result, + _UnaryOperation __unary_op, + _Tp __init, + _BinaryOperation __binary_op, + _Inclusive, + /*is_vector=*/std::true_type) noexcept { + return __internal::__brick_transform_scan( + __first, + __last, + __result, + __unary_op, + __init, + __binary_op, + _Inclusive(), + /*is_vector=*/std::false_type()); } -template -_OutputIterator -__pattern_transform_scan(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, _BinaryOperation __binary_op, - _Inclusive) noexcept -{ - return __internal::__brick_transform_scan(__first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(), - typename _Tag::__is_vector{}) - .first; +template +_OutputIterator __pattern_transform_scan( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator __first, + _ForwardIterator __last, + _OutputIterator __result, + _UnaryOperation __unary_op, + _Tp __init, + _BinaryOperation __binary_op, + _Inclusive) noexcept { + return __internal::__brick_transform_scan( + __first, __last, __result, __unary_op, __init, __binary_op, _Inclusive(), typename _Tag::__is_vector{}) + .first; } -template -typename std::enable_if::value, _OutputIterator>::type -__pattern_transform_scan(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, - _BinaryOperation __binary_op, _Inclusive) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; - - return __internal::__except_handler( - [&]() - { - __par_backend::__parallel_transform_scan( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __last - __first, - [__first, __unary_op](_DifferenceType __i) mutable { return __unary_op(__first[__i]); }, __init, - __binary_op, - [__first, __unary_op, __binary_op](_DifferenceType __i, _DifferenceType __j, _Tp __init) - { - // Execute serial __brick_transform_reduce, due to the explicit SIMD vectorization (reduction) requires a commutative operation for the guarantee of correct scan. - return __internal::__brick_transform_reduce(__first + __i, __first + __j, __init, __binary_op, - __unary_op, - /*__is_vector*/ std::false_type()); - }, - [__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __j, _Tp __init) - { - return __internal::__brick_transform_scan(__first + __i, __first + __j, __result + __i, __unary_op, - __init, __binary_op, _Inclusive(), _IsVector{}) - .second; - }); - return __result + (__last - __first); +template +typename std::enable_if::value, _OutputIterator>::type __pattern_transform_scan( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _OutputIterator __result, + _UnaryOperation __unary_op, + _Tp __init, + _BinaryOperation __binary_op, + _Inclusive) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; + + return __internal::__except_handler([&]() { + __par_backend::__parallel_transform_scan( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __last - __first, + [__first, __unary_op](_DifferenceType __i) mutable { return __unary_op(__first[__i]); }, + __init, + __binary_op, + [__first, __unary_op, __binary_op](_DifferenceType __i, _DifferenceType __j, _Tp __init) { + // Execute serial __brick_transform_reduce, due to the explicit SIMD vectorization (reduction) requires a commutative operation for the guarantee of correct scan. + return __internal::__brick_transform_reduce( + __first + __i, + __first + __j, + __init, + __binary_op, + __unary_op, + /*__is_vector*/ std::false_type()); + }, + [__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __j, _Tp __init) { + return __internal::__brick_transform_scan( + __first + __i, + __first + __j, + __result + __i, + __unary_op, + __init, + __binary_op, + _Inclusive(), + _IsVector{}) + .second; }); + return __result + (__last - __first); + }); } -template -typename std::enable_if::value, _OutputIterator>::type -__pattern_transform_scan(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, _RandomAccessIterator __first, - _RandomAccessIterator __last, _OutputIterator __result, _UnaryOperation __unary_op, _Tp __init, - _BinaryOperation __binary_op, _Inclusive) -{ - using __backend_tag = typename decltype(__tag)::__backend_tag; - - typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; - _DifferenceType __n = __last - __first; - - if (__n <= 0) - { - return __result; - } - return __internal::__except_handler( - [&]() - { - __par_backend::__parallel_strict_scan( - __backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __n, __init, - [__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __len) - { - return __internal::__brick_transform_scan(__first + __i, __first + (__i + __len), __result + __i, - __unary_op, _Tp{}, __binary_op, _Inclusive(), _IsVector{}) - .second; - }, - __binary_op, - [__result, &__binary_op](_DifferenceType __i, _DifferenceType __len, _Tp __initial) - { - return *(std::transform(__result + __i, __result + __i + __len, __result + __i, - [&__initial, &__binary_op](const _Tp& __x) - { - _PSTL_PRAGMA_FORCEINLINE - return __binary_op(__initial, __x); - }) - - 1); - }, - [](_Tp) {}); - return __result + (__last - __first); - }); +template +typename std::enable_if::value, _OutputIterator>::type __pattern_transform_scan( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator __first, + _RandomAccessIterator __last, + _OutputIterator __result, + _UnaryOperation __unary_op, + _Tp __init, + _BinaryOperation __binary_op, + _Inclusive) { + using __backend_tag = typename decltype(__tag)::__backend_tag; + + typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType; + _DifferenceType __n = __last - __first; + + if (__n <= 0) { + return __result; + } + return __internal::__except_handler([&]() { + __par_backend::__parallel_strict_scan( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __n, + __init, + [__first, __unary_op, __binary_op, __result](_DifferenceType __i, _DifferenceType __len) { + return __internal::__brick_transform_scan( + __first + __i, + __first + (__i + __len), + __result + __i, + __unary_op, + _Tp{}, + __binary_op, + _Inclusive(), + _IsVector{}) + .second; + }, + __binary_op, + [__result, &__binary_op](_DifferenceType __i, _DifferenceType __len, _Tp __initial) { + return *(std::transform(__result + __i, + __result + __i + __len, + __result + __i, + [&__initial, &__binary_op](const _Tp& __x) { + _PSTL_PRAGMA_FORCEINLINE + return __binary_op(__initial, __x); + }) - + 1); + }, + [](_Tp) {}); + return __result + (__last - __first); + }); } //------------------------------------------------------------------------ @@ -315,64 +453,83 @@ //------------------------------------------------------------------------ template -_OutputIterator -__brick_adjacent_difference(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __d_first, - _BinaryOperation __op, /*is_vector*/ std::false_type) noexcept -{ - return std::adjacent_difference(__first, __last, __d_first, __op); +_OutputIterator __brick_adjacent_difference( + _ForwardIterator __first, + _ForwardIterator __last, + _OutputIterator __d_first, + _BinaryOperation __op, + /*is_vector*/ std::false_type) noexcept { + return std::adjacent_difference(__first, __last, __d_first, __op); } template -_RandomAccessIterator2 -__brick_adjacent_difference(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, - _RandomAccessIterator2 __d_first, BinaryOperation __op, - /*is_vector=*/std::true_type) noexcept -{ - _PSTL_ASSERT(__first != __last); - - typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1; - typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2; - - auto __n = __last - __first; - *__d_first = *__first; - return __unseq_backend::__simd_walk_3( - __first + 1, __n - 1, __first, __d_first + 1, - [&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z) { __z = __op(__x, __y); }); +_RandomAccessIterator2 __brick_adjacent_difference( + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __d_first, + BinaryOperation __op, + /*is_vector=*/std::true_type) noexcept { + _PSTL_ASSERT(__first != __last); + + typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1; + typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2; + + auto __n = __last - __first; + *__d_first = *__first; + return __unseq_backend::__simd_walk_3( + __first + 1, + __n - 1, + __first, + __d_first + 1, + [&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z) { __z = __op(__x, __y); }); } template -_OutputIterator -__pattern_adjacent_difference(_Tag, _ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, - _OutputIterator __d_first, _BinaryOperation __op) noexcept -{ - return __internal::__brick_adjacent_difference(__first, __last, __d_first, __op, typename _Tag::__is_vector{}); +_OutputIterator __pattern_adjacent_difference( + _Tag, + _ExecutionPolicy&&, + _ForwardIterator __first, + _ForwardIterator __last, + _OutputIterator __d_first, + _BinaryOperation __op) noexcept { + return __internal::__brick_adjacent_difference(__first, __last, __d_first, __op, typename _Tag::__is_vector{}); } -template -_RandomAccessIterator2 -__pattern_adjacent_difference(__parallel_tag<_IsVector> __tag, _ExecutionPolicy&& __exec, - _RandomAccessIterator1 __first, _RandomAccessIterator1 __last, - _RandomAccessIterator2 __d_first, _BinaryOperation __op) -{ - _PSTL_ASSERT(__first != __last); - typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1; - typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2; - - using __backend_tag = typename decltype(__tag)::__backend_tag; - - *__d_first = *__first; - __par_backend::__parallel_for(__backend_tag{}, std::forward<_ExecutionPolicy>(__exec), __first, __last - 1, - [&__op, __d_first, __first](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e) - { - _RandomAccessIterator2 __d_b = __d_first + (__b - __first); - __internal::__brick_walk3( - __b, __e, __b + 1, __d_b + 1, - [&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z) - { __z = __op(__y, __x); }, - _IsVector{}); - }); - return __d_first + (__last - __first); +_RandomAccessIterator2 __pattern_adjacent_difference( + __parallel_tag<_IsVector> __tag, + _ExecutionPolicy&& __exec, + _RandomAccessIterator1 __first, + _RandomAccessIterator1 __last, + _RandomAccessIterator2 __d_first, + _BinaryOperation __op) { + _PSTL_ASSERT(__first != __last); + typedef typename std::iterator_traits<_RandomAccessIterator1>::reference _ReferenceType1; + typedef typename std::iterator_traits<_RandomAccessIterator2>::reference _ReferenceType2; + + using __backend_tag = typename decltype(__tag)::__backend_tag; + + *__d_first = *__first; + __par_backend::__parallel_for( + __backend_tag{}, + std::forward<_ExecutionPolicy>(__exec), + __first, + __last - 1, + [&__op, __d_first, __first](_RandomAccessIterator1 __b, _RandomAccessIterator1 __e) { + _RandomAccessIterator2 __d_b = __d_first + (__b - __first); + __internal::__brick_walk3( + __b, + __e, + __b + 1, + __d_b + 1, + [&__op](_ReferenceType1 __x, _ReferenceType1 __y, _ReferenceType2 __z) { __z = __op(__y, __x); }, + _IsVector{}); + }); + return __d_first + (__last - __first); } } // namespace __internal diff --git a/libcxx/include/pstl/internal/utils.h b/libcxx/include/pstl/internal/utils.h --- a/libcxx/include/pstl/internal/utils.h +++ b/libcxx/include/pstl/internal/utils.h @@ -10,168 +10,127 @@ #ifndef _PSTL_UTILS_H #define _PSTL_UTILS_H -#include #include +#include #include _PSTL_HIDE_FROM_ABI_PUSH -namespace __pstl -{ -namespace __internal -{ +namespace __pstl { +namespace __internal { template -auto -__except_handler(_Fp __f) -> decltype(__f()) -{ +auto __except_handler(_Fp __f) -> decltype(__f()) { #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - try - { + try { #endif // _LIBCPP_HAS_NO_EXCEPTIONS - return __f(); + return __f(); #ifndef _LIBCPP_HAS_NO_EXCEPTIONS - } - catch (const std::bad_alloc&) - { - throw; // re-throw bad_alloc according to the standard [algorithms.parallel.exceptions] - } - catch (...) - { - std::terminate(); // Good bye according to the standard [algorithms.parallel.exceptions] - } + } catch (const std::bad_alloc&) { + throw; // re-throw bad_alloc according to the standard [algorithms.parallel.exceptions] + } catch (...) { + std::terminate(); // Good bye according to the standard [algorithms.parallel.exceptions] + } #endif // _LIBCPP_HAS_NO_EXCEPTIONS } template -void -__invoke_if(std::true_type, _Fp __f) -{ - __f(); +void __invoke_if(std::true_type, _Fp __f) { + __f(); } template -void __invoke_if(std::false_type, _Fp) -{ -} +void __invoke_if(std::false_type, _Fp) {} template -void -__invoke_if_not(std::false_type, _Fp __f) -{ - __f(); +void __invoke_if_not(std::false_type, _Fp __f) { + __f(); } template -void __invoke_if_not(std::true_type, _Fp) -{ -} +void __invoke_if_not(std::true_type, _Fp) {} template -auto -__invoke_if_else(std::true_type, _F1 __f1, _F2) -> decltype(__f1()) -{ - return __f1(); +auto __invoke_if_else(std::true_type, _F1 __f1, _F2) -> decltype(__f1()) { + return __f1(); } template -auto -__invoke_if_else(std::false_type, _F1, _F2 __f2) -> decltype(__f2()) -{ - return __f2(); +auto __invoke_if_else(std::false_type, _F1, _F2 __f2) -> decltype(__f2()) { + return __f2(); } //! Unary operator that returns reference to its argument. -struct __no_op -{ - template - _Tp&& - operator()(_Tp&& __a) const - { - return std::forward<_Tp>(__a); - } +struct __no_op { + template + _Tp&& operator()(_Tp&& __a) const { + return std::forward<_Tp>(__a); + } }; template -class __reorder_pred -{ - _Pred _M_pred; - - public: - explicit __reorder_pred(_Pred __pred) : _M_pred(__pred) {} - - template - bool - operator()(_FTp&& __a, _STp&& __b) - { - return _M_pred(std::forward<_STp>(__b), std::forward<_FTp>(__a)); - } +class __reorder_pred { + _Pred _M_pred; + +public: + explicit __reorder_pred(_Pred __pred) : _M_pred(__pred) {} + + template + bool operator()(_FTp&& __a, _STp&& __b) { + return _M_pred(std::forward<_STp>(__b), std::forward<_FTp>(__a)); + } }; //! Like a polymorphic lambda for pred(...,value) template -class __equal_value_by_pred -{ - const _Tp& _M_value; - _Predicate _M_pred; - - public: - __equal_value_by_pred(const _Tp& __value, _Predicate __pred) : _M_value(__value), _M_pred(__pred) {} - - template - bool - operator()(_Arg&& __arg) - { - return _M_pred(std::forward<_Arg>(__arg), _M_value); - } +class __equal_value_by_pred { + const _Tp& _M_value; + _Predicate _M_pred; + +public: + __equal_value_by_pred(const _Tp& __value, _Predicate __pred) : _M_value(__value), _M_pred(__pred) {} + + template + bool operator()(_Arg&& __arg) { + return _M_pred(std::forward<_Arg>(__arg), _M_value); + } }; //! Like a polymorphic lambda for ==value template -class __equal_value -{ - const _Tp& _M_value; - - public: - explicit __equal_value(const _Tp& __value) : _M_value(__value) {} - - template - bool - operator()(_Arg&& __arg) const - { - return std::forward<_Arg>(__arg) == _M_value; - } +class __equal_value { + const _Tp& _M_value; + +public: + explicit __equal_value(const _Tp& __value) : _M_value(__value) {} + + template + bool operator()(_Arg&& __arg) const { + return std::forward<_Arg>(__arg) == _M_value; + } }; //! Logical negation of ==value template -class __not_equal_value -{ - const _Tp& _M_value; - - public: - explicit __not_equal_value(const _Tp& __value) : _M_value(__value) {} - - template - bool - operator()(_Arg&& __arg) const - { - return !(std::forward<_Arg>(__arg) == _M_value); - } +class __not_equal_value { + const _Tp& _M_value; + +public: + explicit __not_equal_value(const _Tp& __value) : _M_value(__value) {} + + template + bool operator()(_Arg&& __arg) const { + return !(std::forward<_Arg>(__arg) == _M_value); + } }; template -_ForwardIterator -__cmp_iterators_by_values(_ForwardIterator __a, _ForwardIterator __b, _Compare __comp) -{ - if (__a < __b) - { // we should return closer iterator - return __comp(*__b, *__a) ? __b : __a; - } - else - { - return __comp(*__a, *__b) ? __a : __b; - } +_ForwardIterator __cmp_iterators_by_values(_ForwardIterator __a, _ForwardIterator __b, _Compare __comp) { + if (__a < __b) { // we should return closer iterator + return __comp(*__b, *__a) ? __b : __a; + } else { + return __comp(*__a, *__b) ? __a : __b; + } } } // namespace __internal diff --git a/libcxx/utils/data/ignore_format.txt b/libcxx/utils/data/ignore_format.txt --- a/libcxx/utils/data/ignore_format.txt +++ b/libcxx/utils/data/ignore_format.txt @@ -506,20 +506,6 @@ libcxx/include/__numeric/transform_reduce.h libcxx/include/optional libcxx/include/ostream -libcxx/include/pstl/internal/algorithm_fwd.h -libcxx/include/pstl/internal/algorithm_impl.h -libcxx/include/pstl/internal/execution_defs.h -libcxx/include/pstl/internal/execution_impl.h -libcxx/include/pstl/internal/glue_algorithm_defs.h -libcxx/include/pstl/internal/glue_algorithm_impl.h -libcxx/include/pstl/internal/glue_execution_defs.h -libcxx/include/pstl/internal/glue_memory_defs.h -libcxx/include/pstl/internal/glue_memory_impl.h -libcxx/include/pstl/internal/glue_numeric_defs.h -libcxx/include/pstl/internal/glue_numeric_impl.h -libcxx/include/pstl/internal/memory_impl.h -libcxx/include/pstl/internal/numeric_fwd.h -libcxx/include/pstl/internal/numeric_impl.h libcxx/include/pstl/internal/omp/parallel_for_each.h libcxx/include/pstl/internal/omp/parallel_for.h libcxx/include/pstl/internal/omp/parallel_invoke.h @@ -538,7 +524,6 @@ libcxx/include/pstl/internal/parallel_impl.h libcxx/include/pstl/internal/pstl_config.h libcxx/include/pstl/internal/unseq_backend_simd.h -libcxx/include/pstl/internal/utils.h libcxx/include/queue libcxx/include/__random/bernoulli_distribution.h libcxx/include/__random/binomial_distribution.h