Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
queue.hpp
Go to the documentation of this file.
1// Copyright 2024, Toyota Motor Corporation
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_INTRUSIVE_QUEUE_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_INTRUSIVE_QUEUE_HPP_
7
8// parasoft-begin-suppress AUTOSAR-A16_2_2-a "Arene Base aggregate headers permitted by A16-2-2 Permit #1"
9
10#include "arene/base/contracts.hpp"
11#include "arene/base/intrusive/detail/default_tag.hpp"
12#include "arene/base/intrusive/singly_linked_node.hpp"
13#include "arene/base/stdlib_choice/cstddef.hpp"
14#include "arene/base/stdlib_choice/exchange.hpp"
15#include "arene/base/stdlib_choice/is_base_of.hpp"
16#include "arene/base/stdlib_choice/is_const.hpp"
17#include "arene/base/stdlib_choice/move.hpp"
18#include "arene/base/utility/swap.hpp"
19
20// parasoft-end-suppress AUTOSAR-A16_2_2-a
21
22// parasoft-begin-suppress AUTOSAR-M2_10_1-a "Similar identifiers permitted by M2-10-1 Permit #1 v1.0.0"
23
24namespace arene {
25namespace base {
26namespace intrusive {
27
28/// @brief Intrusive queue implementation.
29/// @tparam T The type of the elements in the queue.
30/// @tparam Tag The tag of the priority queue to work on. Default to @c
31/// default_tag.
32template <typename T, typename Tag = detail::default_tag>
33class queue {
34 /// @brief linked node type
36
37 static_assert(std::is_base_of<linked_node, T>::value, "T must be derived from singly_linked_node<Tag>");
38 static_assert(!std::is_const<T>::value, "T must not be const");
39
40 public:
41 /// @brief value type
42 using value_type = T;
43 /// @brief size type
45 /// @brief reference type
46 using reference = T&;
47 /// @brief const reference type
48 using const_reference = T const&;
49
50 /// @brief Default constructor.
51 explicit constexpr queue() noexcept = default;
52
53 /// @brief Move constructor.
54 /// @param other The queue to move from.
55 constexpr queue(queue&& other) noexcept
57 head_(std::exchange(other.head_, nullptr)),
58 tail_(std::exchange(other.tail_, nullptr)) {}
59
60 /// @brief Move assignment operator.
61 /// @param other The queue to move assign from.
62 /// @return Reference to the modified queue.
63 constexpr auto operator=(queue&& other) noexcept -> queue& {
64 if (this == &other) {
65 return *this;
66 }
67
68 queue temp{std::move(other)};
69 swap(temp);
70 return *this;
71 }
72
73 // parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
74 /// @brief Deleted copy constructor
75 ///
76 /// Intrusive queue does not support copy
77 ///
78 queue(queue const&) = delete;
79 // parasoft-end-suppress CERT_C-EXP37-a-3
80
81 // parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
82 /// @brief Deleted copy assignment operator
83 ///
84 /// Intrusive queue does not support copy
85 ///
86 auto operator=(queue const&) -> queue& = delete;
87 // parasoft-end-suppress CERT_C-EXP37-a-3
88
89 /// @brief Trivial destructor.
90 /// This is a tradeoff. C++14 doesn't allow user-provided
91 /// destructor to be constexpr.
92 ~queue() = default;
93
94 /// @brief Get the reference to the front element of the queue.
95 /// @pre The queue must not be empty.
96 /// @return Reference to the front element.
97 constexpr auto front() noexcept -> reference {
98 ARENE_PRECONDITION(!empty());
99 return static_cast<reference>(*head_);
100 }
101
102 /// @brief Get the reference to the back element of the queue.
103 /// @pre The queue must not be empty.
104 /// @return Reference to the back element.
105 constexpr auto back() noexcept -> reference {
106 ARENE_PRECONDITION(!empty());
107 return static_cast<reference>(*tail_);
108 }
109
110 /// @brief Get the size of the queue.
111 /// @return The number of elements in the queue.
112 constexpr auto size() const noexcept -> size_type { return size_; }
113
114 /// @brief Check if the queue is empty.
115 /// @return @c true if the queue is empty, @c false otherwise.
116 constexpr auto empty() const noexcept -> bool { return size() == size_type{}; }
117
118 /// @brief Push an element into the queue.
119 /// @pre The element must not be in any queue.
120 /// @param value The element to push.
121 constexpr void push(reference value) noexcept {
122 // The value must not be in any queue
123 ARENE_PRECONDITION(!value.linked_node::is_linked());
124 if (empty()) {
125 head_ = static_cast<linked_node*>(&value);
126 tail_ = head_;
127 } else {
128 get_next_link(*tail_, Tag{}, detail::singly_linked_node_pass_key{}) = &value;
129 tail_ = static_cast<linked_node*>(&value);
130 }
131 // The last element is always self-pointing
132 // to indicate it's in a queue
133 get_next_link(value, Tag{}, detail::singly_linked_node_pass_key{}) = static_cast<linked_node*>(&value);
134
135 ++size_;
136 }
137
138 /// @brief Remove the front element from the queue.
139 /// @pre The queue must not be empty.
140 constexpr void pop() noexcept {
141 ARENE_PRECONDITION(!empty());
142 if (size() == 1U) {
143 get_next_link(*head_, Tag{}, detail::singly_linked_node_pass_key{}) = nullptr;
144 head_ = nullptr;
145 tail_ = nullptr;
146 } else {
147 auto prev_head = head_;
148 head_ = get_next_link(*head_, Tag{}, detail::singly_linked_node_pass_key{});
149 get_next_link(*prev_head, Tag{}, detail::singly_linked_node_pass_key{}) = nullptr;
150 }
151 --size_;
152 }
153
154 /// @brief Swap the contents of two queues.
155 /// @param other The queue to swap with.
156 constexpr void swap(queue& other) noexcept {
157 using ::arene::base::swap; // constexpr eligible swap
158 swap(size_, other.size_);
159 swap(head_, other.head_);
160 swap(tail_, other.tail_);
161 }
162
163 /// @brief deleted equality operator
164 ///
165 /// Queue does not support equality comparison as the definition
166 /// of equality is not clear for intrusive containers.
167 constexpr auto operator==(queue const& other) const noexcept -> bool = delete;
168
169 /// @brief deleted equality operator
170 ///
171 /// Queue does not support inequality comparison as the definition
172 /// of equality is not clear for intrusive containers.
173 constexpr auto operator!=(queue const& other) const noexcept -> bool = delete;
174
175 private:
176 // parasoft-begin-suppress AUTOSAR-A12_1_2-a "False positive: move constructors are exempt from this rule"
177 /// @brief number of nodes in the queue
178 std::size_t size_{};
179 /// @brief head node
180 linked_node* head_{nullptr};
181 /// @brief tail node
182 linked_node* tail_{nullptr};
183 // parasoft-end-suppress AUTOSAR-A12_1_2-a
184};
185} // namespace intrusive
186} // namespace base
187} // namespace arene
188#endif // INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_INTRUSIVE_QUEUE_HPP_
Intrusive queue implementation.
Definition queue.hpp:33
constexpr queue(queue &&other) noexcept
Move constructor.
Definition queue.hpp:55
constexpr queue() noexcept=default
Default constructor.
constexpr void pop() noexcept
Remove the front element from the queue.
Definition queue.hpp:140
constexpr auto back() noexcept -> reference
Get the reference to the back element of the queue.
Definition queue.hpp:105
constexpr auto size() const noexcept -> size_type
Get the size of the queue.
Definition queue.hpp:112
constexpr auto operator=(queue &&other) noexcept -> queue &
Move assignment operator.
Definition queue.hpp:63
constexpr auto operator==(queue const &other) const noexcept -> bool=delete
deleted equality operator
auto operator=(queue const &) -> queue &=delete
Deleted copy assignment operator.
queue(queue const &)=delete
Deleted copy constructor.
constexpr void push(reference value) noexcept
Push an element into the queue.
Definition queue.hpp:121
constexpr auto empty() const noexcept -> bool
Check if the queue is empty.
Definition queue.hpp:116
constexpr auto operator!=(queue const &other) const noexcept -> bool=delete
deleted equality operator
constexpr auto front() noexcept -> reference
Get the reference to the front element of the queue.
Definition queue.hpp:97
constexpr void swap(queue &other) noexcept
Swap the contents of two queues.
Definition queue.hpp:156
~queue()=default
Trivial destructor. This is a tradeoff. C++14 doesn't allow user-provided destructor to be constexpr.
Definition binary_tree_node.hpp:14
Definition array_exceptions_disabled.cpp:11
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10