distortos  v0.4.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 
27 #define DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED __GNUC_PREREQ(4, 9)
28 
29 namespace distortos
30 {
31 
42 template<typename T>
43 class FifoQueue
44 {
45 public:
46 
48  using Storage = typename std::aligned_storage<sizeof(T), alignof(T)>::type;
49 
51  using StorageUniquePointer =
52  std::unique_ptr<Storage[], internal::FifoQueueBase::StorageUniquePointer::deleter_type>;
53 
62  FifoQueue(StorageUniquePointer&& storageUniquePointer, const size_t maxElements) :
63  fifoQueueBase_{{storageUniquePointer.release(), storageUniquePointer.get_deleter()}, sizeof(T), maxElements}
64  {
65 
66  }
67 
74  ~FifoQueue();
75 
76 #if DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED == 1
77 
94  template<typename... Args>
95  int emplace(Args&&... args)
96  {
97  const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
98  return emplaceInternal(semaphoreWaitFunctor, std::forward<Args>(args)...);
99  }
100 
101 #endif // DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED == 1
102 
116  int pop(T& value)
117  {
118  const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
119  return popInternal(semaphoreWaitFunctor, value);
120  }
121 
134  int push(const T& value)
135  {
136  const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
137  return pushInternal(semaphoreWaitFunctor, value);
138  }
139 
153  int push(T&& value)
154  {
155  const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
156  return pushInternal(semaphoreWaitFunctor, std::move(value));
157  }
158 
159 #if DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED == 1
160 
175  template<typename... Args>
176  int tryEmplace(Args&&... args)
177  {
178  const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
179  return emplaceInternal(semaphoreTryWaitFunctor, std::forward<Args>(args)...);
180  }
181 
199  template<typename... Args>
200  int tryEmplaceFor(const TickClock::duration duration, Args&&... args)
201  {
202  const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
203  return emplaceInternal(semaphoreTryWaitForFunctor, std::forward<Args>(args)...);
204  }
205 
227  template<typename Rep, typename Period, typename... Args>
228  int tryEmplaceFor(const std::chrono::duration<Rep, Period> duration, Args&&... args)
229  {
230  return tryEmplaceFor(std::chrono::duration_cast<TickClock::duration>(duration), std::forward<Args>(args)...);
231  }
232 
250  template<typename... Args>
251  int tryEmplaceUntil(const TickClock::time_point timePoint, Args&&... args)
252  {
253  const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
254  return emplaceInternal(semaphoreTryWaitUntilFunctor, std::forward<Args>(args)...);
255  }
256 
277  template<typename Duration, typename... Args>
278  int tryEmplaceUntil(const std::chrono::time_point<TickClock, Duration> timePoint, Args&&... args)
279  {
280  return tryEmplaceUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint),
281  std::forward<Args>(args)...);
282  }
283 
284 #endif // DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED == 1
285 
297  int tryPop(T& value)
298  {
299  internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
300  return popInternal(semaphoreTryWaitFunctor, value);
301  }
302 
317  int tryPopFor(const TickClock::duration duration, T& value)
318  {
319  const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
320  return popInternal(semaphoreTryWaitForFunctor, value);
321  }
322 
342  template<typename Rep, typename Period>
343  int tryPopFor(const std::chrono::duration<Rep, Period> duration, T& value)
344  {
345  return tryPopFor(std::chrono::duration_cast<TickClock::duration>(duration), value);
346  }
347 
362  int tryPopUntil(const TickClock::time_point timePoint, T& value)
363  {
364  const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
365  return popInternal(semaphoreTryWaitUntilFunctor, value);
366  }
367 
386  template<typename Duration>
387  int tryPopUntil(const std::chrono::time_point<TickClock, Duration> timePoint, T& value)
388  {
389  return tryPopUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), value);
390  }
391 
402  int tryPush(const T& value)
403  {
404  const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
405  return pushInternal(semaphoreTryWaitFunctor, value);
406  }
407 
419  int tryPush(T&& value)
420  {
421  const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
422  return pushInternal(semaphoreTryWaitFunctor, std::move(value));
423  }
424 
438  int tryPushFor(const TickClock::duration duration, const T& value)
439  {
440  const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
441  return pushInternal(semaphoreTryWaitForFunctor, value);
442  }
443 
462  template<typename Rep, typename Period>
463  int tryPushFor(const std::chrono::duration<Rep, Period> duration, const T& value)
464  {
465  return tryPushFor(std::chrono::duration_cast<TickClock::duration>(duration), value);
466  }
467 
482  int tryPushFor(const TickClock::duration duration, T&& value)
483  {
484  const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
485  return pushInternal(semaphoreTryWaitForFunctor, std::move(value));
486  }
487 
507  template<typename Rep, typename Period>
508  int tryPushFor(const std::chrono::duration<Rep, Period> duration, T&& value)
509  {
510  return tryPushFor(std::chrono::duration_cast<TickClock::duration>(duration), std::move(value));
511  }
512 
526  int tryPushUntil(const TickClock::time_point timePoint, const T& value)
527  {
528  const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
529  return pushInternal(semaphoreTryWaitUntilFunctor, value);
530  }
531 
549  template<typename Duration>
550  int tryPushUntil(const std::chrono::time_point<TickClock, Duration> timePoint, const T& value)
551  {
552  return tryPushUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), value);
553  }
554 
569  int tryPushUntil(const TickClock::time_point timePoint, T&& value)
570  {
571  const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
572  return pushInternal(semaphoreTryWaitUntilFunctor, std::move(value));
573  }
574 
593  template<typename Duration>
594  int tryPushUntil(const std::chrono::time_point<TickClock, Duration> timePoint, T&& value)
595  {
596  return tryPushUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), std::move(value));
597  }
598 
599 private:
600 
601 #if DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED == 1
602 
620  template<typename... Args>
621  int emplaceInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, Args&&... args);
622 
623 #endif // DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED == 1
624 
639  int popInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, T& value);
640 
654  int pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, const T& value);
655 
670  int pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, T&& value);
671 
674 };
675 
676 template<typename T>
678 {
679  T value;
680  while (tryPop(value) == 0);
681 }
682 
683 #if DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED == 1
684 
685 template<typename T>
686 template<typename... Args>
687 int FifoQueue<T>::emplaceInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, Args&&... args)
688 {
689  const auto emplaceFunctor = internal::makeBoundQueueFunctor(
690  [&args...](void* const storage)
691  {
692  new (storage) T{std::forward<Args>(args)...};
693  });
694  return fifoQueueBase_.push(waitSemaphoreFunctor, emplaceFunctor);
695 }
696 
697 #endif // DISTORTOS_FIFOQUEUE_EMPLACE_SUPPORTED == 1
698 
699 template<typename T>
700 int FifoQueue<T>::popInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, T& value)
701 {
702  const internal::SwapPopQueueFunctor<T> swapPopQueueFunctor {value};
703  return fifoQueueBase_.pop(waitSemaphoreFunctor, swapPopQueueFunctor);
704 }
705 
706 template<typename T>
707 int FifoQueue<T>::pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, const T& value)
708 {
709  const internal::CopyConstructQueueFunctor<T> copyConstructQueueFunctor {value};
710  return fifoQueueBase_.push(waitSemaphoreFunctor, copyConstructQueueFunctor);
711 }
712 
713 template<typename T>
714 int FifoQueue<T>::pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, T&& value)
715 {
716  const internal::MoveConstructQueueFunctor<T> moveConstructQueueFunctor {std::move(value)};
717  return fifoQueueBase_.push(waitSemaphoreFunctor, moveConstructQueueFunctor);
718 }
719 
720 } // namespace distortos
721 
722 #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:251
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:278
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:362
SemaphoreTryWaitFunctor class header.
int tryPush(T &&value)
Tries to push the element to the queue.
Definition: FifoQueue.hpp:419
int tryPush(const T &value)
Tries to push the element to the queue.
Definition: FifoQueue.hpp:402
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:508
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:52
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:463
FifoQueue(StorageUniquePointer &&storageUniquePointer, const size_t maxElements)
FifoQueue&#39;s constructor.
Definition: FifoQueue.hpp:62
int emplaceInternal(const internal::SemaphoreFunctor &waitSemaphoreFunctor, Args &&... args)
Emplaces the element in the queue.
Definition: FifoQueue.hpp:687
typename std::aligned_storage< sizeof(OperationCountingType), alignof(OperationCountingType)>::type Storage
type of uninitialized storage for data
Definition: FifoQueue.hpp:48
int pop(T &value)
Pops the oldest (first) element from the queue.
Definition: FifoQueue.hpp:116
FifoQueue class is a simple FIFO queue for thread-thread, thread-interrupt or interrupt-interrupt com...
Definition: FifoQueue.hpp:43
int emplace(Args &&... args)
Emplaces the element in the queue.
Definition: FifoQueue.hpp:95
std::chrono::time_point< TickClock > time_point
basic time_point type of clock
Definition: TickClock.hpp:42
~FifoQueue()
FifoQueue&#39;s destructor.
Definition: FifoQueue.hpp:677
FifoQueueBase class header.
int pop(const SemaphoreFunctor &waitSemaphoreFunctor, const QueueFunctor &functor)
Implementation of pop() using type-erased functor.
Definition: FifoQueueBase.hpp:74
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:594
int tryPop(T &value)
Tries to pop the oldest (first) element from the queue.
Definition: FifoQueue.hpp:297
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:317
int push(T &&value)
Pushes the element to the queue.
Definition: FifoQueue.hpp:153
BoundQueueFunctor class header.
internal::FifoQueueBase fifoQueueBase_
contained internal::FifoQueueBase object which implements whole functionality
Definition: FifoQueue.hpp:673
FifoQueueBase class implements basic functionality of FifoQueue template class.
Definition: FifoQueueBase.hpp:29
Top-level namespace of distortos project.
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:707
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:387
std::chrono::duration< rep, period > duration
basic duration type of clock
Definition: TickClock.hpp:39
SwapPopQueueFunctor class header.
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:343
int popInternal(const internal::SemaphoreFunctor &waitSemaphoreFunctor, T &value)
Pops the oldest (first) element from the queue.
Definition: FifoQueue.hpp:700
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:228
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:526
int push(const T &value)
Pushes the element to the queue.
Definition: FifoQueue.hpp:134
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:482
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:550
int tryEmplace(Args &&... args)
Tries to emplace the element in the queue.
Definition: FifoQueue.hpp:176
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:438
int push(const SemaphoreFunctor &waitSemaphoreFunctor, const QueueFunctor &functor)
Implementation of push() using type-erased functor.
Definition: FifoQueueBase.hpp:91
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:569
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:200
Definition: MoveConstructQueueFunctor.hpp:32