First, to respond to a comment, boost set_intersection takes ranges as parameters compared to the STL that accepts iterators.
Other than that, there is no real difference in terms of algorithm and complexity.
As far as I know, there is no ready-made library to do what you want to do, which is just a check if the two sequences are unique and immediately terminate if they are not.
You should also understand that you will always have the “worst case scenario” when they are truly unique.
The complexity is O (N + M), although you can also use binary search in one of the collections, which will make it O (N log M) or O (M log N), and if one of them is much larger than the other it can be big savings. (e.g., N = 1,000,000, M = 20, M log N is only about 400).
You can “reduce” by taking the median of one, find it in the other and compare the subranges in the individual threads.
There is also a “terrible” decision that your functor receives a call at the intersection, thereby choosing you from the loop. (Yes, there is one, even if it is hidden in the algorithm). Perhaps we can write our own, although this O (N + M) is very simple. I will do it with 4 iterators:
template< typename Iter1, typename Iter2 > bool intersects( Iter1 iter1, Iter1 iter1End, Iter2 iter2, Iter2 iter2End ) { while( iter1 != iter1End && iter2 != iter2End ) { if( *iter1 < *iter2 ) { ++iter1; } else if ( *iter2 < *iter1 ) { ++iter2; } else return true; } return false; } // Predicate version where the compare version returns <0 >0 or 0 template< typename Iter1, typename Iter2, typename Comp > bool intersects( Iter1 iter1, Iter1 iter1End, Iter2 iter2, Iter2 iter2End, Comp comp ) { while( iter1 != iter1End && iter2 != iter2End ) { int res = comp( *iter1, *iter2 ); if( res < 0 ) { ++iter1; } else if ( res > 0 ) { ++iter2; } else return true; } return false; }