$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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