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;
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;
iter;
std::weak_ptr<void> iterValid;
- std::shared_ptr<void> iterWrapperCount;
+ std::shared_ptr<char> iterWrapperCount;
};
TSLQIterWrapper<false, false> iter();
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;
};
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>())
{
}
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);
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;
}
}
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;
}
} 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();
}
}
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>
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) {
return false;
} else {
++iter;
+ if(containerPtr->rend() == iter) {
+ return false;
+ }
}
} else {
if(containerPtr->end() == iter) {
return false;
} else {
++iter;
+ if(containerPtr->end() == iter) {
+ return false;
+ }
}
}
}
}
}
-
return *iter;
}
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);
}
--- /dev/null
+#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);
+ }
+}