Simple queue that provides the user with an interface to query, manipulate and dequeue its content.
- non thread safe queue using a ring buffer
- provides a member function template with a callable non-type template parameter to statically generate the traversal functionality
- performant but compromises on encapsulation/seperation of concerns
- relies on functionality from
function_signatureandparam_packcontained in theTMP_librepo - to be used for adding order-matching capabilites to the
CppOrderBook2project
template<typename ContentType, size_t length>
requires std::is_default_constructible_v<ContentType> && std::is_nothrow_copy_assignable_v<ContentType> &&
std::is_nothrow_copy_constructible_v<ContentType> && (std::has_single_bit(length))
struct TraversableQueue
ContentType: type that will be enqueued- type constaints ensure that queue elements can be default constructed when the queue object is constructed, (nothrow) copy assigned when an element is enqueued and (nothrow) copy constructed when it's dequeued
length: max number of element the queue can contain, determines the size of the ring buffer- constrained to powers of two to prevent costly modulus operations when computing indices in ring buffer
bool enqueue(const ContentType&) noexcept
- enqueues a new element
- returns
trueif enqueueing was successful,falseif the queue was already filled to capacity so the new element could not be enqueued
std::optional<ContentType> dequeue() noexcept
- dequeues an element from the queue
- returns a
std::optionalcontaining the dequeued element if the queue wasn't empty and an emptystd::optionalif it was
- centerpiece of the
traverse_contentmethod templates - has to be
constexpr - has to be callable with a first argument of type
TraverseStateType, a second of typeContentType&and an optional third argument of the users choosing (more arguments can obviously be passed if the second argument is a sum type) TraverseStateTypeis provided by the user via the choice oftraveser- has to return
std::tuple<TraverseStateType, bool, bool> - when iterating over content,
TraverseStateTypeis returned during every iteration and passed totraverserin the next, thus tranferring state across iterations traversermay change the queue's content via its second argument- the first
boolin the return type indicates whether an element is to be dequeued, the secondboolstops the traversal iftrueis returned - if the first
boolisfalseonce (i.e. entry in currenct iteration is not dequeued), returningtruein a later iteration constitutes an error, it's up to the user providingtraverserto ensure that doesn't happen
template<auto traverser>
requires (function_signature::arg_types_t<traverser>::size == 3)
std::tuple_element_t<0, function_signature::ret_type_t<traverser>>
traverse_content(function_signature::arg_types_t<traverser>::template index_t<0> initial_state, function_signature::arg_types_t<traverser>::template index_t<3> arg) noexcept
- method template that takes a
traverserobject as a non-type parameter - the properties of
traverserdescribed above are checked statically - the method takes
TraverseStateTypeas its first argument, signifying the initial state of traversal - the second argument is optional and can be chosen by user (method template overload omitting the second argument is provided and has an analogous signature)
- type checks use
function_signatureandparam_packfrom theTMP_librepo