
Hi Robert,
This is a subject in which I've had some interest. In my case this resulted in the "dataflow iterator" part of the serialization library. I've just looked at the documention referred to below rather than the code. Still, I have some questions:
Its not clear to me what the benefit of using ranges is compared to a pair of iterators.
Manual loops: for ( crange<some_array_type> r(some_array); r; ++r) do_something( *r, some_data); Also, while coding, sometimes I have more complex loos, in which case I need to decrement r, etc.
It makes dealing with containers/STL algorithms simpler by using ranges (as opposed to iterators).
for ( crange<some_array_type> r(some_array); r; ++r) do_something( *r, some_data);
How is this simpler or more transparent than
for(some_array::iterator i=some_array.begin(); i != some_array.end(); ++i) do_something( *i, some_data);
more compact, and not error prone. Also, very useful in combination with algorithms that return ranges.
Also, the library provides wrappers for all STL algorithms (for the purpose of STL algorithms, all containers are ranges as well):
typedef std::vector<std::string> word_array; word_array v; // STL version std::copy( v.begin(), v.end(), print); // rng:: version rng::copy( v, print);
I don't see this as adding any value or conceptual transparency.
Not sure I understand what you mean.
Also, the counterparts for STL algorithms that return an iterator will return a range, allowing for: // fill a vector with all the indexes at which a certain string is found std::string str = "I'm a cool programmer, really cool that is", find = "cool"; std::vector<int> result; crange<std::string> r(str); while ( r = rng::search(r, find)) result.push_back ( r.begin() - str.begin() );
I'm not really sure that I understand this example. It would seem the standard stl equivalent would be
std::vector<int> result; std::string str = "I'm a cool programmer, really cool that is"; std::string find = "cool";
std::string::const_iterator r = str.begin(); while(r = stl::search(r, find.begin(), find.end())) result.push_back ( r.begin() - str.begin() );
which to my mind isn't any different or more complex.
in fact, you forgot to compare r to str.end()
// take all employees from Romania, and print their names rng::copy( transformed( filtered(empls,from_ro), get_empl_name), std::ostream_iterator<std::string>(std::cout," "));
I don't see how this is better than using iterator adaptors for composition.
Please, try the above with iterator adaptors, and show me the code. Best, John -- John Torjo, Contributing editor, C/C++ Users Journal -- "Win32 GUI Generics" -- generics & GUI do mix, after all -- http://www.torjo.com/win32gui/ -- v1.5 - tooltips at your fingertips (work for menus too!) + bitmap buttons (work for MessageBox too!) + tab dialogs, hyper links, lite html