
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.