Details
-
Bug
-
Status: Open
-
Minor
-
Resolution: Unresolved
-
4.2.0
-
None
-
Incorrect Behavior
Description
While investigating purify errors in 21.string.append.cpp, I ran into bunch FMR failures [this same failure occurs in other tests also]. They point to a legitimate bug in basic_string::replace() and possibly others like vector::insert(). I'm not really sure what the best approach for fixing this is because the issue itself is a little weird. There is also the issue of exception safety which makes it a little more interesting.
#include <cassert> #include <string> #include <vector> template <class _IteratorT> struct dumb_input_iterator { typedef typename _IteratorT::value_type value_type; typedef typename _IteratorT::difference_type difference_type; typedef typename _IteratorT::pointer pointer; typedef typename _IteratorT::reference reference; typedef std::input_iterator_tag iterator_category; dumb_input_iterator (const _IteratorT &__rhs) : _C_iter (__rhs) {} reference operator* () const { return _C_iter.operator*(); } pointer operator-> () const { return _C_iter.operator->(); } dumb_input_iterator& operator++ () { return _C_iter.operator++(), *this; } dumb_input_iterator operator++ (int) { dumb_input_iterator __tmp(*this); _C_iter.operator++(); return __tmp; } bool operator== (const dumb_input_iterator &__rhs) const { return _C_iter == __rhs._C_iter; } bool operator!= (const dumb_input_iterator &__rhs) const { return !(_C_iter == __rhs._C_iter); } private: _IteratorT _C_iter; }; int main() { // i'm not exactly sure why you'd do this, but the following code // creates input iterators on top of bidirectional iterators. when // passing an input iterator to these [and possibly other] methods // it is assumed that the iterator does not refer to elements inside // the container, which is wrong. size_t n; typedef std::string string; string s(16, 'a'); // loop in an attempt to ensure internal buffer reallocation for (n = 0; n < 8; ++n) { size_t i = s.size (); const dumb_input_iterator<string::iterator> db (s.begin ()); const dumb_input_iterator<string::iterator> de (s.end ()); s.append (db, de); // s.append (s.begin (), s.end ()); // works as expected for (; i < s.size (); ++i) assert (s[i] == 'a'); } typedef std::vector<int> vector; vector v(16, 1); // loop in an attempt to ensure internal buffer reallocation for (n = 0; n < 8; ++n) { size_t i = v.size (); const dumb_input_iterator<vector::iterator> db (v.begin ()); const dumb_input_iterator<vector::iterator> de (v.end ()); v.insert (v.end (), db, de); // v.insert (v.end (), v.begin (), v.end ()); // works as expected for (; i < v.size (); ++i) assert (v[i] == 1); } return 0; }