algorithm.hpp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248
  1. /* Copyright 2016-2024 Joaquin M Lopez Munoz.
  2. * Distributed under the Boost Software License, Version 1.0.
  3. * (See accompanying file LICENSE_1_0.txt or copy at
  4. * http://www.boost.org/LICENSE_1_0.txt)
  5. *
  6. * See http://www.boost.org/libs/poly_collection for library home page.
  7. */
  8. #ifndef BOOST_POLY_COLLECTION_ALGORITHM_HPP
  9. #define BOOST_POLY_COLLECTION_ALGORITHM_HPP
  10. #if defined(_MSC_VER)
  11. #pragma once
  12. #endif
  13. #include <algorithm>
  14. #include <boost/config.hpp>
  15. #include <boost/poly_collection/detail/auto_iterator.hpp>
  16. #include <boost/poly_collection/detail/copyable.hpp>
  17. #include <boost/poly_collection/detail/functional.hpp>
  18. #include <boost/poly_collection/detail/iterator_traits.hpp>
  19. #include <boost/poly_collection/detail/segment_split.hpp>
  20. #include <boost/poly_collection/detail/type_restitution.hpp>
  21. #include <iterator>
  22. #include <random>
  23. #include <type_traits>
  24. #include <utility>
  25. /* Improved performance versions of std algorithms over poly_collection.
  26. * poly_collection::alg is expected to be faster than the homonym std::alg
  27. * because the latter does a traversal over a segmented structured, where
  28. * incrementing requires checking for segment change, whereas the former
  29. * for-loops over flat segments.
  30. * Additionally, poly_collection::alg<Ti...>(...,f) *restitutes* Ti when
  31. * passing elements to f, i.e. if the concrete type of the element is Ti
  32. * then f is invoked with a [const] Ti&, which can dramatically improve
  33. * performance when f has specific overloads for Ti (like, for instance,
  34. * generic lambdas) as static optimization can kick in (devirtualization
  35. * being a particular example).
  36. */
  37. #if defined(BOOST_MSVC)
  38. #pragma warning(push)
  39. #pragma warning(disable:4714) /* marked as __forceinline not inlined */
  40. #endif
  41. namespace boost{
  42. namespace poly_collection{
  43. namespace detail{
  44. namespace algorithm{
  45. template<typename Iterator>
  46. using enable_if_poly_collection_iterator=typename std::enable_if<
  47. !std::is_void<typename poly_collection_of<Iterator>::type>::value
  48. >::type*;
  49. BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_all_of,std::all_of)
  50. template<
  51. typename... Ts,typename Iterator,typename Predicate,
  52. enable_if_poly_collection_iterator<Iterator> =nullptr
  53. >
  54. BOOST_FORCEINLINE
  55. bool all_of(const Iterator& first,const Iterator& last,Predicate pred)
  56. {
  57. using model_type=typename iterator_traits<Iterator>::model_type;
  58. auto alg=restitute_range<model_type,Ts...>(std_all_of{},pred);
  59. for(auto i:detail::segment_split(first,last))if(!alg(i))return false;
  60. return true;
  61. }
  62. BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_any_of,std::any_of)
  63. template<
  64. typename... Ts,typename Iterator,typename Predicate,
  65. enable_if_poly_collection_iterator<Iterator> =nullptr
  66. >
  67. BOOST_FORCEINLINE bool any_of(
  68. const Iterator& first,const Iterator& last,Predicate pred)
  69. {
  70. using model_type=typename iterator_traits<Iterator>::model_type;
  71. auto alg=restitute_range<model_type,Ts...>(std_any_of{},pred);
  72. for(auto i:detail::segment_split(first,last))if(alg(i))return true;
  73. return false;
  74. }
  75. BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_none_of,std::none_of)
  76. template<
  77. typename... Ts,typename Iterator,typename Predicate,
  78. enable_if_poly_collection_iterator<Iterator> =nullptr
  79. >
  80. BOOST_FORCEINLINE bool none_of(
  81. const Iterator& first,const Iterator& last,Predicate pred)
  82. {
  83. using model_type=typename iterator_traits<Iterator>::model_type;
  84. auto alg=restitute_range<model_type,Ts...>(std_none_of{},pred);
  85. for(auto i:detail::segment_split(first,last))if(!alg(i))return false;
  86. return true;
  87. }
  88. struct for_each_alg
  89. {
  90. template<typename InputIterator,typename Function>
  91. void operator()(
  92. InputIterator first,InputIterator last,Function& f)const /* note the & */
  93. {
  94. for(;first!=last;++first)f(*first);
  95. }
  96. };
  97. template<typename... Ts,typename Iterator,typename Function,
  98. enable_if_poly_collection_iterator<Iterator> =nullptr
  99. >
  100. BOOST_FORCEINLINE Function for_each(
  101. const Iterator& first,const Iterator& last,Function f)
  102. {
  103. using model_type=typename iterator_traits<Iterator>::model_type;
  104. for_each_segment(
  105. first,last,restitute_range<model_type,Ts...>(for_each_alg{},f));
  106. return f;
  107. }
  108. struct for_each_n_alg
  109. {
  110. template<
  111. typename InputIterator,typename Size,typename Function
  112. >
  113. InputIterator operator()(
  114. InputIterator first,Size n,Function& f)const /* note the & */
  115. {
  116. for(;n>0;++first,(void)--n)f(*first);
  117. return first;
  118. }
  119. };
  120. template<
  121. typename... Ts,typename Iterator,typename Size,typename Function,
  122. enable_if_poly_collection_iterator<Iterator> =nullptr
  123. >
  124. BOOST_FORCEINLINE Iterator for_each_n(const Iterator& first,Size n,Function f)
  125. {
  126. using traits=iterator_traits<Iterator>;
  127. using model_type=typename traits::model_type;
  128. using local_base_iterator=typename traits::local_base_iterator;
  129. if(n<=0)return first;
  130. auto alg=restitute_iterator<model_type,Ts...>(
  131. cast_return<local_base_iterator>(for_each_n_alg{}));
  132. auto lbit=traits::local_base_iterator_from(first);
  133. auto sit=traits::base_segment_info_iterator_from(first);
  134. for(;;){
  135. Size m=static_cast<Size>(sit->end()-lbit);
  136. if(n<=m){
  137. auto it=alg(sit->type_info(),lbit,n,f);
  138. return traits::iterator_from(
  139. it,traits::end_base_segment_info_iterator_from(first));
  140. }
  141. else{
  142. alg(sit->type_info(),lbit,m,f);
  143. n-=m;
  144. }
  145. ++sit;
  146. lbit=sit->begin();
  147. }
  148. }
  149. template<
  150. typename Algorithm,typename... Ts,
  151. typename Iterator,typename... Args,
  152. enable_if_poly_collection_iterator<Iterator> =nullptr
  153. >
  154. BOOST_FORCEINLINE Iterator generic_find(
  155. const Iterator& first,const Iterator& last,Args&&... args)
  156. {
  157. using traits=iterator_traits<Iterator>;
  158. using model_type=typename traits::model_type;
  159. using local_base_iterator=typename traits::local_base_iterator;
  160. auto alg=restitute_range<model_type,Ts...>(
  161. cast_return<local_base_iterator>(Algorithm{}),
  162. std::forward<Args>(args)...);
  163. for(auto i:detail::segment_split(first,last)){
  164. auto it=alg(i);
  165. if(it!=i.end())
  166. return traits::iterator_from(
  167. it,traits::end_base_segment_info_iterator_from(last));
  168. }
  169. return last;
  170. }
  171. BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_find,std::find)
  172. template<
  173. typename... Ts,typename Iterator,typename T,
  174. enable_if_poly_collection_iterator<Iterator> =nullptr
  175. >
  176. BOOST_FORCEINLINE Iterator find(
  177. const Iterator& first,const Iterator& last,const T& x)
  178. {
  179. return generic_find<std_find,Ts...>(first,last,x);
  180. }
  181. BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_find_if,std::find_if)
  182. template<
  183. typename... Ts,typename Iterator,typename Predicate,
  184. enable_if_poly_collection_iterator<Iterator> =nullptr
  185. >
  186. BOOST_FORCEINLINE Iterator find_if(
  187. const Iterator& first,const Iterator& last,Predicate pred)
  188. {
  189. return generic_find<std_find_if,Ts...>(first,last,pred);
  190. }
  191. BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_find_if_not,std::find_if_not)
  192. template<
  193. typename... Ts,typename Iterator,typename Predicate,
  194. enable_if_poly_collection_iterator<Iterator> =nullptr
  195. >
  196. BOOST_FORCEINLINE Iterator find_if_not(
  197. const Iterator& first,const Iterator& last,Predicate pred)
  198. {
  199. return generic_find<std_find_if_not,Ts...>(first,last,pred);
  200. }
  201. /* find_end defined after search below */
  202. BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_find_first_of,std::find_first_of)
  203. template<
  204. typename... Ts,typename Iterator,typename ForwardIterator,
  205. enable_if_poly_collection_iterator<Iterator> =nullptr
  206. >
  207. BOOST_FORCEINLINE Iterator find_first_of(
  208. const Iterator& first1,const Iterator& last1,
  209. ForwardIterator first2,ForwardIterator last2)
  210. {
  211. return generic_find<std_find_first_of,Ts...>(first1,last1,first2,last2);
  212. }
  213. template<
  214. typename... Ts,typename Iterator,
  215. typename ForwardIterator,typename BinaryPredicate,
  216. enable_if_poly_collection_iterator<Iterator> =nullptr
  217. >
  218. BOOST_FORCEINLINE Iterator find_first_of(
  219. const Iterator& first1,const Iterator& last1,
  220. ForwardIterator first2,ForwardIterator last2,BinaryPredicate pred)
  221. {
  222. return generic_find<std_find_first_of,Ts...>(first1,last1,first2,last2,pred);
  223. }
  224. template<typename... Ts>
  225. struct adjacent_find_alg
  226. {
  227. template<
  228. typename LocalIterator,typename BinaryPredicate,
  229. typename TypeIndex,typename LocalBaseIterator
  230. >
  231. LocalBaseIterator operator()(
  232. LocalIterator first,LocalIterator last,BinaryPredicate pred,
  233. bool& carry,TypeIndex& prev_info, /* note the &s */
  234. LocalBaseIterator& prev)const
  235. {
  236. using traits=iterator_traits<LocalIterator>;
  237. using model_type=typename traits::model_type;
  238. if(first==last)return LocalBaseIterator{last};
  239. if(carry){
  240. auto p=restitute_iterator<model_type,Ts...>(deref_to(pred));
  241. if(p(prev_info,prev,first))return prev;
  242. }
  243. auto res=std::adjacent_find(first,last,pred);
  244. if(res==last){
  245. carry=true;
  246. prev_info=traits::template index<
  247. typename std::iterator_traits<LocalIterator>::value_type>();
  248. prev=LocalBaseIterator{last-1};
  249. }
  250. else carry=false;
  251. return LocalBaseIterator{res};
  252. }
  253. };
  254. template<
  255. typename... Ts,typename Iterator,typename BinaryPredicate,
  256. enable_if_poly_collection_iterator<Iterator> =nullptr
  257. >
  258. BOOST_FORCEINLINE Iterator adjacent_find(
  259. const Iterator& first,const Iterator& last,BinaryPredicate pred)
  260. {
  261. using traits=iterator_traits<Iterator>;
  262. using local_base_iterator=typename traits::local_base_iterator;
  263. bool carry=false;
  264. auto prev_info=
  265. make_copyable(traits::template index<void>());
  266. local_base_iterator prev;
  267. return generic_find<adjacent_find_alg<Ts...>,Ts...>(
  268. first,last,pred,carry,prev_info,prev);
  269. }
  270. template<
  271. typename... Ts,typename Iterator,
  272. enable_if_poly_collection_iterator<Iterator> =nullptr
  273. >
  274. BOOST_FORCEINLINE Iterator adjacent_find(
  275. const Iterator& first,const Iterator& last)
  276. {
  277. return algorithm::adjacent_find<Ts...>(first,last,transparent_equal_to{});
  278. }
  279. template<
  280. typename Algorithm,typename... Ts,
  281. typename Iterator,typename... Args,
  282. enable_if_poly_collection_iterator<Iterator> =nullptr
  283. >
  284. BOOST_FORCEINLINE std::ptrdiff_t generic_count(
  285. const Iterator& first,const Iterator& last,Args&&... args)
  286. {
  287. using model_type=typename iterator_traits<Iterator>::model_type;
  288. auto alg=restitute_range<model_type,Ts...>(
  289. Algorithm{},std::forward<Args>(args)...);
  290. std::ptrdiff_t res=0;
  291. for(auto i:detail::segment_split(first,last))res+=alg(i);
  292. return res;
  293. }
  294. BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_count,std::count)
  295. template<
  296. typename... Ts,typename Iterator,typename T,
  297. enable_if_poly_collection_iterator<Iterator> =nullptr
  298. >
  299. BOOST_FORCEINLINE std::ptrdiff_t count(
  300. const Iterator& first,const Iterator& last,const T& x)
  301. {
  302. return generic_count<std_count,Ts...>(first,last,x);
  303. }
  304. BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_count_if,std::count_if)
  305. template<
  306. typename... Ts,typename Iterator,typename Predicate,
  307. enable_if_poly_collection_iterator<Iterator> =nullptr
  308. >
  309. BOOST_FORCEINLINE std::ptrdiff_t count_if(
  310. const Iterator& first,const Iterator& last,Predicate pred)
  311. {
  312. return generic_count<std_count_if,Ts...>(first,last,pred);
  313. }
  314. struct mismatch_alg
  315. {
  316. template<
  317. typename InputIterator1,
  318. typename InputIterator2,typename BinaryPredicate
  319. >
  320. InputIterator1 operator()(
  321. InputIterator1 first1,InputIterator1 last1,
  322. InputIterator2& first2,BinaryPredicate pred)const /* note the & */
  323. {
  324. while(first1!=last1&&pred(*first1,*first2)){
  325. ++first1;
  326. ++first2;
  327. }
  328. return first1;
  329. }
  330. template<
  331. typename InputIterator1,
  332. typename InputIterator2,typename BinaryPredicate
  333. >
  334. InputIterator1 operator()(
  335. InputIterator1 first1,InputIterator1 last1,
  336. InputIterator2& first2,InputIterator2 last2, /* note the & */
  337. BinaryPredicate pred)const
  338. {
  339. while(first1!=last1&&first2!=last2&&pred(*first1,*first2)){
  340. ++first1;
  341. ++first2;
  342. }
  343. return first1;
  344. }
  345. };
  346. template<
  347. typename... Ts,typename Iterator,
  348. typename InputIterator,typename BinaryPredicate,
  349. enable_if_poly_collection_iterator<Iterator> =nullptr
  350. >
  351. BOOST_FORCEINLINE std::pair<Iterator,InputIterator> mismatch(
  352. const Iterator& first1,const Iterator& last1,
  353. InputIterator first2,BinaryPredicate pred)
  354. {
  355. auto it=generic_find<mismatch_alg,Ts...>(first1,last1,first2,pred);
  356. return {it,first2};
  357. }
  358. template<
  359. typename... Ts,typename Iterator,typename InputIterator,
  360. enable_if_poly_collection_iterator<Iterator> =nullptr
  361. >
  362. BOOST_FORCEINLINE std::pair<Iterator,InputIterator> mismatch(
  363. const Iterator& first1,const Iterator& last1,InputIterator first2)
  364. {
  365. return algorithm::mismatch<Ts...>(
  366. first1,last1,first2,transparent_equal_to{});
  367. }
  368. template<
  369. typename... Ts,typename Iterator,
  370. typename InputIterator,typename BinaryPredicate,
  371. enable_if_poly_collection_iterator<Iterator> =nullptr
  372. >
  373. BOOST_FORCEINLINE std::pair<Iterator,InputIterator> mismatch(
  374. const Iterator& first1,const Iterator& last1,
  375. InputIterator first2,InputIterator last2,BinaryPredicate pred)
  376. {
  377. auto it=generic_find<mismatch_alg,Ts...>(first1,last1,first2,last2,pred);
  378. return {it,first2};
  379. }
  380. template<
  381. typename... Ts,typename Iterator,typename InputIterator,
  382. enable_if_poly_collection_iterator<Iterator> =nullptr
  383. >
  384. BOOST_FORCEINLINE std::pair<Iterator,InputIterator> mismatch(
  385. const Iterator& first1,const Iterator& last1,
  386. InputIterator first2,InputIterator last2)
  387. {
  388. return algorithm::mismatch<Ts...>(
  389. first1,last1,first2,last2,transparent_equal_to{});
  390. }
  391. struct equal_alg
  392. {
  393. template<
  394. typename InputIterator1,
  395. typename InputIterator2,typename BinaryPredicate
  396. >
  397. bool operator()(
  398. InputIterator1 first1,InputIterator1 last1,
  399. InputIterator2& first2,BinaryPredicate pred)const /* note the & */
  400. {
  401. for(;first1!=last1;++first1,++first2){
  402. if(!pred(*first1,*first2))return false;
  403. }
  404. return true;
  405. }
  406. template<
  407. typename InputIterator1,
  408. typename InputIterator2,typename BinaryPredicate
  409. >
  410. bool operator()(
  411. InputIterator1 first1,InputIterator1 last1,
  412. InputIterator2& first2,InputIterator2 last2, /* note the & */
  413. BinaryPredicate pred)const
  414. {
  415. for(;first1!=last1&&first2!=last2;++first1,++first2){
  416. if(!pred(*first1,*first2))return false;
  417. }
  418. return first1==last1; /* don't check first2==last2 as op is partial */
  419. }
  420. };
  421. template<
  422. typename... Ts,typename Iterator,
  423. typename InputIterator,typename BinaryPredicate,
  424. enable_if_poly_collection_iterator<Iterator> =nullptr
  425. >
  426. BOOST_FORCEINLINE bool equal(
  427. const Iterator& first1,const Iterator& last1,
  428. InputIterator first2,BinaryPredicate pred)
  429. {
  430. using model_type=typename iterator_traits<Iterator>::model_type;
  431. auto alg=restitute_range<model_type,Ts...>(equal_alg{},first2,pred);
  432. for(auto i:detail::segment_split(first1,last1))if(!alg(i))return false;
  433. return true;
  434. }
  435. template<
  436. typename... Ts,typename Iterator,typename InputIterator,
  437. enable_if_poly_collection_iterator<Iterator> =nullptr
  438. >
  439. BOOST_FORCEINLINE bool equal(
  440. const Iterator& first1,const Iterator& last1,InputIterator first2)
  441. {
  442. return algorithm::equal<Ts...>(first1,last1,first2,transparent_equal_to{});
  443. }
  444. template<
  445. typename... Ts,typename Iterator,
  446. typename InputIterator,typename BinaryPredicate,
  447. enable_if_poly_collection_iterator<Iterator> =nullptr
  448. >
  449. BOOST_FORCEINLINE bool equal(
  450. const Iterator& first1,const Iterator& last1,
  451. InputIterator first2,InputIterator last2,BinaryPredicate pred)
  452. {
  453. using model_type=typename iterator_traits<Iterator>::model_type;
  454. auto alg=restitute_range<model_type,Ts...>(equal_alg{},first2,last2,pred);
  455. for(auto i:detail::segment_split(first1,last1))if(!alg(i))return false;
  456. return first2==last2;
  457. }
  458. template<
  459. typename... Ts,typename Iterator,typename InputIterator,
  460. enable_if_poly_collection_iterator<Iterator> =nullptr
  461. >
  462. BOOST_FORCEINLINE bool equal(
  463. const Iterator& first1,const Iterator& last1,
  464. InputIterator first2,InputIterator last2)
  465. {
  466. return algorithm::equal<Ts...>(
  467. first1,last1,first2,last2,transparent_equal_to{});
  468. }
  469. template<
  470. typename Iterator,
  471. enable_if_poly_collection_iterator<Iterator> =nullptr
  472. >
  473. BOOST_FORCEINLINE std::ptrdiff_t fast_distance(
  474. const Iterator& first,const Iterator& last)
  475. {
  476. using traits=iterator_traits<Iterator>;
  477. if(first==last)return 0;
  478. auto sfirst=traits::base_segment_info_iterator_from(first),
  479. slast=traits::base_segment_info_iterator_from(last);
  480. if(sfirst==slast){
  481. return std::distance(
  482. traits::local_base_iterator_from(first),
  483. traits::local_base_iterator_from(last));
  484. }
  485. else{
  486. std::ptrdiff_t m=std::distance(
  487. traits::local_base_iterator_from(first),sfirst->end());
  488. while(++sfirst!=slast)m+=std::distance(sfirst->begin(),sfirst->end());
  489. if(slast!=traits::end_base_segment_info_iterator_from(last)){
  490. m+=std::distance(
  491. slast->begin(),traits::local_base_iterator_from(last));
  492. }
  493. return m;
  494. }
  495. }
  496. template<
  497. typename... Ts,typename Iterator,
  498. typename ForwardIterator,typename BinaryPredicate,
  499. enable_if_poly_collection_iterator<Iterator> =nullptr
  500. >
  501. BOOST_FORCEINLINE bool is_permutation_suffix(
  502. const Iterator& first1,const Iterator& last1,
  503. ForwardIterator first2,ForwardIterator last2,BinaryPredicate pred)
  504. {
  505. using traits=iterator_traits<Iterator>;
  506. using model_type=typename traits::model_type;
  507. auto send=traits::end_base_segment_info_iterator_from(last1);
  508. for(auto i:detail::segment_split(first1,last1)){
  509. for(auto lbscan=i.begin();lbscan!=i.end();++lbscan){
  510. auto& info=i.type_info();
  511. auto p=head_closure(
  512. restitute_iterator<model_type,Ts...>(deref_1st_to(pred)),info,lbscan);
  513. auto scan=traits::iterator_from(lbscan,send);
  514. if(algorithm::find_if<Ts...>(first1,scan,p)!=scan)continue;
  515. std::ptrdiff_t matches=std::count_if(first2,last2,p);
  516. if(matches==0||
  517. matches!=algorithm::count_if<Ts...>(scan,last1,p))return false;
  518. }
  519. }
  520. return true;
  521. }
  522. template<
  523. typename... Ts,typename Iterator,
  524. typename ForwardIterator,typename BinaryPredicate,
  525. enable_if_poly_collection_iterator<Iterator> =nullptr
  526. >
  527. BOOST_FORCEINLINE bool is_permutation(
  528. Iterator first1,Iterator last1,ForwardIterator first2,BinaryPredicate pred)
  529. {
  530. std::tie(first1,first2)=algorithm::mismatch<Ts...>(first1,last1,first2,pred);
  531. auto last2=std::next(first2,algorithm::fast_distance(first1,last1));
  532. return is_permutation_suffix<Ts...>(first1,last1,first2,last2,pred);
  533. }
  534. template<
  535. typename... Ts,typename Iterator,typename ForwardIterator,
  536. enable_if_poly_collection_iterator<Iterator> =nullptr
  537. >
  538. BOOST_FORCEINLINE bool is_permutation(
  539. const Iterator& first1,const Iterator& last1,ForwardIterator first2)
  540. {
  541. return algorithm::is_permutation<Ts...>(
  542. first1,last1,first2,transparent_equal_to{});
  543. }
  544. template<
  545. typename... Ts,typename Iterator,
  546. typename ForwardIterator,typename BinaryPredicate,
  547. enable_if_poly_collection_iterator<Iterator> =nullptr
  548. >
  549. BOOST_FORCEINLINE bool is_permutation(
  550. Iterator first1,Iterator last1,
  551. ForwardIterator first2,ForwardIterator last2,BinaryPredicate pred)
  552. {
  553. std::tie(first1,first2)=algorithm::mismatch<Ts...>(
  554. first1,last1,first2,last2,pred);
  555. if(algorithm::fast_distance(first1,last1)!=std::distance(first2,last2))
  556. return false;
  557. else return is_permutation_suffix<Ts...>(first1,last1,first2,last2,pred);
  558. }
  559. template<
  560. typename... Ts,typename Iterator,typename ForwardIterator,
  561. enable_if_poly_collection_iterator<Iterator> =nullptr
  562. >
  563. BOOST_FORCEINLINE bool is_permutation(
  564. const Iterator& first1,const Iterator& last1,
  565. ForwardIterator first2,ForwardIterator last2)
  566. {
  567. return algorithm::is_permutation<Ts...>(
  568. first1,last1,first2,last2,transparent_equal_to{});
  569. }
  570. template<
  571. typename... Ts,typename Iterator,
  572. typename ForwardIterator,typename BinaryPredicate,
  573. enable_if_poly_collection_iterator<Iterator> =nullptr
  574. >
  575. BOOST_FORCEINLINE Iterator search(
  576. const Iterator& first1,const Iterator& last1,
  577. ForwardIterator first2,ForwardIterator last2,BinaryPredicate pred)
  578. {
  579. using traits=iterator_traits<Iterator>;
  580. auto send=traits::end_base_segment_info_iterator_from(last1);
  581. for(auto i:detail::segment_split(first1,last1)){
  582. for(auto lbit=i.begin(),lbend=i.end();lbit!=lbend;++lbit){
  583. Iterator it=traits::iterator_from(lbit,send);
  584. if(algorithm::mismatch<Ts...>(it,last1,first2,last2,pred).second==last2)
  585. return it;
  586. }
  587. }
  588. return last1;
  589. }
  590. template<
  591. typename... Ts,typename Iterator,typename ForwardIterator,
  592. enable_if_poly_collection_iterator<Iterator> =nullptr
  593. >
  594. BOOST_FORCEINLINE Iterator search(
  595. const Iterator& first1,const Iterator& last1,
  596. ForwardIterator first2,ForwardIterator last2)
  597. {
  598. return algorithm::search<Ts...>(
  599. first1,last1,first2,last2,transparent_equal_to{});
  600. }
  601. template<
  602. typename... Ts,typename Iterator,
  603. typename ForwardIterator,typename BinaryPredicate,
  604. enable_if_poly_collection_iterator<Iterator> =nullptr
  605. >
  606. BOOST_FORCEINLINE Iterator find_end(
  607. Iterator first1,Iterator last1,
  608. ForwardIterator first2,ForwardIterator last2,BinaryPredicate pred)
  609. {
  610. if(first2==last2)return last1;
  611. for(Iterator res=last1;;){
  612. Iterator res1=algorithm::search<Ts...>(first1,last1,first2,last2,pred);
  613. if(res1==last1)return res;
  614. else{
  615. first1=res=res1;
  616. ++first1;
  617. }
  618. }
  619. }
  620. template<
  621. typename... Ts,typename Iterator,typename ForwardIterator,
  622. enable_if_poly_collection_iterator<Iterator> =nullptr
  623. >
  624. BOOST_FORCEINLINE Iterator find_end(
  625. const Iterator& first1,const Iterator& last1,
  626. ForwardIterator first2,ForwardIterator last2)
  627. {
  628. return algorithm::find_end<Ts...>(
  629. first1,last1,first2,last2,transparent_equal_to{});
  630. }
  631. struct search_n_alg
  632. {
  633. template<
  634. typename ForwardIterator,typename Size,
  635. typename T,typename BinaryPredicate
  636. >
  637. ForwardIterator operator()(
  638. ForwardIterator first,ForwardIterator last,
  639. Size count,bool& carry,Size& remain,const T& x, /* note the &s */
  640. BinaryPredicate pred)const
  641. {
  642. for(;first!=last;++first){
  643. if(!pred(*first,x)){carry=false;remain=count;continue;}
  644. auto res=first;
  645. for(;;){
  646. if(--remain==0||++first==last)return res;
  647. if(!pred(*first,x)){carry=false;remain=count;break;}
  648. }
  649. }
  650. return last;
  651. }
  652. };
  653. template<
  654. typename... Ts,typename Iterator,
  655. typename Size,typename T,typename BinaryPredicate,
  656. enable_if_poly_collection_iterator<Iterator> =nullptr
  657. >
  658. BOOST_FORCEINLINE Iterator search_n(
  659. const Iterator& first,const Iterator& last,
  660. Size count,const T& x,BinaryPredicate pred)
  661. {
  662. using traits=iterator_traits<Iterator>;
  663. using model_type=typename traits::model_type;
  664. using local_base_iterator=typename traits::local_base_iterator;
  665. if(count<=0)return first;
  666. bool carry=false;
  667. auto remain=count;
  668. auto alg=restitute_range<model_type,Ts...>(
  669. cast_return<local_base_iterator>(search_n_alg{}),
  670. count,carry,remain,x,pred);
  671. local_base_iterator prev;
  672. for(auto i:detail::segment_split(first,last)){
  673. auto it=alg(i);
  674. if(it!=i.end()){
  675. if(remain==0)
  676. return traits::iterator_from(
  677. carry?prev:it,
  678. traits::end_base_segment_info_iterator_from(last));
  679. else if(!carry){prev=it;carry=true;}
  680. }
  681. }
  682. return last;
  683. }
  684. template<
  685. typename... Ts,typename Iterator,
  686. typename Size,typename T,
  687. enable_if_poly_collection_iterator<Iterator> =nullptr
  688. >
  689. BOOST_FORCEINLINE Iterator search_n(
  690. const Iterator& first,const Iterator& last,Size count,const T& x)
  691. {
  692. return algorithm::search_n<Ts...>(
  693. first,last,count,x,transparent_equal_to{});
  694. }
  695. template<
  696. typename Algorithm,typename... Ts,
  697. typename Iterator,typename OutputIterator,typename... Args,
  698. enable_if_poly_collection_iterator<Iterator> =nullptr
  699. >
  700. BOOST_FORCEINLINE OutputIterator generic_copy(
  701. const Iterator& first,const Iterator& last,OutputIterator res,Args&&... args)
  702. {
  703. using model_type=typename iterator_traits<Iterator>::model_type;
  704. for(auto i:detail::segment_split(first,last)){
  705. auto alg=restitute_range<model_type,Ts...>(
  706. Algorithm{},res,std::forward<Args>(args)...);
  707. res=alg(i);
  708. }
  709. return res;
  710. }
  711. BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_copy,std::copy)
  712. template<
  713. typename... Ts,typename Iterator,typename OutputIterator,
  714. enable_if_poly_collection_iterator<Iterator> =nullptr
  715. >
  716. BOOST_FORCEINLINE OutputIterator copy(
  717. const Iterator& first,const Iterator& last,OutputIterator res)
  718. {
  719. return generic_copy<std_copy,Ts...>(first,last,res);
  720. }
  721. BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_copy_n,std::copy_n)
  722. template<
  723. typename... Ts,typename Iterator,typename Size,typename OutputIterator,
  724. enable_if_poly_collection_iterator<Iterator> =nullptr
  725. >
  726. BOOST_FORCEINLINE OutputIterator copy_n(
  727. const Iterator& first,Size count,OutputIterator res)
  728. {
  729. using traits=iterator_traits<Iterator>;
  730. using model_type=typename traits::model_type;
  731. if(count<=0)return res;
  732. auto lbit=traits::local_base_iterator_from(first);
  733. auto sit=traits::base_segment_info_iterator_from(first);
  734. for(;;){
  735. auto n=(std::min)(count,static_cast<Size>(sit->end()-lbit));
  736. auto alg=restitute_iterator<model_type,Ts...>(std_copy_n{},n,res);
  737. res=alg(sit->type_info(),lbit);
  738. if((count-=n)==0)break;
  739. ++sit;
  740. lbit=sit->begin();
  741. }
  742. return res;
  743. }
  744. BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_copy_if,std::copy_if)
  745. template<
  746. typename... Ts,typename Iterator,typename OutputIterator,typename Predicate,
  747. enable_if_poly_collection_iterator<Iterator> =nullptr
  748. >
  749. BOOST_FORCEINLINE OutputIterator copy_if(
  750. const Iterator& first,const Iterator& last,OutputIterator res,Predicate pred)
  751. {
  752. return generic_copy<std_copy_if,Ts...>(first,last,res,pred);
  753. }
  754. BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_move,std::move)
  755. template<
  756. typename... Ts,typename Iterator,typename OutputIterator,
  757. enable_if_poly_collection_iterator<Iterator> =nullptr
  758. >
  759. BOOST_FORCEINLINE OutputIterator move(
  760. const Iterator& first,const Iterator& last,OutputIterator res)
  761. {
  762. return generic_copy<std_move,Ts...>(first,last,res);
  763. }
  764. BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_transform,std::transform)
  765. template<
  766. typename... Ts,typename Iterator,
  767. typename OutputIterator,typename UnaryOperation,
  768. enable_if_poly_collection_iterator<Iterator> =nullptr
  769. >
  770. BOOST_FORCEINLINE OutputIterator transform(
  771. const Iterator& first,const Iterator& last,
  772. OutputIterator res,UnaryOperation op)
  773. {
  774. return generic_copy<std_transform,Ts...>(first,last,res,op);
  775. }
  776. struct transform2_alg
  777. {
  778. template<
  779. typename InputIterator1,typename InputIterator2,
  780. typename OutputIterator,typename BinaryOperation
  781. >
  782. OutputIterator operator()(
  783. InputIterator1 first1,InputIterator1 last1,
  784. OutputIterator res, /* third place for compatibility with generic_copy */
  785. InputIterator2& first2, BinaryOperation op)const /* note the & */
  786. {
  787. while(first1!=last1)*res++=op(*first1++,*first2++);
  788. return res;
  789. }
  790. };
  791. template<
  792. typename... Ts,typename Iterator,typename InputIterator,
  793. typename OutputIterator,typename BinaryOperation,
  794. enable_if_poly_collection_iterator<Iterator> =nullptr
  795. >
  796. BOOST_FORCEINLINE OutputIterator transform(
  797. const Iterator& first1,const Iterator& last1,InputIterator first2,
  798. OutputIterator res,BinaryOperation op)
  799. {
  800. return generic_copy<transform2_alg,Ts...>(first1,last1,res,first2,op);
  801. }
  802. struct replace_copy_alg
  803. {
  804. /* std::replace_copy broken in VS2015, internal ticket VSO#279818
  805. * "<algorithm>: replace_copy() and replace_copy_if() shouldn't use the
  806. * conditional operator".
  807. */
  808. template<typename InputIterator,typename OutputIterator,typename T>
  809. OutputIterator operator()(
  810. InputIterator first,InputIterator last,OutputIterator res,
  811. const T& old_x,const T& new_x)
  812. {
  813. for(;first!=last;++first,++res){
  814. if(*first==old_x)*res=new_x;
  815. else *res=*first;
  816. }
  817. return res;
  818. }
  819. };
  820. template<
  821. typename... Ts,typename Iterator,typename OutputIterator,typename T,
  822. enable_if_poly_collection_iterator<Iterator> =nullptr
  823. >
  824. BOOST_FORCEINLINE OutputIterator replace_copy(
  825. const Iterator& first,const Iterator& last,OutputIterator res,
  826. const T& old_x,const T& new_x)
  827. {
  828. return generic_copy<replace_copy_alg,Ts...>(first,last,res,old_x,new_x);
  829. }
  830. struct replace_copy_if_alg
  831. {
  832. /* std::replace_copy_if broken in VS2015, internal ticket VSO#279818
  833. * "<algorithm>: replace_copy() and replace_copy_if() shouldn't use the
  834. * conditional operator".
  835. */
  836. template<
  837. typename InputIterator,typename OutputIterator,
  838. typename Predicate,typename T
  839. >
  840. OutputIterator operator()(
  841. InputIterator first,InputIterator last,OutputIterator res,
  842. Predicate pred,const T& new_x)
  843. {
  844. for(;first!=last;++first,++res){
  845. if(pred(*first))*res=new_x;
  846. else *res=*first;
  847. }
  848. return res;
  849. }
  850. };
  851. template<
  852. typename... Ts,typename Iterator,typename OutputIterator,
  853. typename Predicate,typename T,
  854. enable_if_poly_collection_iterator<Iterator> =nullptr
  855. >
  856. BOOST_FORCEINLINE OutputIterator replace_copy_if(
  857. const Iterator& first,const Iterator& last,OutputIterator res,
  858. Predicate pred,const T& new_x)
  859. {
  860. return generic_copy<replace_copy_if_alg,Ts...>(first,last,res,pred,new_x);
  861. }
  862. BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_remove_copy,std::remove_copy)
  863. template<
  864. typename... Ts,typename Iterator,typename OutputIterator,typename T,
  865. enable_if_poly_collection_iterator<Iterator> =nullptr
  866. >
  867. BOOST_FORCEINLINE OutputIterator remove_copy(
  868. const Iterator& first,const Iterator& last,OutputIterator res,const T& x)
  869. {
  870. return generic_copy<std_remove_copy,Ts...>(first,last,res,x);
  871. }
  872. BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(
  873. std_remove_copy_if,std::remove_copy_if)
  874. template<
  875. typename... Ts,typename Iterator,typename OutputIterator,typename Predicate,
  876. enable_if_poly_collection_iterator<Iterator> =nullptr
  877. >
  878. BOOST_FORCEINLINE OutputIterator remove_copy_if(
  879. const Iterator& first,const Iterator& last,OutputIterator res,Predicate pred)
  880. {
  881. return generic_copy<std_remove_copy_if,Ts...>(first,last,res,pred);
  882. }
  883. template<typename... Ts>
  884. struct unique_copy_alg
  885. {
  886. template<
  887. typename LocalIterator,typename OutputIterator,
  888. typename BinaryPredicate,typename TypeIndex,typename LocalBaseIterator
  889. >
  890. OutputIterator operator()(
  891. LocalIterator first,LocalIterator last,
  892. OutputIterator res, BinaryPredicate pred,
  893. bool& carry,TypeIndex& prev_info, /* note the &s */
  894. LocalBaseIterator& prev)const
  895. {
  896. using traits=iterator_traits<LocalIterator>;
  897. using model_type=typename traits::model_type;
  898. if(carry){
  899. auto p=restitute_iterator<model_type,Ts...>(deref_to(pred));
  900. for(;first!=last;++first)if(!p(prev_info,prev,first))break;
  901. }
  902. if(first==last)return res;
  903. res=std::unique_copy(first,last,res,pred);
  904. carry=true;
  905. prev_info=traits::template index<
  906. typename std::iterator_traits<LocalIterator>::value_type>();
  907. prev=LocalBaseIterator{last-1};
  908. return res;
  909. }
  910. };
  911. template<
  912. typename... Ts,typename Iterator,
  913. typename OutputIterator,typename BinaryPredicate,
  914. enable_if_poly_collection_iterator<Iterator> =nullptr
  915. >
  916. BOOST_FORCEINLINE OutputIterator unique_copy(
  917. const Iterator& first,const Iterator& last,
  918. OutputIterator res,BinaryPredicate pred)
  919. {
  920. using traits=iterator_traits<Iterator>;
  921. using local_base_iterator=typename traits::local_base_iterator;
  922. bool carry=false;
  923. auto prev_info=
  924. make_copyable(traits::template index<void>());
  925. local_base_iterator prev;
  926. return generic_copy<unique_copy_alg<Ts...>,Ts...>(
  927. first,last,res,pred,carry,prev_info,prev);
  928. }
  929. template<
  930. typename... Ts,typename Iterator,typename OutputIterator,
  931. enable_if_poly_collection_iterator<Iterator> =nullptr
  932. >
  933. BOOST_FORCEINLINE OutputIterator unique_copy(
  934. const Iterator& first,const Iterator& last,OutputIterator res)
  935. {
  936. return algorithm::unique_copy<Ts...>(first,last,res,transparent_equal_to{});
  937. }
  938. template<
  939. typename... Ts,typename Iterator,typename OutputIterator,
  940. enable_if_poly_collection_iterator<Iterator> =nullptr
  941. >
  942. BOOST_FORCEINLINE OutputIterator rotate_copy(
  943. const Iterator& first,const Iterator& middle,const Iterator& last,
  944. OutputIterator res)
  945. {
  946. res=algorithm::copy<Ts...>(middle,last,res);
  947. return algorithm::copy<Ts...>(first,middle,res);
  948. }
  949. struct sample_alg
  950. {
  951. template<
  952. typename InputIterator,typename OutputIterator,
  953. typename Distance,typename UniformRandomBitGenerator
  954. >
  955. OutputIterator operator()(
  956. InputIterator first,InputIterator last,
  957. OutputIterator res,Distance& n,Distance& m, /* note the &s */
  958. UniformRandomBitGenerator& g)const
  959. {
  960. for(;first!=last&&n!=0;++first){
  961. auto r=std::uniform_int_distribution<Distance>(0,--m)(g);
  962. if (r<n){
  963. *res++=*first;
  964. --n;
  965. }
  966. }
  967. return res;
  968. }
  969. };
  970. template<
  971. typename... Ts,typename Iterator,typename OutputIterator,
  972. typename Distance,typename UniformRandomBitGenerator,
  973. enable_if_poly_collection_iterator<Iterator> =nullptr
  974. >
  975. BOOST_FORCEINLINE OutputIterator sample(
  976. const Iterator& first,const Iterator& last,
  977. OutputIterator res,Distance n,UniformRandomBitGenerator&& g)
  978. {
  979. using model_type=typename iterator_traits<Iterator>::model_type;
  980. Distance m=static_cast<Distance>(algorithm::fast_distance(first,last));
  981. n=(std::min)(n,m);
  982. for(auto i:detail::segment_split(first,last)){
  983. auto alg=restitute_range<model_type,Ts...>(sample_alg{},res,n,m,g);
  984. res=alg(i);
  985. if(n==0)return res;
  986. }
  987. return res; /* never reached */
  988. }
  989. template<
  990. typename... Ts,typename Iterator,typename Predicate,
  991. enable_if_poly_collection_iterator<Iterator> =nullptr
  992. >
  993. BOOST_FORCEINLINE bool is_partitioned(
  994. const Iterator& first,const Iterator& last,Predicate pred)
  995. {
  996. auto it=algorithm::find_if_not<Ts...>(first,last,pred);
  997. if(it==last)return true;
  998. return algorithm::none_of<Ts...>(++it,last,pred);
  999. }
  1000. BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(
  1001. std_partition_copy,std::partition_copy)
  1002. template<
  1003. typename... Ts,typename Iterator,
  1004. typename OutputIterator1,typename OutputIterator2,typename Predicate,
  1005. enable_if_poly_collection_iterator<Iterator> =nullptr
  1006. >
  1007. BOOST_FORCEINLINE std::pair<OutputIterator1,OutputIterator2> partition_copy(
  1008. const Iterator& first,const Iterator& last,
  1009. OutputIterator1 rest,OutputIterator2 resf,Predicate pred)
  1010. {
  1011. using model_type=typename iterator_traits<Iterator>::model_type;
  1012. for(auto i:detail::segment_split(first,last)){
  1013. auto alg=restitute_range<model_type,Ts...>(
  1014. std_partition_copy{},rest,resf,pred);
  1015. std::tie(rest,resf)=alg(i);
  1016. }
  1017. return {rest,resf};
  1018. }
  1019. template<typename Predicate,typename... Ts>
  1020. struct partition_point_pred
  1021. {
  1022. partition_point_pred(const Predicate& pred):pred(pred){}
  1023. template<typename Iterator>
  1024. bool operator()(const Iterator& it)const
  1025. {
  1026. using traits=iterator_traits<Iterator>;
  1027. using model_type=typename traits::model_type;
  1028. auto p=restitute_iterator<model_type,Ts...>(deref_to(pred));
  1029. return p(
  1030. traits::base_segment_info_iterator_from(it)->type_info(),
  1031. traits::local_base_iterator_from(it));
  1032. }
  1033. Predicate pred;
  1034. };
  1035. template<
  1036. typename... Ts,typename Iterator,typename Predicate,
  1037. enable_if_poly_collection_iterator<Iterator> =nullptr
  1038. >
  1039. BOOST_FORCEINLINE Iterator partition_point(
  1040. const Iterator& first,const Iterator& last,Predicate pred)
  1041. {
  1042. auto_iterator<Iterator> afirst{first},alast{last};
  1043. partition_point_pred<Predicate,Ts...> p{pred};
  1044. return *std::partition_point(afirst,alast,p);
  1045. }
  1046. } /* namespace poly_collection::detail::algorithm */
  1047. } /* namespace poly_collection::detail */
  1048. /* non-modifying sequence operations */
  1049. using detail::algorithm::all_of;
  1050. using detail::algorithm::any_of;
  1051. using detail::algorithm::none_of;
  1052. using detail::algorithm::for_each;
  1053. using detail::algorithm::for_each_n;
  1054. using detail::algorithm::find;
  1055. using detail::algorithm::find_if;
  1056. using detail::algorithm::find_if_not;
  1057. using detail::algorithm::find_end;
  1058. using detail::algorithm::find_first_of;
  1059. using detail::algorithm::adjacent_find;
  1060. using detail::algorithm::count;
  1061. using detail::algorithm::count_if;
  1062. using detail::algorithm::mismatch;
  1063. using detail::algorithm::equal;
  1064. using detail::algorithm::is_permutation;
  1065. using detail::algorithm::search;
  1066. using detail::algorithm::search_n;
  1067. /* modifying sequence operations */
  1068. using detail::algorithm::copy;
  1069. using detail::algorithm::copy_n;
  1070. using detail::algorithm::copy_if;
  1071. /* copy_backward requires BidirectionalIterator */
  1072. using detail::algorithm::move;
  1073. /* move_backward requires BidirectionalIterator */
  1074. /* swap_ranges requires Swappable */
  1075. /* iter_swap requires Swappable */
  1076. using detail::algorithm::transform;
  1077. /* replace requires Assignable */
  1078. /* replace_if requires Assignable */
  1079. using detail::algorithm::replace_copy;
  1080. using detail::algorithm::replace_copy_if;
  1081. /* fill requires Assignable */
  1082. /* fill_n requires Assignable */
  1083. /* generate requires Assignable */
  1084. /* generate_n requires Assignable */
  1085. /* remove requires MoveAssignable */
  1086. /* remove_if requires MoveAssignable */
  1087. using detail::algorithm::remove_copy;
  1088. using detail::algorithm::remove_copy_if;
  1089. /* unique requires MoveAssignable */
  1090. using detail::algorithm::unique_copy;
  1091. /* reverse requires BidirectionalIterator */
  1092. /* reverse_copy requires BidirectionalIterator */
  1093. /* rotate requires MoveAssignable */
  1094. using detail::algorithm::rotate_copy;
  1095. using detail::algorithm::sample;
  1096. /* shuffle requires RandomAccessIterator */
  1097. using detail::algorithm::is_partitioned;
  1098. /* partition requires Swappable */
  1099. /* stable_partition requires Swappable */
  1100. using detail::algorithm::partition_copy;
  1101. using detail::algorithm::partition_point;
  1102. /* sorting and related operations not provided */
  1103. } /* namespace poly_collection */
  1104. } /* namespace boost */
  1105. #if defined(BOOST_MSVC)
  1106. #pragma warning(pop) /* C4714 */
  1107. #endif
  1108. #endif