@@ -119,6 +119,90 @@ void BM_InsertValueRehash(benchmark::State& st, Container c, GenInputs gen) {
119119 }
120120}
121121
122+ // Wrap any Iterator into an input iterator
123+ template <typename Iterator>
124+ class InputIterator {
125+ using iter_traits = std::iterator_traits<Iterator>;
126+
127+ public:
128+ using iterator_category = std::input_iterator_tag;
129+ using value_type = typename iter_traits::value_type;
130+ using difference_type = typename iter_traits::difference_type;
131+ using pointer = typename iter_traits::pointer;
132+ using reference = typename iter_traits::reference;
133+
134+ InputIterator (Iterator it) : current_(it) {}
135+
136+ reference operator *() { return *current_; }
137+ InputIterator& operator ++() {
138+ ++current_;
139+ return *this ;
140+ }
141+ InputIterator operator ++(int ) {
142+ InputIterator tmp = *this ;
143+ ++(*this );
144+ return tmp;
145+ }
146+
147+ friend bool operator ==(const InputIterator& lhs, const InputIterator& rhs) { return lhs.current_ == rhs.current_ ; }
148+ friend bool operator !=(const InputIterator& lhs, const InputIterator& rhs) { return !(lhs == rhs); }
149+
150+ private:
151+ Iterator current_;
152+ };
153+
154+ template <typename Iterator>
155+ InputIterator<Iterator> make_input_iterator (Iterator it) {
156+ return InputIterator<Iterator>(it);
157+ }
158+
159+ // Test case: vector is empty
160+ template <class Container , class GenInputs >
161+ void BM_InsertIterInputIterIterEmpty (benchmark::State& st, Container _, GenInputs gen) {
162+ auto in = gen (st.range (0 ));
163+ benchmark::DoNotOptimize (&in);
164+ for (auto _ : st) {
165+ Container c;
166+ benchmark::DoNotOptimize (&c);
167+ benchmark::DoNotOptimize (c.insert (c.begin (), make_input_iterator (in.begin ()), make_input_iterator (in.end ())));
168+ benchmark::ClobberMemory ();
169+ }
170+ }
171+
172+ // Test case: vector is half full
173+ template <class Container , class GenInputs >
174+ void BM_InsertIterInputIterIterHalfFull (benchmark::State& st, Container c, GenInputs gen) {
175+ for (auto _ : st) {
176+ st.PauseTiming ();
177+ c = gen (st.range (0 ));
178+ c.reserve (c.size () * 2 );
179+ auto in = gen (c.size () + 10 );
180+ benchmark::DoNotOptimize (&c);
181+ benchmark::DoNotOptimize (&in);
182+ st.ResumeTiming ();
183+
184+ benchmark::DoNotOptimize (c.insert (c.begin (), make_input_iterator (in.begin ()), make_input_iterator (in.end ())));
185+ benchmark::ClobberMemory ();
186+ }
187+ }
188+
189+ // Test case: vector is almost full
190+ template <class Container , class GenInputs >
191+ void BM_InsertIterInputIterIterFull (benchmark::State& st, Container c, GenInputs gen) {
192+ for (auto _ : st) {
193+ st.PauseTiming ();
194+ c = gen (st.range (0 ));
195+ c.reserve (c.size () + 5 );
196+ auto in = gen (10 );
197+ benchmark::DoNotOptimize (&c);
198+ benchmark::DoNotOptimize (&in);
199+ st.ResumeTiming ();
200+
201+ benchmark::DoNotOptimize (c.insert (c.begin (), make_input_iterator (in.begin ()), make_input_iterator (in.end ())));
202+ benchmark::ClobberMemory ();
203+ }
204+ }
205+
122206template <class Container , class GenInputs >
123207void BM_InsertDuplicate (benchmark::State& st, Container c, GenInputs gen) {
124208 auto in = gen (st.range (0 ));
0 commit comments