density
C++11 library for paged memory management, function queues, heterogeneous queues and lifo memory management
Classes | Public Types | Public Member Functions | Static Public Attributes | Friends | List of all members
sp_heter_queue< RUNTIME_TYPE, ALLOCATOR_TYPE, PROD_CARDINALITY, CONSUMER_CARDINALITY, BUSY_WAIT_FUNC > Class Template Reference

#include <sp_heter_queue.h>

Classes

class  consume_operation
 
class  put_transaction
 
class  reentrant_consume_operation
 
class  reentrant_put_transaction
 

Public Types

using runtime_type = RUNTIME_TYPE
 
using value_type = std::pair< const runtime_type &, void *const >
 
using allocator_type = ALLOCATOR_TYPE
 
using pointer = value_type *
 
using const_pointer = const value_type *
 
using reference = value_type
 
using const_reference = const value_type &
 
using size_type = std::size_t
 
using difference_type = std::ptrdiff_t
 

Public Member Functions

constexpr sp_heter_queue () noexcept=default
 
constexpr sp_heter_queue (const ALLOCATOR_TYPE &i_source_allocator) noexcept
 
constexpr sp_heter_queue (ALLOCATOR_TYPE &&i_source_allocator) noexcept
 
constexpr sp_heter_queue (const ALLOCATOR_TYPE &i_source_allocator, const BUSY_WAIT_FUNC &i_source_wait) noexcept
 
constexpr sp_heter_queue (ALLOCATOR_TYPE &&i_source_allocator, const BUSY_WAIT_FUNC &i_source_wait) noexcept
 
constexpr sp_heter_queue (const ALLOCATOR_TYPE &i_source_allocator, BUSY_WAIT_FUNC &&i_source_wait) noexcept
 
constexpr sp_heter_queue (ALLOCATOR_TYPE &&i_source_allocator, BUSY_WAIT_FUNC &&i_source_wait) noexcept
 
 sp_heter_queue (sp_heter_queue &&i_source) noexcept=default
 
sp_heter_queueoperator= (sp_heter_queue &&i_source) noexcept
 
allocator_type get_allocator () noexcept(std::is_nothrow_copy_constructible< allocator_type >::value)
 
allocator_type & get_allocator_ref () noexcept
 
const allocator_type & get_allocator_ref () const noexcept
 
 ~sp_heter_queue ()
 
bool empty () const noexcept
 
void clear () noexcept
 
template<typename ELEMENT_TYPE >
void push (ELEMENT_TYPE &&i_source)
 
template<typename ELEMENT_TYPE , typename... CONSTRUCTION_PARAMS>
void emplace (CONSTRUCTION_PARAMS &&...i_construction_params)
 
void dyn_push (const runtime_type &i_type)
 
void dyn_push_copy (const runtime_type &i_type, const void *i_source)
 
void dyn_push_move (const runtime_type &i_type, void *i_source)
 
template<typename ELEMENT_TYPE >
put_transaction< typename std::decay< ELEMENT_TYPE >::type > start_push (ELEMENT_TYPE &&i_source)
 
template<typename ELEMENT_TYPE , typename... CONSTRUCTION_PARAMS>
put_transaction< ELEMENT_TYPE > start_emplace (CONSTRUCTION_PARAMS &&...i_construction_params)
 
put_transaction start_dyn_push (const runtime_type &i_type)
 
put_transaction start_dyn_push_copy (const runtime_type &i_type, const void *i_source)
 
put_transaction start_dyn_push_move (const runtime_type &i_type, void *i_source)
 
template<typename ELEMENT_TYPE >
bool try_push (progress_guarantee i_progress_guarantee, ELEMENT_TYPE &&i_source) noexcept( noexcept(std::declval< sp_heter_queue >() .template try_emplace< typename std::decay< ELEMENT_TYPE >::type >( i_progress_guarantee, std::forward< ELEMENT_TYPE >(i_source))))
 
template<typename ELEMENT_TYPE , typename... CONSTRUCTION_PARAMS>
bool try_emplace (progress_guarantee i_progress_guarantee, CONSTRUCTION_PARAMS &&...i_construction_params) noexcept( noexcept(std::declval< sp_heter_queue >().template try_start_emplace< ELEMENT_TYPE >( i_progress_guarantee, std::forward< CONSTRUCTION_PARAMS >(i_construction_params)...)))
 
bool try_dyn_push (progress_guarantee i_progress_guarantee, const runtime_type &i_type)
 
bool try_dyn_push_copy (progress_guarantee i_progress_guarantee, const runtime_type &i_type, const void *i_source)
 
bool try_dyn_push_move (progress_guarantee i_progress_guarantee, const runtime_type &i_type, void *i_source)
 
template<typename ELEMENT_TYPE >
put_transaction< typename std::decay< ELEMENT_TYPE >::type > try_start_push (progress_guarantee i_progress_guarantee, ELEMENT_TYPE &&i_source) noexcept(noexcept(std::declval< sp_heter_queue >() .template try_start_emplace< typename std::decay< ELEMENT_TYPE >::type >( i_progress_guarantee, std::forward< ELEMENT_TYPE >(i_source))))
 
template<typename ELEMENT_TYPE , typename... CONSTRUCTION_PARAMS>
put_transaction< ELEMENT_TYPE > try_start_emplace (progress_guarantee i_progress_guarantee, CONSTRUCTION_PARAMS &&...i_construction_params) noexcept( noexcept(ELEMENT_TYPE(std::forward< CONSTRUCTION_PARAMS >(i_construction_params)...))&& noexcept(runtime_type(runtime_type::template make< ELEMENT_TYPE >())))
 
put_transaction try_start_dyn_push (progress_guarantee i_progress_guarantee, const runtime_type &i_type)
 
put_transaction try_start_dyn_push_copy (progress_guarantee i_progress_guarantee, const runtime_type &i_type, const void *i_source)
 
put_transaction try_start_dyn_push_move (progress_guarantee i_progress_guarantee, const runtime_type &i_type, void *i_source)
 
bool try_pop () noexcept
 
consume_operation try_start_consume () noexcept
 
bool try_start_consume (consume_operation &i_consume) noexcept
 
template<typename ELEMENT_TYPE >
void reentrant_push (ELEMENT_TYPE &&i_source)
 
template<typename ELEMENT_TYPE , typename... CONSTRUCTION_PARAMS>
void reentrant_emplace (CONSTRUCTION_PARAMS &&...i_construction_params)
 
void reentrant_dyn_push (const runtime_type &i_type)
 
void reentrant_dyn_push_copy (const runtime_type &i_type, const void *i_source)
 
void reentrant_dyn_push_move (const runtime_type &i_type, void *i_source)
 
template<typename ELEMENT_TYPE >
reentrant_put_transaction< typename std::decay< ELEMENT_TYPE >::type > start_reentrant_push (ELEMENT_TYPE &&i_source)
 
template<typename ELEMENT_TYPE , typename... CONSTRUCTION_PARAMS>
reentrant_put_transaction< ELEMENT_TYPE > start_reentrant_emplace (CONSTRUCTION_PARAMS &&...i_construction_params)
 
reentrant_put_transaction start_reentrant_dyn_push (const runtime_type &i_type)
 
reentrant_put_transaction start_reentrant_dyn_push_copy (const runtime_type &i_type, const void *i_source)
 
reentrant_put_transaction start_reentrant_dyn_push_move (const runtime_type &i_type, void *i_source)
 
template<typename ELEMENT_TYPE >
bool try_reentrant_push (progress_guarantee i_progress_guarantee, ELEMENT_TYPE &&i_source) noexcept(noexcept(std::declval< sp_heter_queue >() .template try_reentrant_emplace< typename std::decay< ELEMENT_TYPE >::type >( i_progress_guarantee, std::forward< ELEMENT_TYPE >(i_source))))
 
