[range] as_literal always returning iterator_range

Hi all, I think there is a problem with the behavior of boost::as_literal. If I got it right, it is supposed to create an iterator_range from null-terminated strings, which is fine. However, it also creates iterator_ranges from exisiting ranges, i.e., it converts general ranges to iterator_ranges. I think as_literal should fall back to identity (i.e., just return its argument) if its argument is already a range. With the current behavior, the type information of the range is lost. This is a problem if I write generic code and want to dispatch several cases based on the type of the range. Consider the following example: ------------------------------- template<class Rng> void f( Rng const& r ) {...} template<class T> void f( iterator_range<T*> const& r ) {...} void f( std::string const& s ) {...} void f( std::vector const& v ) {...} template<class Rng> void g( Rng const& r ) { f(as_literal(r)); ... } ------------------------------- Function g() accepts general ranges as well as zero-terminated strings. It dispatches its argument using the type of the range and the overloads of f(), in order to execute special code for some ranges like strings and vectors. (In my particular case, I have special treatment for ranges of contiguous memory.) This is not possible anymore after calling as_literal, because it always returns an iterator_range. Wouldn't it be better to return the original range, for example like this: template< class Rng > typename enable_if< has_range_const_iterator<Rng>, Rng &>::type as_literal (Rng& r ) { return r; } Regards, Tobias -- Dr. Tobias Germer | tgermer@think-cell.com Software Engineer think-cell Software GmbH | Chausseestr. 8/E | 10115 Berlin | Germany http://www.think-cell.com | phone +49 30 666473-10 | US phone +1 800 891 8091 Amtsgericht Berlin-Charlottenburg, HRB 85229 | European Union VAT Id DE813474306 Directors: Dr. Markus Hannebauer, Dr. Arno Schoedl

Den 03-05-2011 14:22, Tobias Germer skrev:
Hi all,
I think there is a problem with the behavior of boost::as_literal. If I got it right, it is supposed to create an iterator_range from null-terminated strings, which is fine. However, it also creates iterator_ranges from exisiting ranges, i.e., it converts general ranges to iterator_ranges. I think as_literal should fall back to identity (i.e., just return its argument) if its argument is already a range.
With the current behavior, the type information of the range is lost. This is a problem if I write generic code and want to dispatch several cases based on the type of the range. Consider the following example:
I think what you are proposing needs a new name unless we can guarantee that no code is broken. -Thorsten

On 05/03/2011 05:22 AM, Tobias Germer wrote:
Hi all,
I think there is a problem with the behavior of boost::as_literal. If I got it right, it is supposed to create an iterator_range from null-terminated strings, which is fine. However, it also creates iterator_ranges from exisiting ranges, i.e., it converts general ranges to iterator_ranges. I think as_literal should fall back to identity (i.e., just return its argument) if its argument is already a range.
With the current behavior, the type information of the range is lost. This is a problem if I write generic code and want to dispatch several cases based on the type of the range. Consider the following example:
------------------------------- template<class Rng> void f( Rng const& r ) {...} template<class T> void f( iterator_range<T*> const& r ) {...} void f( std::string const& s ) {...} void f( std::vector const& v ) {...}
template<class Rng> void g( Rng const& r ) { f(as_literal(r)); ... }
-------------------------------
Function g() accepts general ranges as well as zero-terminated strings. It dispatches its argument using the type of the range and the overloads of f(), in order to execute special code for some ranges like strings and vectors. (In my particular case, I have special treatment for ranges of contiguous memory.)
Note that at least in your case, it seems there should be a more direct way to achieve what you want, e.g. an iterator/range trait to determine if an iterator can be handled like a pointer to contiguous memory.
participants (3)
-
Jeremy Maitin-Shepard
-
Thorsten Ottosen
-
Tobias Germer