Boost logo

Boost :

From: Rob Stewart (stewart_at_[hidden])
Date: 2004-05-25 12:03:02


From: "Reece Dunn" <msclrhd_at_[hidden]>
>
> What I am interested in is a comparison between

Here it is. I have some comments regarding both and some that
are unique to one or the other. I'll start with the common ones.

* I think that data() would be better named "buffer." The
  typical usage of it would be to expose the entire buffer for
  external manipulation. c_str() is the means by which to expose
  the string data.

* A better way to handle exposing the buffer would be to have
  buffer() return a proxy class that implicitly converts to
  char *, thus exposing the string's buffer. The benefit, though
  would be for the dtor to recompute the length (and inform the
  string of it) or do invariant checks. Unfortunately, you can't
  let the dtor throw exceptions, so this doesn't work as nicely
  as I'd like.

* Should fixed_string support zero-length strings?

> my implementation at:
>
> boost-sandbox/boost/fixed_string

* const_iter_offset() should be named "iter_offset" like its
  non-const counterpart. It is a const mf, so overload
  resolution will find it.

* I'm not sure that there's enough value in
  const_iter_offset()/iter_offset() versus begin()/end() (const
  and non-const) in the derived class. You eliminate four
  trivial functions, but you may eliminate opportunities for
  optimizations. (I'm thinking there may be derived types that
  have a better way of computing end and that returning the
  result of adding zero to a pointer is slower than simply
  returning the pointer.)

* fixed_string doesn't have a const overload of at(). Calling
  fixed_string's at() "at" seems wrong. You should take the tack
  of requiring a derivate of detail::basic_string_impl to provide
  uniquely named, implementation functions that basic_string_impl
  uses to provide the public interface. You could even suggest
  that such functions be made private with the basic_string_impl
  specialization made a friend. Your current approach will
  generate many "hiding" warnings, too.

* fixed_string's at() shouldn't test the length and throw an
  exception since detail::basic_string_impl::at() does it and
  detail::basic_string_impl::operator[] calls it.

* The same out of range testing code is repeated in many
  functions. I suggest factoring it out into a validate() mf
  called from the rest.

* fixed_string::swap() is missing.

* detail::basic_string_impl::get_allocator() expects
  string_type::get_allocator() but that isn't listed in the
  requirements levied on the derived type and isn't defined in
  fixed_string.

* I wouldn't expect fixed_string's StringPolicy to govern how to
  determine the length of a string passed to a mf as a CharT *.

* If I kept looking, I'm sure I'd find many more things, but you
  are more interested in philosophical differences, so I'll stop
  here. Look at the end of the message for my summary.

> and John Nagle's implementation at:
>
> http://www.animats.com/source

* fixed_string_base must implement the entire std::basic_string
  I/F.

* A core I/F in fixed_string_base must be done via pure virtual
  functions, relying on the derived classes to implement those
  functions. Then there should be a large number of mfs that can
  be implemented in terms of that core set.

* The current implementation puts all of the onus on derived
  classes.

Summary:

The two classes take quite different approaches to solve the
problem. Reece's approach is like iterator_adaptor and its ilk,
relying on a parameterized base class to manage the derived class
to get the required behavior. John's approach is to use an ABC
and let the derived class implement required functionality.

One problem with Reece's approach is how to expose a core
I/F in the derived class for use by the base class without that
core I/F being part of the public interface of the derived type.
Since those functions are typically unsafe for normal use,
exposing them is risky. By contrast, John's approach relies on
pure virtual functions to require the derived class to offer the
required I/F. Since those pvf's can be declared private in both
fixed_string_base and the derived class, they needn't ever be
part of the public I/F.

I think John's approach is better, only because it does less type
indirection. It relies on the more ordinary pvf approach to the
core functionality. Otherwise, the two libraries provide the
same functionality (or can when complete).

No doubt there's something else you'd rather I focused on. If
so, direct me to it and I'll let you know what I think.

-- 
Rob Stewart                           stewart_at_[hidden]
Software Engineer                     http://www.sig.com
Susquehanna International Group, LLP  using std::disclaimer;

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk