Here's a modification to:
1) hide the intermediate struct (as usual in std.algorithm, I forgot what this trick is called) 2) work with ranges, not just arrays (ie will work with iota, see unittest)
3) accept input without "in" attribute;
4) accept arbitrary predicate, not just "==x"

Please comment if I'm doing anything not casher.

5) In particular, is there a way to avoid the dummy argument in this(int ignore)? 6) for (3), I didn't use "in": I believe that is the usual behavior in std.algorithm, where the caller is responsible to pass in items.dup or items.save if he so wishes. Is that true? 7) I had to remove nothrow and pure, is that needed in the general range case? how to fix it if it is?

----
unittest{
   assert(iota(10).findIndexes!`a%3==1`==[1,4,7]);
}
auto findIndexes(alias pred,R)(R items)  if(isInputRange!R) {
        import std.functional:unaryFun;
        struct FindIndexes(alias pred2) {
                private size_t _front;
this(int ignore=0) {//TODO:this() not allowed so... anything better?
                        while(!items.empty){
                                if(pred2(items.front)) break;
                                _front++;
                                items.popFront;
                        }
                }
                @property bool empty() const {
                        return items.empty;
                }
                @property size_t front() const {
                        return _front;
                }
                void popFront() {
                        _front++;
                        items.popFront;
                        while(!items.empty){
                                if(pred2(items.front)) break;
                                _front++;
                                items.popFront;
                        }
                }
        }
        return FindIndexes!(unaryFun!pred)();
}
----

Reply via email to