
Martin wrote:
I have looked at both implementation and got some comments:
1. Both implementations use a size independent base class. I can see the need for such a class but don't understand how to use it in the way proposed.
There are some examples in the associated C-string compatibility sections (boost/fixed_string/safe_strings.hpp for mine; boost_fixed_string_string.hpp for John's). This allows you to write: inline char * strcpy( boost::char_string & d, const char * s ) { return( d.assign( s )); } as opposed to: template< size_t n > inline char * strcpy( boost::fixed_string< n, char > & d, const char * s ) { return( d.assign( s )); } allowing you to migrate code that relies on strcpy, etc easier and not have to templatize each function (so you can keep them in a static/dynamic library for example).
The base class only implements a few methods so in my view it is more or less useless. E.g. a function taking a "base" argument can't iterate or look at the string content without converting it to a c-string (so it could just as well use a c-string argument). Why not implement the full interface in the base class?
The base class actually has the full basic_string interface (minus the constructors). It exposes 14 virtual functions that are implemented by fixed_string (allowing the proper implementation to be called). The complete basic_string interface is implemented by detail::basic_string_impl (which is based on flex_string), so for example, at( szie_t ) is used to implement operator[] as well and [const_]iter_offset is used for the begin(), end() variations.
2. I couldn't find any background discussion on what non-const operations should be allowed on the string. Only the std::string interface is mentioned but since the fixed_string is guaranteed to be continuos it makes sense to also allow non-const access to the string.
There wasn't that much discussion, although John is in favour of const-only (safer). Feel free to add to the discussion and I'll take a lopok at implementing them if they are reasonable.
In both versions c_str() is const while data() is const only in the sandbox version. I think a const c_str() and non-const data() (as an overload to keep the std::string interface) is the way to go.
The only objection to this I can see would be relating to the safety of the underlying string and co buffer overflow quarantees on using the non-const data.
3. As mentioned in other posts, length is messy and I don't think there are any way to safely store the length inside the class. There will always be a risk that the non-const operations add/removes a '\0' in the wrong place. One
Maybe the c_str() in fixed_string< n, CharT > should perform a validation to ensure that: str[ len ] == CharT() and optionally (it is not a requirement that this holds, if it does not, then the full string is not printable, just as if you tried to output "Hello\0Foobar!"): str[ 0..(len - 1)] != CharT() That way the string integrity is kept, while allowing simple implementations of operations such as length and push_back.
solution may be to add something similar to the CString's "ReleaseBuffer()" (with a better name) that allows you to force an update of the length after an unsafe operation.
That is a possibility (see John's implementation). The question is: how does this affect performance? I am not saying my solution is the way to go, just evaluating the various options.
And last just an idea I got from the flex_string implementation: Why not allow use of the "struct hack" as a performance option. e.g.
[snip]
This is interesting. Does it have any specific advantages over the two implementations? Regards, Reece _________________________________________________________________ Want to block unwanted pop-ups? Download the free MSN Toolbar now! http://toolbar.msn.co.uk/