
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), 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)... Another problem is that the conversion, implict or otherwise, 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'. 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(). The make_range() function it calls for that: make_range( T* const r, bool ) { return iterator_range<T*>( r, r + length(r) ); } is also duplicated by: inline const char* str_end( const char* s, const char* ) { return s + strlen( s ); } ... Yes, some will object that the 'desired' direct deduction of length would be broken for 'typical' local buffers that are not completely filled (if there is no clear way of distinguishing them from literals): void foo() { char buf[ 256 ] = "a small string"; as_literal( buf ).size() == std::strlen( buf ); // in status quo as_literal( buf ).size() == _countof( buf ) - 1; // as proposed } but that could then also be said for the current implict conversion from such a "char buf[ 256 ]" into a boost::iterator_range<char const*>... I'd vote that this be handled with a runtime assertion that if a plain char array is passed it must be 'completely filled' (i.e. strlen( buf ) == _countof( buf ) ) otherwise the range must be explicitly constructed (iterator_range<char const *>( buf, buf + actual length )... 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... Additionaly#2 the boost::range_detail::is_char_ptr() function in as_literal.hpp is a runtime function when it seems it could be a metafunction... -- "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