struct clientmap : map_base2<Client *> {
void rename(Client *v, const char *newk) {
- if (remove(v)) {
- auto pos = m.lower_bound(std::string_view(newk)) - m.begin();
- auto vec = std::move(m).extract();
- vec.insert(vec.begin() + pos, v);
- // FIXME: this is actually UB. better do some const_casting and std::rotate
- m.replace(std::move(vec));
- }
+ auto it1 = m.find(v);
+ if (it1 == m.end())
+ return;
+ auto it2 = m.lower_bound(std::string_view(newk));
+ // Have to to this with a const_cast on the underlying vector, instead
+ // of m.extract/m.replace, because it's UB to replace with an unsorted
+ // vector. This will be an actual problem in e.g. libcxx with hardening
+ // enabled, since they assert that the array is sorted.
+ Client **p = const_cast<Client **>(&*it1);
+ Client **q = const_cast<Client **>(&*it2);
+ if (p < q)
+ std::rotate(p, p+1, q);
+ else
+ std::rotate(q, p, p+1);
}
};
-struct channelmap : map_base2<Channel *> {
-};
+using channelmap = map_base2<Channel *>;
struct stringset : map_base2<std::string> {
template<typename K>
std::string get(const K& k) = delete;