template<typename ELEMENT_TYPE , typename... CONSTRUCTION_PARAMS>
bool try_reentrant_emplace (progress_guarantee i_progress_guarantee, CONSTRUCTION_PARAMS &&...i_construction_params) noexcept( noexcept( std::declval< sp_heter_queue >().template try_start_reentrant_emplace< ELEMENT_TYPE >( i_progress_guarantee, std::forward< CONSTRUCTION_PARAMS >(i_construction_params)...)))
 
bool try_reentrant_dyn_push (progress_guarantee i_progress_guarantee, const runtime_type &i_type)
 
bool try_reentrant_dyn_push_copy (progress_guarantee i_progress_guarantee, const runtime_type &i_type, const void *i_source)
 
bool try_reentrant_dyn_push_move (progress_guarantee i_progress_guarantee, const runtime_type &i_type, void *i_source)
 
template<typename ELEMENT_TYPE >
reentrant_put_transaction< typename std::decay< ELEMENT_TYPE >::type > try_start_reentrant_push (progress_guarantee i_progress_guarantee, ELEMENT_TYPE &&i_source) noexcept(noexcept(std::declval< sp_heter_queue >() .template try_start_reentrant_emplace< typename std::decay< ELEMENT_TYPE >::type >( i_progress_guarantee, std::forward< ELEMENT_TYPE >(i_source))))
 
template<typename ELEMENT_TYPE , typename... CONSTRUCTION_PARAMS>
reentrant_put_transaction< ELEMENT_TYPE > try_start_reentrant_emplace (progress_guarantee i_progress_guarantee, CONSTRUCTION_PARAMS &&...i_construction_params) noexcept( noexcept(ELEMENT_TYPE(std::forward< CONSTRUCTION_PARAMS >(i_construction_params)...))&& noexcept(runtime_type(runtime_type::template make< ELEMENT_TYPE >())))
 
reentrant_put_transaction try_start_reentrant_dyn_push (progress_guarantee i_progress_guarantee, const runtime_type &i_type)
 
reentrant_put_transaction try_start_reentrant_dyn_push_copy (progress_guarantee i_progress_guarantee, const runtime_type &i_type, const void *i_source)
 
reentrant_put_transaction try_start_reentrant_dyn_push_move (progress_guarantee i_progress_guarantee, const runtime_type &i_type, void *i_source)
 
bool try_reentrant_pop () noexcept
 
reentrant_consume_operation try_start_reentrant_consume () noexcept
 
bool try_start_reentrant_consume (reentrant_consume_operation &i_consume) noexcept
 

Static Public Attributes

static constexpr size_t min_alignment = Base::min_alignment
 
static constexpr bool concurrent_puts = PROD_CARDINALITY == concurrency_multiple
 
static constexpr bool concurrent_consumes = CONSUMER_CARDINALITY == concurrency_multiple
 
static constexpr bool concurrent_put_consumes = true
 
static constexpr bool is_seq_cst = true
 

Friends

void swap (sp_heter_queue &i_first, sp_heter_queue &i_second) noexcept
 

Detailed Description

template<typename RUNTIME_TYPE = runtime_type<>, typename ALLOCATOR_TYPE = default_allocator, concurrency_cardinality PROD_CARDINALITY = concurrency_multiple, concurrency_cardinality CONSUMER_CARDINALITY = concurrency_multiple, typename BUSY_WAIT_FUNC = default_busy_wait>
class density::sp_heter_queue< RUNTIME_TYPE, ALLOCATOR_TYPE, PROD_CARDINALITY, CONSUMER_CARDINALITY, BUSY_WAIT_FUNC >

Concurrent heterogeneous FIFO container-like class template. sp_heter_queue is a concurrent version of heter_queue that uses a mix of lock free algorithms and spin locking. This class is very similar to lf_heter_queue, with the difference in multiple-producers mode it uses a spin-locking mutex to synchronize the write to the tail pointer.

Implementation note: In single-producer mode this class template is equivalent to lf_heter_queue, and the busy-wait function is not used.

Template Parameters
RUNTIME_TYPERuntime-type object used to store the actual complete type of each element. This type must satisfy the requirements of RuntimeType. The default is runtime_type.
ALLOCATOR_TYPEAllocator type to be used. This type must satisfy the requirements of both UntypedAllocator and PagedAllocator. The default is density::default_allocator.
PROD_CARDINALITYspecifies whether multiple threads can do put transactions concurrently. Must be a member of density::concurrency_cardinality.
CONSUMER_CARDINALITYspecifies whether multiple threads can do consume operations concurrently. Must be a member of density::concurrency_cardinality.
BUSY_WAIT_FUNCcallable object to be invoked (with an empty parameter list) in the body of the spin lock. The default is density::default_busy_wait, that calls std::this_thread::yield.


Thread safeness: A thread doing put operations and another thread doing consumes don't need to be synchronized. If PROD_CARDINALITY is concurrency_multiple, multiple threads are allowed to put without any synchronization. If CONSUMER_CARDINALITY is concurrency_multiple, multiple threads are allowed to consume without any synchronization.
Exception safeness: Any function of sp_heter_queue is noexcept or provides the strong exception guarantee.

The default allocator, default_allocator, delegates legacy memory operations to the system. Since the storage elements whose size exceeds a fixed limit can't be allocated in a page, they require a legacy memory allocation, and in this case the put can't be lock-free.

This class template provides all the put functions provided by heter_queue, and furthermore it adds the try_ variants, that:

Also raw allocation functions have the try_ versions. They do not throw in case of failure, but just return null.

This table shows all the put functions supported by sp_heter_queue:

Put functions
Group Normal Transactional Reentrant Transactional-Reentrant Type binding Constructor
push Compile time Copy/Move
emplace Compile time Any
dynamic push Runtime Default
dynamic push (copy) Runtime Copy
dynamic push (move) Runtime Move
try push Compile time Copy/Move
try emplace Compile time Any
try dynamic push Runtime Default
try dynamic push (copy) Runtime Copy
try dynamic push (move) Runtime Move

Constructor & Destructor Documentation

constexpr sp_heter_queue ( )
defaultnoexcept

Default constructor. The allocator is default-constructed.

Complexity: constant.
Throws: nothing.
Exception guarantee: strong (in case of exception the function has no observable effects).
Implementation notes: This constructor does not allocate memory and never throws.

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
SpQueue queue;
assert(queue.empty());
constexpr sp_heter_queue ( const ALLOCATOR_TYPE &  i_source_allocator)
inlineexplicitnoexcept

Constructor with allocator parameter. The allocator is copy-constructed.

Parameters
i_source_allocatorsource used to copy-construct the allocator.

Complexity: constant.
Throws: whatever the copy constructor of the allocator throws.
Exception guarantee: strong (in case of exception the function has no observable effects).
Implementation notes: This constructor does not allocate memory. It throws anything the copy constructor of the allocator throws.

default_allocator allocator;
using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
SpQueue queue(allocator);
assert(queue.empty());
constexpr sp_heter_queue ( ALLOCATOR_TYPE &&  i_source_allocator)
inlineexplicitnoexcept

Constructor with allocator parameter. The allocator is move-constructed.

Parameters
i_source_allocatorsource used to move-construct the allocator.

Complexity: constant.
Throws: nothing.
Exception guarantee: strong (in case of exception the function has no observable effects).
Implementation notes: This constructor does not allocate memory. It throws anything the move constructor of the allocator throws.

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
default_allocator allocator;
SpQueue queue(std::move(allocator));
assert(queue.empty());
constexpr sp_heter_queue ( const ALLOCATOR_TYPE &  i_source_allocator,
const BUSY_WAIT_FUNC &  i_source_wait 
)
inlinenoexcept

