|
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