algorithm.hpp 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247
  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