Constructor with allocator and busy-wait callable.

Parameters
i_source_allocatorsource used to copy-construct the allocator.
i_source_waitsource used to copy-construct the busy wait callable.

Complexity: constant.
Throws: whatever the copy constructor of the allocator throws.
Exception guarantee: strong (in case of exception the function has no observable effects).
Implementation notes: This constructor does not allocate memory. It throws anything the copy constructor of the allocator throws.

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
default_allocator allocator;
default_busy_wait busy_wait;
SpQueue queue(allocator, busy_wait);
assert(queue.empty());
constexpr sp_heter_queue ( ALLOCATOR_TYPE &&  i_source_allocator,
const BUSY_WAIT_FUNC &  i_source_wait 
)
inlinenoexcept

Constructor with allocator and busy-wait callable.

Parameters
i_source_allocatorsource used to move-construct the allocator.
i_source_waitsource used to copy-construct the busy wait callable.

Complexity: constant.
Throws: nothing.
Exception guarantee: strong (in case of exception the function has no observable effects).
Implementation notes: This constructor does not allocate memory. It throws anything the move constructor of the allocator throws.

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
default_allocator allocator;
default_busy_wait busy_wait;
SpQueue queue(std::move(allocator), busy_wait);
assert(queue.empty());
constexpr sp_heter_queue ( const ALLOCATOR_TYPE &  i_source_allocator,
BUSY_WAIT_FUNC &&  i_source_wait 
)
inlinenoexcept

Constructor with allocator and busy-wait callable.

Parameters
i_source_allocatorsource used to copy-construct the allocator.
i_source_waitsource used to copy-construct the busy wait callable.

Complexity: constant.
Throws: whatever the copy constructor of the allocator throws.
Exception guarantee: strong (in case of exception the function has no observable effects).
Implementation notes: This constructor does not allocate memory. It throws anything the copy constructor of the allocator throws.

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
default_allocator allocator;
default_busy_wait busy_wait;
SpQueue queue(allocator, std::move(busy_wait));
assert(queue.empty());
constexpr sp_heter_queue ( ALLOCATOR_TYPE &&  i_source_allocator,
BUSY_WAIT_FUNC &&  i_source_wait 
)
inlinenoexcept

Constructor with allocator and busy-wait callable.

Parameters
i_source_allocatorsource used to move-construct the allocator.
i_source_waitsource used to copy-construct the busy wait callable.

Complexity: constant.
Throws: nothing.
Exception guarantee: strong (in case of exception the function has no observable effects).
Implementation notes: This constructor does not allocate memory. It throws anything the move constructor of the allocator throws.

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
default_allocator allocator;
default_busy_wait busy_wait;
SpQueue queue(std::move(allocator), std::move(busy_wait));
assert(queue.empty());
sp_heter_queue ( sp_heter_queue< RUNTIME_TYPE, ALLOCATOR_TYPE, PROD_CARDINALITY, CONSUMER_CARDINALITY, BUSY_WAIT_FUNC > &&  i_source)
defaultnoexcept

Move constructor. The allocator is move-constructed from the one of the source.

Parameters
i_sourcesource to move the elements from. After the call the source is left in some valid but indeterminate state.

Complexity: constant.
Throws: nothing.
Implementation notes:

  • After the call the source is left empty.
using MyRunTimeType = runtime_type<
f_default_construct,
f_copy_construct,
f_destroy,
f_size,
f_alignment,
f_equal>;
sp_heter_queue<MyRunTimeType> queue;
queue.push(std::string());
queue.push(std::make_pair(4., 1));
sp_heter_queue<MyRunTimeType> queue_1(std::move(queue));
assert(queue.empty());
assert(!queue_1.empty());
~sp_heter_queue ( )
inline

Destructor.

Complexity: linear.
Effects on iterators: any iterator pointing to this queue is invalidated.
Throws: Nothing.

Member Function Documentation

sp_heter_queue& operator= ( sp_heter_queue< RUNTIME_TYPE, ALLOCATOR_TYPE, PROD_CARDINALITY, CONSUMER_CARDINALITY, BUSY_WAIT_FUNC > &&  i_source)
inlinenoexcept

Move assignment. The allocator is move-assigned from the one of the source.

Parameters
i_sourcesource to move the elements from. After the call the source is left in some valid but indeterminate state.

Complexity: Unspecified.
Effects on iterators: Any iterator pointing to this queue or to the source queue is invalidated.
Throws: Nothing.


Implementation notes:

  • After the call the source is left empty.
  • The complexity is linear in the number of elements in this queue.
using MyRunTimeType = runtime_type<
f_default_construct,
f_copy_construct,
f_destroy,
f_size,
f_alignment,
f_equal>;
using SpQueue =
sp_heter_queue<MyRunTimeType, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
SpQueue queue;
queue.push(std::string("abc"));
queue.push(std::make_pair(4., 1));
SpQueue queue_1;
queue_1 = std::move(queue);
assert(queue.empty());
assert(!queue_1.empty());
allocator_type get_allocator ( )
inlinenoexcept

Returns a copy of the allocator

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
SpQueue queue;
assert(queue.get_allocator() == default_allocator());
allocator_type& get_allocator_ref ( )
inlinenoexcept

Returns a reference to the allocator

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
SpQueue queue;
assert(queue.get_allocator_ref() == default_allocator());
const allocator_type& get_allocator_ref ( ) const
inlinenoexcept

Returns a const reference to the allocator

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
SpQueue queue;
auto const & queue_ref = queue;
assert(queue_ref.get_allocator_ref() == default_allocator());
bool empty ( ) const
inlinenoexcept

Returns whether the queue contains no elements.

Complexity: Unspecified.
Throws: Nothing.

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
SpQueue queue;
assert(queue.empty());
queue.push(1);
assert(!queue.empty());
void clear ( )
inlinenoexcept

Deletes all the elements in the queue.

Complexity: linear.
Effects on iterators: any iterator is invalidated
Throws: Nothing.

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
SpQueue queue;
queue.push(1);
queue.clear();
assert(queue.empty());
void push ( ELEMENT_TYPE &&  i_source)
inline

Appends at the end of the queue an element of type ELEMENT_TYPE, copy-constructing or move-constructing it from the source.

Parameters
i_sourceobject to be used as source to construct of new element.
  • If this argument is an l-value, the new element copy-constructed
  • If this argument is an r-value, the new element move-constructed


Requires:

  • ELEMENT_TYPE must be copy constructible (in case of l-value) or move constructible (in case of r-value)

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: unspecified.
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

using SpQueue = sp_heter_queue<
runtime_type<>,
PROD_CARDINALITY,
CONSUMER_CARDINALITY>;
SpQueue queue;
queue.push(12);
queue.push(std::string("Hello world!!"));
void emplace ( CONSTRUCTION_PARAMS &&...  i_construction_params)
inline

Appends at the end of the queue an element of type ELEMENT_TYPE, in-place-constructing it from a perfect forwarded parameter pack.
Note: the template argument ELEMENT_TYPE can't be deduced from the parameters so it must explicitly specified.

Parameters
i_construction_paramsconstruction parameters for the new element.


Requires:

  • ELEMENT_TYPE must be constructible with std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: unspecified.
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

using SpQueue = sp_heter_queue<
runtime_type<>,
PROD_CARDINALITY,
CONSUMER_CARDINALITY>;
SpQueue queue;
queue.template emplace<int>();
queue.template emplace<std::string>(12, '-');
void dyn_push ( const runtime_type &  i_type)
inline

Adds at the end of the queue an element of a type known at runtime, default-constructing it.

