1818
1919#include " benchmark/benchmark.h"
2020#include " ../../GenerateInput.h"
21+ #include " test_iterators.h"
2122#include " test_macros.h"
2223
2324int main (int argc, char ** argv) {
2425 auto std_copy = [](auto first, auto last, auto out) { return std::copy (first, last, out); };
2526
2627 // {std,ranges}::copy(normal container)
2728 {
28- auto bm = []<class Container >(std::string name, auto copy) {
29+ auto bm = []<class ContainerIn , class ContainerOut = std::vector<typename ContainerIn::value_type>>(
30+ std::string name, auto copy) {
2931 benchmark::RegisterBenchmark (name, [copy](auto & st) {
3032 std::size_t const n = st.range (0 );
31- using ValueType = typename Container ::value_type;
32- Container c;
33+ using ValueType = typename ContainerIn ::value_type;
34+ ContainerIn c;
3335 std::generate_n (std::back_inserter (c), n, [] { return Generate<ValueType>::random (); });
3436
35- std::vector<ValueType> out (n);
37+ ContainerOut out (n);
3638
3739 for ([[maybe_unused]] auto _ : st) {
3840 benchmark::DoNotOptimize (c);
@@ -42,12 +44,21 @@ int main(int argc, char** argv) {
4244 }
4345 })->Range (8 , 1 << 20 );
4446 };
47+ // Copy from normal containers to vector<int>
4548 bm.operator ()<std::vector<int >>(" std::copy(vector<int>)" , std_copy);
4649 bm.operator ()<std::deque<int >>(" std::copy(deque<int>)" , std_copy);
4750 bm.operator ()<std::list<int >>(" std::copy(list<int>)" , std_copy);
4851 bm.operator ()<std::vector<int >>(" rng::copy(vector<int>)" , std::ranges::copy);
4952 bm.operator ()<std::deque<int >>(" rng::copy(deque<int>)" , std::ranges::copy);
5053 bm.operator ()<std::list<int >>(" rng::copy(list<int>)" , std::ranges::copy);
54+
55+ // Copy from normal containers to vector<bool>
56+ bm.operator ()<std::vector<int >, std::vector<bool >>(" std::copy(vector<int>, std::vector<bool>)" , std_copy);
57+ bm.operator ()<std::deque<int >, std::vector<bool >>(" std::copy(deque<int>, std::vector<bool>)" , std_copy);
58+ bm.operator ()<std::list<int >, std::vector<bool >>(" std::copy(list<int>, std::vector<bool>)" , std_copy);
59+ bm.operator ()<std::vector<int >, std::vector<bool >>(" rng::copy(vector<int>, std::vector<bool>)" , std::ranges::copy);
60+ bm.operator ()<std::deque<int >, std::vector<bool >>(" rng::copy(deque<int>, std::vector<bool>)" , std::ranges::copy);
61+ bm.operator ()<std::list<int >, std::vector<bool >>(" rng::copy(list<int>, std::vector<bool>)" , std::ranges::copy);
5162 }
5263
5364 // {std,ranges}::copy(vector<bool>)
@@ -76,6 +87,32 @@ int main(int argc, char** argv) {
7687#endif
7788 }
7889
90+ // {std,ranges}::copy(forward_iterator, forward_iterator, vector<bool>)
91+ {
92+ auto bm = []<template <class > class Iter >(std::string name, auto copy) {
93+ benchmark::RegisterBenchmark (name, [copy](auto & st) {
94+ std::size_t const n = st.range (0 );
95+ std::vector<int > in (n, 1 );
96+ std::vector<bool > out (n);
97+ auto first = Iter (in.begin ());
98+ auto last = Iter (in.end ());
99+ auto dst = out.begin ();
100+ for ([[maybe_unused]] auto _ : st) {
101+ benchmark::DoNotOptimize (in);
102+ benchmark::DoNotOptimize (out);
103+ auto result = copy (first, last, dst);
104+ benchmark::DoNotOptimize (result);
105+ }
106+ })->Range (64 , 1 << 20 );
107+ };
108+ bm.operator ()<forward_iterator>(" std::copy(forward_iterator, vector<bool>)" , std_copy);
109+ bm.operator ()<random_access_iterator>(" std::copy(random_access_iterator, vector<bool>)" , std_copy);
110+ #if TEST_STD_VER >= 23 // vector<bool>::iterator is not an output_iterator before C++23
111+ bm.operator ()<forward_iterator>(" rng::copy(forward_iterator, vector<bool>)" , std::ranges::copy);
112+ bm.operator ()<random_access_iterator>(" rng::copy(random_access_iterator, vector<bool>)" , std::ranges::copy);
113+ #endif
114+ }
115+
79116 benchmark::Initialize (&argc, argv);
80117 benchmark::RunSpecifiedBenchmarks ();
81118 benchmark::Shutdown ();
0 commit comments