17#ifndef REALTIME_TOOLS__LOCK_FREE_QUEUE_HPP_
18#define REALTIME_TOOLS__LOCK_FREE_QUEUE_HPP_
25#include <boost/lockfree/queue.hpp>
26#include <boost/lockfree/spsc_queue.hpp>
27#include <boost/lockfree/stack.hpp>
39template <
typename T, std::
size_t Capacity>
40struct has_capacity<boost::lockfree::spsc_queue<T, boost::lockfree::capacity<Capacity>>>
45template <
typename T, std::
size_t Capacity>
46struct has_capacity<boost::lockfree::queue<T, boost::lockfree::capacity<Capacity>>> : std::true_type
50template <
typename T, std::
size_t Capacity,
bool FixedSize>
52 T, boost::lockfree::capacity<Capacity>, boost::lockfree::fixed_sized<FixedSize>>> : std::true_type
67template <
typename T, std::
size_t Capacity>
68struct is_spsc_queue<boost::lockfree::spsc_queue<T, boost::lockfree::capacity<Capacity>>>
78 static constexpr std::size_t value = 0;
82template <
typename T, std::
size_t Capacity>
84 boost::lockfree::spsc_queue<T, boost::lockfree::capacity<Capacity>>>
86 static constexpr std::size_t value = Capacity;
90template <
typename T, std::
size_t Capacity>
92 boost::lockfree::queue<T, boost::lockfree::capacity<Capacity>>>
94 static constexpr std::size_t value = Capacity;
98template <
typename T, std::
size_t Capacity,
bool FixedSize>
100 T, boost::lockfree::capacity<Capacity>, boost::lockfree::fixed_sized<FixedSize>>>
102 static constexpr std::size_t value = Capacity;
117template <
typename DataType,
typename LockFreeContainer>
129 typename std::enable_if_t<HasCapacity, int> = 0>
131 : capacity_(detail::get_boost_lockfree_queue_capacity<LockFreeContainer>::value)
142 typename std::enable_if_t<!HasCapacity, int> = 1>
153 [[nodiscard]]
bool pop(T & data) {
return data_queue_.pop(data); }
162 template <
typename U>
163 [[nodiscard]] std::enable_if_t<std::is_convertible_v<T, U>,
bool>
pop(U & data)
165 return data_queue_.pop(data);
175 [[nodiscard]]
bool push(
const T & data)
178 return data_queue_.push(data);
180 return data_queue_.bounded_push(data);
191 template <
typename U>
192 [[nodiscard]] std::enable_if_t<std::is_convertible_v<const U &, T>,
bool>
push(
const U & data)
195 return data_queue_.push(data);
197 return data_queue_.bounded_push(data);
221 template <
typename U>
222 [[nodiscard]] std::enable_if_t<std::is_convertible_v<const U &, T>,
bool>
bounded_push(
227 data_queue_.pop(dummy);
251 const std::size_t available = data_queue_.read_available();
252 for (std::size_t i = 1; i < available; ++i) {
253 data_queue_.consume_one([](
const T &) {});
255 return data_queue_.pop(data);
257 return data_queue_.consume_all([&data](
const T & d) { data = d; }) > 0;
271 return data_queue_.read_available() == 0;
273 return data_queue_.empty();
290 typename std::enable_if_t<IsSPSCQueue, int> = 0>
293 return data_queue_.read_available();
325 LockFreeContainer data_queue_;
326 std::size_t capacity_;
334template <
class DataType, std::
size_t Capacity = 0>
338 DataType, boost::lockfree::spsc_queue<DataType, boost::lockfree::capacity<Capacity>>>>;
346template <
class DataType, std::
size_t Capacity = 0,
bool FixedSize = true>
350 DataType, boost::lockfree::queue<DataType, boost::lockfree::fixed_sized<FixedSize>>>,
353 boost::lockfree::queue<
354 DataType, boost::lockfree::capacity<Capacity>, boost::lockfree::fixed_sized<FixedSize>>>>;