@@ -48,6 +48,76 @@ void BM_Assignment(benchmark::State& st, Container) {
4848 }
4949}
5050
51+ // Wrap any Iterator into an input iterator
52+ template <typename Iterator>
53+ class InputIterator {
54+ using iter_traits = std::iterator_traits<Iterator>;
55+
56+ public:
57+ using iterator_category = std::input_iterator_tag;
58+ using value_type = typename iter_traits::value_type;
59+ using difference_type = typename iter_traits::difference_type;
60+ using pointer = typename iter_traits::pointer;
61+ using reference = typename iter_traits::reference;
62+
63+ InputIterator (Iterator it) : current_(it) {}
64+
65+ reference operator *() { return *current_; }
66+ InputIterator& operator ++() {
67+ ++current_;
68+ return *this ;
69+ }
70+ InputIterator operator ++(int ) {
71+ InputIterator tmp = *this ;
72+ ++(*this );
73+ return tmp;
74+ }
75+
76+ friend bool operator ==(const InputIterator& lhs, const InputIterator& rhs) { return lhs.current_ == rhs.current_ ; }
77+ friend bool operator !=(const InputIterator& lhs, const InputIterator& rhs) { return !(lhs == rhs); }
78+
79+ private:
80+ Iterator current_;
81+ };
82+
83+ template <typename Iterator>
84+ InputIterator<Iterator> make_input_iterator (Iterator it) {
85+ return InputIterator<Iterator>(it);
86+ }
87+
88+ template <class Container ,
89+ class GenInputs ,
90+ typename std::enable_if<std::is_trivial<typename Container::value_type>::value>::type* = nullptr >
91+ void BM_AssignInputIterIter (benchmark::State& st, Container c, GenInputs gen) {
92+ auto in = gen (st.range (1 ));
93+ benchmark::DoNotOptimize (&in);
94+ for (auto _ : st) {
95+ st.PauseTiming ();
96+ c.resize (st.range (0 ));
97+ benchmark::DoNotOptimize (&c);
98+ st.ResumeTiming ();
99+ c.assign (make_input_iterator (in.begin ()), make_input_iterator (in.end ()));
100+ benchmark::ClobberMemory ();
101+ }
102+ }
103+
104+ template <class Container ,
105+ class GenInputs ,
106+ typename std::enable_if<!std::is_trivial<typename Container::value_type>::value>::type* = nullptr >
107+ void BM_AssignInputIterIter (benchmark::State& st, Container c, GenInputs gen) {
108+ auto v = gen (1 , 100 );
109+ auto in = gen (st.range (1 ), 32 );
110+ benchmark::DoNotOptimize (&in);
111+ for (auto _ : st) {
112+ st.PauseTiming ();
113+ c.resize (st.range (0 ), v[0 ]);
114+ benchmark::DoNotOptimize (&c);
115+ st.ResumeTiming ();
116+ c.assign (make_input_iterator (in.begin ()), make_input_iterator (in.end ()));
117+ benchmark::ClobberMemory ();
118+ }
119+ }
120+
51121template <class Container >
52122void BM_ConstructSizeValue (benchmark::State& st, Container, typename Container::value_type const & val) {
53123 const auto size = st.range (0 );
0 commit comments