Parameters
i_typetype of the new element.


Requires:

  • The function RUNTIME_TYPE::default_construct must be invokable. If RUNTIMETYPE is runtime_type this means that default_construct must be included in the feature list.

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: unspecified.
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

using MyRunTimeType = runtime_type<f_default_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>
queue;
auto const type = MyRunTimeType::template make<int>();
queue.dyn_push(type); // appends 0
void dyn_push_copy ( const runtime_type &  i_type,
const void *  i_source 
)
inline

Appends at the end of the queue an element of a type known at runtime, copy-constructing it from the source.

Parameters
i_typetype of the new element.
i_sourcepointer to the object to use as source. If this pointer does dot point to an object whose dynamic type is the target type i_type was bound to, the behavior is undefined.


Requires:

  • The function RUNTIME_TYPE::copy_construct must be invokable. If RUNTIMETYPE is runtime_type this means that copy_construct must be included in the feature list.

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: unspecified.
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

using MyRunTimeType = runtime_type<f_copy_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>
queue;
std::string const source("Hello world!!");
auto const type = MyRunTimeType::make<decltype(source)>();
queue.dyn_push_copy(type, &source);
void dyn_push_move ( const runtime_type &  i_type,
void *  i_source 
)
inline

Adds at the end of the queue an element of a type known at runtime, move-constructing it from the source.

Parameters
i_typetype of the new element
i_sourcepointer to the object to use as source. If this pointer does dot point to an object whose dynamic type is the target type i_type was bound to, the behavior is undefined.


Requires:

  • The function RUNTIME_TYPE::move_construct must be invokable. If RUNTIMETYPE is runtime_type this means that move_construct must be included in the feature list.

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: unspecified.
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

using MyRunTimeType = runtime_type<f_move_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>
queue;
std::string source("Hello world!!");
auto const type = MyRunTimeType::make<decltype(source)>();
queue.dyn_push_move(type, &source);
put_transaction<typename std::decay<ELEMENT_TYPE>::type> start_push ( ELEMENT_TYPE &&  i_source)
inline

Begins a transaction that appends an element of type ELEMENT_TYPE, copy-constructing or move-constructing it from the source.
This function allocates the required space, constructs the new element, and returns a transaction object that may be used to allocate raw space associated to the element being inserted, or to alter the element in some way.
Call the member function commit on the returned transaction in order to make the effects observable. If the transaction is destroyed before commit has been called, the transaction is canceled and it has no observable effects. Until the returned transaction is committed or canceled, the queue is not in a consistent state. If any function is called in this timespan by the same thread, the behavior is undefined.

Parameters
i_sourceobject to be used as source to construct of new element.
  • If this argument is an l-value, the new element copy-constructed.
  • If this argument is an r-value, the new element move-constructed.
Returns
The associated transaction object.


Requires:

  • ELEMENT_TYPE must be copy constructible (in case of l-value) or move constructible (in case of r-value)

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: unspecified.
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

using SpQueue = sp_heter_queue<
runtime_type<>,
PROD_CARDINALITY,
CONSUMER_CARDINALITY>;
SpQueue queue;
auto put = queue.start_push(12);
put.element() += 2;
put.commit(); // commits a 14
put_transaction<ELEMENT_TYPE> start_emplace ( CONSTRUCTION_PARAMS &&...  i_construction_params)
inline

Begins a transaction that appends an element of a type ELEMENT_TYPE, in-place-constructing it from a perfect forwarded parameter pack.
This function allocates the required space, constructs the new element, and returns a transaction object that may be used to allocate raw space associated to the element being inserted, or to alter the element in some way.
Call the member function commit on the returned transaction in order to make the effects observable. If the transaction is destroyed before commit has been called, the transaction is canceled and it has no observable effects. Until the returned transaction is committed or canceled, the queue is not in a consistent state. If any function is called in this timespan by the same thread, the behavior is undefined.

Parameters
i_construction_paramsconstruction parameters for the new element.
Returns
The associated transaction object.


Requires:

  • ELEMENT_TYPE must be constructible with std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: unspecified.
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

using SpQueue = sp_heter_queue<
runtime_type<>,
PROD_CARDINALITY,
CONSUMER_CARDINALITY>;
SpQueue queue;
auto put = queue.template start_emplace<std::string>(4, '*');
put.element() += "****";
put.commit(); // commits a "********"
put_transaction start_dyn_push ( const runtime_type &  i_type)
inline

Begins a transaction that appends an element of a type known at runtime, default-constructing it.
This function allocates space for and constructs the new element, and returns a transaction object that may be used to allocate raw space associated to the element being inserted, or to alter the element in some way.
Call the member function commit on the returned transaction in order to make the effects observable. If the transaction is destroyed before commit has been called, the transaction is canceled and it has no observable effects. Until the returned transaction is committed or canceled, the queue is not in a consistent state. If any function is called in this timespan by the same thread, the behavior is undefined.

Parameters
i_typetype of the new element.
Returns
The associated transaction object.

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: unspecified.
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

using MyRunTimeType = runtime_type<f_default_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>
queue;
auto const type = MyRunTimeType::make<int>();
auto put = queue.start_dyn_push(type);
put.commit();
put_transaction start_dyn_push_copy ( const runtime_type &  i_type,
const void *  i_source 
)
inline

Begins a transaction that appends an element of a type known at runtime, copy-constructing it from the source..
This function allocates space for and constructs the new element, and returns a transaction object that may be used to allocate raw space associated to the element being inserted, or to alter the element in some way.
Call the member function commit on the returned transaction in order to make the effects observable. If the transaction is destroyed before commit has been called, the transaction is canceled and it has no observable effects. Until the returned transaction is committed or canceled, the queue is not in a consistent state. If any function is called in this timespan by the same thread, the behavior is undefined.

Parameters
i_typetype of the new element.
i_sourcepointer to the object to use as source. If this pointer does dot point to an object whose dynamic type is the target type i_type was bound to, the behavior is undefined.
Returns
The associated transaction object.

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: unspecified.
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

using MyRunTimeType = runtime_type<f_copy_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>
queue;
std::string const source("Hello world!!");
auto const type = MyRunTimeType::make<decltype(source)>();
auto put = queue.start_dyn_push_copy(type, &source);
put.commit();
put_transaction start_dyn_push_move ( const runtime_type &  i_type,
void *  i_source 
)
inline

Begins a transaction that appends an element of a type known at runtime, move-constructing it from the source..
This function allocates space for and constructs the new element, and returns a transaction object that may be used to allocate raw space associated to the element being inserted, or to alter the element in some way.
Call the member function commit on the returned transaction in order to make the effects observable. If the transaction is destroyed before commit has been called, the transaction is canceled and it has no observable effects. Until the returned transaction is committed or canceled, the queue is not in a consistent state. If any function is called in this timespan by the same thread, the behavior is undefined.

Parameters
i_typetype of the new element.
i_sourcepointer to the object to use as source. If this pointer does dot point to an object whose dynamic type is the target type i_type was bound to, the behavior is undefined.
Returns
The associated transaction object.

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: unspecified.
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

using MyRunTimeType = runtime_type<f_move_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>
queue;
std::string source("Hello world!!");
auto const type = MyRunTimeType::make<decltype(source)>();
auto put = queue.start_dyn_push_move(type, &source);
put.commit();
bool try_push ( progress_guarantee  i_progress_guarantee,
ELEMENT_TYPE &&  i_source 
)
inlinenoexcept

