ChimeraTK-cppext 01.05.02
Loading...
Searching...
No Matches
cppext::future_queue< T, FEATURES > Class Template Reference

A lockfree multi-producer single-consumer queue of a fixed length which the receiver can wait on in case the queue is empty. More...

#include <future_queue.hpp>

+ Inheritance diagram for cppext::future_queue< T, FEATURES >:
+ Collaboration diagram for cppext::future_queue< T, FEATURES >:

Public Types

typedefvalue_type
 

Public Member Functions

 future_queue (size_t length)
 The length specifies how many objects the queue can contain at a time.
 
 future_queue ()
 The default constructor creates only a place holder which can later be assigned with a properly constructed queue.
 
 future_queue (const future_queue &other)=default
 Copy constructor: After copying the object both *this and the other object will refer to the same queue.
 
future_queueoperator= (const future_queue &other)=default
 Copy assignment operator: After the assignment both *this and the other object will refer to the same queue.
 
template<typename U = T, typename std::enable_if< std::is_same< T, U >::value &&!std::is_same< U, void >::value, int >::type = 0>
bool push (U &&t)
 Push object t to the queue.
 
template<typename U = T, typename std::enable_if<!std::is_same< U, void >::value &&std::is_copy_constructible< T >::value, int >::type = 0>
bool push (const U &t)
 This push() is for non-void data types passed by Lvalue reference.
 
bool push (void)
 This version of push() is valid only for T=void.
 
template<typename U = T, typename std::enable_if< std::is_same< T, U >::value &&!std::is_same< U, void >::value, int >::type = 0>
bool push_overwrite (U &&t)
 Push object t to the queue.
 
template<typename U = T, typename std::enable_if<!std::is_same< U, void >::value &&std::is_copy_constructible< T >::value, int >::type = 0>
bool push_overwrite (const U &t)
 This push_overwrite() is for non-void data types passed by Lvalue reference.
 
bool push_overwrite ()
 This version of push_overwrite() is valid only for T=void.
 
template<typename U = T, typename std::enable_if< std::is_same< T, U >::value &&!std::is_same< U, void >::value, int >::type = 0>
bool pop (U &t)
 Pop object off the queue and store it in t.
 
bool pop ()
 This pop() is for all data types (for non-void data types the value will be discarded)
 
template<typename U = T, typename std::enable_if< std::is_same< T, U >::value &&!std::is_same< U, void >::value, int >::type = 0>
void pop_wait (U &t)
 Pop object off the queue and store it in t.
 
void pop_wait ()
 This pop_wait() is for all data types (for non-void data types the value will be discarded)
 
template<typename U = T, typename std::enable_if< std::is_same< T, U >::value &&!std::is_same< U, void >::value, int >::type = 0>
Ufront ()
 Obtain the front element of the queue without removing it.
 
template<typename U = T, typename std::enable_if< std::is_same< T, U >::value &&std::is_same< U, void >::value, int >::type = 0>
void front () const
 This front() is for void data types.
 
template<typename T2 , typename FEATURES2 = MOVE_DATA, typename CALLABLE >
future_queue< T2, FEATURES2then (CALLABLE callable, std::launch policy=std::launch::async)
 Add continuation: Whenever there is a new element in the queue, process it with the callable and put the result into a new queue.
 
- Public Member Functions inherited from cppext::future_queue_base
size_t write_available () const
 Number of push operations which can be performed before the queue is full.
 
size_t read_available () const
 Number of pop operations which can be performed before the queue is empty.
 
bool push_exception (std::exception_ptr exception)
 Push an exception pointer (inplace of a value) into the queue.
 
bool push_overwrite_exception (std::exception_ptr exception)
 Like push_exception() but overwrite the last pushed value in case the queue is full.
 
bool empty ()
 Check if there is currently no data on the queue.
 
void wait ()
 Wait until the queue is not empty.
 
size_t size () const
 return length of the queue
 
bool operator== (const future_queue_base &other) const
 Check whether two future_queue instances use the same shared state, i.e.
 
bool operator!= (const future_queue_base &other) const
 

Additional Inherited Members

- Protected Member Functions inherited from cppext::future_queue_base
 future_queue_base (const detail::shared_state_ptr &d_ptr_)
 
 future_queue_base ()
 
bool obtain_write_slot (size_t &index)
 reserve next available write slot.
 
void update_read_index_max ()
 update readIndexMax after a write operation was completed
 
size_t setNotificationQueue (future_queue< size_t, MOVE_DATA > &notificationQueue, size_t indexToSend)
 Set the notification queue in the shared state, as done in when_any.
 
