3333#include < boost/container/experimental/segmented_find.hpp>
3434#include < boost/container/experimental/segmented_find_if.hpp>
3535#include < boost/container/experimental/segmented_find_if_not.hpp>
36+ #include < boost/container/experimental/segmented_find_last.hpp>
37+ #include < boost/container/experimental/segmented_find_last_if.hpp>
38+ #include < boost/container/experimental/segmented_find_last_if_not.hpp>
3639#include < boost/container/experimental/segmented_for_each.hpp>
3740#include < boost/container/experimental/segmented_generate.hpp>
3841#include < boost/container/experimental/segmented_generate_n.hpp>
@@ -415,6 +418,32 @@ FwdIt partition_point(FwdIt first, FwdIt last, Pred pred)
415418
416419#endif
417420
421+ template <class FwdIt , class T >
422+ FwdIt find_last (FwdIt first, FwdIt last, const T& val)
423+ {
424+ FwdIt result = last;
425+ for (; first != last; ++first)
426+ if (*first == val) result = first;
427+ return result;
428+ }
429+
430+ template <class FwdIt , class Pred >
431+ FwdIt find_last_if (FwdIt first, FwdIt last, Pred pred)
432+ {
433+ FwdIt result = last;
434+ for (; first != last; ++first)
435+ if (pred (*first)) result = first;
436+ return result;
437+ }
438+
439+ template <class FwdIt , class Pred >
440+ FwdIt find_last_if_not (FwdIt first, FwdIt last, Pred pred)
441+ {
442+ FwdIt result = last;
443+ for (; first != last; ++first)
444+ if (!pred (*first)) result = first;
445+ return result;
446+ }
418447
419448
420449// Not benchmarked:
@@ -425,7 +454,6 @@ FwdIt partition_point(FwdIt first, FwdIt last, Pred pred)
425454// find_end
426455// find_first_of
427456// adjacent_find
428- // mismatch
429457// copy_backward
430458// move
431459// move_backward
@@ -498,10 +526,6 @@ FwdIt partition_point(FwdIt first, FwdIt last, Pred pred)
498526// lexicographical_compare_three_way
499527
500528// range-based?
501- // find_last
502- // find_last_if
503- // find_last_if_not
504- //
505529// contains
506530// contains_subrange
507531// starts_with
@@ -917,6 +941,96 @@ void bench_find_if_not(C c, std::size_t iters, const char* cname,
917941 print_ratio (label, cname, r1, r2);
918942}
919943
944+ template <class C >
945+ void bench_find_last (C c, std::size_t iters, const char * cname,
946+ const typename C::value_type& val, const char * label)
947+ {
948+ int result = 0 ;
949+
950+ cpu_timer t1;
951+ for (std::size_t i = 0 ; i < iters; ++i) {
952+ clobber ();
953+ t1.resume ();
954+ typename C::iterator it = bench_detail::find_last (c.begin (), c.end (), val);
955+ result = (it == c.end ()) ? 0 : 1 ;
956+ t1.stop ();
957+ escape (&result);
958+ }
959+ double r1 = calc_ns_per_elem (t1.elapsed ().wall , iters, c.size ());
960+
961+ cpu_timer t2;
962+ for (std::size_t i = 0 ; i < iters; ++i) {
963+ clobber ();
964+ t2.resume ();
965+ typename C::iterator it = bc::segmented_find_last (c.begin (), c.end (), val);
966+ result = (it == c.end ()) ? 0 : 1 ;
967+ t2.stop ();
968+ escape (&result);
969+ }
970+ double r2 = calc_ns_per_elem (t2.elapsed ().wall , iters, c.size ());
971+ print_ratio (label, cname, r1, r2);
972+ }
973+
974+ template <class C , class Pred >
975+ void bench_find_last_if (C c, std::size_t iters, const char * cname,
976+ Pred pred, const char * label)
977+ {
978+ int result = 0 ;
979+
980+ cpu_timer t1;
981+ for (std::size_t i = 0 ; i < iters; ++i) {
982+ clobber ();
983+ t1.resume ();
984+ typename C::iterator it = bench_detail::find_last_if (c.begin (), c.end (), pred);
985+ result = (it != c.end ()) ? int_value (*it) : -1 ;
986+ t1.stop ();
987+ escape (&result);
988+ }
989+ double r1 = calc_ns_per_elem (t1.elapsed ().wall , iters, c.size ());
990+
991+ cpu_timer t2;
992+ for (std::size_t i = 0 ; i < iters; ++i) {
993+ clobber ();
994+ t2.resume ();
995+ typename C::iterator it = bc::segmented_find_last_if (c.begin (), c.end (), pred);
996+ result = (it != c.end ()) ? int_value (*it) : -1 ;
997+ t2.stop ();
998+ escape (&result);
999+ }
1000+ double r2 = calc_ns_per_elem (t2.elapsed ().wall , iters, c.size ());
1001+ print_ratio (label, cname, r1, r2);
1002+ }
1003+
1004+ template <class C , class Pred >
1005+ void bench_find_last_if_not (C c, std::size_t iters, const char * cname,
1006+ Pred pred, const char * label)
1007+ {
1008+ int result = 0 ;
1009+
1010+ cpu_timer t1;
1011+ for (std::size_t i = 0 ; i < iters; ++i) {
1012+ clobber ();
1013+ t1.resume ();
1014+ typename C::iterator it = bench_detail::find_last_if_not (c.begin (), c.end (), pred);
1015+ result = (it != c.end ()) ? int_value (*it) : -1 ;
1016+ t1.stop ();
1017+ escape (&result);
1018+ }
1019+ double r1 = calc_ns_per_elem (t1.elapsed ().wall , iters, c.size ());
1020+
1021+ cpu_timer t2;
1022+ for (std::size_t i = 0 ; i < iters; ++i) {
1023+ clobber ();
1024+ t2.resume ();
1025+ typename C::iterator it = bc::segmented_find_last_if_not (c.begin (), c.end (), pred);
1026+ result = (it != c.end ()) ? int_value (*it) : -1 ;
1027+ t2.stop ();
1028+ escape (&result);
1029+ }
1030+ double r2 = calc_ns_per_elem (t2.elapsed ().wall , iters, c.size ());
1031+ print_ratio (label, cname, r1, r2);
1032+ }
1033+
9201034template <class C >
9211035void bench_equal (C c, C& c2, std::size_t iters, const char * cname,
9221036 const char * label)
@@ -1864,6 +1978,18 @@ void run_all(const C& c, std::size_t iters, const char* cname)
18641978 bench_find_if_not (c, iters, cname, unequal_to_ref<VT>(VT (static_cast <int >(c.size () / 2 ))), " find_if_not(hit)" );
18651979 bench_find_if_not (c, iters, cname, is_zero_or_positive<VT>(), " find_if_not(miss)" );
18661980
1981+ // find_last
1982+ bench_find_last (c, iters, cname, VT (static_cast <int >(c.size () / 2 )), " find_last(hit)" );
1983+ bench_find_last (c, iters, cname, VT (-1 ), " find_last(miss)" );
1984+
1985+ // find_last_if
1986+ bench_find_last_if (c, iters, cname, equal_to_ref<VT>(VT (static_cast <int >(c.size () / 2 ))), " find_last_if(hit)" );
1987+ bench_find_last_if (c, iters, cname, is_negative<VT>(), " find_last_if(miss)" );
1988+
1989+ // find_last_if_not
1990+ bench_find_last_if_not (c, iters, cname, unequal_to_ref<VT>(VT (static_cast <int >(c.size () / 2 ))), " find_last_if_not(hit)" );
1991+ bench_find_last_if_not (c, iters, cname, is_zero_or_positive<VT>(), " find_last_if_not(miss)" );
1992+
18671993 // for_each
18681994 bench_for_each (c, iters, cname);
18691995
@@ -1915,9 +2041,7 @@ void run_all(const C& c, std::size_t iters, const char* cname)
19152041 {
19162042 C c2 (c);
19172043 bench_mismatch (c, c2, iters, cname, " mismatch(hit)" );
1918- typename C::iterator last = c2.end ();
1919- --last;
1920- *last = VT (-1 );
2044+ c2[c2.size ()/2 ] = VT (-1 );
19212045 bench_mismatch (c, c2, iters, cname, " mismatch(miss)" );
19222046 }
19232047
0 commit comments