I don’t understand why std::flat_set etc. lack merge member functions. There’s already a perfect algo for implementing it — std::ranges::merge
. And I know that while de jure time complexity is supposed to be the same, de facto we get an overhead for copying/moving objects instead of simple repointings. And still, that could’ve preserved API (afak, the same motivation was for having dummy std::unordered_container::merge()
to simplify profiling checks). Now that the API’s broken, and every appearance of smth.merge()
has to be handled in some way (have a question about that too below), we can’t simply switch to flat versions.
import std;
using namespace std;
int main(){
set set1{ 0,2,4 }, set2{ 1,3,5 }; /*can be easily changed to
unordered_set and vice versa but not to flat_set*/
//...
set1.merge(set2); /*such statements will become invalid if we
switch to flat versions*/
}
Besides vanilla curiosity, I’m driven to figure out an elegant workaround. So far I only see the solution with this kinda global function, with which all calls to merge()
should be replaced.
template <class T> requires (T t, T f) { t.merge(f); }
T & merger(T & first, T & second) {
first.merge(second);
return first;
}
template <class T>
T merger(T first, T second) {
using underlying = decltype(T().extract());
underlying buff(first.size() + second.size());
ranges::merge(first.extract(), second.extract(), buff.begin());
return T{ buff };
}
6