Add WIP UnitTests for TSLQueue

This commit is contained in:
Stephen Seo 2019-10-24 20:25:41 +09:00
parent aa132fbf12
commit 78862dc29d
3 changed files with 196 additions and 18 deletions

View file

@ -56,6 +56,7 @@ if(CMAKE_BUILD_TYPE MATCHES "Debug")
set(UDPC_UnitTest_SOURCES set(UDPC_UnitTest_SOURCES
src/test/UDPC_UnitTest.cpp src/test/UDPC_UnitTest.cpp
src/test/TestTSQueue.cpp src/test/TestTSQueue.cpp
src/test/TestTSLQueue.cpp
src/test/TestUDPC.cpp src/test/TestUDPC.cpp
) )
add_executable(UnitTest ${UDPC_UnitTest_SOURCES}) add_executable(UnitTest ${UDPC_UnitTest_SOURCES})

View file

@ -42,7 +42,7 @@ class TSLQueue {
TSLQIterWrapper( TSLQIterWrapper(
std::conditional_t<isConst, const std::list<T>, std::list<T>> *container, std::conditional_t<isConst, const std::list<T>, std::list<T>> *container,
std::weak_ptr<void> iterValid, std::weak_ptr<void> iterValid,
std::shared_ptr<void> iterWrapperCount std::shared_ptr<char> iterWrapperCount
); );
bool isValid() const; bool isValid() const;
@ -54,6 +54,8 @@ class TSLQueue {
TSLQIterWrapper<isConst, isRev>& operator++(); TSLQIterWrapper<isConst, isRev>& operator++();
TSLQIterWrapper<isConst, isRev>& operator--(); TSLQIterWrapper<isConst, isRev>& operator--();
bool set(T &&newValue);
private: private:
std::conditional_t<isConst, const std::list<T>, std::list<T>> std::conditional_t<isConst, const std::list<T>, std::list<T>>
*containerPtr; *containerPtr;
@ -67,7 +69,7 @@ class TSLQueue {
iter; iter;
std::weak_ptr<void> iterValid; std::weak_ptr<void> iterValid;
std::shared_ptr<void> iterWrapperCount; std::shared_ptr<char> iterWrapperCount;
}; };
TSLQIterWrapper<false, false> iter(); TSLQIterWrapper<false, false> iter();
@ -76,8 +78,8 @@ class TSLQueue {
TSLQIterWrapper<true, true> criter(); TSLQIterWrapper<true, true> criter();
private: private:
std::shared_ptr<void> iterValid; std::shared_ptr<char> iterValid;
std::shared_ptr<void> iterWrapperCount; std::shared_ptr<char> iterWrapperCount;
std::mutex mutex; std::mutex mutex;
std::list<T> container; std::list<T> container;
}; };
@ -86,8 +88,8 @@ class TSLQueue {
template <typename T> template <typename T>
TSLQueue<T>::TSLQueue() : TSLQueue<T>::TSLQueue() :
iterValid(std::make_shared<void>()), iterValid(std::make_shared<char>()),
iterWrapperCount(std::make_shared<void>()) iterWrapperCount(std::make_shared<char>())
{ {
} }
@ -97,8 +99,8 @@ TSLQueue<T>::~TSLQueue() {
template <typename T> template <typename T>
TSLQueue<T>::TSLQueue(TSLQueue &&other) : TSLQueue<T>::TSLQueue(TSLQueue &&other) :
iterValid(std::make_shared<void>()), iterValid(std::make_shared<char>()),
iterWrapperCount(std::make_shared<void>()) iterWrapperCount(std::make_shared<char>())
{ {
std::lock_guard lock(other.mutex); std::lock_guard lock(other.mutex);
container = std::move(other.container); container = std::move(other.container);
@ -169,8 +171,8 @@ bool TSLQueue<T>::pop() {
return false; return false;
} else { } else {
container.pop_front(); container.pop_front();
iterValid = std::make_shared<void>(); iterValid = std::make_shared<char>();
iterWrapperCount = std::make_shared<void>(); iterWrapperCount = std::make_shared<char>();
return true; return true;
} }
} }
@ -185,8 +187,8 @@ std::optional<T> TSLQueue<T>::top_and_pop() {
if(!container.empty()) { if(!container.empty()) {
ret = container.front(); ret = container.front();
container.pop_front(); container.pop_front();
iterValid = std::make_shared<void>(); iterValid = std::make_shared<char>();
iterWrapperCount = std::make_shared<void>(); iterWrapperCount = std::make_shared<char>();
} }
return ret; return ret;
} }
@ -205,8 +207,8 @@ std::optional<T> TSLQueue<T>::top_and_pop_and_empty(bool *isEmpty) {
} else { } else {
ret = container.front(); ret = container.front();
container.pop_front(); container.pop_front();
iterValid = std::make_shared<void>(); iterValid = std::make_shared<char>();
iterWrapperCount = std::make_shared<void>(); iterWrapperCount = std::make_shared<char>();
if(isEmpty) { if(isEmpty) {
*isEmpty = container.empty(); *isEmpty = container.empty();
} }
@ -221,8 +223,8 @@ void TSLQueue<T>::clear() {
} }
std::lock_guard lock(mutex); std::lock_guard lock(mutex);
container.clear(); container.clear();
iterValid = std::make_shared<void>(); iterValid = std::make_shared<char>();
iterWrapperCount = std::make_shared<void>(); iterWrapperCount = std::make_shared<char>();
} }
template <typename T> template <typename T>
@ -239,7 +241,7 @@ template <bool isConst, bool isRev>
TSLQueue<T>::TSLQIterWrapper<isConst, isRev>::TSLQIterWrapper( TSLQueue<T>::TSLQIterWrapper<isConst, isRev>::TSLQIterWrapper(
std::conditional_t<isConst, const std::list<T>, std::list<T>> *container, std::conditional_t<isConst, const std::list<T>, std::list<T>> *container,
std::weak_ptr<void> iterValid, std::weak_ptr<void> iterValid,
std::shared_ptr<void> iterWrapperCount) : std::shared_ptr<char> iterWrapperCount) :
containerPtr(container), containerPtr(container),
iterValid(iterValid), iterValid(iterValid),
iterWrapperCount(iterWrapperCount) { iterWrapperCount(iterWrapperCount) {
@ -277,6 +279,9 @@ bool TSLQueue<T>::TSLQIterWrapper<isConst, isRev>::next() {
return false; return false;
} else { } else {
++iter; ++iter;
if(containerPtr->rend() == iter) {
return false;
}
} }
} else { } else {
if(containerPtr->end() == iter) { if(containerPtr->end() == iter) {
@ -284,6 +289,9 @@ bool TSLQueue<T>::TSLQIterWrapper<isConst, isRev>::next() {
return false; return false;
} else { } else {
++iter; ++iter;
if(containerPtr->end() == iter) {
return false;
}
} }
} }
@ -332,7 +340,6 @@ std::optional<T> TSLQueue<T>::TSLQIterWrapper<isConst, isRev>::current() {
} }
} }
} }
return *iter; return *iter;
} }
@ -350,23 +357,41 @@ typename TSLQueue<T>::template TSLQIterWrapper<isConst, isRev>& TSLQueue<T>::TSL
return *this; 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> template <typename T>
typename TSLQueue<T>::template TSLQIterWrapper<false, false> TSLQueue<T>::iter() { typename TSLQueue<T>::template TSLQIterWrapper<false, false> TSLQueue<T>::iter() {
std::lock_guard lock(mutex);
return TSLQIterWrapper<false, false>(&container, iterValid, iterWrapperCount); return TSLQIterWrapper<false, false>(&container, iterValid, iterWrapperCount);
} }
template <typename T> template <typename T>
typename TSLQueue<T>::template TSLQIterWrapper<false, true> TSLQueue<T>::riter() { typename TSLQueue<T>::template TSLQIterWrapper<false, true> TSLQueue<T>::riter() {
std::lock_guard lock(mutex);
return TSLQIterWrapper<false, true>(&container, iterValid, iterWrapperCount); return TSLQIterWrapper<false, true>(&container, iterValid, iterWrapperCount);
} }
template <typename T> template <typename T>
typename TSLQueue<T>::template TSLQIterWrapper<true, false> TSLQueue<T>::citer() { typename TSLQueue<T>::template TSLQIterWrapper<true, false> TSLQueue<T>::citer() {
std::lock_guard lock(mutex);
return TSLQIterWrapper<true, false>(&container, iterValid, iterWrapperCount); return TSLQIterWrapper<true, false>(&container, iterValid, iterWrapperCount);
} }
template <typename T> template <typename T>
typename TSLQueue<T>::template TSLQIterWrapper<true, true> TSLQueue<T>::criter() { typename TSLQueue<T>::template TSLQIterWrapper<true, true> TSLQueue<T>::criter() {
std::lock_guard lock(mutex);
return TSLQIterWrapper<true, true>(&container, iterValid, iterWrapperCount); return TSLQIterWrapper<true, true>(&container, iterValid, iterWrapperCount);
} }

View file

@ -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);
}
}