
Rob Stewart wrote:
John Nagle wrote:
The big question is whether the size specified in the declaration (as in "char_string<80>") includes the trailing null.
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
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
From: "Reece Dunn" <msclrhd@hotmail.com> the the
library implementor.
This is overkill.
I think you misunderstand what I am trying to say. See my comments below.
The purpose of fixed_string is to replace arrays of characters, otherwise, std::string would be the right replacement, right?
correct.
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:
The equivalent would be: fixed_string< 15 > s( "1234567890" ); // [1] assert( 10 == strlen( s )); // C-style assert( 10 == s.size()); // C++-style const size_t LENGTH = 3; fixed_string< LENGTH > t; // [2] t = "ABCEFGHIJKLMNOP"; assert( LENGTH == strlen( t )); // C-style assert( LENGTH == t.length()); // alternate C++-style [1] You need to specify the size of the buffer. You cannot declare an object of type fixed_string_base (as it is abstract), you can only have references and pointers to it so you can operate on variable-capacity strings. [2] This is the point that we are discussing. Should this line be: fixed_string< LENGTH > t; as will work with the current sandbox implementation (my suggestion #2), or should it be: fixed_string< LENGTH + 1 > t; as in my suggestion #1. The code calculates the correct storage and capacity values at the top of the fixed_string class, because buffer overrun checks rely on these values: template< size_t n, typename CharT = char, class CharStringPolicy = std::char_traits< CharT > > class fixed_string: public fixed_string_base< CharT, CharStringPolicy > { BOOST_STATIC_CONSTANT( size_t, storage_c = n + 1 ); // = needs_null ? n + 1 : n BOOST_STATIC_CONSTANT( size_t, capacity_c = n ); // = needs_null ? n : n - 1 // ... }; Different programmers favour the different semantics, so I ask: why not parameterise it, providing a default behaviour.
(I know there is no make_fixed_string() -- yet -- but such a facility would be appropriate.)
Er... the fixed_string constructors! When you declare the object, you should know the size of the buffer you are using, e.g.: fixed_string< 100 > data; but when operating on them, you want to use any capacity buffers, so you either need a template (not good for existing code or code that needs to be in a static/dynamic library), so you use fixed_string_base, or [w]char_string if you want to save typing :). E.g. inline size_t strlen( const char_string & s ) { return( s.length()); }
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.
This is not what we are discussing. See above. The need_null name was to indicate that an extra charcter be reserved for the null, not whether to add a null terminator or not. Sorry for the confusion. I have started work on documentation, but it is currently in text form. I will post the documentation in BoostBook format within the next day or so. Regards, Reece _________________________________________________________________ Stay in touch with absent friends - get MSN Messenger http://www.msn.co.uk/messenger