]> git.seodisparate.com - UDPConnection/commitdiff
Add WIP UnitTests for TSLQueue
authorStephen Seo <seo.disparate@gmail.com>
Thu, 24 Oct 2019 11:25:41 +0000 (20:25 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Thu, 24 Oct 2019 11:25:41 +0000 (20:25 +0900)
cpp_impl/CMakeLists.txt
cpp_impl/src/TSLQueue.hpp
cpp_impl/src/test/TestTSLQueue.cpp [new file with mode: 0644]

index 967969f0f71287e9402bfb91d917be36d0707605..cd671aff2eea389fa03649915737668014b3bc05 100644 (file)
@@ -56,6 +56,7 @@ if(CMAKE_BUILD_TYPE MATCHES "Debug")
         set(UDPC_UnitTest_SOURCES
             src/test/UDPC_UnitTest.cpp
             src/test/TestTSQueue.cpp
+            src/test/TestTSLQueue.cpp
             src/test/TestUDPC.cpp
         )
         add_executable(UnitTest ${UDPC_UnitTest_SOURCES})
index fd28bb30032da49e3e4278d351498fb5117d7fb6..e2b77182decd5a1f643b85e5e2cd0a2b937ae226 100644 (file)
@@ -42,7 +42,7 @@ class TSLQueue {
         TSLQIterWrapper(
             std::conditional_t<isConst, const std::list<T>, std::list<T>> *container,
             std::weak_ptr<void> iterValid,
-            std::shared_ptr<void> iterWrapperCount
+            std::shared_ptr<char> iterWrapperCount
         );
 
         bool isValid() const;
@@ -54,6 +54,8 @@ class TSLQueue {
         TSLQIterWrapper<isConst, isRev>& operator++();
         TSLQIterWrapper<isConst, isRev>& operator--();
 
+        bool set(T &&newValue);
+
       private:
         std::conditional_t<isConst, const std::list<T>, std::list<T>>
             *containerPtr;
@@ -67,7 +69,7 @@ class TSLQueue {
                     iter;
 
         std::weak_ptr<void> iterValid;
-        std::shared_ptr<void> iterWrapperCount;
+        std::shared_ptr<char> iterWrapperCount;
     };
 
     TSLQIterWrapper<false, false> iter();
@@ -76,8 +78,8 @@ class TSLQueue {
     TSLQIterWrapper<true, true> criter();
 
   private:
-    std::shared_ptr<void> iterValid;
-    std::shared_ptr<void> iterWrapperCount;
+    std::shared_ptr<char> iterValid;
+    std::shared_ptr<char> iterWrapperCount;
     std::mutex mutex;
     std::list<T> container;
 };
@@ -86,8 +88,8 @@ class TSLQueue {
 
 template <typename T>
 TSLQueue<T>::TSLQueue() :
-    iterValid(std::make_shared<void>()),
-    iterWrapperCount(std::make_shared<void>())
+    iterValid(std::make_shared<char>()),
+    iterWrapperCount(std::make_shared<char>())
 {
 }
 
@@ -97,8 +99,8 @@ TSLQueue<T>::~TSLQueue() {
 
 template <typename T>
 TSLQueue<T>::TSLQueue(TSLQueue &&other) :
-    iterValid(std::make_shared<void>()),
-    iterWrapperCount(std::make_shared<void>())
+    iterValid(std::make_shared<char>()),
+    iterWrapperCount(std::make_shared<char>())
 {
     std::lock_guard lock(other.mutex);
     container = std::move(other.container);
@@ -169,8 +171,8 @@ bool TSLQueue<T>::pop() {
         return false;
     } else {
         container.pop_front();
-        iterValid = std::make_shared<void>();
-        iterWrapperCount = std::make_shared<void>();
+        iterValid = std::make_shared<char>();
+        iterWrapperCount = std::make_shared<char>();
         return true;
     }
 }
@@ -185,8 +187,8 @@ std::optional<T> TSLQueue<T>::top_and_pop() {
     if(!container.empty()) {
         ret = container.front();
         container.pop_front();
-        iterValid = std::make_shared<void>();
-        iterWrapperCount = std::make_shared<void>();
+        iterValid = std::make_shared<char>();
+        iterWrapperCount = std::make_shared<char>();
     }
     return ret;
 }
@@ -205,8 +207,8 @@ std::optional<T> TSLQueue<T>::top_and_pop_and_empty(bool *isEmpty) {
     } else {
         ret = container.front();
         container.pop_front();
-        iterValid = std::make_shared<void>();
-        iterWrapperCount = std::make_shared<void>();
+        iterValid = std::make_shared<char>();
+        iterWrapperCount = std::make_shared<char>();
         if(isEmpty) {
             *isEmpty = container.empty();
         }
@@ -221,8 +223,8 @@ void TSLQueue<T>::clear() {
     }
     std::lock_guard lock(mutex);
     container.clear();
-    iterValid = std::make_shared<void>();
-    iterWrapperCount = std::make_shared<void>();
+    iterValid = std::make_shared<char>();
+    iterWrapperCount = std::make_shared<char>();
 }
 
 template <typename T>
@@ -239,7 +241,7 @@ template <bool isConst, bool isRev>
 TSLQueue<T>::TSLQIterWrapper<isConst, isRev>::TSLQIterWrapper(
         std::conditional_t<isConst, const std::list<T>, std::list<T>> *container,
         std::weak_ptr<void> iterValid,
-        std::shared_ptr<void> iterWrapperCount) :
+        std::shared_ptr<char> iterWrapperCount) :
             containerPtr(container),
             iterValid(iterValid),
             iterWrapperCount(iterWrapperCount) {
@@ -277,6 +279,9 @@ bool TSLQueue<T>::TSLQIterWrapper<isConst, isRev>::next() {
             return false;
         } else {
             ++iter;
+            if(containerPtr->rend() == iter) {
+                return false;
+            }
         }
     } else {
         if(containerPtr->end() == iter) {
@@ -284,6 +289,9 @@ bool TSLQueue<T>::TSLQIterWrapper<isConst, isRev>::next() {
             return false;
         } else {
             ++iter;
+            if(containerPtr->end() == iter) {
+                return false;
+            }
         }
     }
 
@@ -332,7 +340,6 @@ std::optional<T> TSLQueue<T>::TSLQIterWrapper<isConst, isRev>::current() {
             }
         }
     }
-
     return *iter;
 }
 
@@ -350,23 +357,41 @@ typename TSLQueue<T>::template TSLQIterWrapper<isConst, isRev>& TSLQueue<T>::TSL
     return *this;
 }
 
+template <typename T>
+template <bool isConst, bool isRev>
+bool TSLQueue<T>::TSLQIterWrapper<isConst, isRev>::set(T &&newValue) {
+    if constexpr(isConst) {
+        return false;
+    } else {
+        if(!isValid()) {
+            return false;
+        }
+        *iter = std::forward<T>(newValue);
+        return true;
+    }
+}
+
 template <typename T>
 typename TSLQueue<T>::template TSLQIterWrapper<false, false> TSLQueue<T>::iter() {
+    std::lock_guard lock(mutex);
     return TSLQIterWrapper<false, false>(&container, iterValid, iterWrapperCount);
 }
 
 template <typename T>
 typename TSLQueue<T>::template TSLQIterWrapper<false, true> TSLQueue<T>::riter() {
+    std::lock_guard lock(mutex);
     return TSLQIterWrapper<false, true>(&container, iterValid, iterWrapperCount);
 }
 
 template <typename T>
 typename TSLQueue<T>::template TSLQIterWrapper<true, false> TSLQueue<T>::citer() {
+    std::lock_guard lock(mutex);
     return TSLQIterWrapper<true, false>(&container, iterValid, iterWrapperCount);
 }
 
 template <typename T>
 typename TSLQueue<T>::template TSLQIterWrapper<true, true> TSLQueue<T>::criter() {
+    std::lock_guard lock(mutex);
     return TSLQIterWrapper<true, true>(&container, iterValid, iterWrapperCount);
 }
 
diff --git a/cpp_impl/src/test/TestTSLQueue.cpp b/cpp_impl/src/test/TestTSLQueue.cpp
new file mode 100644 (file)
index 0000000..e06d75c
--- /dev/null
@@ -0,0 +1,152 @@
+#include <gtest/gtest.h>
+
+#include <iostream>
+
+#include "TSLQueue.hpp"
+
+TEST(TSLQueue, Usage) {
+    TSLQueue<int> q;
+    bool isEmpty;
+    std::optional<int> opt;
+
+    // init
+    EXPECT_FALSE(q.pop());
+
+    opt = q.top_and_pop();
+    EXPECT_FALSE(opt.has_value());
+
+    opt = q.top_and_pop_and_empty(&isEmpty);
+    EXPECT_FALSE(opt.has_value());
+    EXPECT_TRUE(isEmpty);
+
+    EXPECT_TRUE(q.empty());
+
+    // push 1, 2, 3
+    q.push(1);
+    EXPECT_FALSE(q.empty());
+    opt = q.top();
+    ASSERT_TRUE(opt.has_value());
+    EXPECT_EQ(opt.value(), 1);
+
+    q.push_nb(2);
+    EXPECT_FALSE(q.empty());
+    opt = q.top_nb();
+    ASSERT_TRUE(opt.has_value());
+    EXPECT_EQ(opt.value(), 1);
+
+    q.push(3);
+    EXPECT_FALSE(q.empty());
+    opt = q.top();
+    ASSERT_TRUE(opt.has_value());
+    EXPECT_EQ(opt.value(), 1);
+
+    // iterators
+    {
+        auto citer = q.citer();
+        opt = citer.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 1);
+        EXPECT_FALSE(citer.set(111));
+
+        EXPECT_TRUE(citer.next());
+        opt = citer.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 2);
+
+        EXPECT_TRUE(citer.next());
+        opt = citer.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 3);
+
+        EXPECT_FALSE(citer.next());
+        opt = citer.current();
+        EXPECT_FALSE(opt.has_value());
+
+        EXPECT_TRUE(citer.isValid());
+        EXPECT_FALSE(citer.next());
+        EXPECT_FALSE(citer.isValid());
+    }
+    {
+        auto criter = q.criter();
+        opt = criter.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 3);
+        EXPECT_FALSE(criter.set(333));
+
+        EXPECT_TRUE(criter.next());
+        opt = criter.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 2);
+
+        EXPECT_TRUE(criter.next());
+        opt = criter.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 1);
+
+        EXPECT_FALSE(criter.next());
+        opt = criter.current();
+        EXPECT_FALSE(opt.has_value());
+    }
+    {
+        // values changed to 10, 20, 30
+        auto iter = q.iter();
+        opt = iter.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 1);
+        EXPECT_TRUE(iter.set(10));
+        opt = iter.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 10);
+
+        EXPECT_TRUE(iter.next());
+        opt = iter.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 2);
+        EXPECT_TRUE(iter.set(20));
+        opt = iter.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 20);
+
+        EXPECT_TRUE(iter.next());
+        opt = iter.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 3);
+        EXPECT_TRUE(iter.set(30));
+        opt = iter.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 30);
+
+        EXPECT_FALSE(iter.next());
+        opt = iter.current();
+        EXPECT_FALSE(opt.has_value());
+    }
+    {
+        // values changed to 1, 2, 3
+        auto riter = q.riter();
+        opt = riter.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 30);
+        EXPECT_TRUE(riter.set(3));
+        opt = riter.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 3);
+
+        EXPECT_TRUE(riter.next());
+        opt = riter.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 20);
+        EXPECT_TRUE(riter.set(2));
+        opt = riter.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 2);
+
+        EXPECT_TRUE(riter.next());
+        opt = riter.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 10);
+        EXPECT_TRUE(riter.set(1));
+        opt = riter.current();
+        ASSERT_TRUE(opt.has_value());
+        EXPECT_EQ(opt.value(), 1);
+    }
+}