Add WIP UnitTests for TSLQueue
This commit is contained in:
parent
aa132fbf12
commit
78862dc29d
3 changed files with 196 additions and 18 deletions
|
@ -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})
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
152
cpp_impl/src/test/TestTSLQueue.cpp
Normal file
152
cpp_impl/src/test/TestTSLQueue.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue