thread-pool
Loading...
Searching...
No Matches
thread_safe_queue.h
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <concepts>
5#include <deque>
6#include <mutex>
7#include <optional>
8
9namespace dp {
16 template <typename Lock>
17 concept is_lockable = requires(Lock&& lock) {
18 lock.lock();
19 lock.unlock();
20 { lock.try_lock() } -> std::convertible_to<bool>;
21 };
22
23 template <typename T, typename Lock = std::mutex>
24 requires is_lockable<Lock>
26 public:
27 using value_type = T;
28 using size_type = typename std::deque<T>::size_type;
29
30 thread_safe_queue() = default;
31
32 void push_back(T&& value) {
33 std::scoped_lock lock(mutex_);
34 data_.push_back(std::forward<T>(value));
35 }
36
37 void push_front(T&& value) {
38 std::scoped_lock lock(mutex_);
39 data_.push_front(std::forward<T>(value));
40 }
41
42 [[nodiscard]] bool empty() const {
43 std::scoped_lock lock(mutex_);
44 return data_.empty();
45 }
46
47 [[nodiscard]] std::optional<T> pop_front() {
48 std::scoped_lock lock(mutex_);
49 if (data_.empty()) return std::nullopt;
50
51 auto front = std::move(data_.front());
52 data_.pop_front();
53 return front;
54 }
55
56 [[nodiscard]] std::optional<T> pop_back() {
57 std::scoped_lock lock(mutex_);
58 if (data_.empty()) return std::nullopt;
59
60 auto back = std::move(data_.back());
61 data_.pop_back();
62 return back;
63 }
64
65 [[nodiscard]] std::optional<T> steal() {
66 std::scoped_lock lock(mutex_);
67 if (data_.empty()) return std::nullopt;
68
69 auto back = std::move(data_.back());
70 data_.pop_back();
71 return back;
72 }
73
74 void rotate_to_front(const T& item) {
75 std::scoped_lock lock(mutex_);
76 auto iter = std::find(data_.begin(), data_.end(), item);
77
78 if (iter != data_.end()) {
79 std::ignore = data_.erase(iter);
80 }
81
82 data_.push_front(item);
83 }
84
85 [[nodiscard]] std::optional<T> copy_front_and_rotate_to_back() {
86 std::scoped_lock lock(mutex_);
87
88 if (data_.empty()) return std::nullopt;
89
90 auto front = data_.front();
91 data_.pop_front();
92
93 data_.push_back(front);
94
95 return front;
96 }
97
98 private:
99 std::deque<T> data_{};
100 mutable Lock mutex_{};
101 };
102} // namespace dp
Definition thread_safe_queue.h:25
std::optional< T > copy_front_and_rotate_to_back()
Definition thread_safe_queue.h:85
std::optional< T > steal()
Definition thread_safe_queue.h:65
void push_front(T &&value)
Definition thread_safe_queue.h:37
void push_back(T &&value)
Definition thread_safe_queue.h:32
thread_safe_queue()=default
T value_type
Definition thread_safe_queue.h:27
std::optional< T > pop_back()
Definition thread_safe_queue.h:56
typename std::deque< T >::size_type size_type
Definition thread_safe_queue.h:28
bool empty() const
Definition thread_safe_queue.h:42
void rotate_to_front(const T &item)
Definition thread_safe_queue.h:74
std::optional< T > pop_front()
Definition thread_safe_queue.h:47
Simple concept for the Lockable and Basic Lockable types as defined by the C++ standard.
Definition thread_safe_queue.h:17
Definition thread_pool.h:21