cppext::detail::shared_state_baseget_notification_queue ()
 Atomically return the notification queue or increment the "previous data" counter (for wait_any).
 
void send_notification (cppext::detail::shared_state_base *notification_queue)
 Send notification to notification queue (if not nullptr).
 
void decrement_previous_data_counter ()
 Decrement the "previous data" counter used in when_any().
 
- Protected Attributes inherited from cppext::future_queue_base
detail::shared_state_ptr d
 pointer to data used to allow sharing the queue (create multiple copies which all refer to the same queue).
 

Detailed Description

template<typename T, typename FEATURES = MOVE_DATA>
class cppext::future_queue< T, FEATURES >

A lockfree multi-producer single-consumer queue of a fixed length which the receiver can wait on in case the queue is empty.

This is similiar like using a lockfree queue of futures but has better performance. In addition the queue allows the sender to overwrite the last written element in case the queue is full. The receiver can also use the function when_any() to get notified when any of the given future_queues is not empty.

The template parameter T specifies the type of the user data stored in the queue. The optional second template parameter takes one of the feature tags. Currently two options are supported:

  • MOVE_DATA (default): Type T must have a move constructor. To place objects on the queue and to retrieve them from the queue, a move operation is performed.
  • SWAP_DATA: The function std::swap() must be overloaded for the type T. When placing objects on the queue, std::swap() is called to exchange the new object with the object currently on the internal queue buffer. This allows avoiding unnecessary memory allocations e.g. when storing std::vector on the queue, especially if all vectors have the same size.

In both cases, T must be default constructible. Upon creation of the queue all internal buffers will be filled with default constructed elements.

Definition at line 229 of file future_queue.hpp.

Member Typedef Documentation

◆ value_type

template<typename T , typename FEATURES = MOVE_DATA>
typedef T cppext::future_queue< T, FEATURES >::value_type

Definition at line 332 of file future_queue.hpp.

Constructor & Destructor Documentation

◆ future_queue() [1/3]

template<typename T , typename FEATURES >
cppext::future_queue< T, FEATURES >::future_queue ( size_t  length)

The length specifies how many objects the queue can contain at a time.

Implementation of future_queue.

Internally additional buffers will be allocated-> All buffers are allocated upon construction, so no dynamic memory allocation is required later.

Definition at line 970 of file future_queue.hpp.

◆ future_queue() [2/3]

template<typename T , typename FEATURES >
cppext::future_queue< T, FEATURES >::future_queue ( )

The default constructor creates only a place holder which can later be assigned with a properly constructed queue.

Definition at line 973 of file future_queue.hpp.

◆ future_queue() [3/3]

template<typename T , typename FEATURES = MOVE_DATA>
cppext::future_queue< T, FEATURES >::future_queue ( const future_queue< T, FEATURES > &  other)
default

Copy constructor: After copying the object both *this and the other object will refer to the same queue.

Member Function Documentation

◆ front() [1/2]

template<typename T , typename FEATURES >
template<typename U , typename std::enable_if< std::is_same< T, U >::value &&!std::is_same< U, void >::value, int >::type >
U & cppext::future_queue< T, FEATURES >::front ( )

Obtain the front element of the queue without removing it.

Various implementations of front().

It is mandatory to make sure that data is available in the queue by calling empty() before calling this function.

Note: No const variant exists, since empty() already changes the state of the queue internally (to acquire ownership on the front element, so push_overwrite() can no longer overwrite it). Without a const variant of empty(), a const variant of front() would be unusable.

This front() is for non-void data types and a non-const *this

Definition at line 1206 of file future_queue.hpp.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ front() [2/2]

template<typename T , typename FEATURES >
template<typename U , typename std::enable_if< std::is_same< T, U >::value &&std::is_same< U, void >::value, int >::type >
void cppext::future_queue< T, FEATURES >::front ( ) const

This front() is for void data types.

Definition at line 1215 of file future_queue.hpp.

◆ operator=()

template<typename T , typename FEATURES = MOVE_DATA>
future_queue & cppext::future_queue< T, FEATURES >::operator= ( const future_queue< T, FEATURES > &  other)
default

Copy assignment operator: After the assignment both *this and the other object will refer to the same queue.

◆ pop() [1/2]

This pop() is for all data types (for non-void data types the value will be discarded)

Definition at line 1133 of file future_queue.hpp.

◆ pop() [2/2]

