Boost logo

Boost :

Subject: Re: [boost] [range] strings
From: Mathias Gaunard (mathias.gaunard_at_[hidden])
Date: 2010-03-08 07:57:33

Domagoj Saric wrote:
> Currently, the following assertion:
> char const test_string[] = "a test string";
> assert( test_string == boost::as_literal( test_string ) );
> fails
> while the following one:
> assert( test_string == boost::as_literal( test_string ).advance_end( 1 ) );
> passes because the left-hand side parameter of operator== is implicitly
> converted to a boost::iterator_range<> object which _includes_ the trailing zero
> (because it is treated as any other array) while the boost::iterator_range<>
> returned by boost::as_literal<>() _excludes_ the trailing zero...
> I 'know' that there is no 'happy' solution for this because the status quo is
> 'consistent' across all types but it, on the other hand, creates problems (or
> unexpected results)

I personally do not find that unexpected. An array of size N is a range
of its N elements.

> like the one outlined above, when strings, char pointers
> and literals are used...For this reason I would prefer more the other 'less than
> happy' solution that would treat strings in a special way (by never including
> the trailing zero)...

I believe this used to be the default, but was changed.

Also, consider char arrays that have zeros in the middle on purpose,
and/or that are not strings.

> Another problem is that the conversion, implict or otherwise

AFAIK there is actually no conversion going on. It just calls
template<typename Range>
bool operator==(Range&, const iterator_range<const char*>&);

> from a char
> container/range whose iterators are not plain char pointers (e.g. std::strings
> in 'secure STL' implementations) does not work (does not compile). My last post
> in the [program_options] thread offers a 'fix'.

as_literal is not meant to be used on anything else but char (or wide
chars) arrays.

> Yet another problem is that the as_literal<>() template function does not use
> the fact that it was passed an array to implicitly/directly deduce the length
> but it still calls std::strlen().

Indeed, but that's the expected and documented behaviour.

> Additionaly the above mentioned implementations of make_range() and str_end()
> add two extra instructions (substraction and addition) because they use strlen()
> that works with 'indexes'/size which then have to be converted to pointers...

I suspect that strlen on a literal is not really a performance concern.
Nevertheless an adaptor to simply remove the last element of the array
range might be useful indeed.

Boost list run by bdawes at, gregod at, cpdaniel at, john at