Boost logo

Boost :

Subject: Re: [boost] [range] strings
From: Domagoj Saric (domagoj.saric_at_[hidden])
Date: 2010-03-08 11:34:07


"Mathias Gaunard" <mathias.gaunard_at_[hidden]> wrote in message
news:hn2s9r$fpu$1_at_dough.gmane.org...
> I personally do not find that unexpected. An array of size N is a range of its
> N elements.

But in the mentioned case it is not IMO apriori obvious we are dealing with
arrays...Consider a use case like this:

bool is_a_recognized_string( char const * const string_to_test )
{
    boost::iterator_range<char const *> const test_string( boost::as_literal(
string_to_test );
    if
    (
        ( test_string == "valid_string1" ) ||
        ( test_string == "valid_string2" ) ||
        ( test_string == "valid_string3" ) ||
        ( test_string == "valid_string4" )
    )
        return true;
    else
        return false;
}

will always return false (unless the advance_end( 1 ) call is added)...to me
this was rather unexpected...

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

I am/was...that's why I said that there is no 'happy' solution (or so it seems
to me)...

...because if as_literal() would be broken if it would use the size of the array
then, it seems to me, the implicit iterator_range<> constructor is also broken
currently/as it is now...As ilustrated in the above example, or why would the
following two results be different:
typedef iterator_range<char const *> string_chunk_t;

char buf[ 256 ] = "a small string";
string_chunk_t string_chunk1( buf );
string_chunk_t string_chunk2( as_literal( buf ) );

Doesn't the very name as_literal() imply that its argument will be treated as
'literal' (a 'full null terminated static array of chars') instead of just as a
plain pointer..?

>> 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*>&);

Sorry, wasn't clear enough, I meant conversion to an iterator_range<> (not using
as_literal())...

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

As above...wasn't refering to as_literal(). Actually this issue is not specific
to strings but for all containers that do not have plain pointers for
iterators...
For example this does not work in Dinkumware STL implementations:
std::vector<unsigned char> storage;
boost::iterator_range<unsigned char const *> storage_chunk( storage );

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

True for the documented part, sorry, didn't look look at the documentation for
quite some time...
But still, consider, the argument from above as to what does the name
as_literal() imply...

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

The strlen is not a problem in the sense of a string length computation because
that is what is needed but the usage of C std::strlen() that works with
indices/integer length..: range works with pointers so std::strlen() requires
the recalculation of the pointer value...maybe 'insignificant' but still
avoidable (with a find( '\0') like operation that returns a pointer/iterator
instead of an index)...

--
"What Huxley teaches is that in the age of advanced technology, spiritual
devastation is more likely to come from an enemy with a smiling face than from
one whose countenance exudes suspicion and hate."
Neil Postman 

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk