forked from PickNikRobotics/RSL
-
Notifications
You must be signed in to change notification settings - Fork 0
/
queue.hpp
79 lines (67 loc) · 2.03 KB
/
queue.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#pragma once
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <optional>
#include <queue>
namespace rsl {
/** @file */
/**
* @brief Thread-safe queue. Particularly useful when multiple threads need to write to and/or read
* from a queue.
*/
template <typename T>
class Queue {
std::queue<T> queue_;
std::condition_variable cv_;
mutable std::mutex mutex_;
public:
/**
* @brief Get the size of the queue
* @return Queue size
*/
[[nodiscard]] auto size() const noexcept {
auto const lock = std::lock_guard(mutex_);
return queue_.size();
}
/**
* @brief Check if the queue is empty
* @return True if the queue is empty, otherwise false
*/
[[nodiscard]] auto empty() const noexcept {
auto const lock = std::lock_guard(mutex_);
return queue_.empty();
}
/**
* @brief Push data into the queue
* @param value Data to push into the queue
*/
void push(T value) noexcept {
auto const lock = std::lock_guard(mutex_);
queue_.push(std::move(value));
cv_.notify_one();
}
/**
* @brief Clear the queue
*/
void clear() noexcept {
auto const lock = std::lock_guard(mutex_);
// Swap queue with an empty queue of the same type to ensure queue_ is left in a
// default-constructed state
decltype(queue_)().swap(queue_);
}
/**
* @brief Wait for given duration then pop from the queue and return the element
* @param wait_time Maximum time to wait for queue to be non-empty
* @return Data popped from the queue or error
*/
[[nodiscard]] auto pop(std::chrono::nanoseconds wait_time = {}) -> std::optional<T> {
auto lock = std::unique_lock(mutex_);
// If queue is empty after wait_time, return nothing
if (!cv_.wait_for(lock, wait_time, [this] { return !queue_.empty(); })) return std::nullopt;
auto value = queue_.front();
queue_.pop();
return value;
}
};
} // namespace rsl