
"Mathias Gaunard" <mathias.gaunard@ens-lyon.org> wrote in message news:hn2s9r$fpu$1@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