Add impl of TSLQueue (TODO UnitTests)
This commit is contained in:
parent
0402442929
commit
04d8abab84
1 changed files with 169 additions and 5 deletions
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <optional>
|
||||
|
||||
#include <list>
|
||||
|
@ -24,7 +26,9 @@ class TSLQueue {
|
|||
TSLQueue &operator=(TSLQueue &&other);
|
||||
|
||||
bool push(const T &data);
|
||||
bool push_nb(const T &data);
|
||||
std::optional<T> top();
|
||||
std::optional<T> top_nb();
|
||||
bool pop();
|
||||
std::optional<T> top_and_pop();
|
||||
std::optional<T> top_and_pop_and_empty(bool *isEmpty);
|
||||
|
@ -35,7 +39,11 @@ class TSLQueue {
|
|||
template <bool isConst, bool isRev>
|
||||
class TSLQIterWrapper {
|
||||
public:
|
||||
TSLQIterWrapper(std::conditional_t<isConst, const std::list<T>, std::list<T>> *container, std::weak_ptr<void> iterValid);
|
||||
TSLQIterWrapper(
|
||||
std::conditional_t<isConst, const std::list<T>, std::list<T>> *container,
|
||||
std::weak_ptr<void> iterValid,
|
||||
std::shared_ptr<void> iterWrapperCount
|
||||
);
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
|
@ -56,16 +64,28 @@ class TSLQueue {
|
|||
iter;
|
||||
|
||||
std::weak_ptr<void> iterValid;
|
||||
std::shared_ptr<void> iterWrapperCount;
|
||||
};
|
||||
|
||||
TSLQIterWrapper<false, false> iter();
|
||||
TSLQIterWrapper<false, true> riter();
|
||||
TSLQIterWrapper<true, false> citer();
|
||||
TSLQIterWrapper<true, true> criter();
|
||||
|
||||
private:
|
||||
std::shared_ptr<void> iterValid;
|
||||
std::shared_ptr<void> iterWrapperCount;
|
||||
std::mutex mutex;
|
||||
std::list<T> container;
|
||||
};
|
||||
|
||||
// implementation
|
||||
|
||||
template <typename T>
|
||||
TSLQueue<T>::TSLQueue() {
|
||||
TSLQueue<T>::TSLQueue() :
|
||||
iterValid(std::make_shared<void>()),
|
||||
iterWrapperCount(std::make_shared<void>())
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -73,20 +93,144 @@ TSLQueue<T>::~TSLQueue() {
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
TSLQueue<T>::TSLQueue(TSLQueue &&other) {
|
||||
TSLQueue<T>::TSLQueue(TSLQueue &&other) :
|
||||
iterValid(std::make_shared<void>()),
|
||||
iterWrapperCount(std::make_shared<void>())
|
||||
{
|
||||
std::lock_guard lock(other.mutex);
|
||||
container = std::move(other.container);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TSLQueue<T> & TSLQueue<T>::operator=(TSLQueue &&other) {
|
||||
std::scoped_lock lock(mutex, other.mutex);
|
||||
container = std::move(other.container);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool TSLQueue<T>::push(const T &data) {
|
||||
while(iterWrapperCount.use_count() > 1) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
std::lock_guard lock(mutex);
|
||||
container.push_back(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool TSLQueue<T>::push_nb(const T &data) {
|
||||
if(iterWrapperCount.use_count() > 1) {
|
||||
return false;
|
||||
} else if(mutex.try_lock()) {
|
||||
container.push_back(data);
|
||||
mutex.unlock();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::optional<T> TSLQueue<T>::top() {
|
||||
while(iterWrapperCount.use_count() > 1) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
std::lock_guard lock(mutex);
|
||||
if(container.empty()) {
|
||||
return std::nullopt;
|
||||
} else {
|
||||
return container.front();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::optional<T> TSLQueue<T>::top_nb() {
|
||||
if(iterWrapperCount.use_count() > 1) {
|
||||
return std::nullopt;
|
||||
} else if(mutex.try_lock()) {
|
||||
std::optional<T> ret = container.front();
|
||||
mutex.unlock();
|
||||
return ret;
|
||||
} else {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool TSLQueue<T>::pop() {
|
||||
while(iterWrapperCount.use_count() > 1) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
std::lock_guard lock(mutex);
|
||||
if(container.empty()) {
|
||||
return false;
|
||||
} else {
|
||||
container.pop_front();
|
||||
iterValid = std::make_shared<void>();
|
||||
iterWrapperCount = std::make_shared<void>();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::optional<T> TSLQueue<T>::top_and_pop() {
|
||||
std::optional<T> ret = std::nullopt;
|
||||
while(iterWrapperCount.use_count() > 1) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
std::lock_guard lock(mutex);
|
||||
if(!container.empty()) {
|
||||
ret = container.front();
|
||||
container.pop_front();
|
||||
iterValid = std::make_shared<void>();
|
||||
iterWrapperCount = std::make_shared<void>();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::optional<T> TSLQueue<T>::top_and_pop_and_empty(bool *isEmpty) {
|
||||
std::optional<T> ret = std::nullopt;
|
||||
while(iterWrapperCount.use_count() > 1) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
std::lock_guard lock(mutex);
|
||||
if(container.empty()) {
|
||||
if(isEmpty) {
|
||||
*isEmpty = true;
|
||||
}
|
||||
} else {
|
||||
ret = container.front();
|
||||
container.pop_front();
|
||||
iterValid = std::make_shared<void>();
|
||||
iterWrapperCount = std::make_shared<void>();
|
||||
if(isEmpty) {
|
||||
*isEmpty = container.empty();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TSLQueue<T>::clear() {
|
||||
while(iterWrapperCount.use_count() > 1) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
std::lock_guard lock(mutex);
|
||||
container.clear();
|
||||
iterValid = std::make_shared<void>();
|
||||
iterWrapperCount = std::make_shared<void>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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::weak_ptr<void> iterValid,
|
||||
std::shared_ptr<void> iterWrapperCount) :
|
||||
containerPtr(container),
|
||||
iterValid(iterValid) {
|
||||
iterValid(iterValid),
|
||||
iterWrapperCount(iterWrapperCount) {
|
||||
if constexpr (isRev) {
|
||||
if constexpr (isConst) {
|
||||
iter = containerPtr->crbegin();
|
||||
|
@ -180,4 +324,24 @@ std::optional<T> TSLQueue<T>::TSLQIterWrapper<isConst, isRev>::current() {
|
|||
return *iter;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename TSLQueue<T>::template TSLQIterWrapper<false, false> TSLQueue<T>::iter() {
|
||||
return TSLQIterWrapper<false, false>(&container, iterValid, iterWrapperCount);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename TSLQueue<T>::template TSLQIterWrapper<false, true> TSLQueue<T>::riter() {
|
||||
return TSLQIterWrapper<false, true>(&container, iterValid, iterWrapperCount);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename TSLQueue<T>::template TSLQIterWrapper<true, false> TSLQueue<T>::citer() {
|
||||
return TSLQIterWrapper<true, false>(&container, iterValid, iterWrapperCount);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename TSLQueue<T>::template TSLQIterWrapper<true, true> TSLQueue<T>::criter() {
|
||||
return TSLQIterWrapper<true, true>(&container, iterValid, iterWrapperCount);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue