@@ -1306,17 +1306,17 @@ struct seg_is_partitioned {
13061306};
13071307
13081308// --- merge ---
1309- template <class C , class OutVec >
1309+ template <class C1 , class C2 , class OutT >
13101310struct std_merge {
1311- const C &c; const C &c2; OutVec &out;
1312- std_merge (const C &c_, const C &c2_, OutVec &o_) : c(c_), c2(c2_), out(o_) {}
1311+ const C1 &c; const C2 &c2; OutT &out;
1312+ std_merge (const C1 &c_, const C2 &c2_, OutT &o_) : c(c_), c2(c2_), out(o_) {}
13131313 BOOST_CONTAINER_FORCEINLINE void operator ()()
13141314 { clobber (); std::merge (c.begin (), c.end (), c2.begin (), c2.end (), out.begin ()); escape (&out[0 ]); }
13151315};
1316- template <class C , class OutVec , bool Wrap = false >
1316+ template <class C1 , class C2 , class OutT , bool Wrap = false >
13171317struct seg_merge {
1318- const C &c; const C &c2; OutVec &out;
1319- seg_merge (const C &c_, const C &c2_, OutVec &o_) : c(c_), c2(c2_), out(o_) {}
1318+ const C1 &c; const C2 &c2; OutT &out;
1319+ seg_merge (const C1 &c_, const C2 &c2_, OutT &o_) : c(c_), c2(c2_), out(o_) {}
13201320 BOOST_CONTAINER_FORCEINLINE void operator ()()
13211321 { clobber (); bc::segmented_merge (iter_w<Wrap>::wrap (c.begin ()), iter_w<Wrap>::wrap (c.end ()), iter_w<Wrap>::wrap (c2.begin ()), iter_w<Wrap>::wrap (c2.end ()), iter_w<Wrap>::wrap (out.begin ())); escape (&out[0 ]); }
13221322};
@@ -1983,16 +1983,15 @@ void bench_is_partitioned(const C &c, std::size_t iters, const char* cname,
19831983 bench_ops::seg_is_partitioned<C, Pred, true >(c, pred, result), label, cname);
19841984}
19851985
1986- template <class C >
1987- void bench_merge (const C &c, const C &c2, std::size_t iters, const char * cname)
1986+ template <class C1 , class C2 , class OutT >
1987+ void bench_merge (const C1 &c1, const C2 &c2, std::size_t iters,
1988+ const char * cname, const char * label)
19881989{
1989- typedef typename C::value_type VT ;
1990- typedef boost::container::vector<VT > out_vec_t ;
1991- out_vec_t out (c.size () + c2.size ());
1992- compare_batch (iters, c.size (),
1993- bench_ops::std_merge<C, out_vec_t >(c, c2, out),
1994- bench_ops::seg_merge<C, out_vec_t >(c, c2, out),
1995- bench_ops::seg_merge<C, out_vec_t , true >(c, c2, out), " merge" , cname);
1990+ OutT out (c1.size () + c2.size ());
1991+ compare_batch (iters, c1.size (),
1992+ bench_ops::std_merge<C1 , C2 , OutT>(c1, c2, out),
1993+ bench_ops::seg_merge<C1 , C2 , OutT>(c1, c2, out),
1994+ bench_ops::seg_merge<C1 , C2 , OutT, true >(c1, c2, out), label, cname);
19961995}
19971996
19981997template <bool IsDual, class C >
@@ -2283,10 +2282,24 @@ void run_all(const C& c, std::size_t iters, const char* cname)
22832282
22842283 // merge
22852284 {
2285+ typedef boost::container::vector<VT > vec_t ;
22862286 C c2 (c);
22872287 for (typename C::iterator it = c2.begin (); it != c2.end (); ++it)
22882288 *it = VT (int_value (*it) * 2 );
2289- bench_merge (c, c2, iters, cname);
2289+ // Flat copies of the inputs for the mixed-shape variants. Both copies
2290+ // are sorted (input data is monotonically generated) so the merge
2291+ // semantics are preserved.
2292+ vec_t v1 (c.begin (), c.end ());
2293+ vec_t v2 (c2.begin (), c2.end ());
2294+
2295+ // merge(1): first range = C, second range = bc::vector, out = bc::vector
2296+ bench_merge<C, vec_t , vec_t >(c, v2, iters, cname, " merge(1S)" );
2297+ // merge(2): first range = bc::vector, second range = C, out = bc::vector
2298+ bench_merge<vec_t , C, vec_t >(v1, c2, iters, cname, " merge(2S)" );
2299+ // merge(2xS): both ranges = C, out = bc::vector
2300+ bench_merge<C, C, vec_t >(c, c2, iters, cname, " merge(2xS)" );
2301+ // merge(3xS): both ranges and out = C
2302+ bench_merge<C, C, C >(c, c2, iters, cname, " merge(3xS)" );
22902303 }
22912304
22922305 // mismatch
0 commit comments