Tries to append at the end of the queue an element of type ELEMENT_TYPE, copy-constructing or move-constructing it from the source.
If the put operation can't be completed with the specified progress guarantee, this function returns false to indicate a failure, and has no observable effects. This function fails if:

  • a memory allocation is necessary but the allocator can't complete it with the specified progress guarantee. A failure with the blocking progress guarantee indicates an out of memory, but no exception is thrown.
  • there is a contention between threads, and the wait-free progress guarantee is requested
  • the algorithm would perform some non wait-free operations (like page pinning), and the wait-free progress guarantee is requested
Parameters
i_progress_guaranteeprogress guarantee to respect
i_sourceobject to be used as source to construct of new element.
  • If this argument is an l-value, the new element copy-constructed
  • If this argument is an r-value, the new element move-constructed
Returns
whether the put operation was successful


Requires:

  • ELEMENT_TYPE must be copy constructible (in case of l-value) or move constructible (in case of r-value)

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: what the construction of the element and the runtime type throws (conditionally noexcept)
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

bool successful = false;
if (queue.try_push(progress_wait_free, 12))
{
successful = queue.try_push(progress_wait_free, std::string("Hello world!!"));
}
bool try_emplace ( progress_guarantee  i_progress_guarantee,
CONSTRUCTION_PARAMS &&...  i_construction_params 
)
inlinenoexcept

Tries to append at the end of the queue an element of type ELEMENT_TYPE, in-place-constructing it from a perfect forwarded parameter pack.
If the put operation can't be completed with the specified progress guarantee, this function returns false to indicate a failure, and has no observable effects. This function fails if:

  • a memory allocation is necessary but the allocator can't complete it with the specified progress guarantee. A failure with the blocking progress guarantee indicates an out of memory, but no exception is thrown.
  • there is a contention between threads, and the wait-free progress guarantee is requested
  • the algorithm would perform some non wait-free operations (like page pinning), and the wait-free progress guarantee is requested


Note: the template argument ELEMENT_TYPE can't be deduced from the parameters so it must explicitly specified.

Parameters
i_progress_guaranteeprogress guarantee to respect
i_construction_paramsconstruction parameters for the new element.
Returns
whether the put operation was successful


Requires:

  • ELEMENT_TYPE must be constructible with std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: what the construction of the element and the runtime type throws (conditionally noexcept)
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

bool successful = false;
if (queue.template try_emplace<int>(progress_wait_free))
{
successful = queue.template try_emplace<std::string>(progress_wait_free, 12, '-');
}
bool try_dyn_push ( progress_guarantee  i_progress_guarantee,
const runtime_type &  i_type 
)
inline

Tries to add at the end of the queue an element of a type known at runtime, default-constructing it.
If the put operation can't be completed with the specified progress guarantee, this function returns false to indicate a failure, and has no observable effects. This function fails if:

  • a memory allocation is necessary but the allocator can't complete it with the specified progress guarantee. A failure with the blocking progress guarantee indicates an out of memory, but no exception is thrown.
  • there is a contention between threads, and the wait-free progress guarantee is requested
  • the algorithm would perform some non wait-free operations (like page pinning), and the wait-free progress guarantee is requested
Parameters
i_progress_guaranteeprogress guarantee to respect
i_typetype of the new element.
Returns
whether the put operation was successful


Requires:

  • The function RUNTIME_TYPE::default_construct must be invokable. If RUNTIMETYPE is runtime_type this means that default_construct must be included in the feature list.

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: what the construction of the element and the runtime type throws
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

using MyRunTimeType = runtime_type<f_default_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>
queue;
auto const type = MyRunTimeType::make<int>();
if (queue.try_dyn_push(progress_wait_free, type)) // appends 0
{
// ...
}
bool try_dyn_push_copy ( progress_guarantee  i_progress_guarantee,
const runtime_type &  i_type,
const void *  i_source 
)
inline

Tries to add at the end of the queue an element of a type known at runtime, copy-constructing it from the source.
If the put operation can't be completed with the specified progress guarantee, this function returns false to indicate a failure, and has no observable effects. This function fails if:

  • a memory allocation is necessary but the allocator can't complete it with the specified progress guarantee. A failure with the blocking progress guarantee indicates an out of memory, but no exception is thrown.
  • there is a contention between threads, and the wait-free progress guarantee is requested
  • the algorithm would perform some non wait-free operations (like page pinning), and the wait-free progress guarantee is requested
Parameters
i_progress_guaranteeprogress guarantee to respect
i_typetype of the new element.
i_sourcepointer to the object to use as source. If this pointer does dot point to an object whose dynamic type is the target type i_type was bound to, the behavior is undefined.
Returns
whether the put operation was successful


Requires:

  • The function RUNTIME_TYPE::copy_construct must be invokable. If RUNTIMETYPE is runtime_type this means that copy_construct must be included in the feature list.

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: what the construction of the element and the runtime type throws
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

using MyRunTimeType = runtime_type<f_copy_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>
queue;
std::string const source("Hello world!!");
auto const type = MyRunTimeType::make<decltype(source)>();
if (queue.try_dyn_push_copy(progress_wait_free, type, &source))
{
// ...
}
bool try_dyn_push_move ( progress_guarantee  i_progress_guarantee,
const runtime_type &  i_type,
void *  i_source 
)
inline

Tries add at the end of the queue an element of a type known at runtime, move-constructing it from the source.
If the put operation can't be completed with the specified progress guarantee, this function returns false to indicate a failure, and has no observable effects. This function fails if:

  • a memory allocation is necessary but the allocator can't complete it with the specified progress guarantee. A failure with the blocking progress guarantee indicates an out of memory, but no exception is thrown.
  • there is a contention between threads, and the wait-free progress guarantee is requested
  • the algorithm would perform some non wait-free operations (like page pinning), and the wait-free progress guarantee is requested
Parameters
i_progress_guaranteeprogress guarantee to respect
i_typetype of the new element
i_sourcepointer to the object to use as source. If this pointer does dot point to an object whose dynamic type is the target type i_type was bound to, the behavior is undefined.
Returns
whether the put operation was successful


Requires:

  • The function RUNTIME_TYPE::move_construct must be invokable. If RUNTIMETYPE is runtime_type this means that move_construct must be included in the feature list.

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: what the construction of the element and the runtime type throws
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

using MyRunTimeType = runtime_type<f_move_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>
queue;
std::string source("Hello world!!");
auto const type = MyRunTimeType::make<decltype(source)>();
if (queue.try_dyn_push_move(progress_wait_free, type, &source))
{
// ...
}
put_transaction<typename std::decay<ELEMENT_TYPE>::type> try_start_push ( progress_guarantee  i_progress_guarantee,
ELEMENT_TYPE &&  i_source 
)
inlinenoexcept

Tries to begin a transaction that appends an element of type ELEMENT_TYPE, copy-constructing or move-constructing it from the source.
If the put operation can't be completed with the specified progress guarantee, this function returns an empty transaction to indicate a failure, and has no observable effects. This function fails if:

  • a memory allocation is necessary but the allocator can't complete it with the specified progress guarantee. A failure with the blocking progress guarantee indicates an out of memory, but no exception is thrown.
  • there is a contention between threads, and the wait-free progress guarantee is requested
  • the algorithm would perform some non wait-free operations (like page pinning), and the wait-free progress guarantee is requested


This function allocates the required space, constructs the new element, and returns a transaction object that may be used to allocate raw space associated to the element being inserted, or to alter the element in some way.
Call the member function commit on the returned transaction in order to make the effects observable. If the transaction is destroyed before commit has been called, the transaction is canceled and it has no observable effects. Until the returned transaction is committed or canceled, the queue is not in a consistent state. If any function is called in this timespan by the same thread, the behavior is undefined.

Parameters
i_progress_guaranteeprogress guarantee to respect
i_sourceobject to be used as source to construct of new element.
  • If this argument is an l-value, the new element copy-constructed.
  • If this argument is an r-value, the new element move-constructed.
