Follow-up from new functor MR: rework how the prepare and apply_single components are used
The following discussion from !1541 (merged) should be addressed:
-
@graven started a discussion: (+3 comments) As you were describing this bit of code during the meeting today:
OutputType MyFunctor::operator()( InputType const& input ) const { auto outside_loop1 = subfunctor1.prepare(); auto outside_loop2 = subfunctor2.prepare(); OutputType output; for ( auto const& object : input ) { if ( subfunctor1.apply_single( object, outside_loop1 ) || subfunctor2.apply_single( object, outside_loop2 ) ) { output.emplace_back( object ); // this is a dumb implementation for something like vector<Track> -> vector<Track>... } } return output; }
I was thinking that this could be done more like iterators -- specifically, you could transform this into:
OutputType MyFunctor::operator()( InputType const& input ) const { auto fun1 = subfunctor1.prepare(); auto fun2 = subfunctor2.prepare(); // ... however many more subfunctors OutputType output; for ( auto const& object : input ) { if ( fun1( object ) || fun2( object ) ) { output.emplace_back( object ); // this is a dumb implementation for something like vector<Track> -> vector<Track>... } } return output; }
i.e. by making the return type of
prepare
be 'what ever it is now' plus a pointer back to thesub functor
it was made from (just like a typical iterator can be logically thought of as some offset and a pointer to its parent, i.e. the container) -- and a small call operator which just calls the parent with the provided argument(s) and itself.This would make the code more extensible/generic, as the
MyFunctor::operator()
has to know less, i.e. the 'handshake' is simplified...