This is the mail archive of the libstdc++@sourceware.cygnus.com mailing list for the libstdc++ project. See the libstdc++ home page for more information.
Here is my idea how the basic_string::iterator and
basic_string::const_iterator should look like.
Please note that this is for exposition of the basic design only.
I didn't try to compile it even once. I am only posting this
because yesterday I promised to post something today. It's
late and I can hardly think anymore.
This code is intended to go directly into bits/basic_string.h,
somewhere in between all the typedefs and the first usage of
iterator or const_iterator. I'll try to complete it tomorrow.
Note that it seems that we don't have to specialize
iterator_traits<> for anything. The defauld definition (24.3.1/2)
will work just fine.
// Beginning of the definition of basic_string::iterator and
// basic_string::const_iterator. There is massive amount of
// code duplication here for the larger good. To mitigate
// consequences of the code duplication, the two copies are kept
// as identical as possible. Lines that differ between the two are
// marked with // at the end of the line.
private:
// two helper typedefs for the definition of basic_string::iterator
// and basic_string::const_iterator which follow later.
typedef std::iterator<typename std::random_access_iterator_tag,
typename basic_string::value_type, //
typename basic_string::difference_type,
typename basic_string::pointer, //
typename basic_string::reference> //
__iterator_base; //
typedef std::iterator<typename std::random_access_iterator_tag,
typename basic_string::value_type const, //
typename basic_string::difference_type,
typename basic_string::const_pointer, //
typename basic_string::const_reference> //
__const_iterator_base; //
public:
// basic_string::iterator class //
class iterator : public basic_string::__iterator_base { //
private:
typedef typename basic_string::__iterator_base __inherited; //
typedef iterator _Self; //
public:
typedef typename __inherited::value_type value_type;
typedef typename __inherited::difference_type difference_type;
typedef typename __inherited::pointer pointer;
typedef typename __inherited::reference reference;
typedef typename __inherited::iterator_category iterator_category;
private:
pointer _M_ptr_;
private:
pointer& _M_ptr() { return _M_ptr; }
pointer _M_ptr() const { return _M_ptr; }
public:
iterator() : _M_ptr(0) {} //
// copy constructor, copy assignment and the destructor
// are provided by the compiler.
private:
// dummy second parameter to the following constructor
// will be introduced later
explicit iterator(pointer __ptr) : _M_ptr(__ptr) {} //
friend class basic_string; // needs access to the above
// constructor
friend class basic_string::const_iterator; // ditto //
public:
reference operator*() const { return *(this->_M_ptr()); }
pointer operator->() const { return this->_M_ptr(); }
_Self& operator++() { ++this->_M_ptr(); return *this; }
_Self operator++(int) { return iterator(this->_M_ptr()++); }
_Self& operator--() { --this->_M_ptr(); return *this; }
_Self operator--(int) { return iterator(this->_M_ptr()--); }
_Self& operator+=(difference_type __n)
{ this->_M_ptr()+=__n; return *this; }
_Self& operator-=(difference_type __n)
{ this->_M_ptr()-=__n; return *this; }
reference operator[](difference_type __n) const
{ return this->_M_ptr()[__n]; }
friend _Self operator+(_Self __i, difference_type __n)
{ return _Self(__i)+=n; }
friend _Self operator-(_Self __i, difference_type __n)
{ return _Self(__i)-=n; }
friend difference_type operator-(const _Self __i1,
const _Self __i2)
{ return __i1._M_ptr() - __i2._M_ptr(); }
friend bool operator==(const _Self __i1, const _Self __i2)
{ return __i1._M_ptr() == __i2._M_ptr(); }
friend bool operator!=(const _Self __i1, const _Self __i2)
{ return __i1._M_ptr() != __i2._M_ptr(); }
friend bool operator >(const _Self __i1, const _Self __i2)
{ return __i1._M_ptr() > __i2._M_ptr(); }
friend bool operator <(const _Self __i1, const _Self __i2)
{ return __i1._M_ptr() < __i2._M_ptr(); }
friend bool operator>=(const _Self __i1, const _Self __i2)
{ return __i1._M_ptr() >= __i2._M_ptr(); }
friend bool operator<=(const _Self __i1, const _Self __i2)
{ return __i1._M_ptr() <= __i2._M_ptr(); }
}; // definition of the iterator class
public:
// basic_string::const_iterator class
class const_iterator : public basic_string::__const_iterator_base { //
private:
typedef typename basic_string::__const_iterator_base __inherited; //
typedef const_iterator _Self; //
public:
typedef typename inherited::value_type value_type;
typedef typename inherited::difference_type difference_type;
typedef typename inherited::pointer pointer;
typedef typename inherited::reference reference;
typedef typename inherited::iterator_category iterator_category;
private:
pointer _M_ptr_; // Note that this is actually (const value_type *)
private:
pointer& _M_ptr() { return _M_ptr; }
pointer _M_ptr() const { return _M_ptr; }
public:
const_iterator() : _M_ptr(0) {} //
// copy constructor, copy assignment and the destructor
// are provided by the compiler.
private:
// dummy second parameter to the following constructor
// will be introduced later
explicit const_iterator(pointer __ptr) : _M_ptr(__ptr) {} //
friend class basic_string; // needs access to the above
// constructor
// Line is missing here, compared to the basic_string::iterator //
public:
reference operator*() const { return *(this->_M_ptr()); }
pointer operator->() const { return this->_M_ptr(); }
_Self& operator++() { ++this->_M_ptr(); return *this; }
_Self operator++(int) { return iterator(this->_M_ptr()++); }
_Self& operator--() { --this->_M_ptr(); return *this; }
_Self operator--(int) { return iterator(this->_M_ptr()--); }
_Self& operator+=(difference_type __n)
{ this->_M_ptr()+=__n; return *this; }
_Self& operator-=(difference_type __n)
{ this->_M_ptr()-=__n; return *this; }
reference operator[](difference_type __n) const
{ return this->_M_ptr()[__n]; }
friend _Self operator+(_Self __i, difference_type __n)
{ return _Self(__i)+=n; }
friend _Self operator-(_Self __i, difference_type __n)
{ return _Self(__i)-=n; }
friend difference_type operator-(const _Self __i1,
const _Self __i2)
{ return __i1._M_ptr() - __i2._M_ptr(); }
friend bool operator==(const _Self __i1, const _Self __i2)
{ return __i1._M_ptr() == __i2._M_ptr(); }
friend bool operator!=(const _Self __i1, const _Self __i2)
{ return __i1._M_ptr() != __i2._M_ptr(); }
friend bool operator >(const _Self __i1, const _Self __i2)
{ return __i1._M_ptr() > __i2._M_ptr(); }
friend bool operator <(const _Self __i1, const _Self __i2)
{ return __i1._M_ptr() < __i2._M_ptr(); }
friend bool operator>=(const _Self __i1, const _Self __i2)
{ return __i1._M_ptr() >= __i2._M_ptr(); }
friend bool operator<=(const _Self __i1, const _Self __i2)
{ return __i1._M_ptr() <= __i2._M_ptr(); }
public: //
friend bool operator==(const const_iterator __i1, //
const basic_string::iterator __i2) //
{ return __i1._M_ptr() == __i2._M_ptr(); } //
// here will go 11 more like that. //
public: //
// converting constructor iterator ==>> const_iterator //
const_iterator(const basic_string::iterator __i) //
: _M_ptr_(__i._M_ptr()) {} //
}; // definition of the const_iterator class
// The end of the basic_string::iterator and basic_string::const_iterator
// stuff