Boost logo

Boost :

From: Rob Stewart (stewart_at_[hidden])
Date: 2004-05-27 09:34:58


From: "Reece Dunn" <msclrhd_at_[hidden]>
> John Nagle wrote:
> >Reece Dunn wrote:
> >>John Nagle wrote:
> > I think the relationship between "size()" and "capacity()"
> >has to be such that if "size() < capacity()" you can add a
> >character. So "capacity()" should not include the trailing
> >null.
>
> Makes sense.

I agree.

> > For consistency with "<string>", "size()" can't include
> >the trailing null.
>
> This applies for both basic_string::size() and strlen( s ).

Right.

> > The big question is whether the size specified in the
> >declaration (as in "char_string<80>") includes the
> >trailing null.
> >
> > I don't want to express an opinion on this until
> >I've had some sleep. I can think of good arguments
> >for both sides.
>
> I have modified the sandbox implementation to make it easy to switch between
> the two models; it is currently using the 2nd model (adding space for the
> null). One possibility is putting the choice of models as a template
> parameter (e.g. bool need_null -- see comments in the sandbox code for an
> implementation), that way the decision is up to the programmer and not the
> library implementor.

This is overkill. The purpose of fixed_string is to replace
arrays of characters, otherwise, std::string would be the right
replacement, right? Given that assumption, look to the syntax
you're replacing:

   char s[] = "1234567890";
   assert(10 == strlen(s));
   size_t const LENGTH = 3;
   char t[LENGTH + 1];
   strncpy(t, "ABCEFGHIJKLMNOP", LENGTH);
   assert(LENGTH == strlen(t));

Now do the same with the new class:

   fixed_string_base s(make_fixed_string("1234567890"));
   assert(10 == strlen(s));
   assert(10 == s.size()); // using the new interface
   size_t const LENGTH = 3;
   char_string<LENGTH> t;
   t = "ABCEFGHIJKLMNOP";
   assert(LENGTH == strlen(t));
   assert(LENGTH == t.size()); // using the new interface

(I know there is no make_fixed_string() -- yet -- but such a
facility would be appropriate.)

I think this clearer reveals that fixed_string's size parameter
should specify the number of characters. Remember, one can use
boost::array to manage a fixed size, non-string buffer. If
buffer overrun protection is insufficient in boost::array, that
should be fixed (or a new class should be added to Boost). Thus,
fixed_string can ignore that usage.

> >>>Should the trailing null be counted in "capacity?"
> >>
> >>This is a good point. At the moment fixed_string< n >::capacity() == n. It
> >>would therefore make sense that this be changed so that either:
> >>
> >>[1] fixed_string< n >::capacity() == n - 1 -- this would seem
> >>counter-intuitive, as fixed_string< 1 > would not be able to store any
> >>characters!

Counter-intuitive, IMO.

> >>[2] change CharT str[ n ] to CharT str[ n + 1 ] -- i.e. add an extra
> >>character for the trailing null. This would make more sense, as it is
> >>similar to:
> >> char * str = new char[ s.length() + 1 ];

That makes the most sense. I've always written such array
allocations with the "+ 1" to clearly show that I'm accounting
for the null terminator and to handle the case like I showed
above in which the maximum length is a const "variable."

-- 
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