aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2017-02-27 16:40:03 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2017-02-28 12:31:38 +0900
commit6c6b5b1bc18e16d0b40b674c8a48e0104ec73729 (patch)
tree53587f877fba6d3f08e3105a9a6981fe92d34205
parent2a5301b5a50c49b480b2c3968b4bca2610a8d6f0 (diff)
downloadlibquotient-6c6b5b1bc18e16d0b40b674c8a48e0104ec73729.tar.gz
libquotient-6c6b5b1bc18e16d0b40b674c8a48e0104ec73729.zip
Renamed logging_util.h to util.h and moved (improved) Owning<> and lookup() there
Because these fall outside of SyncJob and Event context, respectively. In addition, Owning<> has gained a move assignment operator (because we have a move constructor) and assign() convenience method to take ownership over an existing container; also, Owning<>::release() is done the right way now (the previous version was copying the return value to a new container instead of releasing the old container).
-rw-r--r--events/event.cpp2
-rw-r--r--events/event.h48
-rw-r--r--events/roommessageevent.cpp1
-rw-r--r--events/unknownevent.cpp2
-rw-r--r--jobs/syncjob.cpp3
-rw-r--r--jobs/syncjob.h33
-rw-r--r--logging_util.h63
-rw-r--r--util.h169
8 files changed, 174 insertions, 147 deletions
diff --git a/events/event.cpp b/events/event.cpp
index 11983f53..8ad56f1b 100644
--- a/events/event.cpp
+++ b/events/event.cpp
@@ -23,7 +23,7 @@
#include <QtCore/QDateTime>
#include <QtCore/QDebug>
-#include "../logging_util.h"
+#include "util.h"
#include "roommessageevent.h"
#include "roomnameevent.h"
#include "roomaliasesevent.h"
diff --git a/events/event.h b/events/event.h
index 12b0ebd5..f60dfb64 100644
--- a/events/event.h
+++ b/events/event.h
@@ -60,52 +60,4 @@ namespace QMatrixClient
using Events = QVector<Event*>;
Events eventsFromJson(const QJsonArray& json);
-
- /**
- * @brief Lookup a value by a key in a varargs list
- *
- * The below overloaded function template takes the value of its first
- * argument (selector) as a key and searches for it in the key-value map
- * passed in a varargs list (every next pair of arguments forms a key-value
- * pair). If a match is found, the respective value is returned; otherwise,
- * the last value (fallback) is returned.
- *
- * All options should be of the same type or implicitly castable to the
- * type of the first option. Note that pointers to methods of different
- * classes are of different object types, in particular.
- *
- * Below is an example of usage to select a parser depending on contents of
- * a JSON object:
- * {@code
- * auto parser = lookup(obj.value["type"].toString(),
- * "type1", fn1,
- * "type2", fn2,
- * fallbackFn);
- * parser(obj);
- * }
- *
- * The implementation is based on tail recursion; every recursion step
- * removes 2 arguments (match and option). There's no selector value for the
- * fallback option (the last one); therefore, the total number of lookup()
- * arguments should be even: selector + n key-value pairs + fallback
- *
- * @note Beware of calling lookup() with a <code>const char*</code> selector
- * (the first parameter) - most likely it won't do what you expect because
- * of shallow comparison.
- */
- template <typename ValueT, typename SelectorT, typename KeyT, typename... Ts>
- ValueT lookup(SelectorT selector, KeyT key, ValueT value, Ts... remainingMapping)
- {
- if( selector == key )
- return value;
-
- // Drop the failed key-value pair and recurse with 2 arguments less.
- return lookup(selector, remainingMapping...);
- }
-
- template <typename SelectorT, typename ValueT>
- ValueT lookup(SelectorT/*unused*/, ValueT fallback)
- {
- return fallback;
- }
}
diff --git a/events/roommessageevent.cpp b/events/roommessageevent.cpp
index bb28d682..34315363 100644
--- a/events/roommessageevent.cpp
+++ b/events/roommessageevent.cpp
@@ -17,6 +17,7 @@
*/
#include "roommessageevent.h"
+#include "util.h"
#include <QtCore/QMimeDatabase>
#include <QtCore/QDebug>
diff --git a/events/unknownevent.cpp b/events/unknownevent.cpp
index 90551409..70dcfcbb 100644
--- a/events/unknownevent.cpp
+++ b/events/unknownevent.cpp
@@ -21,7 +21,7 @@
#include <QtCore/QJsonDocument>
#include <QtCore/QDebug>
-#include "../logging_util.h"
+#include "util.h"
using namespace QMatrixClient;
diff --git a/jobs/syncjob.cpp b/jobs/syncjob.cpp
index 554ac0f7..cec9595f 100644
--- a/jobs/syncjob.cpp
+++ b/jobs/syncjob.cpp
@@ -96,8 +96,7 @@ BaseJob::Status SyncJob::parseJson(const QJsonDocument& data)
void SyncRoomData::EventList::fromJson(const QJsonObject& roomContents)
{
- auto l = eventsFromJson(roomContents[jsonKey].toObject()["events"].toArray());
- swap(l);
+ assign(eventsFromJson(roomContents[jsonKey].toObject()["events"].toArray()));
}
SyncRoomData::SyncRoomData(QString roomId_, JoinState joinState_, const QJsonObject& room_)
diff --git a/jobs/syncjob.h b/jobs/syncjob.h
index be1d4776..b41c09d4 100644
--- a/jobs/syncjob.h
+++ b/jobs/syncjob.h
@@ -22,41 +22,10 @@
#include "../joinstate.h"
#include "../events/event.h"
+#include "util.h"
namespace QMatrixClient
{
- /**
- * @brief A crude wrapper around a container of pointers that owns pointers
- * to contained objects
- *
- * Similar to vector<unique_ptr<>>, upon deletion, EventsHolder
- * will delete all events contained in it.
- */
- template <typename ContainerT>
- class Owning : public ContainerT
- {
- public:
- Owning() = default;
-#if defined(_MSC_VER) && _MSC_VER < 1900
- // Workaround: Dangerous (auto_ptr style) copy constructor because
- // VS2013 (unnecessarily) instantiates EventList::QVector<>::toList()
- // which instantiates QList< Owning<> > which needs the contained
- // object to have a non-deleted copy constructor.
- Owning(Owning& other) : ContainerT(std::move(other)) { }
-#else
- Owning(Owning&) = delete;
-#endif
- Owning(Owning&& other) : ContainerT(std::move(other)) { }
- ~Owning() { for (auto e: *this) delete e; }
-
- /**
- * @brief returns the underlying events and releases the ownership
- *
- * Acts similar to unique_ptr::release.
- */
- ContainerT release() { return std::move(*this); }
- };
-
class SyncRoomData
{
public:
diff --git a/logging_util.h b/logging_util.h
deleted file mode 100644
index 47b2e062..00000000
--- a/logging_util.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/******************************************************************************
- * Copyright (C) 2016 Kitsune Ral <kitsune-ral@users.sf.net>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file logging_util.h - a collection of utilities to facilitate debug logging.
- */
-
-#pragma once
-
-#include <QtCore/QDebug>
-
-namespace QMatrixClient {
-
-// QDebug manipulators
-
-using QDebugManip = QDebug (*)(QDebug);
-
-/**
- * @brief QDebug manipulator to setup the stream for JSON output.
- *
- * Originally made to encapsulate the change in QDebug behavior in Qt 5.4
- * and the respective addition of QDebug::noquote().
- * Together with the operator<<() helper, the proposed usage is
- * (similar to std:: I/O manipulators):
- *
- * @example qDebug() << formatJson << json_object; // (QJsonObject, or QJsonValue, etc.)
- */
-static QDebugManip formatJson = [](QDebug debug_object) {
-#if QT_VERSION < QT_VERSION_CHECK(5, 4, 0)
- return debug_object;
-#else
- return debug_object.noquote();
-#endif
- };
-
-/**
- * @brief A helper operator to facilitate using formatJson (and possibly other manipulators)
- *
- * @param debug_object to output the json to
- * @param qdm a QDebug manipulator
- * @return a copy of debug_object that has its mode altered by qdm
- */
-inline QDebug operator<< (QDebug debug_object, QDebugManip qdm) {
- return qdm(debug_object);
-}
-
-}
-
diff --git a/util.h b/util.h
new file mode 100644
index 00000000..bc16c413
--- /dev/null
+++ b/util.h
@@ -0,0 +1,169 @@
+/******************************************************************************
+ * Copyright (C) 2016 Kitsune Ral <kitsune-ral@users.sf.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file logging_util.h - a collection of utilities to facilitate debug logging.
+ */
+
+#pragma once
+
+#include <QtCore/QDebug>
+
+namespace QMatrixClient
+{
+
+ // QDebug manipulators
+
+ using QDebugManip = QDebug (*)(QDebug);
+
+ /**
+ * @brief QDebug manipulator to setup the stream for JSON output.
+ *
+ * Originally made to encapsulate the change in QDebug behavior in Qt 5.4
+ * and the respective addition of QDebug::noquote().
+ * Together with the operator<<() helper, the proposed usage is
+ * (similar to std:: I/O manipulators):
+ *
+ * @example qDebug() << formatJson << json_object; // (QJsonObject, etc.)
+ */
+ static QDebugManip formatJson = [](QDebug debug_object) {
+ #if QT_VERSION < QT_VERSION_CHECK(5, 4, 0)
+ return debug_object;
+ #else
+ return debug_object.noquote();
+ #endif
+ };
+
+ /**
+ * @brief A helper operator to facilitate usage of formatJson (and possibly
+ * other manipulators)
+ *
+ * @param debug_object to output the json to
+ * @param qdm a QDebug manipulator
+ * @return a copy of debug_object that has its mode altered by qdm
+ */
+ inline QDebug operator<< (QDebug debug_object, QDebugManip qdm)
+ {
+ return qdm(debug_object);
+ }
+
+ /**
+ * @brief A crude wrapper around a container of pointers that owns pointers
+ * to contained objects
+ *
+ * Similar to vector<unique_ptr<>>, upon deletion, this wrapper
+ * will delete all events contained in it. This wrapper can be used
+ * over Qt containers, which are incompatible with unique_ptr and even
+ * with QScopedPointer (which is the reason of its creation).
+ */
+ template <typename ContainerT>
+ class Owning : public ContainerT
+ {
+ public:
+ Owning() = default;
+#if defined(_MSC_VER) && _MSC_VER < 1900
+ // Workaround: Dangerous (auto_ptr style) copy constructor because
+ // in case of Owning< QVector<> > VS2013 (unnecessarily) instantiates
+ // QVector<>::toList() which instantiates QList< Owning<> > which
+ // requires the contained object to have a copy constructor.
+ Owning(Owning& other) : ContainerT(std::move(other)) { }
+#else
+ Owning(Owning&) = delete;
+#endif
+ Owning(Owning&& other) = default;
+ Owning& operator=(Owning&& other)
+ {
+ assign(other.release());
+ return *this;
+ }
+
+ ~Owning() { cleanup(); }
+
+ void assign(ContainerT&& other)
+ {
+ if (&other == this)
+ return;
+ cleanup();
+ ContainerT::operator=(other);
+ }
+
+ /**
+ * @brief returns the underlying container and releases the ownership
+ *
+ * Acts similar to unique_ptr::release.
+ */
+ ContainerT release()
+ {
+ ContainerT c;
+ ContainerT::swap(c);
+ return c;
+ }
+ private:
+ void cleanup() { for (auto e: *this) delete e; }
+ };
+
+ /**
+ * @brief Lookup a value by a key in a varargs list
+ *
+ * This function template takes the value of its first argument (selector)
+ * as a key and searches for it in the key-value map passed in a varargs list
+ * (every next pair of arguments forms a key-value pair). If a match is found,
+ * the respective value is returned; if no pairs matched, the last value
+ * (fallback) is returned.
+ *
+ * All options should be of the same type or implicitly castable to the
+ * type of the first option. Note that pointers to methods of different
+ * classes are of different object types, in particular.
+ *
+ * Below is an example of usage to select a parser depending on contents of
+ * a JSON object:
+ * {@code
+ * auto parser = lookup(obj.value["type"].toString(),
+ * "type1", fn1,
+ * "type2", fn2,
+ * fallbackFn);
+ * parser(obj);
+ * }
+ *
+ * The implementation is based on tail recursion; every recursion step
+ * removes 2 arguments (match and option). There's no selector value for the
+ * fallback option (the last one); therefore, the total number of lookup()
+ * arguments should be even: selector + n key-value pairs + fallback
+ *
+ * @note Beware of calling lookup() with a <code>const char*</code> selector
+ * (the first parameter) - most likely it won't do what you expect because
+ * of shallow comparison.
+ */
+ template <typename ValueT, typename SelectorT, typename KeyT, typename... Ts>
+ ValueT lookup(SelectorT selector, KeyT key, ValueT value, Ts... remainingMapping)
+ {
+ if( selector == key )
+ return value;
+
+ // Drop the failed key-value pair and recurse with 2 arguments less.
+ return lookup(selector, remainingMapping...);
+ }
+
+ template <typename SelectorT, typename ValueT>
+ ValueT lookup(SelectorT/*unused*/, ValueT fallback)
+ {
+ return fallback;
+ }
+
+}
+