Returns
The associated transaction object.


Requires:

  • ELEMENT_TYPE must be copy constructible (in case of l-value) or move constructible (in case of r-value)

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: what the construction of the element and the runtime type throws (conditionally noexcept)
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

if (auto put = queue.try_start_push(progress_wait_free, 12))
{
// ..
put.element() += 2;
put.commit(); // commits a 14
}
put_transaction<ELEMENT_TYPE> try_start_emplace ( progress_guarantee  i_progress_guarantee,
CONSTRUCTION_PARAMS &&...  i_construction_params 
)
inlinenoexcept

Tries to begin a transaction that appends an element of a type ELEMENT_TYPE, in-place-constructing it from a perfect forwarded parameter pack.
If the put operation can't be completed with the specified progress guarantee, this function returns an empty transaction to indicate a failure, and has no observable effects. This function fails if:

  • a memory allocation is necessary but the allocator can't complete it with the specified progress guarantee. A failure with the blocking progress guarantee indicates an out of memory, but no exception is thrown.
  • there is a contention between threads, and the wait-free progress guarantee is requested
  • the algorithm would perform some non wait-free operations (like page pinning), and the wait-free progress guarantee is requested


This function allocates the required space, constructs the new element, and returns a transaction object that may be used to allocate raw space associated to the element being inserted, or to alter the element in some way.
Call the member function commit on the returned transaction in order to make the effects observable. If the transaction is destroyed before commit has been called, the transaction is canceled and it has no observable effects. Until the returned transaction is committed or canceled, the queue is not in a consistent state. If any function is called in this timespan by the same thread, the behavior is undefined.

Parameters
i_progress_guaranteeprogress guarantee to respect
i_construction_paramsconstruction parameters for the new element.
Returns
The associated transaction object.


Requires:

  • ELEMENT_TYPE must be constructible with std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: what the construction of the element and of the runtime type throws (conditionally noexcept)
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

if (
auto put = queue.template try_start_emplace<std::string>(progress_wait_free, 4, '*'))
{
// ..
put.element() += "****";
put.commit(); // commits a "********"
}
put_transaction try_start_dyn_push ( progress_guarantee  i_progress_guarantee,
const runtime_type &  i_type 
)
inline

Tries to begin a transaction that appends an element of a type known at runtime, default-constructing it.
If the put operation can't be completed with the specified progress guarantee, this function returns an empty transaction to indicate a failure, and has no observable effects. This function fails if:

  • a memory allocation is necessary but the allocator can't complete it with the specified progress guarantee. A failure with the blocking progress guarantee indicates an out of memory, but no exception is thrown.
  • there is a contention between threads, and the wait-free progress guarantee is requested
  • the algorithm would perform some non wait-free operations (like page pinning), and the wait-free progress guarantee is requested


This function allocates space for and constructs the new element, and returns a transaction object that may be used to allocate raw space associated to the element being inserted, or to alter the element in some way.
Call the member function commit on the returned transaction in order to make the effects observable. If the transaction is destroyed before commit has been called, the transaction is canceled and it has no observable effects. Until the returned transaction is committed or canceled, the queue is not in a consistent state. If any function is called in this timespan by the same thread, the behavior is undefined.

Parameters
i_progress_guaranteeprogress guarantee to respect
i_typetype of the new element.
Returns
The associated transaction object.

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: what the construction of the element and the runtime type throws
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

using MyRunTimeType = runtime_type<f_default_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>
queue;
auto const type = MyRunTimeType::make<int>();
if (auto put = queue.try_start_dyn_push(progress_wait_free, type))
{
// ....
put.commit();
}
put_transaction try_start_dyn_push_copy ( progress_guarantee  i_progress_guarantee,
const runtime_type &  i_type,
const void *  i_source 
)
inline

Tries to begin a transaction that appends an element of a type known at runtime, copy-constructing it from the source.
If the put operation can't be completed with the specified progress guarantee, this function returns an empty transaction to indicate a failure, and has no observable effects. This function fails if:

  • a memory allocation is necessary but the allocator can't complete it with the specified progress guarantee. A failure with the blocking progress guarantee indicates an out of memory, but no exception is thrown.
  • there is a contention between threads, and the wait-free progress guarantee is requested
  • the algorithm would perform some non wait-free operations (like page pinning), and the wait-free progress guarantee is requested


This function allocates space for and constructs the new element, and returns a transaction object that may be used to allocate raw space associated to the element being inserted, or to alter the element in some way.
Call the member function commit on the returned transaction in order to make the effects observable. If the transaction is destroyed before commit has been called, the transaction is canceled and it has no observable effects. Until the returned transaction is committed or canceled, the queue is not in a consistent state. If any function is called in this timespan by the same thread, the behavior is undefined.

Parameters
i_progress_guaranteeprogress guarantee to respect
i_typetype of the new element.
i_sourcepointer to the object to use as source. If this pointer does dot point to an object whose dynamic type is the target type i_type was bound to, the behavior is undefined.
Returns
The associated transaction object.

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: what the construction of the element and the runtime type throws
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

using MyRunTimeType = runtime_type<f_copy_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>
queue;
std::string const source("Hello world!!");
auto const type = MyRunTimeType::make<decltype(source)>();
if (auto put = queue.try_start_dyn_push_copy(progress_wait_free, type, &source))
{
// ...
put.commit();
}
put_transaction try_start_dyn_push_move ( progress_guarantee  i_progress_guarantee,
const runtime_type &  i_type,
void *  i_source 
)
inline

Tries to begin a transaction that appends an element of a type known at runtime, move-constructing it from the source.
If the put operation can't be completed with the specified progress guarantee, this function returns an empty transaction to indicate a failure, and has no observable effects. This function fails if:

  • a memory allocation is necessary but the allocator can't complete it with the specified progress guarantee. A failure with the blocking progress guarantee indicates an out of memory, but no exception is thrown.
  • there is a contention between threads, and the wait-free progress guarantee is requested
  • the algorithm would perform some non wait-free operations (like page pinning), and the wait-free progress guarantee is requested


This function allocates space for and constructs the new element, and returns a transaction object that may be used to allocate raw space associated to the element being inserted, or to alter the element in some way.
Call the member function commit on the returned transaction in order to make the effects observable. If the transaction is destroyed before commit has been called, the transaction is canceled and it has no observable effects. Until the returned transaction is committed or canceled, the queue is not in a consistent state. If any function is called in this timespan by the same thread, the behavior is undefined.

Parameters
i_progress_guaranteeprogress guarantee to respect
i_typetype of the new element.
i_sourcepointer to the object to use as source. If this pointer does dot point to an object whose dynamic type is the target type i_type was bound to, the behavior is undefined.
Returns
The associated transaction object.

Complexity: constant.
Effects on iterators: no iterator is invalidated
Throws: what the construction of the element and the runtime type throws
Exception guarantee: strong (in case of exception the function has no observable effects).

Examples

using MyRunTimeType = runtime_type<f_move_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>
queue;
std::string source("Hello world!!");
auto const type = MyRunTimeType::make<decltype(source)>();
if (auto put = queue.try_start_dyn_push_move(progress_wait_free, type, &source))
{
// ..
put.commit();
}
bool try_pop ( )
inlinenoexcept

Removes and destroy the first element of the queue, if the queue is not empty. Otherwise it has no effect. This function discards the element. Use a consume function if you want to access the element before it gets destroyed.

Returns
whether an element was actually removed.

Complexity: constant.
Effects on iterators: any iterator pointing to the first element is invalidated
Throws: nothing

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
SpQueue queue;
bool pop_result = queue.try_pop();
assert(pop_result == false);
queue.push(1);
queue.push(2);
pop_result = queue.try_pop();
assert(pop_result == true);
auto consume = queue.try_start_consume();
assert(consume.template element<int>() == 2);
consume.commit();
consume_operation try_start_consume ( )
inlinenoexcept