template<typename T , typename FEATURES >
template<typename U , typename std::enable_if< std::is_same< T, U >::value &&!std::is_same< U, void >::value, int >::type >
bool cppext::future_queue< T, FEATURES >::pop ( U t)

Pop object off the queue and store it in t.

Various implementations of pop().

If no data is available, false is returned

This pop() is for non-void data types

Definition at line 1105 of file future_queue.hpp.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pop_wait() [1/2]

template<typename T , typename FEATURES >
void cppext::future_queue< T, FEATURES >::pop_wait ( )

This pop_wait() is for all data types (for non-void data types the value will be discarded)

Definition at line 1182 of file future_queue.hpp.

◆ pop_wait() [2/2]

template<typename T , typename FEATURES >
template<typename U , typename std::enable_if< std::is_same< T, U >::value &&!std::is_same< U, void >::value, int >::type >
void cppext::future_queue< T, FEATURES >::pop_wait ( U t)

Pop object off the queue and store it in t.

This pop_void() is for non-void data types.

This function will block until data is available.

Definition at line 1157 of file future_queue.hpp.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ push() [1/3]

template<typename T , typename FEATURES >
template<typename U , typename std::enable_if<!std::is_same< U, void >::value &&std::is_copy_constructible< T >::value, int >::type >
bool cppext::future_queue< T, FEATURES >::push ( const U t)

This push() is for non-void data types passed by Lvalue reference.

Definition at line 1007 of file future_queue.hpp.

◆ push() [2/3]

template<typename T , typename FEATURES >
template<typename U , typename std::enable_if< std::is_same< T, U >::value &&!std::is_same< U, void >::value, int >::type >
bool cppext::future_queue< T, FEATURES >::push ( U &&  t)

Push object t to the queue.

Various implementations of push().

Returns true if successful and false if queue is full.

This push() is for non-void data types passed by Rvalue reference

Definition at line 981 of file future_queue.hpp.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ push() [3/3]

template<typename T , typename FEATURES >
bool cppext::future_queue< T, FEATURES >::push ( void  )

This version of push() is valid only for T=void.

This push() is for void data type.

Definition at line 1015 of file future_queue.hpp.

◆ push_overwrite() [1/3]

template<typename T , typename FEATURES = MOVE_DATA>
bool cppext::future_queue< T, FEATURES >::push_overwrite ( )

This version of push_overwrite() is valid only for T=void.

◆ push_overwrite() [2/3]

template<typename T , typename FEATURES >
template<typename U , typename std::enable_if<!std::is_same< U, void >::value &&std::is_copy_constructible< T >::value, int >::type >
bool cppext::future_queue< T, FEATURES >::push_overwrite ( const U t)

This push_overwrite() is for non-void data types passed by Lvalue reference.

Definition at line 1093 of file future_queue.hpp.

◆ push_overwrite() [3/3]

template<typename T , typename FEATURES >
template<typename U , typename std::enable_if< std::is_same< T, U >::value &&!std::is_same< U, void >::value, int >::type >
bool cppext::future_queue< T, FEATURES >::push_overwrite ( U &&  t)

Push object t to the queue.

This push_overwrite() is for non-void data types passed by Rvalue reference.

If the queue is full, the last element will be overwritten and false will be returned. If no data had to be overwritten, true is returned.

When using this function, the queue must have a length of at least 2.

Note: when used in a multi-producer context and false is returned, it is not defined whether other data or data written in this call to push_overwrite() has been discarded.

Definition at line 1042 of file future_queue.hpp.

+ Here is the call graph for this function:

◆ then()

template<typename T , typename FEATURES >
future_queue< T2, FEATURES2 > cppext::future_queue< T, FEATURES >::then ( CALLABLE  callable,
std::launch  policy = std::launch::async 
)

Add continuation: Whenever there is a new element in the queue, process it with the callable and put the result into a new queue.

The new queue will be returned by this function.

The signature of the callable must be "T2(T)", i.e. it has a single argument of the value type T of the queue then() is called on, and the return type matches the value type of the returned queue.

Two different launch policies can be selected:

  • std::launch::async will launch a new thread and trigger data processing asynchronously in the background. Each value will be processed in the order they are pushed to the queue and in the same thread.
  • std::launch::deferred will defer data processing until the data is accessed on the resulting queue. Checking the presence through empty() is already counted an access. If the same data is accessed multiple times (e.g. by calling front() several times), the callable is only executed once. If neither std::launch::async (which is the default) nor std::launch::deferred is specified, the behaviour is undefined.

Definition at line 1592 of file future_queue.hpp.

+ Here is the call graph for this function:

The documentation for this class was generated from the following file: