diff --git a/experimental/bench_segmented_algos.cpp b/experimental/bench_segmented_algos.cpp index 05f31ec..8bcaa0b 100644 --- a/experimental/bench_segmented_algos.cpp +++ b/experimental/bench_segmented_algos.cpp @@ -416,6 +416,24 @@ FwdIt partition_point(FwdIt first, FwdIt last, Pred pred) #endif +#if BOOST_CXX_VERSION < 201402L + +// Portable two-range std::mismatch (std::mismatch with 4 args is C++14). +template +std::pair mismatch(InIt1 first1, InIt1 last1, InIt2 first2, InIt2 last2) +{ + while (first1 != last1 && first2 != last2 && *first1 == *first2) { + ++first1; ++first2; + } + return std::pair(first1, first2); +} + +#else + +using std::mismatch; + +#endif + template BidirIt find_last_dispatch(BidirIt first, BidirIt last, const T& val, std::bidirectional_iterator_tag) { @@ -497,7 +515,6 @@ BOOST_CONTAINER_FORCEINLINE It find_last_if_not(It first, It last, Pred pred) return find_last_if_not_dispatch(first, last, pred, cat()); } - //Not benchmarked: //inplace_merge @@ -557,7 +574,6 @@ BOOST_CONTAINER_FORCEINLINE It find_last_if_not(It first, It last, Pred pred) //is_heap_until (random-access non-implementable?) //not implemented (c++14) -//mismatch with two full ranges //equal with two full ranges //not implemented (c++17) @@ -1255,6 +1271,22 @@ struct seg_mismatch { { clobber(); result = (bc::segmented_mismatch(c.begin(), c.end(), range2.begin()).first == c.end()) ? 1 : 0; escape(&result); } }; +// --- mismatch (two-range) --- +template +struct std_mismatch_2r { + const C &c; R2 &range2; int &result; + std_mismatch_2r(const C &c_, R2 &r2_, int &r_) : c(c_), range2(r2_), result(r_) {} + BOOST_CONTAINER_FORCEINLINE void operator()() + { clobber(); result = (bench_detail::mismatch(c.begin(), c.end(), range2.begin(), range2.end()).first == c.end()) ? 1 : 0; escape(&result); } +}; +template +struct seg_mismatch_2r { + const C &c; R2 &range2; int &result; + seg_mismatch_2r(const C &c_, R2 &r2_, int &r_) : c(c_), range2(r2_), result(r_) {} + BOOST_CONTAINER_FORCEINLINE void operator()() + { clobber(); result = (bc::segmented_mismatch(c.begin(), c.end(), range2.begin(), range2.end()).first == c.end()) ? 1 : 0; escape(&result); } +}; + // --- swap_ranges --- template struct std_swap_ranges { @@ -1875,6 +1907,19 @@ void bench_mismatch(const C &c, const C &c2, std::size_t iters, const char* cnam bench_ops::seg_mismatch(c, range2, result), label, cname); } +template +void bench_mismatch_2r(const C &c, const C &c2, std::size_t iters, const char* cname, + const char* label) +{ + typedef typename C::value_type VT; + typedef typename boost::move_detail::if_c, boost::container::vector >::type range2_t; + range2_t range2(c2.begin(), c2.end()); + int result = 0; + compare_batch(iters, c.size(), + bench_ops::std_mismatch_2r(c, range2, result), + bench_ops::seg_mismatch_2r(c, range2, result), label, cname); +} + template void bench_swap_ranges(const C &c, std::size_t iters, const char* cname) { @@ -2142,6 +2187,18 @@ void run_all(const C& c, std::size_t iters, const char* cname) bench_mismatch(c, c2, iters, cname, "mismatch(2xS miss)"); } + //mismatch (two ranges) + { + C c2(c); + *boost::container::make_iterator_uadvance(c2.begin(), c2.size()/2) = min1; + bench_mismatch_2r(c, c2, iters, cname, "mismatch_2r(hit)"); + bench_mismatch_2r(c, c2, iters, cname, "mismatch_2r(2xS hit)"); + *boost::container::make_iterator_uadvance(c2.begin(), c2.size()/2) = + *boost::container::make_iterator_uadvance(c.begin(), c.size()/2); + bench_mismatch_2r(c, c2, iters, cname, "mismatch_2r(miss)"); + bench_mismatch_2r(c, c2, iters, cname, "mismatch_2r(2xS miss)"); + } + //none_of bench_none_of(c, iters, cname, is_negative(), "none_of(hit)"); bench_none_of(c, iters, cname, equal_to_ref(VT(static_cast(c.size()/2))), "none_of(miss)");