Tries to start a consume operation.

Returns
a consume_operation which is empty if there are no elements to consume

A non-empty consume must be committed for the consume to have effect.

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
SpQueue queue;
auto consume_1 = queue.try_start_consume();
assert(!consume_1);
queue.push(42);
auto consume_2 = queue.try_start_consume();
assert(consume_2);
assert(consume_2.template element<int>() == 42);
consume_2.commit();
bool try_start_consume ( consume_operation i_consume)
inlinenoexcept

Tries to start a consume operation using an existing consume_operation object.

Parameters
i_consumereference to a consume_operation to be used. If it is non-empty it gets canceled before trying to start the new consume.
Returns
whether i_consume is non-empty after the call, that is whether the queue was not empty.

A non-empty consume must be committed for the consume to have effect.

This overload is similar to the one taking no arguments and returning a consume_operation, but it's more efficient if the next consumable element is in the same page of the last element i_consume has visited because in this case it doesn't perform page pinning.

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
SpQueue queue;
typename SpQueue::consume_operation consume_1;
bool const bool_1 = queue.try_start_consume(consume_1);
assert(!bool_1 && !consume_1);
queue.push(42);
typename SpQueue::consume_operation consume_2;
auto bool_2 = queue.try_start_consume(consume_2);
assert(consume_2 && bool_2);
assert(consume_2.template element<int>() == 42);
consume_2.commit();
void reentrant_push ( ELEMENT_TYPE &&  i_source)
inline

Same to sp_heter_queue::push, but allows reentrancy: during the construction of the element the queue is in a valid state.

Examples

queue.reentrant_push(12);
queue.reentrant_push(std::string("Hello world!!"));
void reentrant_emplace ( CONSTRUCTION_PARAMS &&...  i_construction_params)
inline

Same to sp_heter_queue::emplace, but allows reentrancy: during the construction of the element the queue is in a valid state.

Examples

queue.template reentrant_emplace<int>();
queue.template reentrant_emplace<std::string>(12, '-');
void reentrant_dyn_push ( const runtime_type &  i_type)
inline

Same to sp_heter_queue::dyn_push, but allows reentrancy: during the construction of the element the queue is in a valid state.

Examples

using MyRunTimeType = runtime_type<f_default_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType> queue;
auto const type = MyRunTimeType::make<int>();
queue.reentrant_dyn_push(type); // appends 0
void reentrant_dyn_push_copy ( const runtime_type &  i_type,
const void *  i_source 
)
inline

Same to sp_heter_queue::dyn_push_copy, but allows reentrancy: during the construction of the element the queue is in a valid state.

Examples

using MyRunTimeType = runtime_type<f_copy_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType> queue;
std::string const source("Hello world!!");
auto const type = MyRunTimeType::make<decltype(source)>();
queue.reentrant_dyn_push_copy(type, &source);
void reentrant_dyn_push_move ( const runtime_type &  i_type,
void *  i_source 
)
inline

Same to sp_heter_queue::dyn_push_move, but allows reentrancy: during the construction of the element the queue is in a valid state.

Examples

using MyRunTimeType = runtime_type<f_move_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType> queue;
std::string source("Hello world!!");
auto const type = MyRunTimeType::make<decltype(source)>();
queue.reentrant_dyn_push_move(type, &source);
reentrant_put_transaction<typename std::decay<ELEMENT_TYPE>::type> start_reentrant_push ( ELEMENT_TYPE &&  i_source)
inline

Same to sp_heter_queue::start_push, but allows reentrancy: during the construction of the element, and until the state of the transaction gets destroyed, the queue is in a valid state.

Examples

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
SpQueue queue;
auto put = queue.start_reentrant_push(12);
put.element() += 2;
put.commit(); // commits a 14
reentrant_put_transaction<ELEMENT_TYPE> start_reentrant_emplace ( CONSTRUCTION_PARAMS &&...  i_construction_params)
inline

Same to sp_heter_queue::start_emplace, but allows reentrancy: during the construction of the element, and until the state of the transaction gets destroyed, the queue is in a valid state.

Examples

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
SpQueue queue;
auto put = queue.template start_reentrant_emplace<std::string>(4, '*');
put.element() += "****";
put.commit(); // commits a "********"
reentrant_put_transaction start_reentrant_dyn_push ( const runtime_type &  i_type)
inline

Same to sp_heter_queue::start_dyn_push, but allows reentrancy: during the construction of the element, and until the state of the transaction gets destroyed, the queue is in a valid state.

Examples

using MyRunTimeType = runtime_type<f_default_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType> queue;
auto const type = MyRunTimeType::make<int>();
auto put = queue.start_reentrant_dyn_push(type);
put.commit();
reentrant_put_transaction start_reentrant_dyn_push_copy ( const runtime_type &  i_type,
const void *  i_source 
)
inline

Same to sp_heter_queue::start_dyn_push_copy, but allows reentrancy: during the construction of the element, and until the state of the transaction gets destroyed, the queue is in a valid state.

Examples

using MyRunTimeType = runtime_type<f_copy_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType> queue;
std::string const source("Hello world!!");
auto const type = MyRunTimeType::make<decltype(source)>();
auto put = queue.start_reentrant_dyn_push_copy(type, &source);
put.commit();
reentrant_put_transaction start_reentrant_dyn_push_move ( const runtime_type &  i_type,
void *  i_source 
)
inline

Same to sp_heter_queue::start_dyn_push_move, but allows reentrancy: during the construction of the element, and until the state of the transaction gets destroyed, the queue is in a valid state.

Examples

using MyRunTimeType = runtime_type<f_move_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType> queue;
std::string source("Hello world!!");
auto const type = MyRunTimeType::make<decltype(source)>();
auto put = queue.start_reentrant_dyn_push_move(type, &source);
put.commit();
bool try_reentrant_push ( progress_guarantee  i_progress_guarantee,
ELEMENT_TYPE &&  i_source 
)
inlinenoexcept

Same to sp_heter_queue::try_push, but allows reentrancy: during the construction of the element the queue is in a valid state.

Examples

if (queue.try_reentrant_push(progress_blocking, 12))
{
if (queue.try_reentrant_push(progress_blocking, std::string("Hello world!!")))
{
// ...
}
}
bool try_reentrant_emplace ( progress_guarantee  i_progress_guarantee,
CONSTRUCTION_PARAMS &&...  i_construction_params 
)
inlinenoexcept

Same to sp_heter_queue::try_emplace, but allows reentrancy: during the construction of the element the queue is in a valid state.

Examples

if (
auto put =
queue.template try_start_reentrant_emplace<std::string>(progress_blocking, 4, '*'))
{
// ...
put.element() += "****";
put.commit(); // commits a "********"
}
bool try_reentrant_dyn_push ( progress_guarantee  i_progress_guarantee,
const runtime_type &  i_type 
)
inline

Same to sp_heter_queue::try_dyn_push, but allows reentrancy: during the construction of the element the queue is in a valid state.

Examples

using MyRunTimeType = runtime_type<f_default_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType> queue;
auto const type = MyRunTimeType::make<int>();
if (queue.try_reentrant_dyn_push(progress_blocking, type)) // appends 0
{
// ...
}
bool try_reentrant_dyn_push_copy ( progress_guarantee  i_progress_guarantee,
const runtime_type &  i_type,
const void *  i_source 
)
inline

Same to sp_heter_queue::try_dyn_push_copy, but allows reentrancy: during the construction of the element the queue is in a valid state.

Examples

