1// -*- C++ -*- 2//===-- glue_algorithm_impl.h ---------------------------------------------===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef _PSTL_GLUE_ALGORITHM_IMPL_H 11#define _PSTL_GLUE_ALGORITHM_IMPL_H 12 13#include <functional> 14 15#include "execution_defs.h" 16#include "utils.h" 17#include "algorithm_fwd.h" 18#include "numeric_fwd.h" /* count and count_if use __pattern_transform_reduce */ 19 20namespace std 21{ 22 23// [alg.any_of] 24 25template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate> 26__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> 27any_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) 28{ 29 using namespace __pstl; 30 return __internal::__pattern_any_of( 31 std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, 32 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 33 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 34} 35 36// [alg.all_of] 37 38template <class _ExecutionPolicy, class _ForwardIterator, class _Pred> 39__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> 40all_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred) 41{ 42 return !std::any_of(std::forward<_ExecutionPolicy>(__exec), __first, __last, 43 __pstl::__internal::__not_pred<_Pred>(__pred)); 44} 45 46// [alg.none_of] 47 48template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate> 49__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> 50none_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) 51{ 52 return !std::any_of(std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred); 53} 54 55// [alg.foreach] 56 57template <class _ExecutionPolicy, class _ForwardIterator, class _Function> 58__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 59for_each(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Function __f) 60{ 61 using namespace __pstl; 62 __internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last, __f, 63 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 64 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 65} 66 67template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Function> 68__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 69for_each_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __n, _Function __f) 70{ 71 using namespace __pstl; 72 return __internal::__pattern_walk1_n( 73 std::forward<_ExecutionPolicy>(__exec), __first, __n, __f, 74 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 75 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 76} 77 78// [alg.find] 79 80template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate> 81__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 82find_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) 83{ 84 using namespace __pstl; 85 return __internal::__pattern_find_if( 86 std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, 87 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 88 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 89} 90 91template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate> 92__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 93find_if_not(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) 94{ 95 return std::find_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, 96 __pstl::__internal::__not_pred<_Predicate>(__pred)); 97} 98 99template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> 100__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 101find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) 102{ 103 return std::find_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, 104 __pstl::__internal::__equal_value<_Tp>(__value)); 105} 106 107// [alg.find.end] 108template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 109__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> 110find_end(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, 111 _ForwardIterator2 __s_last, _BinaryPredicate __pred) 112{ 113 using namespace __pstl; 114 return __internal::__pattern_find_end( 115 std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred, 116 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec), 117 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec)); 118} 119 120template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> 121__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> 122find_end(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, 123 _ForwardIterator2 __s_last) 124{ 125 return std::find_end(std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, 126 __pstl::__internal::__pstl_equal()); 127} 128 129// [alg.find_first_of] 130template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 131__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> 132find_first_of(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, 133 _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred) 134{ 135 using namespace __pstl; 136 return __internal::__pattern_find_first_of( 137 std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred, 138 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec), 139 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec)); 140} 141 142template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> 143__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> 144find_first_of(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, 145 _ForwardIterator2 __s_first, _ForwardIterator2 __s_last) 146{ 147 return std::find_first_of(std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, 148 __pstl::__internal::__pstl_equal()); 149} 150 151// [alg.adjacent_find] 152template <class _ExecutionPolicy, class _ForwardIterator> 153__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 154adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) 155{ 156 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 157 using namespace __pstl; 158 return __internal::__pattern_adjacent_find( 159 std::forward<_ExecutionPolicy>(__exec), __first, __last, std::equal_to<_ValueType>(), 160 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 161 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), /*first_semantic*/ false); 162} 163 164template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate> 165__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 166adjacent_find(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) 167{ 168 using namespace __pstl; 169 return __internal::__pattern_adjacent_find( 170 std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, 171 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 172 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), /*first_semantic*/ false); 173} 174 175// [alg.count] 176 177// Implementation note: count and count_if call the pattern directly instead of calling std::transform_reduce 178// so that we do not have to include <numeric>. 179 180template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> 181__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, 182 typename iterator_traits<_ForwardIterator>::difference_type> 183count(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) 184{ 185 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 186 using namespace __pstl; 187 return __internal::__pattern_count( 188 std::forward<_ExecutionPolicy>(__exec), __first, __last, 189 [&__value](const _ValueType& __x) { return __value == __x; }, 190 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 191 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 192} 193 194template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate> 195__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, 196 typename iterator_traits<_ForwardIterator>::difference_type> 197count_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) 198{ 199 using namespace __pstl; 200 return __internal::__pattern_count( 201 std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, 202 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 203 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 204} 205 206// [alg.search] 207 208template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 209__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> 210search(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, 211 _ForwardIterator2 __s_last, _BinaryPredicate __pred) 212{ 213 using namespace __pstl; 214 return __internal::__pattern_search( 215 std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, __pred, 216 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec), 217 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec)); 218} 219 220template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> 221__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator1> 222search(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first, 223 _ForwardIterator2 __s_last) 224{ 225 return std::search(std::forward<_ExecutionPolicy>(__exec), __first, __last, __s_first, __s_last, 226 __pstl::__internal::__pstl_equal()); 227} 228 229template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate> 230__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 231search_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count, 232 const _Tp& __value, _BinaryPredicate __pred) 233{ 234 using namespace __pstl; 235 return __internal::__pattern_search_n( 236 std::forward<_ExecutionPolicy>(__exec), __first, __last, __count, __value, __pred, 237 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 238 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 239} 240 241template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp> 242__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 243search_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Size __count, 244 const _Tp& __value) 245{ 246 return std::search_n(std::forward<_ExecutionPolicy>(__exec), __first, __last, __count, __value, 247 std::equal_to<typename iterator_traits<_ForwardIterator>::value_type>()); 248} 249 250// [alg.copy] 251 252template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> 253__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 254copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result) 255{ 256 using namespace __pstl; 257 const auto __is_vector = 258 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec); 259 260 return __internal::__pattern_walk2_brick( 261 std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, 262 [__is_vector](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res) { 263 return __internal::__brick_copy(__begin, __end, __res, __is_vector); 264 }, 265 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec)); 266} 267 268template <class _ExecutionPolicy, class _ForwardIterator1, class _Size, class _ForwardIterator2> 269__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 270copy_n(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _Size __n, _ForwardIterator2 __result) 271{ 272 using namespace __pstl; 273 const auto __is_vector = 274 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec); 275 276 return __internal::__pattern_walk2_brick_n( 277 std::forward<_ExecutionPolicy>(__exec), __first, __n, __result, 278 [__is_vector](_ForwardIterator1 __begin, _Size __sz, _ForwardIterator2 __res) { 279 return __internal::__brick_copy_n(__begin, __sz, __res, __is_vector); 280 }, 281 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec)); 282} 283 284template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate> 285__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 286copy_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, 287 _Predicate __pred) 288{ 289 using namespace __pstl; 290 return __internal::__pattern_copy_if( 291 std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred, 292 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec), 293 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec)); 294} 295 296// [alg.swap] 297 298template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> 299__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 300swap_ranges(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, 301 _ForwardIterator2 __first2) 302{ 303 using namespace __pstl; 304 typedef typename iterator_traits<_ForwardIterator1>::reference _ReferenceType1; 305 typedef typename iterator_traits<_ForwardIterator2>::reference _ReferenceType2; 306 return __internal::__pattern_walk2( 307 std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, 308 [](_ReferenceType1 __x, _ReferenceType2 __y) { 309 using std::swap; 310 swap(__x, __y); 311 }, 312 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec), 313 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec)); 314} 315 316// [alg.transform] 317 318template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _UnaryOperation> 319__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 320transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, 321 _UnaryOperation __op) 322{ 323 typedef typename iterator_traits<_ForwardIterator1>::reference _InputType; 324 typedef typename iterator_traits<_ForwardIterator2>::reference _OutputType; 325 using namespace __pstl; 326 return __internal::__pattern_walk2( 327 std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, 328 [__op](_InputType __x, _OutputType __y) mutable { __y = __op(__x); }, 329 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec), 330 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec)); 331} 332 333template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator, 334 class _BinaryOperation> 335__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 336transform(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, 337 _ForwardIterator __result, _BinaryOperation __op) 338{ 339 typedef typename iterator_traits<_ForwardIterator1>::reference _Input1Type; 340 typedef typename iterator_traits<_ForwardIterator2>::reference _Input2Type; 341 typedef typename iterator_traits<_ForwardIterator>::reference _OutputType; 342 using namespace __pstl; 343 return __internal::__pattern_walk3( 344 std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __result, 345 [__op](_Input1Type x, _Input2Type y, _OutputType z) mutable { z = __op(x, y); }, 346 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, 347 _ForwardIterator>(__exec), 348 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, 349 _ForwardIterator>(__exec)); 350} 351 352// [alg.replace] 353 354template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _Tp> 355__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 356replace_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred, 357 const _Tp& __new_value) 358{ 359 using namespace __pstl; 360 typedef typename iterator_traits<_ForwardIterator>::reference _ElementType; 361 __internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __last, 362 [&__pred, &__new_value](_ElementType __elem) { 363 if (__pred(__elem)) 364 { 365 __elem = __new_value; 366 } 367 }, 368 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 369 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 370} 371 372template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> 373__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 374replace(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, 375 const _Tp& __new_value) 376{ 377 std::replace_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, 378 __pstl::__internal::__equal_value<_Tp>(__old_value), __new_value); 379} 380 381template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _UnaryPredicate, class _Tp> 382__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 383replace_copy_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, 384 _ForwardIterator2 __result, _UnaryPredicate __pred, const _Tp& __new_value) 385{ 386 typedef typename iterator_traits<_ForwardIterator1>::reference _InputType; 387 typedef typename iterator_traits<_ForwardIterator2>::reference _OutputType; 388 using namespace __pstl; 389 return __internal::__pattern_walk2( 390 std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, 391 [__pred, &__new_value](_InputType __x, _OutputType __y) mutable { __y = __pred(__x) ? __new_value : __x; }, 392 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec), 393 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec)); 394} 395 396template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp> 397__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 398replace_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, 399 const _Tp& __old_value, const _Tp& __new_value) 400{ 401 return std::replace_copy_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, 402 __pstl::__internal::__equal_value<_Tp>(__old_value), __new_value); 403} 404 405// [alg.fill] 406 407template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> 408__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 409fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) 410{ 411 using namespace __pstl; 412 __internal::__pattern_fill(std::forward<_ExecutionPolicy>(__exec), __first, __last, __value, 413 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 414 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 415} 416 417template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp> 418__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 419fill_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __count, const _Tp& __value) 420{ 421 if (__count <= 0) 422 return __first; 423 424 using namespace __pstl; 425 return __internal::__pattern_fill_n( 426 std::forward<_ExecutionPolicy>(__exec), __first, __count, __value, 427 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 428 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 429} 430 431// [alg.generate] 432template <class _ExecutionPolicy, class _ForwardIterator, class _Generator> 433__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 434generate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Generator __g) 435{ 436 using namespace __pstl; 437 __internal::__pattern_generate( 438 std::forward<_ExecutionPolicy>(__exec), __first, __last, __g, 439 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 440 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 441} 442 443template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Generator> 444__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 445generate_n(_ExecutionPolicy&& __exec, _ForwardIterator __first, _Size __count, _Generator __g) 446{ 447 if (__count <= 0) 448 return __first; 449 450 using namespace __pstl; 451 return __internal::__pattern_generate_n( 452 std::forward<_ExecutionPolicy>(__exec), __first, __count, __g, 453 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 454 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 455} 456 457// [alg.remove] 458 459template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate> 460__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 461remove_copy_if(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, 462 _ForwardIterator2 __result, _Predicate __pred) 463{ 464 return std::copy_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, 465 __pstl::__internal::__not_pred<_Predicate>(__pred)); 466} 467 468template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp> 469__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 470remove_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, 471 const _Tp& __value) 472{ 473 return std::copy_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, 474 __pstl::__internal::__not_equal_value<_Tp>(__value)); 475} 476 477template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate> 478__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 479remove_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) 480{ 481 using namespace __pstl; 482 return __internal::__pattern_remove_if( 483 std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, 484 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 485 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 486} 487 488template <class _ExecutionPolicy, class _ForwardIterator, class _Tp> 489__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 490remove(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) 491{ 492 return std::remove_if(std::forward<_ExecutionPolicy>(__exec), __first, __last, 493 __pstl::__internal::__equal_value<_Tp>(__value)); 494} 495 496// [alg.unique] 497 498template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate> 499__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 500unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred) 501{ 502 using namespace __pstl; 503 return __internal::__pattern_unique( 504 std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, 505 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 506 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 507} 508 509template <class _ExecutionPolicy, class _ForwardIterator> 510__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 511unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) 512{ 513 return std::unique(std::forward<_ExecutionPolicy>(__exec), __first, __last, __pstl::__internal::__pstl_equal()); 514} 515 516template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 517__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 518unique_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result, 519 _BinaryPredicate __pred) 520{ 521 using namespace __pstl; 522 return __internal::__pattern_unique_copy( 523 std::forward<_ExecutionPolicy>(__exec), __first, __last, __result, __pred, 524 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec), 525 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec)); 526} 527 528template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> 529__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 530unique_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __result) 531{ 532 return std::unique_copy(__exec, __first, __last, __result, __pstl::__internal::__pstl_equal()); 533} 534 535// [alg.reverse] 536 537template <class _ExecutionPolicy, class _BidirectionalIterator> 538__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 539reverse(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last) 540{ 541 using namespace __pstl; 542 __internal::__pattern_reverse( 543 std::forward<_ExecutionPolicy>(__exec), __first, __last, 544 __internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec), 545 __internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec)); 546} 547 548template <class _ExecutionPolicy, class _BidirectionalIterator, class _ForwardIterator> 549__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 550reverse_copy(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, 551 _ForwardIterator __d_first) 552{ 553 using namespace __pstl; 554 return __internal::__pattern_reverse_copy( 555 std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, 556 __internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator, _ForwardIterator>(__exec), 557 __internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator, _ForwardIterator>(__exec)); 558} 559 560// [alg.rotate] 561 562template <class _ExecutionPolicy, class _ForwardIterator> 563__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 564rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) 565{ 566 using namespace __pstl; 567 return __internal::__pattern_rotate( 568 std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, 569 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 570 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 571} 572 573template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> 574__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 575rotate_copy(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __middle, _ForwardIterator1 __last, 576 _ForwardIterator2 __result) 577{ 578 using namespace __pstl; 579 return __internal::__pattern_rotate_copy( 580 std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __result, 581 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec), 582 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec)); 583} 584 585// [alg.partitions] 586 587template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate> 588__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> 589is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) 590{ 591 using namespace __pstl; 592 return __internal::__pattern_is_partitioned( 593 std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, 594 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 595 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 596} 597 598template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate> 599__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 600partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred) 601{ 602 using namespace __pstl; 603 return __internal::__pattern_partition( 604 std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, 605 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 606 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 607} 608 609template <class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate> 610__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _BidirectionalIterator> 611stable_partition(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last, 612 _UnaryPredicate __pred) 613{ 614 using namespace __pstl; 615 return __internal::__pattern_stable_partition( 616 std::forward<_ExecutionPolicy>(__exec), __first, __last, __pred, 617 __internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec), 618 __internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec)); 619} 620 621template <class _ExecutionPolicy, class _ForwardIterator, class _ForwardIterator1, class _ForwardIterator2, 622 class _UnaryPredicate> 623__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> 624partition_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, 625 _ForwardIterator1 __out_true, _ForwardIterator2 __out_false, _UnaryPredicate __pred) 626{ 627 using namespace __pstl; 628 return __internal::__pattern_partition_copy( 629 std::forward<_ExecutionPolicy>(__exec), __first, __last, __out_true, __out_false, __pred, 630 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator, _ForwardIterator1, 631 _ForwardIterator2>(__exec), 632 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator, _ForwardIterator1, 633 _ForwardIterator2>(__exec)); 634} 635 636// [alg.sort] 637 638template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> 639__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 640sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 641{ 642 typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType; 643 using namespace __pstl; 644 return __internal::__pattern_sort( 645 std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, 646 __internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec), 647 __internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec), 648 typename std::is_move_constructible<_InputType>::type()); 649} 650 651template <class _ExecutionPolicy, class _RandomAccessIterator> 652__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 653sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) 654{ 655 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType; 656 std::sort(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); 657} 658 659// [stable.sort] 660 661template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> 662__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 663stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 664{ 665 using namespace __pstl; 666 return __internal::__pattern_stable_sort( 667 std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, 668 __internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec), 669 __internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec)); 670} 671 672template <class _ExecutionPolicy, class _RandomAccessIterator> 673__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 674stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) 675{ 676 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType; 677 std::stable_sort(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); 678} 679 680// [mismatch] 681 682template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 683__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> 684mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, 685 _ForwardIterator2 __last2, _BinaryPredicate __pred) 686{ 687 using namespace __pstl; 688 return __internal::__pattern_mismatch( 689 std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __pred, 690 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec), 691 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec)); 692} 693 694template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 695__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> 696mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, 697 _BinaryPredicate __pred) 698{ 699 return std::mismatch(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, 700 std::next(__first2, std::distance(__first1, __last1)), __pred); 701} 702 703template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> 704__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> 705mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, 706 _ForwardIterator2 __last2) 707{ 708 return std::mismatch(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, 709 __pstl::__internal::__pstl_equal()); 710} 711 712template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> 713__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator1, _ForwardIterator2>> 714mismatch(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) 715{ 716 //TODO: to get rid of "distance" 717 return std::mismatch(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, 718 std::next(__first2, std::distance(__first1, __last1))); 719} 720 721// [alg.equal] 722 723template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 724__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> 725equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, 726 _BinaryPredicate __p) 727{ 728 using namespace __pstl; 729 return __internal::__pattern_equal( 730 std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __p, 731 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec), 732 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec)); 733} 734 735template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> 736__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> 737equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2) 738{ 739 return std::equal(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, 740 __pstl::__internal::__pstl_equal()); 741} 742 743template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> 744__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> 745equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, 746 _ForwardIterator2 __last2, _BinaryPredicate __p) 747{ 748 using namespace __pstl; 749 return __internal::__pattern_equal( 750 std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __p, 751 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec), 752 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec)); 753} 754 755template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> 756__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> 757equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, 758 _ForwardIterator2 __last2) 759{ 760 return std::equal(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, 761 __pstl::__internal::__pstl_equal()); 762} 763 764// [alg.move] 765template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> 766__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> 767move(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __d_first) 768{ 769 using namespace __pstl; 770 const auto __is_vector = 771 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec); 772 773 return __internal::__pattern_walk2_brick( 774 std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, 775 [__is_vector](_ForwardIterator1 __begin, _ForwardIterator1 __end, _ForwardIterator2 __res) { 776 return __internal::__brick_move(__begin, __end, __res, __is_vector); 777 }, 778 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec)); 779} 780 781// [partial.sort] 782 783template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> 784__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 785partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __middle, 786 _RandomAccessIterator __last, _Compare __comp) 787{ 788 using namespace __pstl; 789 __internal::__pattern_partial_sort( 790 std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp, 791 __internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec), 792 __internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec)); 793} 794 795template <class _ExecutionPolicy, class _RandomAccessIterator> 796__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 797partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __middle, 798 _RandomAccessIterator __last) 799{ 800 typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType; 801 std::partial_sort(std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, std::less<_InputType>()); 802} 803 804// [partial.sort.copy] 805 806template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator, class _Compare> 807__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> 808partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, 809 _RandomAccessIterator __d_first, _RandomAccessIterator __d_last, _Compare __comp) 810{ 811 using namespace __pstl; 812 return __internal::__pattern_partial_sort_copy( 813 std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __d_last, __comp, 814 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator, _RandomAccessIterator>(__exec), 815 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator, _RandomAccessIterator>(__exec)); 816} 817 818template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator> 819__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> 820partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, 821 _RandomAccessIterator __d_first, _RandomAccessIterator __d_last) 822{ 823 return std::partial_sort_copy(std::forward<_ExecutionPolicy>(__exec), __first, __last, __d_first, __d_last, 824 __pstl::__internal::__pstl_less()); 825} 826 827// [is.sorted] 828template <class _ExecutionPolicy, class _ForwardIterator, class _Compare> 829__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 830is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 831{ 832 using namespace __pstl; 833 const _ForwardIterator __res = __internal::__pattern_adjacent_find( 834 std::forward<_ExecutionPolicy>(__exec), __first, __last, __pstl::__internal::__reorder_pred<_Compare>(__comp), 835 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 836 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), /*first_semantic*/ false); 837 return __res == __last ? __last : std::next(__res); 838} 839 840template <class _ExecutionPolicy, class _ForwardIterator> 841__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 842is_sorted_until(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) 843{ 844 typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType; 845 return is_sorted_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); 846} 847 848template <class _ExecutionPolicy, class _ForwardIterator, class _Compare> 849__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> 850is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 851{ 852 using namespace __pstl; 853 return __internal::__pattern_adjacent_find( 854 std::forward<_ExecutionPolicy>(__exec), __first, __last, __internal::__reorder_pred<_Compare>(__comp), 855 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 856 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 857 /*or_semantic*/ true) == __last; 858} 859 860template <class _ExecutionPolicy, class _ForwardIterator> 861__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> 862is_sorted(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) 863{ 864 typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType; 865 return std::is_sorted(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); 866} 867 868// [alg.merge] 869template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator, 870 class _Compare> 871__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 872merge(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, 873 _ForwardIterator2 __last2, _ForwardIterator __d_first, _Compare __comp) 874{ 875 using namespace __pstl; 876 return __internal::__pattern_merge( 877 std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __d_first, __comp, 878 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, 879 _ForwardIterator>(__exec), 880 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, 881 _ForwardIterator>(__exec)); 882} 883 884template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> 885__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 886merge(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, 887 _ForwardIterator2 __last2, _ForwardIterator __d_first) 888{ 889 return std::merge(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __d_first, 890 __pstl::__internal::__pstl_less()); 891} 892 893template <class _ExecutionPolicy, class _BidirectionalIterator, class _Compare> 894__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 895inplace_merge(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __middle, 896 _BidirectionalIterator __last, _Compare __comp) 897{ 898 using namespace __pstl; 899 __internal::__pattern_inplace_merge( 900 std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, __comp, 901 __internal::__is_vectorization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec), 902 __internal::__is_parallelization_preferred<_ExecutionPolicy, _BidirectionalIterator>(__exec)); 903} 904 905template <class _ExecutionPolicy, class _BidirectionalIterator> 906__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 907inplace_merge(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __middle, 908 _BidirectionalIterator __last) 909{ 910 typedef typename std::iterator_traits<_BidirectionalIterator>::value_type _InputType; 911 std::inplace_merge(std::forward<_ExecutionPolicy>(__exec), __first, __middle, __last, std::less<_InputType>()); 912} 913 914// [includes] 915 916template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare> 917__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> 918includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, 919 _ForwardIterator2 __last2, _Compare __comp) 920{ 921 using namespace __pstl; 922 return __internal::__pattern_includes( 923 std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp, 924 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec), 925 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec)); 926} 927 928template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> 929__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> 930includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, 931 _ForwardIterator2 __last2) 932{ 933 return std::includes(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, 934 __pstl::__internal::__pstl_less()); 935} 936 937// [set.union] 938 939template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator, 940 class _Compare> 941__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 942set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, 943 _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp) 944{ 945 using namespace __pstl; 946 return __internal::__pattern_set_union( 947 std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, 948 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, 949 _ForwardIterator>(__exec), 950 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, 951 _ForwardIterator>(__exec)); 952} 953 954template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> 955__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 956set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, 957 _ForwardIterator2 __last2, _ForwardIterator __result) 958{ 959 return std::set_union(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, 960 __pstl::__internal::__pstl_less()); 961} 962 963// [set.intersection] 964 965template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator, 966 class _Compare> 967__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 968set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, 969 _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp) 970{ 971 using namespace __pstl; 972 return __internal::__pattern_set_intersection( 973 std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, 974 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, 975 _ForwardIterator>(__exec), 976 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, 977 _ForwardIterator>(__exec)); 978} 979 980template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> 981__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 982set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, 983 _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result) 984{ 985 return std::set_intersection(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, 986 __pstl::__internal::__pstl_less()); 987} 988 989// [set.difference] 990 991template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator, 992 class _Compare> 993__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 994set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, 995 _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, _Compare __comp) 996{ 997 using namespace __pstl; 998 return __internal::__pattern_set_difference( 999 std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, 1000 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, 1001 _ForwardIterator>(__exec), 1002 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, 1003 _ForwardIterator>(__exec)); 1004} 1005 1006template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> 1007__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 1008set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, 1009 _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result) 1010{ 1011 return std::set_difference(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, 1012 __pstl::__internal::__pstl_less()); 1013} 1014 1015// [set.symmetric.difference] 1016 1017template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator, 1018 class _Compare> 1019__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 1020set_symmetric_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, 1021 _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result, 1022 _Compare __comp) 1023{ 1024 using namespace __pstl; 1025 return __internal::__pattern_set_symmetric_difference( 1026 std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp, 1027 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, 1028 _ForwardIterator>(__exec), 1029 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2, 1030 _ForwardIterator>(__exec)); 1031} 1032 1033template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator> 1034__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 1035set_symmetric_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, 1036 _ForwardIterator2 __first2, _ForwardIterator2 __last2, _ForwardIterator __result) 1037{ 1038 return std::set_symmetric_difference(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, 1039 __result, __pstl::__internal::__pstl_less()); 1040} 1041 1042// [is.heap] 1043template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> 1044__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> 1045is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 1046{ 1047 using namespace __pstl; 1048 return __internal::__pattern_is_heap_until( 1049 std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, 1050 __internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec), 1051 __internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec)); 1052} 1053 1054template <class _ExecutionPolicy, class _RandomAccessIterator> 1055__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _RandomAccessIterator> 1056is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) 1057{ 1058 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType; 1059 return std::is_heap_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); 1060} 1061 1062template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> 1063__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> 1064is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) 1065{ 1066 return std::is_heap_until(std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp) == __last; 1067} 1068 1069template <class _ExecutionPolicy, class _RandomAccessIterator> 1070__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> 1071is_heap(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last) 1072{ 1073 typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _InputType; 1074 return std::is_heap(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); 1075} 1076 1077// [alg.min.max] 1078 1079template <class _ExecutionPolicy, class _ForwardIterator, class _Compare> 1080__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 1081min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 1082{ 1083 using namespace __pstl; 1084 return __internal::__pattern_min_element( 1085 std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, 1086 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 1087 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 1088} 1089 1090template <class _ExecutionPolicy, class _ForwardIterator> 1091__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 1092min_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) 1093{ 1094 typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType; 1095 return std::min_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_InputType>()); 1096} 1097 1098template <class _ExecutionPolicy, class _ForwardIterator, class _Compare> 1099__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 1100max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 1101{ 1102 return min_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, 1103 __pstl::__internal::__reorder_pred<_Compare>(__comp)); 1104} 1105 1106template <class _ExecutionPolicy, class _ForwardIterator> 1107__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator> 1108max_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) 1109{ 1110 typedef typename std::iterator_traits<_ForwardIterator>::value_type _InputType; 1111 return std::min_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, 1112 __pstl::__internal::__reorder_pred<std::less<_InputType>>(std::less<_InputType>())); 1113} 1114 1115template <class _ExecutionPolicy, class _ForwardIterator, class _Compare> 1116__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>> 1117minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp) 1118{ 1119 using namespace __pstl; 1120 return __internal::__pattern_minmax_element( 1121 std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp, 1122 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec), 1123 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator>(__exec)); 1124} 1125 1126template <class _ExecutionPolicy, class _ForwardIterator> 1127__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, std::pair<_ForwardIterator, _ForwardIterator>> 1128minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last) 1129{ 1130 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; 1131 return std::minmax_element(std::forward<_ExecutionPolicy>(__exec), __first, __last, std::less<_ValueType>()); 1132} 1133 1134// [alg.nth.element] 1135 1136template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare> 1137__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 1138nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __nth, 1139 _RandomAccessIterator __last, _Compare __comp) 1140{ 1141 using namespace __pstl; 1142 __internal::__pattern_nth_element( 1143 std::forward<_ExecutionPolicy>(__exec), __first, __nth, __last, __comp, 1144 __internal::__is_vectorization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec), 1145 __internal::__is_parallelization_preferred<_ExecutionPolicy, _RandomAccessIterator>(__exec)); 1146} 1147 1148template <class _ExecutionPolicy, class _RandomAccessIterator> 1149__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> 1150nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __nth, 1151 _RandomAccessIterator __last) 1152{ 1153 typedef typename iterator_traits<_RandomAccessIterator>::value_type _InputType; 1154 std::nth_element(std::forward<_ExecutionPolicy>(__exec), __first, __nth, __last, std::less<_InputType>()); 1155} 1156 1157// [alg.lex.comparison] 1158 1159template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare> 1160__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> 1161lexicographical_compare(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, 1162 _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp) 1163{ 1164 using namespace __pstl; 1165 return __internal::__pattern_lexicographical_compare( 1166 std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __comp, 1167 __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec), 1168 __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1, _ForwardIterator2>(__exec)); 1169} 1170 1171template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> 1172__pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> 1173lexicographical_compare(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, 1174 _ForwardIterator2 __first2, _ForwardIterator2 __last2) 1175{ 1176 return std::lexicographical_compare(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, 1177 __pstl::__internal::__pstl_less()); 1178} 1179 1180} // namespace std 1181 1182#endif /* _PSTL_GLUE_ALGORITHM_IMPL_H */ 1183