Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Queue.h
Go to the documentation of this file.
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Containers_Queue_h_
5#define _Stroika_Foundation_Containers_Queue_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
10#include "Stroika/Foundation/Containers/Common.h"
12
13/**
14 * \file
15 *
16 * \note Code-Status: <a href="Code-Status.md#Beta">Beta</a>
17 *
18 *
19 * TODO:
20 * @todo trial balloon - EnqueueAll(CONTAINER), and Enqueue (STARTIT, ENDIT), enques
21 * items in order from start to end, so that when iterating over the resulting queue, you
22 * encounter the items in the order you added them. That makes EnqueueAll(CONTINER) as simple
23 * as EnqueueAll(C.begin(),C.end()).
24 *
25 * @todo Embellish test cases (regression tests), and fix/make sure copying works.
26 *
27 * @todo Review
28 * http://github.com/SophistSolutions/Stroika/blob/master/Archive/Stroika_FINAL_for_STERL_1992/Library/Foundation/Headers/Queue.hh
29 * for any important lackings
30 *
31 * @todo Draw a picture of q Q of people waiting in line (in docs below)
32 *
33 */
34
36
38 using Traversal::IInputIterator;
39 using Traversal::IIterableOfTo;
40 using Traversal::Iterable;
41 using Traversal::Iterator;
42
43 /**
44 * \brief A Queue is a first-in-first-out (FIFO) data structure, where elements are arranged
45 * in well-ordered fashion, from HEAD to TAIL.
46 *
47 * The HEAD if the Queue is where elements are removed. The TAIL of the queue is where
48 * elements enter the queue.
49 *
50 * Queues always iterate from Head (aka front) to Tail: the same order as removals
51 * would encounter items, dequeing them.
52 *
53 * @see Sedgewick, 30-31.(@todo CHECK REFERNECE)
54 *
55 * Related classes include Deques, which allow addition and removal at
56 * either end, and PriorityQueues, which allow removal based on the priority
57 * assigned to an item.
58 *
59 * \note Diagram:
60 *
61 * | | | | | | | |
62 * FRONT=>| - | | - | | - | | - |<= BACK
63 * (HEAD) | 0 | | 1 | | 2 | | 3 | (TAIL)
64 * | | | | | | | |
65 * items removed from this end new items added here
66 * ^^dont access middle^^
67 *
68 * @see Deque<T> - which allow addition and removal at either end
69 * @see PriorityQueues<T, TRAITS> - which allow removal based on the priority
70 * assigned to an item.
71 *
72 * \em Concrete Implementations:
73 * o @see Concrete::Queue_Array<>
74 * o @see Concrete::Queue_DoublyLinkedList<>
75 *
76 * \em Factory:
77 * @see Queue_Factory<> to see default implementations.
78 *
79 * \note \em Thread-Safety <a href="Thread-Safety.md#C++-Standard-Thread-Safety">C++-Standard-Thread-Safety</a>
80 *
81 * \note See <a href="./ReadMe.md">ReadMe.md</a> for common features of all Stroika containers (especially
82 * constructors, iterators, etc)
83 *
84 * \note <a href="Design-Overview.md#Comparisons">Comparisons</a>:
85 * o static_assert (totally_ordered<T> ==> totally_ordered<Queue<T>>);
86 *
87 * o EqualsComparer provided as alias to SequentialEqualsComparer
88 * Two Queues are considered equal if they contain the same elements (by comparing them
89 * with EQUALS_COMPARER (which defaults to equal_to<T>)
90 * in exactly the same order (iteration).
91 * o Since ordering in a Queue is well defined, we can use this ordering between elements to define
92 * the obvious sequential ordering three way comparison on queues (Iterable::SequentialThreeWayComparer)
93 */
94 template <typename T>
95 class [[nodiscard]] Queue : public Iterable<T> {
96 private:
97 using inherited = Iterable<T>;
98
99 public:
100 /**
101 * Use this typedef in templates to recover the basic functional container pattern of concrete types.
102 */
104
105 public:
106 /**
107 * @see inherited::value_type
108 */
110
111 protected:
112 class _IRep;
113
114 public:
115 /**
116 * Construct a new Queue object. Overloads that take an argument container or start/end iterators, iterate from
117 * start to end, adding the items to the tail of the Queue, so the resulting Queue will be in the same order (when iterated or dequeued)
118 * as the order of the items its created from.
119 *
120 * \note <a href="ReadMe.md#Container Constructors">See general information about container constructors that applies here</a>
121 */
122 Queue ();
123 Queue (Queue&&) noexcept = default;
124 Queue (const Queue&) noexcept = default;
125 Queue (const initializer_list<value_type>& src);
126 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
127 requires (not derived_from<remove_cvref_t<ITERABLE_OF_ADDABLE>, Queue<T>>)
128 explicit Queue (ITERABLE_OF_ADDABLE&& src)
129#if qCompilerAndStdLib_RequiresNotMatchInlineOutOfLineForTemplateClassBeingDefined_Buggy
130 : Queue{}
131 {
132 AddAllToTail (forward<ITERABLE_OF_ADDABLE> (src));
133 _AssertRepValidType ();
134 }
135#endif
136 ;
137 template <IInputIterator<T> ITERATOR_OF_ADDABLE>
138 Queue (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE&& end);
139
140 protected:
141 explicit Queue (shared_ptr<_IRep>&& rep) noexcept;
142 explicit Queue (const shared_ptr<_IRep>& rep) noexcept;
143
144 public:
145 /**
146 */
147 nonvirtual Queue& operator= (Queue&&) noexcept = default;
148 nonvirtual Queue& operator= (const Queue&) = default;
149
150 public:
151 /**
152 * Add the given item to the end of the Q, so it will be removed last of all the items currently in the Q.
153 *
154 * \note mutates container
155 *
156 * @aliases Enqueue, push_back
157 */
158 nonvirtual void AddTail (ArgByValueType<value_type> item);
159
160 public:
161 /**
162 * \brief Add the given item to the end of the Q, so it will be removed last of all the items currently in the Q (stlish alias)
163 */
164 nonvirtual void push_back (ArgByValueType<value_type> item);
165
166 public:
167 /**
168 * \pre not empty ()
169 * @see HeadIf ()
170 */
171 nonvirtual value_type Head () const;
172
173 public:
174 /**
175 * @aliases Head
176 * \pre not empty ()
177 */
178 nonvirtual T front () const;
179
180 public:
181 /**
182 */
183 nonvirtual optional<value_type> HeadIf () const;
184
185 public:
186 /**
187 * \pre not empty ()
188 * \note mutates container
189 */
190 nonvirtual value_type RemoveHead ();
191
192 public:
193 /**
194 * \pre not empty ()
195 * \note mutates container
196 */
197 nonvirtual value_type pop_back ();
198
199 public:
200 /**
201 * \note mutates container
202 */
203 nonvirtual optional<value_type> RemoveHeadIf ();
204
205 public:
206 /**
207 * @aliases AddTail ()
208 *
209 * \brief add item to the end of the Q (line).
210 *
211 * \note mutates container
212 */
213 nonvirtual void Enqueue (ArgByValueType<value_type> item);
214
215 public:
216 /**
217 * \brief Alias for RemoveHead () - remove item from the head of the Q (line).
218 *
219 * \note mutates container
220 * \pre not empty ()
221 */
222 nonvirtual value_type Dequeue ();
223
224 public:
225 /**
226 * Items are appended to the tail of the Q in same order they are encountered iterating from start to end of the container (or start to end iterators given).
227 *
228 * This also implies that ordering will be preserved in iterating over the Queue, or in Dequeing those elements.
229 *
230 * \pre IIterableOfTo<ITERABLE_OF_ADDABLE, T> or IInputIterator<T>
231 *
232 * \note This works efficiently because a Queue<> iterates from head to tail, and that's the order in which you would want to
233 * add them to copy the Queue (unlike with Stack).
234 *
235 * \note mutates container
236 */
237 template <IIterableOfTo<T> ITERABLE_OF_ADDABLE>
238 nonvirtual void AddAllToTail (ITERABLE_OF_ADDABLE&& s);
239 template <IInputIterator<T> ITERATOR_OF_ADDABLE>
240 nonvirtual void AddAllToTail (ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE&& end);
241
242 public:
243 /**
244 * \note mutates container
245 */
246 nonvirtual void RemoveAll ();
247
248 public:
249 /**
250 * \brief STL-ish alias for RemoveAll ().
251 *
252 * \note mutates container
253 */
254 nonvirtual void clear ();
255
256 public:
257 /**
258 * \brief Simply indirect to @Iterable<T>::SequentialEqualsComparer
259 */
260 template <typename T_EQUALS_COMPARER = equal_to<T>>
261 using EqualsComparer = typename Iterable<T>::template SequentialEqualsComparer<T_EQUALS_COMPARER>;
262
263 public:
264 /**
265 */
266 template <typename ELEMENT_COMPARER = compare_three_way>
267 using ThreeWayComparer = typename Iterable<T>::template SequentialThreeWayComparer<ELEMENT_COMPARER>;
268
269 public:
270 /**
271 * simply indirect to @Queue<>::EqualsComparer
272 */
273 nonvirtual bool operator== (const Queue& rhs) const
274 requires (equality_comparable<T>);
275
276 public:
277 /**
278 * simply indirect to @Queue<>::ThreeWayComparer (only defined if T::operator<=> is defined)
279 */
280 nonvirtual auto operator<=> (const Queue& rhs) const
281 requires (three_way_comparable<T>);
282
283 protected:
284 /**
285 */
286 template <typename T2>
287 using _SafeReadRepAccessor = typename inherited::template _SafeReadRepAccessor<T2>;
288
289 protected:
290 /**
291 */
292 template <typename T2>
293 using _SafeReadWriteRepAccessor = typename inherited::template _SafeReadWriteRepAccessor<T2>;
294
295 protected:
296 nonvirtual void _AssertRepValidType () const noexcept;
297 };
298
299 /**
300 * \brief Implementation detail for Queue<T> implementors.
301 *
302 * Protected abstract interface to support concrete implementations of
303 * the Queue<T> container API.
304 */
305 template <typename T>
306 class Queue<T>::_IRep : public Iterable<T>::_IRep {
307 private:
308 using inherited = typename Iterable<T>::_IRep;
309
310 protected:
311 _IRep () = default;
312
313 public:
314 virtual ~_IRep () = default;
315
316 public:
317 virtual shared_ptr<_IRep> CloneEmpty () const = 0;
318 virtual void AddTail (ArgByValueType<value_type> item) = 0;
319 virtual value_type RemoveHead () = 0;
320 virtual optional<value_type> RemoveHeadIf () = 0;
321 virtual value_type Head () const = 0;
322 virtual optional<value_type> HeadIf () const = 0;
323 };
324
325}
326
327/*
328 ********************************************************************************
329 ******************************* Implementation Details *************************
330 ********************************************************************************
331 */
332
333#include "Queue.inl"
334
335#endif /*_Stroika_Foundation_Containers_Queue_h_ */
Implementation detail for Queue<T> implementors.
Definition Queue.h:306
A Queue is a first-in-first-out (FIFO) data structure, where elements are arranged in well-ordered fa...
Definition Queue.h:95
typename inherited::value_type value_type
Definition Queue.h:109
typename Iterable< T >::template SequentialEqualsComparer< T_EQUALS_COMPARER > EqualsComparer
Simply indirect to @Iterable<T>::SequentialEqualsComparer.
Definition Queue.h:261
Implementation detail for iterator implementors.
Definition Iterable.h:1569
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
Definition Iterable.h:237
T value_type
value_type is an alias for the type iterated over - like vector<T>::value_type
Definition Iterable.h:248
conditional_t<(sizeof(CHECK_T)<=2 *sizeof(void *)) and is_trivially_copyable_v< CHECK_T >, CHECK_T, const CHECK_T & > ArgByValueType
This is an alias for 'T' - but how we want to pass it on stack as formal parameter.
Definition TypeHints.h:32