QXcbXSettings: replace a QLinkedList with a std::vector

Required to change an erase() loop into std::remove_if to
avoid running into quadratic behavior.

While at it, made QXcbXSettingsCallback a proper struct,
used aggregate initialization, and ported another loop to
C++11 range-for.

Saves ~0.5KiB in text size on optimized GCC 5.3 Linux AMD64
builds, and a lot of heap allocations.

Change-Id: I228bb853519ed2590375dc511e527f47bb8daa34
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
Marc Mutz 2016-01-08 19:55:49 +01:00
parent fb1863e64a
commit a836b4735c

View File

@ -36,6 +36,9 @@
#include <QtCore/QByteArray> #include <QtCore/QByteArray>
#include <QtCore/QtEndian> #include <QtCore/QtEndian>
#include <vector>
#include <algorithm>
#ifdef XCB_USE_XLIB #ifdef XCB_USE_XLIB
#include <X11/extensions/XIproto.h> #include <X11/extensions/XIproto.h>
#endif //XCB_USE_XLIB #endif //XCB_USE_XLIB
@ -49,9 +52,8 @@ enum XSettingsType {
XSettingsTypeColor = 2 XSettingsTypeColor = 2
}; };
class QXcbXSettingsCallback struct QXcbXSettingsCallback
{ {
public:
QXcbXSettings::PropertyChangeFunc func; QXcbXSettings::PropertyChangeFunc func;
void *handle; void *handle;
}; };
@ -69,23 +71,19 @@ public:
return; return;
this->value = value; this->value = value;
this->last_change_serial = last_change_serial; this->last_change_serial = last_change_serial;
QLinkedList<QXcbXSettingsCallback>::const_iterator it = callback_links.begin(); for (const auto &callback : callback_links)
for (;it != callback_links.end();++it) { callback.func(screen, name, value, callback.handle);
it->func(screen,name,value,it->handle);
}
} }
void addCallback(QXcbXSettings::PropertyChangeFunc func, void *handle) void addCallback(QXcbXSettings::PropertyChangeFunc func, void *handle)
{ {
QXcbXSettingsCallback callback; QXcbXSettingsCallback callback = { func, handle };
callback.func = func; callback_links.push_back(callback);
callback.handle = handle;
callback_links.append(callback);
} }
QVariant value; QVariant value;
int last_change_serial; int last_change_serial;
QLinkedList<QXcbXSettingsCallback> callback_links; std::vector<QXcbXSettingsCallback> callback_links;
}; };
@ -299,14 +297,13 @@ void QXcbXSettings::registerCallbackForProperty(const QByteArray &property, QXcb
void QXcbXSettings::removeCallbackForHandle(const QByteArray &property, void *handle) void QXcbXSettings::removeCallbackForHandle(const QByteArray &property, void *handle)
{ {
Q_D(QXcbXSettings); Q_D(QXcbXSettings);
QXcbXSettingsPropertyValue &value = d->settings[property]; auto &callbacks = d->settings[property].callback_links;
QLinkedList<QXcbXSettingsCallback>::iterator it = value.callback_links.begin();
while (it != value.callback_links.end()) { auto isCallbackForHandle = [handle](const QXcbXSettingsCallback &cb) { return cb.handle == handle; };
if (it->handle == handle)
it = value.callback_links.erase(it); callbacks.erase(std::remove_if(callbacks.begin(), callbacks.end(),
else isCallbackForHandle),
++it; callbacks.end());
}
} }
void QXcbXSettings::removeCallbackForHandle(void *handle) void QXcbXSettings::removeCallbackForHandle(void *handle)