From 201e2e16ffc714b30eb1f862485b95af48272e40 Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Mon, 6 Sep 2021 19:58:10 +0200
Subject: [PATCH] MISC: Add a concept for the mutexes

---
 src/Lib/Log.hh   | 23 ++++++++++++++++-------
 src/Lib/Utils.hh | 11 +++++++++++
 2 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/src/Lib/Log.hh b/src/Lib/Log.hh
index 0cfcc0d5..428fb358 100644
--- a/src/Lib/Log.hh
+++ b/src/Lib/Log.hh
@@ -119,22 +119,28 @@ public:
 // Class used to check the messageQueue and send needFlush or something like
 // that messages. It needs to be moved to its own thread and connected with the
 // queue version of the QObject::connect method.
-template <class MutexType, class MessageQueueType> class LogSinkUpdater final {
-    MutexType *const messageQueueLock;
-    MessageQueueType *const messageQueue;
+template <class Mutex, class MessageQueue>
+requires MutexType<Mutex>
+class LogSinkUpdater final {
+    VIVY_UNMOVABLE_OBJECT(LogSinkUpdater)
 
-    using size_type = typename MessageQueueType::size_type;
+    Mutex *const messageQueueLock;
+    MessageQueue *const messageQueue;
+
+    using size_type = typename MessageQueue::size_type;
 
 public:
-    explicit LogSinkUpdater(MutexType *const lock, MessageQueueType *const queue) noexcept
+    explicit LogSinkUpdater(Mutex *const lock, MessageQueue *const queue)
         : messageQueueLock(lock)
         , messageQueue(queue)
     {
+        if (lock == nullptr || queue == nullptr)
+            throw std::logic_error("Can't pass null pointers for the queue and its lock");
     }
 
     bool isMessageAvailable() const noexcept
     {
-        std::lock_guard<MutexType> lockGuard(*messageQueueLock);
+        std::lock_guard<Mutex> lockGuard(*messageQueueLock);
         size_type size = messageQueue->size();
         return size != 0;
     }
@@ -142,9 +148,12 @@ public:
 
 // LogSinkUpdater controller, needed because templated Q_OBJECT are not
 // supported by Qt. This controller is specialized for a std implementation of
-// the message queue.
+// the message queue. For a Qt version use the following types:
+//      using MutexType        = QMutex;
+//      using MessageQueueType = QVector<QTuple<QStringView, LogMessage>>;
 class StlLogSinkUpdater final : public QThread {
     Q_OBJECT
+    VIVY_UNMOVABLE_OBJECT(StlLogSinkUpdater)
 
 public:
     using MutexType        = std::mutex;
diff --git a/src/Lib/Utils.hh b/src/Lib/Utils.hh
index 22cbce60..52a3b8db 100644
--- a/src/Lib/Utils.hh
+++ b/src/Lib/Utils.hh
@@ -70,6 +70,17 @@ concept PropertyConstViewable = requires(T element)
     // clang-format on
 };
 
+// Concept for mutexes
+template <typename T>
+concept MutexType = requires(T mtx)
+{
+    // clang-format off
+    { mtx.lock() }     -> std::same_as<void>;
+    { mtx.try_lock() } -> std::same_as<bool>;
+    { mtx.unlock() }   -> std::same_as<void>;
+    // clang-format on
+};
+
 // Concept with a better name for inheritence between types
 template <class T, class U>
 concept Derived = std::is_base_of<U, T>::value;
-- 
GitLab