Add common LHCbID overlap gymnastics functions
In several places in the code we are interested in getting the overlap in two lists of LHCbIDs. If it can be assumed they are sorted in some way, this can be written faster than the standard quadratic scaling.
This pseudocode from @graven is an example:
template <typename Predicate>
struct counting_inserter {
Predicate pred;
size_t count = 0;
counting_inserter(Predicate pred) : pred{std::move(pred)} {}
counting_inserter& operator++() { return *this; } // nop
counting_inserter& operator*() { return *this; } // redirect to self, so that our op= is called
counting_inserter& operator=( const LHCbID& id ) {
if (std::invoke(pred,id)) ++count;
return *this;
} // raison d'etre
};
size_t nCommonVelo( LHCb::span<LHCbID const> lhs, LHCb::span<LHCbID const> rhs ) const {
return std::set_intersection( begin( lhs ), end( lhs ), begin( rhs ), end( rhs ),
counting_inserter{[](const LHCID& id){ return id.isVelo(); } } )
.count;
Such functionality should be placed in a common library, to avoid this high amount of boilerplate in across the codebase.