|
Boost : |
From: Reece Dunn (msclrhd_at_[hidden])
Date: 2004-05-20 17:47:56
Rob Stewart wrote:
>From: "Reece Dunn" <msclrhd_at_[hidden]>
> >
> > 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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk