Run Code
|
API
|
Code Wall
|
Misc
|
Feedback
|
Login
|
Theme
|
Privacy
|
Patreon
Lockable static queue
#include <iostream> #include <type_traits> #include <memory> #include <mutex> template <typename T, size_t SIZE> class StaticQueue { // Lockable FIFO model T internalArray_[SIZE]; size_t first_; size_t last_; size_t count_; // concurrency part std::mutex mutable m; public: //********************************************************************** class Iterator { size_t desiredId_; size_t realIdElement_; StaticQueue& aquireObject_; void SetValue(size_t desired) { desiredId_ = desired; realIdElement_ = aquireObject_.first_ + desiredId_; if(realIdElement_ >= SIZE) { realIdElement_ %= SIZE; } } public: Iterator(StaticQueue& q, size_t id): desiredId_{id}, realIdElement_{}, aquireObject_{q} { SetValue(id); } //################################################################ // permits only read values // because these need to be protected // in order to thread which has iterator couldn't // modify the captured object without locked mutex T const& operator*() const { return aquireObject_.internalArray_[realIdElement_]; } T const& operator->() const { return aquireObject_.internalArray_[realIdElement_]; } //################################################################ friend bool operator==(Iterator const& lhs, Iterator const& rhs) { return lhs.desiredId_ == rhs.desiredId_ && &lhs.aquireObject_ == &rhs.aquireObject_; } friend bool operator!=(Iterator const& lhs, Iterator const& rhs) { return !(lhs == rhs); } Iterator& operator++() { SetValue(desiredId_ + 1); return *this; } Iterator& operator++(int) { auto thisObject = *this; SetValue(desiredId_ + 1); return thisObject; } Iterator& operator--() { SetValue(desiredId_ - 1); return *this; } Iterator& operator--(int) { auto thisObject = *this; SetValue(desiredId_ - 1); return thisObject; } }; StaticQueue(): first_{0}, last_{0}, count_{0} { } // copy/move semantics depends by T StaticQueue(StaticQueue const&) = default; StaticQueue(StaticQueue&&) = default; StaticQueue& operator=(StaticQueue const&) = default; StaticQueue& operator=(StaticQueue&&) = default; // the class can be inherited virtual ~StaticQueue() = default; // C++14 signatures of begin/end /** auto begin () { return Iterator(*this, 0); } auto begin () const { return Iterator(*this, 0); } auto cbegin () const { return Iterator(*this, 0); } auto end () { return Iterator(*this, count_); } auto end () const { return Iterator(*this, count_); } auto cend () const { return Iterator(*this, count_); }*/ Iterator begin () { return Iterator(*this, 0); } Iterator const begin () const { return Iterator(*this, 0); } Iterator const cbegin () const { return Iterator(*this, 0); } Iterator end () { return Iterator(*this, count_); } Iterator const end () const { return Iterator(*this, count_); } Iterator const cend () const { return Iterator(*this, count_); } //********************************************************************** bool Push(T const& lobject) noexcept(std::is_nothrow_copy_assignable<T>::value) { std::lock_guard<std::mutex> locker{m}; if(count_ < SIZE) { internalArray_[last_] = lobject; last_ = (last_ + 1) % SIZE; ++count_; return true; } return false; } bool Push(T&& robject) noexcept(std::is_nothrow_copy_assignable<T>::value) { std::lock_guard<std::mutex> locker{m}; if(count_ < SIZE) { if(std::is_nothrow_move_assignable<T>::value) { // call move assignable only if it has noexcept specification // in order to don't loose the object when exception will thrown internalArray_[last_] = std::move(robject); } else { // call copy assignable internalArray_[last_] = robject; } last_ = (last_ + 1) % SIZE; ++count_; return true; } return false; } bool Pop(T& value) noexcept(std::is_nothrow_copy_assignable<T>::value) { std::lock_guard<std::mutex> locker{m}; if(count_) { if(std::is_nothrow_move_assignable<T>::value) { // if move assignable operator may throwing exception // element may be loosed from queue and does't be assigned value = std::move(internalArray_[first_]); } else { // safe exception without lose element value = internalArray_[first_]; } first_ = (first_ + 1) % SIZE; --count_; return true; } return false; } std::shared_ptr<T> Pop() noexcept(std::is_nothrow_copy_constructible<T>::value) { std::lock_guard<std::mutex> locker{m}; if(count_) { std::shared_ptr<T> temporary; if(std::is_nothrow_move_constructible<T>::value) { // if move constructor operator may throwing exception // element may be loosed from queue and does't be constructed temporary = std::make_shared<T>(std::move(internalArray_[first_])); } else { // safe exception without lose element temporary = std::make_shared<T>(internalArray_[first_]); } first_ = (first_ + 1) % SIZE; --count_; return temporary; } return std::shared_ptr<T>{nullptr}; } bool Empty() const { std::lock_guard<std::mutex> locker{m}; return count_; } size_t Size() const { std::lock_guard<std::mutex> locker{m}; return count_; } }; int main() { StaticQueue<int, 8> queue; queue.Push(1); queue.Push(2); queue.Push(3); queue.Push(4); queue.Push(5); queue.Push(6); queue.Push(7); queue.Push(8); if(!queue.Push(9)) { auto extracted = queue.Pop(); std::cout << "The extractet element: " << *extracted << std::endl << std::endl; queue.Push(9); } std::cout << "Elements in queue:" << std::endl; for(auto element : queue) { std::cout << element << std::endl; } return 0; }
run
|
edit
|
history
|
help
0
bmp_lb
my template
FindMissingLagrange
dsadasdsa
Rectangle overlap
CurDayMessage
Network UVa
cons1
Splitwise Problem - 1
WeekAgenda