Boost logo

Boost :

Subject: [boost] Boost Iterator Library - small extension proposal
From: Detlef Wilkening (detlef_at_[hidden])
Date: 2011-11-30 15:00:47


Hello Boostler,

at first, excuse my english - I am not a native speaker.

I used sometimes the Boost.Iterator library - especially the filter
iterators. I like them much, but I don't like the work to create the
iterator objects.

---
Example:
struct IsEven
{
    inline bool operator()(int n) const
    {
       return n%2==0;
    }
};
vector<int> v;
IsEven iseven;
filter_iterator<IsEven, vector<int>::iterator>
    filter_iter_begin(iseven, v.begin(), v.end());
filter_iterator<IsEven, vector<int>::iterator>
    filter_iter_end(iseven, v.end(), v.end());
---
My first problem is, that I need 3 times "v.end()" and 2 times "iseven". 
And the type is very long.
I don't think, that the "make" functions makes it much better. I use 
"auto" from C++11 in this example, to make it a little bit shorter.
---
Example:
struct IsEven
{
    inline bool operator()(int n) const
    {
       return n%2==0;
    }
};
vector<int> v;
IsEven iseven;
auto filter_iter_begin2 =
    make_filter_iterator<IsEven>(v.begin(), v.end());
auto filter_iter_end2 =
    make_filter_iterator<IsEven>(v.end(), v.end());
---
Again I need 3 times "v.end()" and 2 times the type "IsEven". And the 
type is again very long - thanks to "auto" in C++11.
My second problem is, that both use cases don't work well with lambda 
expressions in C++11. For "make" I need the type of the lambda, which I 
don't have - and I need it 2 times. And in the first solution I must 
write the lambda expression 2 times, which is not good.
Perhaps there are some other solutions, wich I don't see - than please 
explain them to mee.
-----
My proposal is a new "make" function, which is easer to use (only 1 time 
"v.end()") and works well with lambda expressions, but has furthermore a 
stupid type - but in C++11 with "auto" that doen't matter.
---
template<class Iter, class Fct>
    pair<filter_iterator<Fct, Iter>, filter_iterator<Fct, Iter>>
    make_filter_iterators(Iter begin, Iter end, Fct fct)
{
    filter_iterator<Fct, Iter> filter_iter_begin(fct, begin, end);
    filter_iterator<Fct, Iter> filter_iter_end(fct, end, end);
    return
       pair<filter_iterator<Fct, Iter>, filter_iterator<Fct, Iter>>
      (filter_iter_begin, filter_iter_end);
}
Usage:
vector<int> v;
auto iters = make_filter_iterators(
    v.begin(), v.end(), [](int n){ return n%2==0; });
copy(iters.first, iters.second, ostream_iterator<int>(cout, " "));
---
You see, with "auto" easy to use, and work well with lambda expressions. 
My proposal is to add such a "make" function to all iterator adaptors in 
Boost.Iterator.
Thank you for reading my idea.
Greetings
Detlef Wilkening

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk