distortos  v0.5.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 
63  FifoQueue(StorageUniquePointer&& storageUniquePointer, const size_t maxElements) :
64  fifoQueueBase_{{storageUniquePointer.release(), storageUniquePointer.get_deleter()}, sizeof(T), maxElements}
65  {
66 
67  }
68 
75  ~FifoQueue();
76 
93  template<typename... Args>
94  int emplace(Args&&... args)
95  {
96  const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
97  return emplaceInternal(semaphoreWaitFunctor, std::forward<Args>(args)...);
98  }
99 
113  int pop(T& value)
114  {
115  const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
116  return popInternal(semaphoreWaitFunctor, value);
117  }
118 
131  int push(const T& value)
132  {
133  const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
134  return pushInternal(semaphoreWaitFunctor, value);
135  }
136 
150  int push(T&& value)
151  {
152  const internal::SemaphoreWaitFunctor semaphoreWaitFunctor;
153  return pushInternal(semaphoreWaitFunctor, std::move(value));
154  }
155 
170  template<typename... Args>
171  int tryEmplace(Args&&... args)
172  {
173  const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
174  return emplaceInternal(semaphoreTryWaitFunctor, std::forward<Args>(args)...);
175  }
176 
194  template<typename... Args>
195  int tryEmplaceFor(const TickClock::duration duration, Args&&... args)
196  {
197  const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
198  return emplaceInternal(semaphoreTryWaitForFunctor, std::forward<Args>(args)...);
199  }
200 
222  template<typename Rep, typename Period, typename... Args>
223  int tryEmplaceFor(const std::chrono::duration<Rep, Period> duration, Args&&... args)
224  {
225  return tryEmplaceFor(std::chrono::duration_cast<TickClock::duration>(duration), std::forward<Args>(args)...);
226  }
227 
245  template<typename... Args>
246  int tryEmplaceUntil(const TickClock::time_point timePoint, Args&&... args)
247  {
248  const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
249  return emplaceInternal(semaphoreTryWaitUntilFunctor, std::forward<Args>(args)...);
250  }
251 
272  template<typename Duration, typename... Args>
273  int tryEmplaceUntil(const std::chrono::time_point<TickClock, Duration> timePoint, Args&&... args)
274  {
275  return tryEmplaceUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint),
276  std::forward<Args>(args)...);
277  }
278 
290  int tryPop(T& value)
291  {
292  internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
293  return popInternal(semaphoreTryWaitFunctor, value);
294  }
295 
310  int tryPopFor(const TickClock::duration duration, T& value)
311  {
312  const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
313  return popInternal(semaphoreTryWaitForFunctor, value);
314  }
315 
335  template<typename Rep, typename Period>
336  int tryPopFor(const std::chrono::duration<Rep, Period> duration, T& value)
337  {
338  return tryPopFor(std::chrono::duration_cast<TickClock::duration>(duration), value);
339  }
340 
355  int tryPopUntil(const TickClock::time_point timePoint, T& value)
356  {
357  const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
358  return popInternal(semaphoreTryWaitUntilFunctor, value);
359  }
360 
379  template<typename Duration>
380  int tryPopUntil(const std::chrono::time_point<TickClock, Duration> timePoint, T& value)
381  {
382  return tryPopUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), value);
383  }
384 
395  int tryPush(const T& value)
396  {
397  const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
398  return pushInternal(semaphoreTryWaitFunctor, value);
399  }
400 
412  int tryPush(T&& value)
413  {
414  const internal::SemaphoreTryWaitFunctor semaphoreTryWaitFunctor;
415  return pushInternal(semaphoreTryWaitFunctor, std::move(value));
416  }
417 
431  int tryPushFor(const TickClock::duration duration, const T& value)
432  {
433  const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
434  return pushInternal(semaphoreTryWaitForFunctor, value);
435  }
436 
455  template<typename Rep, typename Period>
456  int tryPushFor(const std::chrono::duration<Rep, Period> duration, const T& value)
457  {
458  return tryPushFor(std::chrono::duration_cast<TickClock::duration>(duration), value);
459  }
460 
475  int tryPushFor(const TickClock::duration duration, T&& value)
476  {
477  const internal::SemaphoreTryWaitForFunctor semaphoreTryWaitForFunctor {duration};
478  return pushInternal(semaphoreTryWaitForFunctor, std::move(value));
479  }
480 
500  template<typename Rep, typename Period>
501  int tryPushFor(const std::chrono::duration<Rep, Period> duration, T&& value)
502  {
503  return tryPushFor(std::chrono::duration_cast<TickClock::duration>(duration), std::move(value));
504  }
505 
519  int tryPushUntil(const TickClock::time_point timePoint, const T& value)
520  {
521  const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
522  return pushInternal(semaphoreTryWaitUntilFunctor, value);
523  }
524 
542  template<typename Duration>
543  int tryPushUntil(const std::chrono::time_point<TickClock, Duration> timePoint, const T& value)
544  {
545  return tryPushUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), value);
546  }
547 
562  int tryPushUntil(const TickClock::time_point timePoint, T&& value)
563  {
564  const internal::SemaphoreTryWaitUntilFunctor semaphoreTryWaitUntilFunctor {timePoint};
565  return pushInternal(semaphoreTryWaitUntilFunctor, std::move(value));
566  }
567 
586  template<typename Duration>
587  int tryPushUntil(const std::chrono::time_point<TickClock, Duration> timePoint, T&& value)
588  {
589  return tryPushUntil(std::chrono::time_point_cast<TickClock::duration>(timePoint), std::move(value));
590  }
591 
592 private:
593 
611  template<typename... Args>
612  int emplaceInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, Args&&... args);
613 
628  int popInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, T& value);
629 
643  int pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, const T& value);
644 
659  int pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, T&& value);
660 
663 };
664 
665 template<typename T>
667 {
668  T value;
669  while (tryPop(value) == 0);
670 }
671 
672 template<typename T>
673 template<typename... Args>
674 int FifoQueue<T>::emplaceInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, Args&&... args)
675 {
676  const auto emplaceFunctor = internal::makeBoundQueueFunctor(
677  [&args...](void* const storage)
678  {
679  new (storage) T{std::forward<Args>(args)...};
680  });
681  return fifoQueueBase_.push(waitSemaphoreFunctor, emplaceFunctor);
682 }
683 
684 template<typename T>
685 int FifoQueue<T>::popInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, T& value)
686 {
687  const internal::SwapPopQueueFunctor<T> swapPopQueueFunctor {value};
688  return fifoQueueBase_.pop(waitSemaphoreFunctor, swapPopQueueFunctor);
689 }
690 
691 template<typename T>
692 int FifoQueue<T>::pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, const T& value)
693 {
694  const internal::CopyConstructQueueFunctor<T> copyConstructQueueFunctor {value};
695  return fifoQueueBase_.push(waitSemaphoreFunctor, copyConstructQueueFunctor);
696 }
697 
698 template<typename T>
699 int FifoQueue<T>::pushInternal(const internal::SemaphoreFunctor& waitSemaphoreFunctor, T&& value)
700 {
701  const internal::MoveConstructQueueFunctor<T> moveConstructQueueFunctor {std::move(value)};
702  return fifoQueueBase_.push(waitSemaphoreFunctor, moveConstructQueueFunctor);
703 }
704 
705 } // namespace distortos
706 
707 #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:246
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:273
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:355
SemaphoreTryWaitFunctor class header.
int tryPush(T &&value)
Tries to push the element to the queue.
Definition: FifoQueue.hpp:412
int tryPush(const T &value)
Tries to push the element to the queue.
Definition: FifoQueue.hpp:395
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:501
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:456
FifoQueue(StorageUniquePointer &&storageUniquePointer, const size_t maxElements)
FifoQueue&#39;s constructor.
Definition: FifoQueue.hpp:63
int emplaceInternal(const internal::SemaphoreFunctor &waitSemaphoreFunctor, Args &&... args)
Emplaces the element in the queue.
Definition: FifoQueue.hpp:674
typename std::aligned_storage< sizeof(OperationCountingType), alignof(OperationCountingType)>::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:113
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:94
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:666
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:587
int tryPop(T &value)
Tries to pop the oldest (first) element from the queue.
Definition: FifoQueue.hpp:290
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:310
int push(T &&value)
Pushes the element to the queue.
Definition: FifoQueue.hpp:150
BoundQueueFunctor class header.
internal::FifoQueueBase fifoQueueBase_
contained internal::FifoQueueBase object which implements whole functionality
Definition: FifoQueue.hpp:662
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:692
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:380
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:336
int popInternal(const internal::SemaphoreFunctor &waitSemaphoreFunctor, T &value)
Pops the oldest (first) element from the queue.
Definition: FifoQueue.hpp:685
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:223
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:519
int push(const T &value)
Pushes the element to the queue.
Definition: FifoQueue.hpp:131
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:475
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:543
int tryEmplace(Args &&... args)
Tries to emplace the element in the queue.
Definition: FifoQueue.hpp:171
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:431
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:562
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:195
Definition: MoveConstructQueueFunctor.hpp:32