distortos  v0.7.0
object-oriented C++ RTOS for microcontrollers
FifoQueue.hpp
Go to the documentation of this file.
1 
12 #ifndef INCLUDE_DISTORTOS_FIFOQUEUE_HPP_
13 #define INCLUDE_DISTORTOS_FIFOQUEUE_HPP_
14 
24 
25 #if __GNUC_PREREQ(5, 1) != 1
26 // GCC 4.8 doesn't support parameter pack expansion in lambdas
27 #error "GCC 5.1 is the minimum version supported by distortos"
28 #endif
29 
30 namespace distortos
31 {
32 
43 template<typename T>
44 class FifoQueue
45 {
46 public:
47 
49  using Storage = typename std::aligned_storage<sizeof(T), alignof(T)>::type;
50 
52  using StorageUniquePointer =
53  std::unique_ptr<Storage[], internal::FifoQueueBase::StorageUniquePointer::deleter_type>;
54 
56  using ValueType = T;
57 
66  FifoQueue(StorageUniquePointer&& storageUniquePointer, const size_t maxElements) :
67  fifoQueueBase_{{storageUniquePointer.release(), storageUniquePointer.get_deleter()}, sizeof(T), maxElements}
68  {
69 
70  }
71 
78  ~FifoQueue();
79 
96  template<typename... Args>
97  int emplace(Args&&... args)
98  {
99  const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
100  return emplaceInternal(semaphoreWaitFunctor, std::forward<Args>(args)...);
101  }
102 
107  size_t getCapacity() const
108  {
109  return fifoQueueBase_.getCapacity();
110  }
111 
125  int pop(T& value)
126  {
127  const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
128  return popInternal(semaphoreWaitFunctor, value);
129  }
130 
143  int push(const T& value)
144  {
145  const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
146  return pushInternal(semaphoreWaitFunctor, value);
147  }
148 
162  int push(T&& value)
163  {
164  const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
165  return pushInternal(semaphoreWaitFunctor, std::move(value));
166  }
167 
182  template<typename... Args>
183  int tryEmplace(Args&&... args)
184  {
185  const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
186  return emplaceInternal(semaphoreTryWaitFunctor, std::forward<Args>(args)...);
187  }
188 
206  template<typename... Args>
207  int tryEmplaceFor(const TickClock::duration duration, Args&&... args)
208  {
209  const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
210  return emplaceInternal(semaphoreTryWaitForFunctor, std::forward<Args>(args)...);
211  }
212 
234  template<typename Rep, typename Period, typename... Args>
235  int tryEmplaceFor(const std::chrono::duration<Rep, Period> duration, Args&&... args)
236  {
237  return tryEmplaceFor(std::chrono::duration_cast<TickClock::duration>(duration), std::forward<Args>(args)...);
238  }
239 
257  template<typename... Args>
258  int tryEmplaceUntil(const TickClock::time_point timePoint, Args&&... args)
259  {
260  const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
261  return emplaceInternal(semaphoreTryWaitUntilFunctor, std::forward<Args>(args)...);
262  }
263 
284  template<typename Duration, typename... Args>
285  int tryEmplaceUntil(const std::chrono::time_point<TickClock, Duration> timePoint, Args&&... args)
286  {
287  return tryEmplaceUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint),
288  std::forward<Args>(args)...);
289  }
290 
302  int tryPop(T& value)
303  {
304  internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
305  return popInternal(semaphoreTryWaitFunctor, value);
306  }
307 
322  int tryPopFor(const TickClock::duration duration, T& value)
323  {
324  const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
325  return popInternal(semaphoreTryWaitForFunctor, value);
326  }
327 
347  template<typename Rep, typename Period>
348  int tryPopFor(const std::chrono::duration<Rep, Period> duration, T& value)
349  {
350  return tryPopFor(std::chrono::duration_cast<TickClock::duration>(duration), value);
351  }
352 
367  int tryPopUntil(const TickClock::time_point timePoint, T& value)
368  {
369  const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
370  return popInternal(semaphoreTryWaitUntilFunctor, value);
371  }
372 
391  template<typename Duration>
392  int tryPopUntil(const std::chrono::time_point<TickClock, Duration> timePoint, T& value)
393  {
394  return tryPopUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), value);
395  }
396 
407  int tryPush(const T& value)
408  {
409  const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
410  return pushInternal(semaphoreTryWaitFunctor, value);
411  }
412 
424  int tryPush(T&& value)
425  {
426  const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
427  return pushInternal(semaphoreTryWaitFunctor, std::move(value));
428  }
429 
443  int tryPushFor(const TickClock::duration duration, const T& value)
444  {
445  const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
446  return pushInternal(semaphoreTryWaitForFunctor, value);
447  }
448 
467  template<typename Rep, typename Period>
468  int tryPushFor(const std::chrono::duration<Rep, Period> duration, const T& value)
469  {
470  return tryPushFor(std::chrono::duration_cast<TickClock::duration>(duration), value);
471  }
472 
487  int tryPushFor(const TickClock::duration duration, T&& value)
488  {
489  const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
490  return pushInternal(semaphoreTryWaitForFunctor, std::move(value));
491  }
492 
512  template<typename Rep, typename Period>
513  int tryPushFor(const std::chrono::duration<Rep, Period> duration, T&& value)
514  {
515  return tryPushFor(std::chrono::duration_cast<TickClock::duration>(duration), std::move(value));
516  }
517 
531  int tryPushUntil(const TickClock::time_point timePoint, const T& value)
532  {
533  const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
534  return pushInternal(semaphoreTryWaitUntilFunctor, value);
535  }
536 
554  template<typename Duration>
555  int tryPushUntil(const std::chrono::time_point<TickClock, Duration> timePoint, const T& value)
556  {
557  return tryPushUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), value);
558  }
559 
574  int tryPushUntil(const TickClock::time_point timePoint, T&& value)
575  {
576  const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
577  return pushInternal(semaphoreTryWaitUntilFunctor, std::move(value));
578  }
579 
598  template<typename Duration>
599  int tryPushUntil(const std::chrono::time_point<TickClock, Duration> timePoint, T&& value)
600  {
601  return tryPushUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), std::move(value));
602  }
603 
604 private:
605 
623  template<typename... Args>
624  int emplaceInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, Args&&... args);
625 
640  int popInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, T& value);
641 
655  int pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, const T& value);
656 
671  int pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, T&& value);
672 
675 };
676 
677 template<typename T>
679 {
680  T value;
681  while (tryPop(value) == 0);
682 }
683 
684 template<typename T>
685 template<typename... Args>
686 int FifoQueue<T>::emplaceInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, Args&&... args)
687 {
688  const auto emplaceFunctor = internal::makeBoundQueueFunctor(
689  [&args...](void* const storage)
690  {
691  new (storage) T{std::forward<Args>(args)...};
692  });
693  return fifoQueueBase_.push(waitSemaphoreFunctor, emplaceFunctor);
694 }
695 
696 template<typename T>
697 int FifoQueue<T>::popInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, T& value)
698 {
699  const internal::SwapPopQueueFunctor<T> swapPopQueueFunctor {value};
700  return fifoQueueBase_.pop(waitSemaphoreFunctor, swapPopQueueFunctor);
701 }
702 
703 template<typename T>
704 int FifoQueue<T>::pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, const T& value)
705 {
706  const internal::CopyConstructQueueFunctor<T> copyConstructQueueFunctor {value};
707  return fifoQueueBase_.push(waitSemaphoreFunctor, copyConstructQueueFunctor);
708 }
709 
710 template<typename T>
711 int FifoQueue<T>::pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, T&& value)
712 {
713  const internal::MoveConstructQueueFunctor<T> moveConstructQueueFunctor {std::move(value)};
714  return fifoQueueBase_.push(waitSemaphoreFunctor, moveConstructQueueFunctor);
715 }
716 
717 } // namespace distortos
718 
719 #endif // INCLUDE_DISTORTOS_FIFOQUEUE_HPP_
constexpr BoundQueueFunctor< F > makeBoundQueueFunctor(F &&boundFunctor)
Helper factory function to make BoundQueueFunctor object with deduced template arguments.
Definition: BoundQueueFunctor.hpp:79
int tryEmplaceUntil(const TickClock::time_point timePoint, Args &&... args)
Tries to emplace the element in the queue until a given time point.
Definition: FifoQueue.hpp:258
size_t getCapacity() const
Definition: FifoQueue.hpp:107
int tryEmplaceUntil(const std::chrono::time_point< TickClock, Duration > timePoint, Args &&... args)
Tries to emplace the element in the queue until a given time point.
Definition: FifoQueue.hpp:285
int tryPopUntil(const TickClock::time_point timePoint, T &value)
Tries to pop the oldest (first) element from the queue until a given time point.
Definition: FifoQueue.hpp:367
SemaphoreTryWaitFunctor class header.
int tryPush(T &&value)
Tries to push the element to the queue.
Definition: FifoQueue.hpp:424
int tryPush(const T &value)
Tries to push the element to the queue.
Definition: FifoQueue.hpp:407
int tryPushFor(const std::chrono::duration< Rep, Period > duration, T &&value)
Tries to push the element to the queue for a given duration of time.
Definition: FifoQueue.hpp:513
SemaphoreTryWaitFunctor class is a SemaphoreFunctor which calls Semaphore::tryWait()
Definition: SemaphoreTryWaitFunctor.hpp:24
std::unique_ptr< Storage[], internal::FifoQueueBase::StorageUniquePointer::deleter_type > StorageUniquePointer
unique_ptr (with deleter) to Storage[]
Definition: FifoQueue.hpp:53
int tryPushFor(const std::chrono::duration< Rep, Period > duration, const T &value)
Tries to push the element to the queue for a given duration of time.
Definition: FifoQueue.hpp:468
FifoQueue(StorageUniquePointer &&storageUniquePointer, const size_t maxElements)
FifoQueue's constructor.
Definition: FifoQueue.hpp:66
int emplaceInternal(const internal::SemaphoreFunctor &waitSemaphoreFunctor, Args &&... args)
Emplaces the element in the queue.
Definition: FifoQueue.hpp:686
typename std::aligned_storage< sizeof(T), alignof(T)>::type Storage
type of uninitialized storage for data
Definition: FifoQueue.hpp:49
int pop(T &value)
Pops the oldest (first) element from the queue.
Definition: FifoQueue.hpp:125
FifoQueue class is a simple FIFO queue for thread-thread, thread-interrupt or interrupt-interrupt com...
Definition: FifoQueue.hpp:44
int emplace(Args &&... args)
Emplaces the element in the queue.
Definition: FifoQueue.hpp:97
std::chrono::time_point< TickClock > time_point
basic time_point type of clock
Definition: TickClock.hpp:42
~FifoQueue()
FifoQueue's destructor.
Definition: FifoQueue.hpp:678
FifoQueueBase class header.
int tryPushUntil(const std::chrono::time_point< TickClock, Duration > timePoint, T &&value)
Tries to push the element to the queue until a given time point.
Definition: FifoQueue.hpp:599
int tryPop(T &value)
Tries to pop the oldest (first) element from the queue.
Definition: FifoQueue.hpp:302
SemaphoreTryWaitUntilFunctor class header.
Definition: SemaphoreTryWaitUntilFunctor.hpp:27
Definition: SwapPopQueueFunctor.hpp:32
CopyConstructQueueFunctor class header.
int tryPopFor(const TickClock::duration duration, T &value)
Tries to pop the oldest (first) element from the queue for a given duration of time.
Definition: FifoQueue.hpp:322
int push(T &&value)
Pushes the element to the queue.
Definition: FifoQueue.hpp:162
BoundQueueFunctor class header.
internal::FifoQueueBase fifoQueueBase_
contained internal::FifoQueueBase object which implements whole functionality
Definition: FifoQueue.hpp:674
FifoQueueBase class implements basic functionality of FifoQueue template class.
Definition: FifoQueueBase.hpp:29
Top-level namespace of distortos project.
Definition: buttons.hpp:33
Definition: CopyConstructQueueFunctor.hpp:30
SemaphoreFunctor is a type-erased interface for functors which execute some action on semaphore (wait...
Definition: SemaphoreFunctor.hpp:34
int pushInternal(const internal::SemaphoreFunctor &waitSemaphoreFunctor, const T &value)
Pushes the element to the queue.
Definition: FifoQueue.hpp:704
SemaphoreTryWaitForFunctor class header.
int tryPopUntil(const std::chrono::time_point< TickClock, Duration > timePoint, T &value)
Tries to pop the oldest (first) element from the queue until a given time point.
Definition: FifoQueue.hpp:392
std::chrono::duration< rep, period > duration
basic duration type of clock
Definition: TickClock.hpp:39
SwapPopQueueFunctor class header.
T ValueType
type of data in queue
Definition: FifoQueue.hpp:56
size_t getCapacity() const
Definition: FifoQueueBase.hpp:57
int tryPopFor(const std::chrono::duration< Rep, Period > duration, T &value)
Tries to pop the oldest (first) element from the queue for a given duration of time.
Definition: FifoQueue.hpp:348
int popInternal(const internal::SemaphoreFunctor &waitSemaphoreFunctor, T &value)
Pops the oldest (first) element from the queue.
Definition: FifoQueue.hpp:697
int tryEmplaceFor(const std::chrono::duration< Rep, Period > duration, Args &&... args)
Tries to emplace the element in the queue for a given duration of time.
Definition: FifoQueue.hpp:235
int tryPushUntil(const TickClock::time_point timePoint, const T &value)
Tries to push the element to the queue until a given time point.
Definition: FifoQueue.hpp:531
int push(const T &value)
Pushes the element to the queue.
Definition: FifoQueue.hpp:143
SemaphoreWaitFunctor class header.
int tryPushFor(const TickClock::duration duration, T &&value)
Tries to push the element to the queue for a given duration of time.
Definition: FifoQueue.hpp:487
int tryPushUntil(const std::chrono::time_point< TickClock, Duration > timePoint, const T &value)
Tries to push the element to the queue until a given time point.
Definition: FifoQueue.hpp:555
int tryEmplace(Args &&... args)
Tries to emplace the element in the queue.
Definition: FifoQueue.hpp:183
int tryPushFor(const TickClock::duration duration, const T &value)
Tries to push the element to the queue for a given duration of time.
Definition: FifoQueue.hpp:443
MoveConstructQueueFunctor class header.
SemaphoreTryWaitForFunctor class is a SemaphoreFunctor which calls Semaphore::tryWaitFor() with bound...
Definition: SemaphoreTryWaitForFunctor.hpp:26
int tryPushUntil(const TickClock::time_point timePoint, T &&value)
Tries to push the element to the queue until a given time point.
Definition: FifoQueue.hpp:574
SemaphoreWaitFunctor class is a SemaphoreFunctor which calls Semaphore::wait()
Definition: SemaphoreWaitFunctor.hpp:24
int tryEmplaceFor(const TickClock::duration duration, Args &&... args)
Tries to emplace the element in the queue for a given duration of time.
Definition: FifoQueue.hpp:207
Definition: MoveConstructQueueFunctor.hpp:32