
Rob Stewart wrote:
From: "Reece Dunn" <msclrhd@hotmail.com>
Currently, this implementation is missing iterator support (and thus all basic_string functionality that relies on begin(), end(), etc). This is because I am wondering how to map them from the basic_string adaptor to
the
implementation (knowing that you cannot have const and non-const virtual functions).
Since when can you not have const and non-const virtual functions?
Let me rephrase: class char_string { virtual iterator begin() = 0; virtual const_iterator begin() = 0; // oops! begin already in vtable!! };
I have two possible solutions: [1] name the const versions cXXX (cbegin(), crend(), etc.) -- the problem with this is that you have 8 virtual functions!
I was meaning to modify the above to: class char_string { virtual iterator begin() = 0; virtual const_iterator cbegin() = 0; // ok - cXXX variant };
You'd have those same eight variations with const and non-const virtual functions.
That's the problem -- too many virtual functions.
[2] direct to non-const versions and convert to const iterators: inline const_iterator begin() const { return( const_iterator( const_cast< basic_string_impl & >( *this ).begin())); } but I am debating whether this is standards compliant and if it is a good design decision.
If the object is really const, then this results in undefined behavior.
I have disregarded this idea.
If there are alternate solutions, I'd like to hear them.
Use const and non-const virtual functions. ;-)
Another possibility would be to construct the iterators from offsets:
inline iterator begin() { return( get_impl().iter_offset( 0 )); } inline reverse_iterator rbegin() { return( reverse_iterator( get_impl().iter_offset( size() - 1 ))); }
That way you would only need two functions (iter_offset and const_iter_offset).
But how would the iterator know whether to give const or non-const access to the elements?
iter_offset = non-const access (e.g. begin()) const_iter_offset = const access (e.g. rend() const) class char_string { virtual iterator iter_offset( difference_type ) = 0; virtual const_iterator const_iter_offset( difference_type ) = 0; }; template< class Derived, ... > class basic_string_impl > { public: inline iterator begin(){ return( get_impl().iter_offset( 0 )); } inline const_iterator begin() const{ return( get_impl().const_iter_offset( 0 )); } }; NOTE: it is not necessary for Derived to be implemented with virtual functions, but each function name is unique so if they are virtual there isn't a problem. I have tested this on VC6, VC7, VC71 and BCB and it works :). Regards, Reece _________________________________________________________________ Stay in touch with absent friends - get MSN Messenger http://www.msn.co.uk/messenger