132 lines
2.6 KiB
C++
132 lines
2.6 KiB
C++
#pragma once
|
|
|
|
namespace utils
|
|
{
|
|
template <typename T>
|
|
class concurrent_list final
|
|
{
|
|
public:
|
|
class element final
|
|
{
|
|
public:
|
|
explicit element(std::recursive_mutex* mutex, std::shared_ptr<T> entry = {},
|
|
std::shared_ptr<element> next = {}) :
|
|
mutex_(mutex),
|
|
entry_(std::move(entry)),
|
|
next_(std::move(next))
|
|
{
|
|
}
|
|
|
|
void remove(const std::shared_ptr<T>& element)
|
|
{
|
|
std::lock_guard _(*this->mutex_);
|
|
if (!this->next_) return;
|
|
|
|
if (this->next_->entry_.get() == element.get())
|
|
{
|
|
this->next_ = this->next_->next_;
|
|
}
|
|
else
|
|
{
|
|
this->next_->remove(element);
|
|
}
|
|
}
|
|
|
|
std::shared_ptr<element> get_next() const
|
|
{
|
|
std::lock_guard _(*this->mutex_);
|
|
return this->next_;
|
|
}
|
|
|
|
std::shared_ptr<T> operator*() const
|
|
{
|
|
std::lock_guard _(*this->mutex_);
|
|
return this->entry_;
|
|
}
|
|
|
|
element& operator++()
|
|
{
|
|
std::lock_guard _(*this->mutex_);
|
|
*this = this->next_ ? *this->next_ : element(this->mutex_);
|
|
return *this;
|
|
}
|
|
|
|
element operator++(int)
|
|
{
|
|
std::lock_guard _(*this->mutex_);
|
|
auto result = *this;
|
|
this->operator++();
|
|
return result;
|
|
}
|
|
|
|
bool operator==(const element& other)
|
|
{
|
|
std::lock_guard _(*this->mutex_);
|
|
return this->entry_.get() == other.entry_.get();
|
|
}
|
|
|
|
bool operator!=(const element& other)
|
|
{
|
|
std::lock_guard _(*this->mutex_);
|
|
return !(*this == other);
|
|
}
|
|
|
|
private:
|
|
std::recursive_mutex* mutex_;
|
|
std::shared_ptr<T> entry_;
|
|
std::shared_ptr<element> next_;
|
|
};
|
|
|
|
element begin()
|
|
{
|
|
std::lock_guard _(this->mutex_);
|
|
return this->entry_ ? *this->entry_ : this->end();
|
|
}
|
|
|
|
element end()
|
|
{
|
|
std::lock_guard _(this->mutex_);
|
|
return element(&this->mutex_);
|
|
}
|
|
|
|
void remove(const element& entry)
|
|
{
|
|
std::lock_guard _(this->mutex_);
|
|
this->remove(*entry);
|
|
}
|
|
|
|
void remove(const std::shared_ptr<T>& element)
|
|
{
|
|
std::lock_guard _(this->mutex_);
|
|
if (!this->entry_) return;
|
|
|
|
if ((**this->entry_).get() == element.get())
|
|
{
|
|
this->entry_ = this->entry_->get_next();
|
|
}
|
|
else
|
|
{
|
|
this->entry_->remove(element);
|
|
}
|
|
}
|
|
|
|
void add(const T& object)
|
|
{
|
|
std::lock_guard _(this->mutex_);
|
|
|
|
const auto object_ptr = std::make_shared<T>(object);
|
|
this->entry_ = std::make_shared<element>(&this->mutex_, object_ptr, this->entry_);
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
std::lock_guard _(this->mutex_);
|
|
this->entry_ = {};
|
|
}
|
|
|
|
private:
|
|
std::recursive_mutex mutex_;
|
|
std::shared_ptr<element> entry_;
|
|
};
|
|
}
|