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
|
||||
src/test/UDPC_UnitTest.cpp
|
||||
src/test/TestTSQueue.cpp
|
||||
src/test/TestTSLQueue.cpp
|
||||
src/test/TestUDPC.cpp
|
||||
)
|
||||
add_executable(UnitTest ${UDPC_UnitTest_SOURCES})
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
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