using MyRunTimeType = runtime_type<f_copy_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType> queue;
std::string const source("Hello world!!");
auto const type = MyRunTimeType::make<decltype(source)>();
if (queue.try_reentrant_dyn_push_copy(progress_blocking, type, &source))
{
// ...
}
bool try_reentrant_dyn_push_move ( progress_guarantee  i_progress_guarantee,
const runtime_type &  i_type,
void *  i_source 
)
inline

Same to sp_heter_queue::try_dyn_push_move, but allows reentrancy: during the construction of the element the queue is in a valid state.

Examples

using MyRunTimeType = runtime_type<f_move_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType> queue;
std::string source("Hello world!!");
auto const type = MyRunTimeType::make<decltype(source)>();
if (queue.try_reentrant_dyn_push_move(progress_blocking, type, &source))
{
// ...
}
reentrant_put_transaction<typename std::decay<ELEMENT_TYPE>::type> try_start_reentrant_push ( progress_guarantee  i_progress_guarantee,
ELEMENT_TYPE &&  i_source 
)
inlinenoexcept

Same to sp_heter_queue::try_start_push, but allows reentrancy: during the construction of the element the queue is in a valid state.

Examples

if (auto put = queue.try_start_reentrant_push(progress_blocking, 12))
{
// ...
put.element() += 2;
put.commit(); // commits a 14
}
reentrant_put_transaction<ELEMENT_TYPE> try_start_reentrant_emplace ( progress_guarantee  i_progress_guarantee,
CONSTRUCTION_PARAMS &&...  i_construction_params 
)
inlinenoexcept

Same to sp_heter_queue::try_start_emplace, but allows reentrancy: during the construction of the element the queue is in a valid state.

Examples

if (
auto put =
queue.template try_start_reentrant_emplace<std::string>(progress_blocking, 4, '*'))
{
// ...
put.element() += "****";
put.commit(); // commits a "********"
}
reentrant_put_transaction try_start_reentrant_dyn_push ( progress_guarantee  i_progress_guarantee,
const runtime_type &  i_type 
)
inline

Same to sp_heter_queue::try_start_dyn_push, but allows reentrancy: during the construction of the element the queue is in a valid state.

Examples

using MyRunTimeType = runtime_type<f_default_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType> queue;
auto const type = MyRunTimeType::make<int>();
if (auto put = queue.try_start_reentrant_dyn_push(progress_blocking, type))
{
// ...
put.commit();
}
reentrant_put_transaction try_start_reentrant_dyn_push_copy ( progress_guarantee  i_progress_guarantee,
const runtime_type &  i_type,
const void *  i_source 
)
inline

Same to sp_heter_queue::try_start_dyn_push_copy, but allows reentrancy: during the construction of the element the queue is in a valid state.

Examples

using MyRunTimeType = runtime_type<f_copy_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType> queue;
std::string const source("Hello world!!");
auto const type = MyRunTimeType::make<decltype(source)>();
if (auto put = queue.try_start_reentrant_dyn_push_copy(progress_blocking, type, &source))
{
// ...
put.commit();
}
reentrant_put_transaction try_start_reentrant_dyn_push_move ( progress_guarantee  i_progress_guarantee,
const runtime_type &  i_type,
void *  i_source 
)
inline

Same to sp_heter_queue::try_start_dyn_push_move, but allows reentrancy: during the construction of the element the queue is in a valid state.

Examples

using MyRunTimeType = runtime_type<f_move_construct, f_destroy, f_size, f_alignment>;
sp_heter_queue<MyRunTimeType> queue;
std::string source("Hello world!!");
auto const type = MyRunTimeType::make<decltype(source)>();
if (auto put = queue.try_start_reentrant_dyn_push_move(progress_blocking, type, &source))
{
// ...
put.commit();
}
bool try_reentrant_pop ( )
inlinenoexcept

Removes and destroy the first element of the queue, if the queue is not empty. Otherwise it has no effect. This is the reentrant version of try_pop. This function discards the element. Use a consume function if you want to access the element before it gets destroyed.

Returns
whether an element was actually removed.

Complexity: constant.
Effects on iterators: any iterator pointing to the first element is invalidated
Throws: nothing

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
SpQueue queue;
bool pop_result = queue.try_reentrant_pop();
assert(pop_result == false);
queue.push(1);
queue.push(2);
pop_result = queue.try_reentrant_pop();
assert(pop_result == true);
auto consume = queue.try_start_reentrant_consume();
assert(consume.template element<int>() == 2);
consume.commit();
reentrant_consume_operation try_start_reentrant_consume ( )
inlinenoexcept

Tries to start a reentrant consume operation. This is the reentrant version of try_start_consume.

Returns
a consume_operation which is empty if there are no elements to consume

A non-empty consume must be committed for the consume to have effect.

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
SpQueue queue;
auto consume_1 = queue.try_start_reentrant_consume();
assert(!consume_1);
queue.push(42);
auto consume_2 = queue.try_start_reentrant_consume();
assert(consume_2);
assert(consume_2.template element<int>() == 42);
consume_2.commit();
bool try_start_reentrant_consume ( reentrant_consume_operation i_consume)
inlinenoexcept

Tries to start a consume operation using an existing consume_operation object. This is the reentrant version of try_start_consume.

Parameters
i_consumereference to a consume_operation to be used. If it is non-empty it gets canceled before trying to start the new consume.
Returns
whether i_consume is non-empty after the call, that is whether the queue was not empty.

A non-empty consume must be committed for the consume to have effect.

This overload is similar to the one taking no arguments and returning a consume_operation. For an sp_heter_queue there is no performance difference between the two overloads. Anyway for lock-free concurrent queue this overload may be faster.

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
SpQueue queue;
typename SpQueue::reentrant_consume_operation consume_1;
bool const bool_1 = queue.try_start_reentrant_consume(consume_1);
assert(!bool_1 && !consume_1);
queue.push(42);
typename SpQueue::reentrant_consume_operation consume_2;
auto bool_2 = queue.try_start_reentrant_consume(consume_2);
assert(consume_2 && bool_2);
assert(consume_2.template element<int>() == 42);
consume_2.commit();

Friends And Related Function Documentation

void swap ( sp_heter_queue< RUNTIME_TYPE, ALLOCATOR_TYPE, PROD_CARDINALITY, CONSUMER_CARDINALITY, BUSY_WAIT_FUNC > &  i_first,
sp_heter_queue< RUNTIME_TYPE, ALLOCATOR_TYPE, PROD_CARDINALITY, CONSUMER_CARDINALITY, BUSY_WAIT_FUNC > &  i_second 
)
friend

Swaps two queues.

using SpQueue =
sp_heter_queue<runtime_type<>, default_allocator, PROD_CARDINALITY, CONSUMER_CARDINALITY>;
SpQueue queue, queue_1;
queue.push(1);
swap(queue, queue_1);
assert(queue.empty());
assert(!queue_1.empty());

Member Data Documentation

constexpr size_t min_alignment = Base::min_alignment
static

Minimum alignment used for the storage of the elements. The storage of elements is always aligned according to the most-derived type.

constexpr bool concurrent_puts = PROD_CARDINALITY == concurrency_multiple
static

Whether multiple threads can do put operations on the same queue without any further synchronization.

constexpr bool concurrent_consumes = CONSUMER_CARDINALITY == concurrency_multiple
static

Whether multiple threads can do consume operations on the same queue without any further synchronization.

constexpr bool concurrent_put_consumes = true
static

Whether puts and consumes can be done concurrently without any further synchronization. In any case unsynchronized concurrency is constrained by concurrent_puts and concurrent_consumes.

constexpr bool is_seq_cst = true
static

Whether this queue is sequential consistent.


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