Warning, file /include/boost/poly_collection/algorithm.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_POLY_COLLECTION_ALGORITHM_HPP
0010 #define BOOST_POLY_COLLECTION_ALGORITHM_HPP
0011
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015
0016 #include <algorithm>
0017 #include <boost/config.hpp>
0018 #include <boost/poly_collection/detail/auto_iterator.hpp>
0019 #include <boost/poly_collection/detail/copyable.hpp>
0020 #include <boost/poly_collection/detail/functional.hpp>
0021 #include <boost/poly_collection/detail/iterator_traits.hpp>
0022 #include <boost/poly_collection/detail/segment_split.hpp>
0023 #include <boost/poly_collection/detail/type_restitution.hpp>
0024 #include <iterator>
0025 #include <random>
0026 #include <type_traits>
0027 #include <utility>
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 #if defined(BOOST_MSVC)
0043 #pragma warning(push)
0044 #pragma warning(disable:4714)
0045 #endif
0046
0047 namespace boost{
0048
0049 namespace poly_collection{
0050
0051 namespace detail{
0052
0053 namespace algorithm{
0054
0055 template<typename Iterator>
0056 using enable_if_poly_collection_iterator=typename std::enable_if<
0057 !std::is_void<typename poly_collection_of<Iterator>::type>::value
0058 >::type*;
0059
0060 BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_all_of,std::all_of)
0061
0062 template<
0063 typename... Ts,typename Iterator,typename Predicate,
0064 enable_if_poly_collection_iterator<Iterator> =nullptr
0065 >
0066 BOOST_FORCEINLINE
0067 bool all_of(const Iterator& first,const Iterator& last,Predicate pred)
0068 {
0069 using model_type=typename iterator_traits<Iterator>::model_type;
0070
0071 auto alg=restitute_range<model_type,Ts...>(std_all_of{},pred);
0072 for(auto i:detail::segment_split(first,last))if(!alg(i))return false;
0073 return true;
0074 }
0075
0076 BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_any_of,std::any_of)
0077
0078 template<
0079 typename... Ts,typename Iterator,typename Predicate,
0080 enable_if_poly_collection_iterator<Iterator> =nullptr
0081 >
0082 BOOST_FORCEINLINE bool any_of(
0083 const Iterator& first,const Iterator& last,Predicate pred)
0084 {
0085 using model_type=typename iterator_traits<Iterator>::model_type;
0086
0087 auto alg=restitute_range<model_type,Ts...>(std_any_of{},pred);
0088 for(auto i:detail::segment_split(first,last))if(alg(i))return true;
0089 return false;
0090 }
0091
0092 BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_none_of,std::none_of)
0093
0094 template<
0095 typename... Ts,typename Iterator,typename Predicate,
0096 enable_if_poly_collection_iterator<Iterator> =nullptr
0097 >
0098 BOOST_FORCEINLINE bool none_of(
0099 const Iterator& first,const Iterator& last,Predicate pred)
0100 {
0101 using model_type=typename iterator_traits<Iterator>::model_type;
0102
0103 auto alg=restitute_range<model_type,Ts...>(std_none_of{},pred);
0104 for(auto i:detail::segment_split(first,last))if(!alg(i))return false;
0105 return true;
0106 }
0107
0108 struct for_each_alg
0109 {
0110 template<typename InputIterator,typename Function>
0111 void operator()(
0112 InputIterator first,InputIterator last,Function& f)const
0113 {
0114 for(;first!=last;++first)f(*first);
0115 }
0116 };
0117
0118 template<typename... Ts,typename Iterator,typename Function,
0119 enable_if_poly_collection_iterator<Iterator> =nullptr
0120 >
0121 BOOST_FORCEINLINE Function for_each(
0122 const Iterator& first,const Iterator& last,Function f)
0123 {
0124 using model_type=typename iterator_traits<Iterator>::model_type;
0125
0126 for_each_segment(
0127 first,last,restitute_range<model_type,Ts...>(for_each_alg{},f));
0128 return f;
0129 }
0130
0131 struct for_each_n_alg
0132 {
0133 template<
0134 typename InputIterator,typename Size,typename Function
0135 >
0136 InputIterator operator()(
0137 InputIterator first,Size n,Function& f)const
0138 {
0139 for(;n>0;++first,(void)--n)f(*first);
0140 return first;
0141 }
0142 };
0143
0144 template<
0145 typename... Ts,typename Iterator,typename Size,typename Function,
0146 enable_if_poly_collection_iterator<Iterator> =nullptr
0147 >
0148 BOOST_FORCEINLINE Iterator for_each_n(const Iterator& first,Size n,Function f)
0149 {
0150 using traits=iterator_traits<Iterator>;
0151 using model_type=typename traits::model_type;
0152 using local_base_iterator=typename traits::local_base_iterator;
0153
0154 if(n<=0)return first;
0155
0156 auto alg=restitute_iterator<model_type,Ts...>(
0157 cast_return<local_base_iterator>(for_each_n_alg{}));
0158 auto lbit=traits::local_base_iterator_from(first);
0159 auto sit=traits::base_segment_info_iterator_from(first);
0160 for(;;){
0161 Size m=static_cast<Size>(sit->end()-lbit);
0162 if(n<=m){
0163 auto it=alg(sit->type_info(),lbit,n,f);
0164 return traits::iterator_from(
0165 it,traits::end_base_segment_info_iterator_from(first));
0166 }
0167 else{
0168 alg(sit->type_info(),lbit,m,f);
0169 n-=m;
0170 }
0171 ++sit;
0172 lbit=sit->begin();
0173 }
0174 }
0175
0176 template<
0177 typename Algorithm,typename... Ts,
0178 typename Iterator,typename... Args,
0179 enable_if_poly_collection_iterator<Iterator> =nullptr
0180 >
0181 BOOST_FORCEINLINE Iterator generic_find(
0182 const Iterator& first,const Iterator& last,Args&&... args)
0183 {
0184 using traits=iterator_traits<Iterator>;
0185 using model_type=typename traits::model_type;
0186 using local_base_iterator=typename traits::local_base_iterator;
0187
0188 auto alg=restitute_range<model_type,Ts...>(
0189 cast_return<local_base_iterator>(Algorithm{}),
0190 std::forward<Args>(args)...);
0191 for(auto i:detail::segment_split(first,last)){
0192 auto it=alg(i);
0193 if(it!=i.end())
0194 return traits::iterator_from(
0195 it,traits::end_base_segment_info_iterator_from(last));
0196 }
0197 return last;
0198 }
0199
0200 BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_find,std::find)
0201
0202 template<
0203 typename... Ts,typename Iterator,typename T,
0204 enable_if_poly_collection_iterator<Iterator> =nullptr
0205 >
0206 BOOST_FORCEINLINE Iterator find(
0207 const Iterator& first,const Iterator& last,const T& x)
0208 {
0209 return generic_find<std_find,Ts...>(first,last,x);
0210 }
0211
0212 BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_find_if,std::find_if)
0213
0214 template<
0215 typename... Ts,typename Iterator,typename Predicate,
0216 enable_if_poly_collection_iterator<Iterator> =nullptr
0217 >
0218 BOOST_FORCEINLINE Iterator find_if(
0219 const Iterator& first,const Iterator& last,Predicate pred)
0220 {
0221 return generic_find<std_find_if,Ts...>(first,last,pred);
0222 }
0223
0224 BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_find_if_not,std::find_if_not)
0225
0226 template<
0227 typename... Ts,typename Iterator,typename Predicate,
0228 enable_if_poly_collection_iterator<Iterator> =nullptr
0229 >
0230 BOOST_FORCEINLINE Iterator find_if_not(
0231 const Iterator& first,const Iterator& last,Predicate pred)
0232 {
0233 return generic_find<std_find_if_not,Ts...>(first,last,pred);
0234 }
0235
0236
0237
0238 BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_find_first_of,std::find_first_of)
0239
0240 template<
0241 typename... Ts,typename Iterator,typename ForwardIterator,
0242 enable_if_poly_collection_iterator<Iterator> =nullptr
0243 >
0244 BOOST_FORCEINLINE Iterator find_first_of(
0245 const Iterator& first1,const Iterator& last1,
0246 ForwardIterator first2,ForwardIterator last2)
0247 {
0248 return generic_find<std_find_first_of,Ts...>(first1,last1,first2,last2);
0249 }
0250
0251 template<
0252 typename... Ts,typename Iterator,
0253 typename ForwardIterator,typename BinaryPredicate,
0254 enable_if_poly_collection_iterator<Iterator> =nullptr
0255 >
0256 BOOST_FORCEINLINE Iterator find_first_of(
0257 const Iterator& first1,const Iterator& last1,
0258 ForwardIterator first2,ForwardIterator last2,BinaryPredicate pred)
0259 {
0260 return generic_find<std_find_first_of,Ts...>(first1,last1,first2,last2,pred);
0261 }
0262
0263 template<typename... Ts>
0264 struct adjacent_find_alg
0265 {
0266 template<
0267 typename LocalIterator,typename BinaryPredicate,
0268 typename TypeIndex,typename LocalBaseIterator
0269 >
0270 LocalBaseIterator operator()(
0271 LocalIterator first,LocalIterator last,BinaryPredicate pred,
0272 bool& carry,TypeIndex& prev_info,
0273 LocalBaseIterator& prev)const
0274 {
0275 using traits=iterator_traits<LocalIterator>;
0276 using model_type=typename traits::model_type;
0277
0278 if(first==last)return LocalBaseIterator{last};
0279 if(carry){
0280 auto p=restitute_iterator<model_type,Ts...>(deref_to(pred));
0281 if(p(prev_info,prev,first))return prev;
0282 }
0283 auto res=std::adjacent_find(first,last,pred);
0284 if(res==last){
0285 carry=true;
0286 prev_info=traits::template index<
0287 typename std::iterator_traits<LocalIterator>::value_type>();
0288 prev=LocalBaseIterator{last-1};
0289 }
0290 else carry=false;
0291 return LocalBaseIterator{res};
0292 }
0293 };
0294
0295 template<
0296 typename... Ts,typename Iterator,typename BinaryPredicate,
0297 enable_if_poly_collection_iterator<Iterator> =nullptr
0298 >
0299 BOOST_FORCEINLINE Iterator adjacent_find(
0300 const Iterator& first,const Iterator& last,BinaryPredicate pred)
0301 {
0302 using traits=iterator_traits<Iterator>;
0303 using local_base_iterator=typename traits::local_base_iterator;
0304
0305 bool carry=false;
0306 auto prev_info=
0307 make_copyable(traits::template index<void>());
0308 local_base_iterator prev;
0309 return generic_find<adjacent_find_alg<Ts...>,Ts...>(
0310 first,last,pred,carry,prev_info,prev);
0311 }
0312
0313 template<
0314 typename... Ts,typename Iterator,
0315 enable_if_poly_collection_iterator<Iterator> =nullptr
0316 >
0317 BOOST_FORCEINLINE Iterator adjacent_find(
0318 const Iterator& first,const Iterator& last)
0319 {
0320 return algorithm::adjacent_find<Ts...>(first,last,transparent_equal_to{});
0321 }
0322
0323 template<
0324 typename Algorithm,typename... Ts,
0325 typename Iterator,typename... Args,
0326 enable_if_poly_collection_iterator<Iterator> =nullptr
0327 >
0328 BOOST_FORCEINLINE std::ptrdiff_t generic_count(
0329 const Iterator& first,const Iterator& last,Args&&... args)
0330 {
0331 using model_type=typename iterator_traits<Iterator>::model_type;
0332
0333 auto alg=restitute_range<model_type,Ts...>(
0334 Algorithm{},std::forward<Args>(args)...);
0335 std::ptrdiff_t res=0;
0336 for(auto i:detail::segment_split(first,last))res+=alg(i);
0337 return res;
0338 }
0339
0340 BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_count,std::count)
0341
0342 template<
0343 typename... Ts,typename Iterator,typename T,
0344 enable_if_poly_collection_iterator<Iterator> =nullptr
0345 >
0346 BOOST_FORCEINLINE std::ptrdiff_t count(
0347 const Iterator& first,const Iterator& last,const T& x)
0348 {
0349 return generic_count<std_count,Ts...>(first,last,x);
0350 }
0351
0352 BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_count_if,std::count_if)
0353
0354 template<
0355 typename... Ts,typename Iterator,typename Predicate,
0356 enable_if_poly_collection_iterator<Iterator> =nullptr
0357 >
0358 BOOST_FORCEINLINE std::ptrdiff_t count_if(
0359 const Iterator& first,const Iterator& last,Predicate pred)
0360 {
0361 return generic_count<std_count_if,Ts...>(first,last,pred);
0362 }
0363
0364 struct mismatch_alg
0365 {
0366 template<
0367 typename InputIterator1,
0368 typename InputIterator2,typename BinaryPredicate
0369 >
0370 InputIterator1 operator()(
0371 InputIterator1 first1,InputIterator1 last1,
0372 InputIterator2& first2,BinaryPredicate pred)const
0373 {
0374 while(first1!=last1&&pred(*first1,*first2)){
0375 ++first1;
0376 ++first2;
0377 }
0378 return first1;
0379 }
0380
0381 template<
0382 typename InputIterator1,
0383 typename InputIterator2,typename BinaryPredicate
0384 >
0385 InputIterator1 operator()(
0386 InputIterator1 first1,InputIterator1 last1,
0387 InputIterator2& first2,InputIterator2 last2,
0388 BinaryPredicate pred)const
0389 {
0390 while(first1!=last1&&first2!=last2&&pred(*first1,*first2)){
0391 ++first1;
0392 ++first2;
0393 }
0394 return first1;
0395 }
0396 };
0397
0398 template<
0399 typename... Ts,typename Iterator,
0400 typename InputIterator,typename BinaryPredicate,
0401 enable_if_poly_collection_iterator<Iterator> =nullptr
0402 >
0403 BOOST_FORCEINLINE std::pair<Iterator,InputIterator> mismatch(
0404 const Iterator& first1,const Iterator& last1,
0405 InputIterator first2,BinaryPredicate pred)
0406 {
0407 auto it=generic_find<mismatch_alg,Ts...>(first1,last1,first2,pred);
0408 return {it,first2};
0409 }
0410
0411 template<
0412 typename... Ts,typename Iterator,typename InputIterator,
0413 enable_if_poly_collection_iterator<Iterator> =nullptr
0414 >
0415 BOOST_FORCEINLINE std::pair<Iterator,InputIterator> mismatch(
0416 const Iterator& first1,const Iterator& last1,InputIterator first2)
0417 {
0418 return algorithm::mismatch<Ts...>(
0419 first1,last1,first2,transparent_equal_to{});
0420 }
0421
0422 template<
0423 typename... Ts,typename Iterator,
0424 typename InputIterator,typename BinaryPredicate,
0425 enable_if_poly_collection_iterator<Iterator> =nullptr
0426 >
0427 BOOST_FORCEINLINE std::pair<Iterator,InputIterator> mismatch(
0428 const Iterator& first1,const Iterator& last1,
0429 InputIterator first2,InputIterator last2,BinaryPredicate pred)
0430 {
0431 auto it=generic_find<mismatch_alg,Ts...>(first1,last1,first2,last2,pred);
0432 return {it,first2};
0433 }
0434
0435 template<
0436 typename... Ts,typename Iterator,typename InputIterator,
0437 enable_if_poly_collection_iterator<Iterator> =nullptr
0438 >
0439 BOOST_FORCEINLINE std::pair<Iterator,InputIterator> mismatch(
0440 const Iterator& first1,const Iterator& last1,
0441 InputIterator first2,InputIterator last2)
0442 {
0443 return algorithm::mismatch<Ts...>(
0444 first1,last1,first2,last2,transparent_equal_to{});
0445 }
0446
0447 struct equal_alg
0448 {
0449 template<
0450 typename InputIterator1,
0451 typename InputIterator2,typename BinaryPredicate
0452 >
0453 bool operator()(
0454 InputIterator1 first1,InputIterator1 last1,
0455 InputIterator2& first2,BinaryPredicate pred)const
0456 {
0457 for(;first1!=last1;++first1,++first2){
0458 if(!pred(*first1,*first2))return false;
0459 }
0460 return true;
0461 }
0462
0463 template<
0464 typename InputIterator1,
0465 typename InputIterator2,typename BinaryPredicate
0466 >
0467 bool operator()(
0468 InputIterator1 first1,InputIterator1 last1,
0469 InputIterator2& first2,InputIterator2 last2,
0470 BinaryPredicate pred)const
0471 {
0472 for(;first1!=last1&&first2!=last2;++first1,++first2){
0473 if(!pred(*first1,*first2))return false;
0474 }
0475 return first1==last1;
0476 }
0477 };
0478
0479 template<
0480 typename... Ts,typename Iterator,
0481 typename InputIterator,typename BinaryPredicate,
0482 enable_if_poly_collection_iterator<Iterator> =nullptr
0483 >
0484 BOOST_FORCEINLINE bool equal(
0485 const Iterator& first1,const Iterator& last1,
0486 InputIterator first2,BinaryPredicate pred)
0487 {
0488 using model_type=typename iterator_traits<Iterator>::model_type;
0489
0490 auto alg=restitute_range<model_type,Ts...>(equal_alg{},first2,pred);
0491 for(auto i:detail::segment_split(first1,last1))if(!alg(i))return false;
0492 return true;
0493 }
0494
0495 template<
0496 typename... Ts,typename Iterator,typename InputIterator,
0497 enable_if_poly_collection_iterator<Iterator> =nullptr
0498 >
0499 BOOST_FORCEINLINE bool equal(
0500 const Iterator& first1,const Iterator& last1,InputIterator first2)
0501 {
0502 return algorithm::equal<Ts...>(first1,last1,first2,transparent_equal_to{});
0503 }
0504
0505 template<
0506 typename... Ts,typename Iterator,
0507 typename InputIterator,typename BinaryPredicate,
0508 enable_if_poly_collection_iterator<Iterator> =nullptr
0509 >
0510 BOOST_FORCEINLINE bool equal(
0511 const Iterator& first1,const Iterator& last1,
0512 InputIterator first2,InputIterator last2,BinaryPredicate pred)
0513 {
0514 using model_type=typename iterator_traits<Iterator>::model_type;
0515
0516 auto alg=restitute_range<model_type,Ts...>(equal_alg{},first2,last2,pred);
0517 for(auto i:detail::segment_split(first1,last1))if(!alg(i))return false;
0518 return first2==last2;
0519 }
0520
0521 template<
0522 typename... Ts,typename Iterator,typename InputIterator,
0523 enable_if_poly_collection_iterator<Iterator> =nullptr
0524 >
0525 BOOST_FORCEINLINE bool equal(
0526 const Iterator& first1,const Iterator& last1,
0527 InputIterator first2,InputIterator last2)
0528 {
0529 return algorithm::equal<Ts...>(
0530 first1,last1,first2,last2,transparent_equal_to{});
0531 }
0532
0533 template<
0534 typename Iterator,
0535 enable_if_poly_collection_iterator<Iterator> =nullptr
0536 >
0537 BOOST_FORCEINLINE std::ptrdiff_t fast_distance(
0538 const Iterator& first,const Iterator& last)
0539 {
0540 using traits=iterator_traits<Iterator>;
0541
0542 if(first==last)return 0;
0543
0544 auto sfirst=traits::base_segment_info_iterator_from(first),
0545 slast=traits::base_segment_info_iterator_from(last);
0546 if(sfirst==slast){
0547 return std::distance(
0548 traits::local_base_iterator_from(first),
0549 traits::local_base_iterator_from(last));
0550 }
0551 else{
0552 std::ptrdiff_t m=std::distance(
0553 traits::local_base_iterator_from(first),sfirst->end());
0554 while(++sfirst!=slast)m+=std::distance(sfirst->begin(),sfirst->end());
0555 if(slast!=traits::end_base_segment_info_iterator_from(last)){
0556 m+=std::distance(
0557 slast->begin(),traits::local_base_iterator_from(last));
0558 }
0559 return m;
0560 }
0561 }
0562
0563 template<
0564 typename... Ts,typename Iterator,
0565 typename ForwardIterator,typename BinaryPredicate,
0566 enable_if_poly_collection_iterator<Iterator> =nullptr
0567 >
0568 BOOST_FORCEINLINE bool is_permutation_suffix(
0569 const Iterator& first1,const Iterator& last1,
0570 ForwardIterator first2,ForwardIterator last2,BinaryPredicate pred)
0571 {
0572 using traits=iterator_traits<Iterator>;
0573 using model_type=typename traits::model_type;
0574
0575 auto send=traits::end_base_segment_info_iterator_from(last1);
0576 for(auto i:detail::segment_split(first1,last1)){
0577 for(auto lbscan=i.begin();lbscan!=i.end();++lbscan){
0578 auto& info=i.type_info();
0579 auto p=head_closure(
0580 restitute_iterator<model_type,Ts...>(deref_1st_to(pred)),info,lbscan);
0581 auto scan=traits::iterator_from(lbscan,send);
0582 if(algorithm::find_if<Ts...>(first1,scan,p)!=scan)continue;
0583 std::ptrdiff_t matches=std::count_if(first2,last2,p);
0584 if(matches==0||
0585 matches!=algorithm::count_if<Ts...>(scan,last1,p))return false;
0586 }
0587 }
0588 return true;
0589 }
0590
0591 template<
0592 typename... Ts,typename Iterator,
0593 typename ForwardIterator,typename BinaryPredicate,
0594 enable_if_poly_collection_iterator<Iterator> =nullptr
0595 >
0596 BOOST_FORCEINLINE bool is_permutation(
0597 Iterator first1,Iterator last1,ForwardIterator first2,BinaryPredicate pred)
0598 {
0599 std::tie(first1,first2)=algorithm::mismatch<Ts...>(first1,last1,first2,pred);
0600 auto last2=std::next(first2,algorithm::fast_distance(first1,last1));
0601 return is_permutation_suffix<Ts...>(first1,last1,first2,last2,pred);
0602 }
0603
0604 template<
0605 typename... Ts,typename Iterator,typename ForwardIterator,
0606 enable_if_poly_collection_iterator<Iterator> =nullptr
0607 >
0608 BOOST_FORCEINLINE bool is_permutation(
0609 const Iterator& first1,const Iterator& last1,ForwardIterator first2)
0610 {
0611 return algorithm::is_permutation<Ts...>(
0612 first1,last1,first2,transparent_equal_to{});
0613 }
0614
0615 template<
0616 typename... Ts,typename Iterator,
0617 typename ForwardIterator,typename BinaryPredicate,
0618 enable_if_poly_collection_iterator<Iterator> =nullptr
0619 >
0620 BOOST_FORCEINLINE bool is_permutation(
0621 Iterator first1,Iterator last1,
0622 ForwardIterator first2,ForwardIterator last2,BinaryPredicate pred)
0623 {
0624 std::tie(first1,first2)=algorithm::mismatch<Ts...>(
0625 first1,last1,first2,last2,pred);
0626 if(algorithm::fast_distance(first1,last1)!=std::distance(first2,last2))
0627 return false;
0628 else return is_permutation_suffix<Ts...>(first1,last1,first2,last2,pred);
0629 }
0630
0631 template<
0632 typename... Ts,typename Iterator,typename ForwardIterator,
0633 enable_if_poly_collection_iterator<Iterator> =nullptr
0634 >
0635 BOOST_FORCEINLINE bool is_permutation(
0636 const Iterator& first1,const Iterator& last1,
0637 ForwardIterator first2,ForwardIterator last2)
0638 {
0639 return algorithm::is_permutation<Ts...>(
0640 first1,last1,first2,last2,transparent_equal_to{});
0641 }
0642
0643 template<
0644 typename... Ts,typename Iterator,
0645 typename ForwardIterator,typename BinaryPredicate,
0646 enable_if_poly_collection_iterator<Iterator> =nullptr
0647 >
0648 BOOST_FORCEINLINE Iterator search(
0649 const Iterator& first1,const Iterator& last1,
0650 ForwardIterator first2,ForwardIterator last2,BinaryPredicate pred)
0651 {
0652 using traits=iterator_traits<Iterator>;
0653
0654 auto send=traits::end_base_segment_info_iterator_from(last1);
0655 for(auto i:detail::segment_split(first1,last1)){
0656 for(auto lbit=i.begin(),lbend=i.end();lbit!=lbend;++lbit){
0657 Iterator it=traits::iterator_from(lbit,send);
0658 if(algorithm::mismatch<Ts...>(it,last1,first2,last2,pred).second==last2)
0659 return it;
0660 }
0661 }
0662 return last1;
0663 }
0664
0665 template<
0666 typename... Ts,typename Iterator,typename ForwardIterator,
0667 enable_if_poly_collection_iterator<Iterator> =nullptr
0668 >
0669 BOOST_FORCEINLINE Iterator search(
0670 const Iterator& first1,const Iterator& last1,
0671 ForwardIterator first2,ForwardIterator last2)
0672 {
0673 return algorithm::search<Ts...>(
0674 first1,last1,first2,last2,transparent_equal_to{});
0675 }
0676
0677 template<
0678 typename... Ts,typename Iterator,
0679 typename ForwardIterator,typename BinaryPredicate,
0680 enable_if_poly_collection_iterator<Iterator> =nullptr
0681 >
0682 BOOST_FORCEINLINE Iterator find_end(
0683 Iterator first1,Iterator last1,
0684 ForwardIterator first2,ForwardIterator last2,BinaryPredicate pred)
0685 {
0686 if(first2==last2)return last1;
0687
0688 for(Iterator res=last1;;){
0689 Iterator res1=algorithm::search<Ts...>(first1,last1,first2,last2,pred);
0690 if(res1==last1)return res;
0691 else{
0692 first1=res=res1;
0693 ++first1;
0694 }
0695 }
0696 }
0697
0698 template<
0699 typename... Ts,typename Iterator,typename ForwardIterator,
0700 enable_if_poly_collection_iterator<Iterator> =nullptr
0701 >
0702 BOOST_FORCEINLINE Iterator find_end(
0703 const Iterator& first1,const Iterator& last1,
0704 ForwardIterator first2,ForwardIterator last2)
0705 {
0706 return algorithm::find_end<Ts...>(
0707 first1,last1,first2,last2,transparent_equal_to{});
0708 }
0709
0710 struct search_n_alg
0711 {
0712 template<
0713 typename ForwardIterator,typename Size,
0714 typename T,typename BinaryPredicate
0715 >
0716 ForwardIterator operator()(
0717 ForwardIterator first,ForwardIterator last,
0718 Size count,bool& carry,Size& remain,const T& x,
0719 BinaryPredicate pred)const
0720 {
0721 for(;first!=last;++first){
0722 if(!pred(*first,x)){carry=false;remain=count;continue;}
0723 auto res=first;
0724 for(;;){
0725 if(--remain==0||++first==last)return res;
0726 if(!pred(*first,x)){carry=false;remain=count;break;}
0727 }
0728 }
0729 return last;
0730 }
0731 };
0732
0733 template<
0734 typename... Ts,typename Iterator,
0735 typename Size,typename T,typename BinaryPredicate,
0736 enable_if_poly_collection_iterator<Iterator> =nullptr
0737 >
0738 BOOST_FORCEINLINE Iterator search_n(
0739 const Iterator& first,const Iterator& last,
0740 Size count,const T& x,BinaryPredicate pred)
0741 {
0742 using traits=iterator_traits<Iterator>;
0743 using model_type=typename traits::model_type;
0744 using local_base_iterator=typename traits::local_base_iterator;
0745
0746 if(count<=0)return first;
0747
0748 bool carry=false;
0749 auto remain=count;
0750 auto alg=restitute_range<model_type,Ts...>(
0751 cast_return<local_base_iterator>(search_n_alg{}),
0752 count,carry,remain,x,pred);
0753 local_base_iterator prev;
0754 for(auto i:detail::segment_split(first,last)){
0755 auto it=alg(i);
0756 if(it!=i.end()){
0757 if(remain==0)
0758 return traits::iterator_from(
0759 carry?prev:it,
0760 traits::end_base_segment_info_iterator_from(last));
0761 else if(!carry){prev=it;carry=true;}
0762 }
0763 }
0764 return last;
0765 }
0766
0767 template<
0768 typename... Ts,typename Iterator,
0769 typename Size,typename T,
0770 enable_if_poly_collection_iterator<Iterator> =nullptr
0771 >
0772 BOOST_FORCEINLINE Iterator search_n(
0773 const Iterator& first,const Iterator& last,Size count,const T& x)
0774 {
0775 return algorithm::search_n<Ts...>(
0776 first,last,count,x,transparent_equal_to{});
0777 }
0778
0779 template<
0780 typename Algorithm,typename... Ts,
0781 typename Iterator,typename OutputIterator,typename... Args,
0782 enable_if_poly_collection_iterator<Iterator> =nullptr
0783 >
0784 BOOST_FORCEINLINE OutputIterator generic_copy(
0785 const Iterator& first,const Iterator& last,OutputIterator res,Args&&... args)
0786 {
0787 using model_type=typename iterator_traits<Iterator>::model_type;
0788
0789 for(auto i:detail::segment_split(first,last)){
0790 auto alg=restitute_range<model_type,Ts...>(
0791 Algorithm{},res,std::forward<Args>(args)...);
0792 res=alg(i);
0793 }
0794 return res;
0795 }
0796
0797 BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_copy,std::copy)
0798
0799 template<
0800 typename... Ts,typename Iterator,typename OutputIterator,
0801 enable_if_poly_collection_iterator<Iterator> =nullptr
0802 >
0803 BOOST_FORCEINLINE OutputIterator copy(
0804 const Iterator& first,const Iterator& last,OutputIterator res)
0805 {
0806 return generic_copy<std_copy,Ts...>(first,last,res);
0807 }
0808
0809 BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_copy_n,std::copy_n)
0810
0811 template<
0812 typename... Ts,typename Iterator,typename Size,typename OutputIterator,
0813 enable_if_poly_collection_iterator<Iterator> =nullptr
0814 >
0815 BOOST_FORCEINLINE OutputIterator copy_n(
0816 const Iterator& first,Size count,OutputIterator res)
0817 {
0818 using traits=iterator_traits<Iterator>;
0819 using model_type=typename traits::model_type;
0820
0821 if(count<=0)return res;
0822
0823 auto lbit=traits::local_base_iterator_from(first);
0824 auto sit=traits::base_segment_info_iterator_from(first);
0825 for(;;){
0826 auto n=(std::min)(count,static_cast<Size>(sit->end()-lbit));
0827 auto alg=restitute_iterator<model_type,Ts...>(std_copy_n{},n,res);
0828 res=alg(sit->type_info(),lbit);
0829 if((count-=n)==0)break;
0830 ++sit;
0831 lbit=sit->begin();
0832 }
0833 return res;
0834 }
0835
0836 BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_copy_if,std::copy_if)
0837
0838 template<
0839 typename... Ts,typename Iterator,typename OutputIterator,typename Predicate,
0840 enable_if_poly_collection_iterator<Iterator> =nullptr
0841 >
0842 BOOST_FORCEINLINE OutputIterator copy_if(
0843 const Iterator& first,const Iterator& last,OutputIterator res,Predicate pred)
0844 {
0845 return generic_copy<std_copy_if,Ts...>(first,last,res,pred);
0846 }
0847
0848 BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_move,std::move)
0849
0850 template<
0851 typename... Ts,typename Iterator,typename OutputIterator,
0852 enable_if_poly_collection_iterator<Iterator> =nullptr
0853 >
0854 BOOST_FORCEINLINE OutputIterator move(
0855 const Iterator& first,const Iterator& last,OutputIterator res)
0856 {
0857 return generic_copy<std_move,Ts...>(first,last,res);
0858 }
0859
0860 BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_transform,std::transform)
0861
0862 template<
0863 typename... Ts,typename Iterator,
0864 typename OutputIterator,typename UnaryOperation,
0865 enable_if_poly_collection_iterator<Iterator> =nullptr
0866 >
0867 BOOST_FORCEINLINE OutputIterator transform(
0868 const Iterator& first,const Iterator& last,
0869 OutputIterator res,UnaryOperation op)
0870 {
0871 return generic_copy<std_transform,Ts...>(first,last,res,op);
0872 }
0873
0874 struct transform2_alg
0875 {
0876 template<
0877 typename InputIterator1,typename InputIterator2,
0878 typename OutputIterator,typename BinaryOperation
0879 >
0880 OutputIterator operator()(
0881 InputIterator1 first1,InputIterator1 last1,
0882 OutputIterator res,
0883 InputIterator2& first2, BinaryOperation op)const
0884 {
0885 while(first1!=last1)*res++=op(*first1++,*first2++);
0886 return res;
0887 }
0888 };
0889
0890 template<
0891 typename... Ts,typename Iterator,typename InputIterator,
0892 typename OutputIterator,typename BinaryOperation,
0893 enable_if_poly_collection_iterator<Iterator> =nullptr
0894 >
0895 BOOST_FORCEINLINE OutputIterator transform(
0896 const Iterator& first1,const Iterator& last1,InputIterator first2,
0897 OutputIterator res,BinaryOperation op)
0898 {
0899 return generic_copy<transform2_alg,Ts...>(first1,last1,res,first2,op);
0900 }
0901
0902 struct replace_copy_alg
0903 {
0904
0905
0906
0907
0908
0909 template<typename InputIterator,typename OutputIterator,typename T>
0910 OutputIterator operator()(
0911 InputIterator first,InputIterator last,OutputIterator res,
0912 const T& old_x,const T& new_x)
0913 {
0914 for(;first!=last;++first,++res){
0915 if(*first==old_x)*res=new_x;
0916 else *res=*first;
0917 }
0918 return res;
0919 }
0920 };
0921
0922 template<
0923 typename... Ts,typename Iterator,typename OutputIterator,typename T,
0924 enable_if_poly_collection_iterator<Iterator> =nullptr
0925 >
0926 BOOST_FORCEINLINE OutputIterator replace_copy(
0927 const Iterator& first,const Iterator& last,OutputIterator res,
0928 const T& old_x,const T& new_x)
0929 {
0930 return generic_copy<replace_copy_alg,Ts...>(first,last,res,old_x,new_x);
0931 }
0932
0933 struct replace_copy_if_alg
0934 {
0935
0936
0937
0938
0939
0940 template<
0941 typename InputIterator,typename OutputIterator,
0942 typename Predicate,typename T
0943 >
0944 OutputIterator operator()(
0945 InputIterator first,InputIterator last,OutputIterator res,
0946 Predicate pred,const T& new_x)
0947 {
0948 for(;first!=last;++first,++res){
0949 if(pred(*first))*res=new_x;
0950 else *res=*first;
0951 }
0952 return res;
0953 }
0954 };
0955
0956 template<
0957 typename... Ts,typename Iterator,typename OutputIterator,
0958 typename Predicate,typename T,
0959 enable_if_poly_collection_iterator<Iterator> =nullptr
0960 >
0961 BOOST_FORCEINLINE OutputIterator replace_copy_if(
0962 const Iterator& first,const Iterator& last,OutputIterator res,
0963 Predicate pred,const T& new_x)
0964 {
0965 return generic_copy<replace_copy_if_alg,Ts...>(first,last,res,pred,new_x);
0966 }
0967
0968 BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(std_remove_copy,std::remove_copy)
0969
0970 template<
0971 typename... Ts,typename Iterator,typename OutputIterator,typename T,
0972 enable_if_poly_collection_iterator<Iterator> =nullptr
0973 >
0974 BOOST_FORCEINLINE OutputIterator remove_copy(
0975 const Iterator& first,const Iterator& last,OutputIterator res,const T& x)
0976 {
0977 return generic_copy<std_remove_copy,Ts...>(first,last,res,x);
0978 }
0979
0980 BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(
0981 std_remove_copy_if,std::remove_copy_if)
0982
0983 template<
0984 typename... Ts,typename Iterator,typename OutputIterator,typename Predicate,
0985 enable_if_poly_collection_iterator<Iterator> =nullptr
0986 >
0987 BOOST_FORCEINLINE OutputIterator remove_copy_if(
0988 const Iterator& first,const Iterator& last,OutputIterator res,Predicate pred)
0989 {
0990 return generic_copy<std_remove_copy_if,Ts...>(first,last,res,pred);
0991 }
0992
0993 template<typename... Ts>
0994 struct unique_copy_alg
0995 {
0996 template<
0997 typename LocalIterator,typename OutputIterator,
0998 typename BinaryPredicate,typename TypeIndex,typename LocalBaseIterator
0999 >
1000 OutputIterator operator()(
1001 LocalIterator first,LocalIterator last,
1002 OutputIterator res, BinaryPredicate pred,
1003 bool& carry,TypeIndex& prev_info,
1004 LocalBaseIterator& prev)const
1005 {
1006 using traits=iterator_traits<LocalIterator>;
1007 using model_type=typename traits::model_type;
1008
1009 if(carry){
1010 auto p=restitute_iterator<model_type,Ts...>(deref_to(pred));
1011 for(;first!=last;++first)if(!p(prev_info,prev,first))break;
1012 }
1013 if(first==last)return res;
1014 res=std::unique_copy(first,last,res,pred);
1015 carry=true;
1016 prev_info=traits::template index<
1017 typename std::iterator_traits<LocalIterator>::value_type>();
1018 prev=LocalBaseIterator{last-1};
1019 return res;
1020 }
1021 };
1022
1023 template<
1024 typename... Ts,typename Iterator,
1025 typename OutputIterator,typename BinaryPredicate,
1026 enable_if_poly_collection_iterator<Iterator> =nullptr
1027 >
1028 BOOST_FORCEINLINE OutputIterator unique_copy(
1029 const Iterator& first,const Iterator& last,
1030 OutputIterator res,BinaryPredicate pred)
1031 {
1032 using traits=iterator_traits<Iterator>;
1033 using local_base_iterator=typename traits::local_base_iterator;
1034
1035 bool carry=false;
1036 auto prev_info=
1037 make_copyable(traits::template index<void>());
1038 local_base_iterator prev;
1039 return generic_copy<unique_copy_alg<Ts...>,Ts...>(
1040 first,last,res,pred,carry,prev_info,prev);
1041 }
1042
1043 template<
1044 typename... Ts,typename Iterator,typename OutputIterator,
1045 enable_if_poly_collection_iterator<Iterator> =nullptr
1046 >
1047 BOOST_FORCEINLINE OutputIterator unique_copy(
1048 const Iterator& first,const Iterator& last,OutputIterator res)
1049 {
1050 return algorithm::unique_copy<Ts...>(first,last,res,transparent_equal_to{});
1051 }
1052
1053 template<
1054 typename... Ts,typename Iterator,typename OutputIterator,
1055 enable_if_poly_collection_iterator<Iterator> =nullptr
1056 >
1057 BOOST_FORCEINLINE OutputIterator rotate_copy(
1058 const Iterator& first,const Iterator& middle,const Iterator& last,
1059 OutputIterator res)
1060 {
1061 res=algorithm::copy<Ts...>(middle,last,res);
1062 return algorithm::copy<Ts...>(first,middle,res);
1063 }
1064
1065 struct sample_alg
1066 {
1067 template<
1068 typename InputIterator,typename OutputIterator,
1069 typename Distance,typename UniformRandomBitGenerator
1070 >
1071 OutputIterator operator()(
1072 InputIterator first,InputIterator last,
1073 OutputIterator res,Distance& n,Distance& m,
1074 UniformRandomBitGenerator& g)const
1075 {
1076 for(;first!=last&&n!=0;++first){
1077 auto r=std::uniform_int_distribution<Distance>(0,--m)(g);
1078 if (r<n){
1079 *res++=*first;
1080 --n;
1081 }
1082 }
1083 return res;
1084 }
1085 };
1086
1087 template<
1088 typename... Ts,typename Iterator,typename OutputIterator,
1089 typename Distance,typename UniformRandomBitGenerator,
1090 enable_if_poly_collection_iterator<Iterator> =nullptr
1091 >
1092 BOOST_FORCEINLINE OutputIterator sample(
1093 const Iterator& first,const Iterator& last,
1094 OutputIterator res,Distance n,UniformRandomBitGenerator&& g)
1095 {
1096 using model_type=typename iterator_traits<Iterator>::model_type;
1097
1098 Distance m=static_cast<Distance>(algorithm::fast_distance(first,last));
1099 n=(std::min)(n,m);
1100
1101 for(auto i:detail::segment_split(first,last)){
1102 auto alg=restitute_range<model_type,Ts...>(sample_alg{},res,n,m,g);
1103 res=alg(i);
1104 if(n==0)return res;
1105 }
1106 return res;
1107 }
1108
1109 template<
1110 typename... Ts,typename Iterator,typename Predicate,
1111 enable_if_poly_collection_iterator<Iterator> =nullptr
1112 >
1113 BOOST_FORCEINLINE bool is_partitioned(
1114 const Iterator& first,const Iterator& last,Predicate pred)
1115 {
1116 auto it=algorithm::find_if_not<Ts...>(first,last,pred);
1117 if(it==last)return true;
1118 return algorithm::none_of<Ts...>(++it,last,pred);
1119 }
1120
1121 BOOST_POLY_COLLECTION_DEFINE_OVERLOAD_SET(
1122 std_partition_copy,std::partition_copy)
1123
1124 template<
1125 typename... Ts,typename Iterator,
1126 typename OutputIterator1,typename OutputIterator2,typename Predicate,
1127 enable_if_poly_collection_iterator<Iterator> =nullptr
1128 >
1129 BOOST_FORCEINLINE std::pair<OutputIterator1,OutputIterator2> partition_copy(
1130 const Iterator& first,const Iterator& last,
1131 OutputIterator1 rest,OutputIterator2 resf,Predicate pred)
1132 {
1133 using model_type=typename iterator_traits<Iterator>::model_type;
1134
1135 for(auto i:detail::segment_split(first,last)){
1136 auto alg=restitute_range<model_type,Ts...>(
1137 std_partition_copy{},rest,resf,pred);
1138 std::tie(rest,resf)=alg(i);
1139 }
1140 return {rest,resf};
1141 }
1142
1143 template<typename Predicate,typename... Ts>
1144 struct partition_point_pred
1145 {
1146 partition_point_pred(const Predicate& pred):pred(pred){}
1147
1148 template<typename Iterator>
1149 bool operator()(const Iterator& it)const
1150 {
1151 using traits=iterator_traits<Iterator>;
1152 using model_type=typename traits::model_type;
1153
1154 auto p=restitute_iterator<model_type,Ts...>(deref_to(pred));
1155 return p(
1156 traits::base_segment_info_iterator_from(it)->type_info(),
1157 traits::local_base_iterator_from(it));
1158 }
1159
1160 Predicate pred;
1161 };
1162
1163 template<
1164 typename... Ts,typename Iterator,typename Predicate,
1165 enable_if_poly_collection_iterator<Iterator> =nullptr
1166 >
1167 BOOST_FORCEINLINE Iterator partition_point(
1168 const Iterator& first,const Iterator& last,Predicate pred)
1169 {
1170 auto_iterator<Iterator> afirst{first},alast{last};
1171 partition_point_pred<Predicate,Ts...> p{pred};
1172 return *std::partition_point(afirst,alast,p);
1173 }
1174
1175 }
1176
1177 }
1178
1179
1180
1181 using detail::algorithm::all_of;
1182 using detail::algorithm::any_of;
1183 using detail::algorithm::none_of;
1184 using detail::algorithm::for_each;
1185 using detail::algorithm::for_each_n;
1186 using detail::algorithm::find;
1187 using detail::algorithm::find_if;
1188 using detail::algorithm::find_if_not;
1189 using detail::algorithm::find_end;
1190 using detail::algorithm::find_first_of;
1191 using detail::algorithm::adjacent_find;
1192 using detail::algorithm::count;
1193 using detail::algorithm::count_if;
1194 using detail::algorithm::mismatch;
1195 using detail::algorithm::equal;
1196 using detail::algorithm::is_permutation;
1197 using detail::algorithm::search;
1198 using detail::algorithm::search_n;
1199
1200
1201
1202 using detail::algorithm::copy;
1203 using detail::algorithm::copy_n;
1204 using detail::algorithm::copy_if;
1205
1206 using detail::algorithm::move;
1207
1208
1209
1210 using detail::algorithm::transform;
1211
1212
1213 using detail::algorithm::replace_copy;
1214 using detail::algorithm::replace_copy_if;
1215
1216
1217
1218
1219
1220
1221 using detail::algorithm::remove_copy;
1222 using detail::algorithm::remove_copy_if;
1223
1224 using detail::algorithm::unique_copy;
1225
1226
1227
1228 using detail::algorithm::rotate_copy;
1229 using detail::algorithm::sample;
1230
1231 using detail::algorithm::is_partitioned;
1232
1233
1234 using detail::algorithm::partition_copy;
1235 using detail::algorithm::partition_point;
1236
1237
1238
1239 }
1240
1241 }
1242
1243 #if defined(BOOST_MSVC)
1244 #pragma warning(pop)
1245 #endif
1246
1247 #endif