From 78862dc29dca83592ea6115133a763c3a531faf3 Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Thu, 24 Oct 2019 20:25:41 +0900 Subject: [PATCH] Add WIP UnitTests for TSLQueue --- cpp_impl/CMakeLists.txt | 1 + cpp_impl/src/TSLQueue.hpp | 61 ++++++++---- cpp_impl/src/test/TestTSLQueue.cpp | 152 +++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+), 18 deletions(-) create mode 100644 cpp_impl/src/test/TestTSLQueue.cpp diff --git a/cpp_impl/CMakeLists.txt b/cpp_impl/CMakeLists.txt index 967969f..cd671af 100644 --- a/cpp_impl/CMakeLists.txt +++ b/cpp_impl/CMakeLists.txt @@ -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}) diff --git a/cpp_impl/src/TSLQueue.hpp b/cpp_impl/src/TSLQueue.hpp index fd28bb3..e2b7718 100644 --- a/cpp_impl/src/TSLQueue.hpp +++ b/cpp_impl/src/TSLQueue.hpp @@ -42,7 +42,7 @@ class TSLQueue { TSLQIterWrapper( std::conditional_t, std::list> *container, std::weak_ptr iterValid, - std::shared_ptr iterWrapperCount + std::shared_ptr iterWrapperCount ); bool isValid() const; @@ -54,6 +54,8 @@ class TSLQueue { TSLQIterWrapper& operator++(); TSLQIterWrapper& operator--(); + bool set(T &&newValue); + private: std::conditional_t, std::list> *containerPtr; @@ -67,7 +69,7 @@ class TSLQueue { iter; std::weak_ptr iterValid; - std::shared_ptr iterWrapperCount; + std::shared_ptr iterWrapperCount; }; TSLQIterWrapper iter(); @@ -76,8 +78,8 @@ class TSLQueue { TSLQIterWrapper criter(); private: - std::shared_ptr iterValid; - std::shared_ptr iterWrapperCount; + std::shared_ptr iterValid; + std::shared_ptr iterWrapperCount; std::mutex mutex; std::list container; }; @@ -86,8 +88,8 @@ class TSLQueue { template TSLQueue::TSLQueue() : - iterValid(std::make_shared()), - iterWrapperCount(std::make_shared()) + iterValid(std::make_shared()), + iterWrapperCount(std::make_shared()) { } @@ -97,8 +99,8 @@ TSLQueue::~TSLQueue() { template TSLQueue::TSLQueue(TSLQueue &&other) : - iterValid(std::make_shared()), - iterWrapperCount(std::make_shared()) + iterValid(std::make_shared()), + iterWrapperCount(std::make_shared()) { std::lock_guard lock(other.mutex); container = std::move(other.container); @@ -169,8 +171,8 @@ bool TSLQueue::pop() { return false; } else { container.pop_front(); - iterValid = std::make_shared(); - iterWrapperCount = std::make_shared(); + iterValid = std::make_shared(); + iterWrapperCount = std::make_shared(); return true; } } @@ -185,8 +187,8 @@ std::optional TSLQueue::top_and_pop() { if(!container.empty()) { ret = container.front(); container.pop_front(); - iterValid = std::make_shared(); - iterWrapperCount = std::make_shared(); + iterValid = std::make_shared(); + iterWrapperCount = std::make_shared(); } return ret; } @@ -205,8 +207,8 @@ std::optional TSLQueue::top_and_pop_and_empty(bool *isEmpty) { } else { ret = container.front(); container.pop_front(); - iterValid = std::make_shared(); - iterWrapperCount = std::make_shared(); + iterValid = std::make_shared(); + iterWrapperCount = std::make_shared(); if(isEmpty) { *isEmpty = container.empty(); } @@ -221,8 +223,8 @@ void TSLQueue::clear() { } std::lock_guard lock(mutex); container.clear(); - iterValid = std::make_shared(); - iterWrapperCount = std::make_shared(); + iterValid = std::make_shared(); + iterWrapperCount = std::make_shared(); } template @@ -239,7 +241,7 @@ template TSLQueue::TSLQIterWrapper::TSLQIterWrapper( std::conditional_t, std::list> *container, std::weak_ptr iterValid, - std::shared_ptr iterWrapperCount) : + std::shared_ptr iterWrapperCount) : containerPtr(container), iterValid(iterValid), iterWrapperCount(iterWrapperCount) { @@ -277,6 +279,9 @@ bool TSLQueue::TSLQIterWrapper::next() { return false; } else { ++iter; + if(containerPtr->rend() == iter) { + return false; + } } } else { if(containerPtr->end() == iter) { @@ -284,6 +289,9 @@ bool TSLQueue::TSLQIterWrapper::next() { return false; } else { ++iter; + if(containerPtr->end() == iter) { + return false; + } } } @@ -332,7 +340,6 @@ std::optional TSLQueue::TSLQIterWrapper::current() { } } } - return *iter; } @@ -350,23 +357,41 @@ typename TSLQueue::template TSLQIterWrapper& TSLQueue::TSL return *this; } +template +template +bool TSLQueue::TSLQIterWrapper::set(T &&newValue) { + if constexpr(isConst) { + return false; + } else { + if(!isValid()) { + return false; + } + *iter = std::forward(newValue); + return true; + } +} + template typename TSLQueue::template TSLQIterWrapper TSLQueue::iter() { + std::lock_guard lock(mutex); return TSLQIterWrapper(&container, iterValid, iterWrapperCount); } template typename TSLQueue::template TSLQIterWrapper TSLQueue::riter() { + std::lock_guard lock(mutex); return TSLQIterWrapper(&container, iterValid, iterWrapperCount); } template typename TSLQueue::template TSLQIterWrapper TSLQueue::citer() { + std::lock_guard lock(mutex); return TSLQIterWrapper(&container, iterValid, iterWrapperCount); } template typename TSLQueue::template TSLQIterWrapper TSLQueue::criter() { + std::lock_guard lock(mutex); return TSLQIterWrapper(&container, iterValid, iterWrapperCount); } diff --git a/cpp_impl/src/test/TestTSLQueue.cpp b/cpp_impl/src/test/TestTSLQueue.cpp new file mode 100644 index 0000000..e06d75c --- /dev/null +++ b/cpp_impl/src/test/TestTSLQueue.cpp @@ -0,0 +1,152 @@ +#include + +#include + +#include "TSLQueue.hpp" + +TEST(TSLQueue, Usage) { + TSLQueue q; + bool isEmpty; + std::optional 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); + } +}