Embedded Template Library 1.0
Loading...
Searching...
No Matches
queue.h
Go to the documentation of this file.
1
2
3/******************************************************************************
4The MIT License(MIT)
5
6Embedded Template Library.
7https://github.com/ETLCPP/etl
8https://www.etlcpp.com
9
10Copyright(c) 2014 John Wellbelove, Mark Kitson
11
12Permission is hereby granted, free of charge, to any person obtaining a copy
13of this software and associated documentation files(the "Software"), to deal
14in the Software without restriction, including without limitation the rights
15to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
16copies of the Software, and to permit persons to whom the Software is
17furnished to do so, subject to the following conditions :
18
19The above copyright notice and this permission notice shall be included in all
20copies or substantial portions of the Software.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
25AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28SOFTWARE.
29******************************************************************************/
30
31#ifndef ETL_QUEUE_INCLUDED
32#define ETL_QUEUE_INCLUDED
33
34#include "platform.h"
35#include "alignment.h"
36#include "exception.h"
37#include "error_handler.h"
38#include "debug_count.h"
39#include "type_traits.h"
40#include "parameter_type.h"
41#include "memory_model.h"
42#include "integral_limits.h"
43#include "utility.h"
44#include "placement_new.h"
45
46#include <stddef.h>
47#include <stdint.h>
48
49//*****************************************************************************
54//*****************************************************************************
55
56namespace etl
57{
58 //***************************************************************************
61 //***************************************************************************
63 {
64 public:
65
66 queue_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
68 {
69 }
70 };
71
72 //***************************************************************************
75 //***************************************************************************
77 {
78 public:
79
80 queue_full(string_type file_name_, numeric_type line_number_)
81 : queue_exception(ETL_ERROR_TEXT("queue:full", ETL_QUEUE_FILE_ID"A"), file_name_, line_number_)
82 {
83 }
84 };
85
86 //***************************************************************************
89 //***************************************************************************
91 {
92 public:
93
94 queue_empty(string_type file_name_, numeric_type line_number_)
95 : queue_exception(ETL_ERROR_TEXT("queue:empty", ETL_QUEUE_FILE_ID"B"), file_name_, line_number_)
96 {
97 }
98 };
99
100 //***************************************************************************
103 //***************************************************************************
104 template <size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
106 {
107 public:
108
111
112 //*************************************************************************
114 //*************************************************************************
116 {
117 return current_size;
118 }
119
120 //*************************************************************************
122 //*************************************************************************
124 {
125 return CAPACITY;
126 }
127
128 //*************************************************************************
130 //*************************************************************************
132 {
133 return CAPACITY;
134 }
135
136 //*************************************************************************
139 //*************************************************************************
140 bool empty() const
141 {
142 return current_size == 0;
143 }
144
145 //*************************************************************************
148 //*************************************************************************
149 bool full() const
150 {
151 return current_size == CAPACITY;
152 }
153
154 //*************************************************************************
157 //*************************************************************************
159 {
160 return max_size() - size();
161 }
162
163 protected:
164
165 //*************************************************************************
167 //*************************************************************************
169 : in(0),
170 out(0),
171 current_size(0),
173 {
174 }
175
176 //*************************************************************************
178 //*************************************************************************
180 {
181 }
182
183 //*************************************************************************
185 //*************************************************************************
186 void add_in()
187 {
188 if (++in == CAPACITY) ETL_UNLIKELY
189 {
190 in = 0;
191 }
192
193 ++current_size;
194 ETL_INCREMENT_DEBUG_COUNT;
195 }
196
197 //*************************************************************************
199 //*************************************************************************
200 void del_out()
201 {
202 if (++out == CAPACITY) ETL_UNLIKELY
203 {
204 out = 0;
205 }
206 --current_size;
207 ETL_DECREMENT_DEBUG_COUNT;
208 }
209
210 //*************************************************************************
212 //*************************************************************************
214 {
215 in = 0;
216 out = 0;
217 current_size = 0;
218 ETL_RESET_DEBUG_COUNT;
219 }
220
226
227 };
228
229 //***************************************************************************
239 //***************************************************************************
240 template <typename T, const size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
241 class iqueue : public etl::queue_base<MEMORY_MODEL>
242 {
243 private:
244
245 typedef typename etl::queue_base<MEMORY_MODEL> base_t;
246
247 public:
248
249 typedef T value_type;
250 typedef T& reference;
251 typedef const T& const_reference;
252#if ETL_USING_CPP11
253 typedef T&& rvalue_reference;
254#endif
255 typedef T* pointer;
256 typedef const T* const_pointer;
257 typedef typename base_t::size_type size_type;
258
259 using base_t::in;
260 using base_t::out;
261 using base_t::CAPACITY;
263 using base_t::full;
264 using base_t::empty;
265 using base_t::add_in;
266 using base_t::del_out;
267
268 //*************************************************************************
271 //*************************************************************************
273 {
274 return p_buffer[out];
275 }
276
277 //*************************************************************************
280 //*************************************************************************
282 {
283 return p_buffer[out];
284 }
285
286 //*************************************************************************
289 //*************************************************************************
291 {
292 return p_buffer[in == 0 ? CAPACITY - 1 : in - 1];
293 }
294
295 //*************************************************************************
298 //*************************************************************************
300 {
301 return p_buffer[in == 0 ? CAPACITY - 1 : in - 1];
302 }
303
304 //*************************************************************************
308 //*************************************************************************
310 {
311#if defined(ETL_CHECK_PUSH_POP)
312 ETL_ASSERT(!full(), ETL_ERROR(queue_full));
313#endif
314 ::new (&p_buffer[in]) T(value);
315 add_in();
316 }
317
318#if ETL_USING_CPP11
319 //*************************************************************************
323 //*************************************************************************
324 void push(rvalue_reference value)
325 {
326#if defined(ETL_CHECK_PUSH_POP)
327 ETL_ASSERT(!full(), ETL_ERROR(queue_full));
328#endif
329 ::new (&p_buffer[in]) T(etl::move(value));
330 add_in();
331 }
332#endif
333
334#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT && !defined(ETL_QUEUE_FORCE_CPP03_IMPLEMENTATION)
335 //*************************************************************************
339 //*************************************************************************
340 template <typename ... Args>
341 reference emplace(Args && ... args)
342 {
343#if defined(ETL_CHECK_PUSH_POP)
344 ETL_ASSERT(!full(), ETL_ERROR(queue_full));
345#endif
346 reference value = p_buffer[in];
347 ::new (&value) T(etl::forward<Args>(args)...);
348 add_in();
349 return value;
350 }
351#else
352 //*************************************************************************
355 //*************************************************************************
357 {
358#if defined(ETL_CHECK_PUSH_POP)
359 ETL_ASSERT(!full(), ETL_ERROR(queue_full));
360#endif
361 reference value = p_buffer[in];
362 ::new (&value) T();
363 add_in();
364 return value;
365 }
366
367 //*************************************************************************
371 //*************************************************************************
372 template <typename T1>
373 reference emplace(const T1& value1)
374 {
375#if defined(ETL_CHECK_PUSH_POP)
376 ETL_ASSERT(!full(), ETL_ERROR(queue_full));
377#endif
378 reference value = p_buffer[in];
379 ::new (&value) T(value1);
380 add_in();
381 return value;
382 }
383
384 //*************************************************************************
389 //*************************************************************************
390 template <typename T1, typename T2>
391 reference emplace(const T1& value1, const T2& value2)
392 {
393#if defined(ETL_CHECK_PUSH_POP)
394 ETL_ASSERT(!full(), ETL_ERROR(queue_full));
395#endif
396 reference value = p_buffer[in];
397 ::new (&value) T(value1, value2);
398 add_in();
399 return value;
400 }
401
402 //*************************************************************************
408 //*************************************************************************
409 template <typename T1, typename T2, typename T3>
410 reference emplace(const T1& value1, const T2& value2, const T3& value3)
411 {
412#if defined(ETL_CHECK_PUSH_POP)
413 ETL_ASSERT(!full(), ETL_ERROR(queue_full));
414#endif
415 reference value = p_buffer[in];
416 ::new (&value) T(value1, value2, value3);
417 add_in();
418 return value;
419 }
420
421 //*************************************************************************
428 //*************************************************************************
429 template <typename T1, typename T2, typename T3, typename T4>
430 reference emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
431 {
432#if defined(ETL_CHECK_PUSH_POP)
433 ETL_ASSERT(!full(), ETL_ERROR(queue_full));
434#endif
435 reference value = p_buffer[in];
436 ::new (&value) T(value1, value2, value3, value4);
437 add_in();
438 return value;
439 }
440#endif
441
442 //*************************************************************************
444 //*************************************************************************
445 void clear()
446 {
448 {
450 }
451 else
452 {
453 while (current_size > 0)
454 {
455 p_buffer[out].~T();
456 del_out();
457 }
458
459 in = 0;
460 out = 0;
461 }
462 }
463
464 //*************************************************************************
468 //*************************************************************************
469 void pop()
470 {
471#if defined(ETL_CHECK_PUSH_POP)
472 ETL_ASSERT_OR_RETURN(!empty(), ETL_ERROR(queue_empty));
473#endif
474 p_buffer[out].~T();
475 del_out();
476 }
477
478 //*************************************************************************
481 //*************************************************************************
483 {
484 destination = ETL_MOVE(front());
485 pop();
486 }
487
488 //*************************************************************************
493 //*************************************************************************
494 template <typename TContainer>
496 {
497 destination.push(ETL_MOVE(front()));
498 pop();
499 }
500
501 //*************************************************************************
503 //*************************************************************************
505 {
506 if (&rhs != this)
507 {
508 clear();
509 clone(rhs);
510 }
511
512 return *this;
513 }
514
515#if ETL_USING_CPP11
516 //*************************************************************************
518 //*************************************************************************
520 {
521 if (&rhs != this)
522 {
523 clear();
525 }
526
527 return *this;
528 }
529#endif
530
531 protected:
532
533 //*************************************************************************
535 //*************************************************************************
536 void clone(const iqueue& other)
537 {
538 clear();
539
540 size_type index = other.out;
541
542 for (size_type i = 0; i < other.size(); ++i)
543 {
544 push(other.p_buffer[index]);
545 index = (index == (CAPACITY - 1)) ? 0 : index + 1;
546 }
547 }
548
549#if ETL_USING_CPP11
550 //*************************************************************************
552 //*************************************************************************
553 void move_clone(iqueue&& other)
554 {
555 clear();
556
557 size_type index = other.out;
558
559 for (size_type i = 0; i < other.size(); ++i)
560 {
561 push(etl::move(other.p_buffer[index]));
562 index = (index == (CAPACITY - 1)) ? 0 : index + 1;
563 }
564 }
565#endif
566
567 //*************************************************************************
569 //*************************************************************************
571 : base_t(max_size_),
572 p_buffer(p_buffer_)
573 {
574 }
575
576 private:
577
578 // Disable copy construction.
579 iqueue(const iqueue&);
580
581 T* p_buffer;
582
583 //*************************************************************************
585 //*************************************************************************
586#if defined(ETL_POLYMORPHIC_QUEUE) || defined(ETL_POLYMORPHIC_CONTAINERS)
587 public:
588 virtual ~iqueue()
589 {
590 }
591#else
592 protected:
594 {
595 }
596#endif
597 };
598
599 //***************************************************************************
606 //***************************************************************************
607 template <typename T, const size_t SIZE, const size_t MEMORY_MODEL = etl::memory_model::MEMORY_MODEL_LARGE>
608 class queue : public etl::iqueue<T, MEMORY_MODEL>
609 {
610 private:
611
613
614 public:
615
616 typedef typename base_t::size_type size_type;
617 typedef typename etl::aligned_storage<sizeof(T), etl::alignment_of<T>::value>::type container_type;
618
619 ETL_STATIC_ASSERT((SIZE <= etl::integral_limits<size_type>::max), "Size too large for memory model");
620
621 static ETL_CONSTANT size_type MAX_SIZE = size_type(SIZE);
622
623 //*************************************************************************
625 //*************************************************************************
627 : base_t(reinterpret_cast<T*>(&buffer[0]), SIZE)
628 {
629 }
630
631 //*************************************************************************
633 //*************************************************************************
635 : base_t(reinterpret_cast<T*>(&buffer[0]), SIZE)
636 {
638 }
639
640#if ETL_USING_CPP11
641 //*************************************************************************
643 //*************************************************************************
644 queue(queue&& rhs)
645 : base_t(reinterpret_cast<T*>(&buffer[0]), SIZE)
646 {
647 base_t::move_clone(etl::move(rhs));
648 }
649#endif
650
651 //*************************************************************************
653 //*************************************************************************
655 {
657 }
658
659 //*************************************************************************
661 //*************************************************************************
663 {
664 if (&rhs != this)
665 {
667 }
668
669 return *this;
670 }
671
672#if ETL_USING_CPP11
673 //*************************************************************************
675 //*************************************************************************
677 {
678 if (&rhs != this)
679 {
680 base_t::move_clone(etl::move(rhs));
681 }
682
683 return *this;
684 }
685#endif
686
687 private:
688
690 container_type buffer[SIZE];
691 };
692
693 template <typename T, const size_t SIZE, const size_t MEMORY_MODEL>
694 ETL_CONSTANT typename queue<T, SIZE, MEMORY_MODEL>::size_type queue<T, SIZE, MEMORY_MODEL>::MAX_SIZE;
695}
696
697#endif
Definition alignment.h:245
#define ETL_ASSERT(b, e)
Definition error_handler.h:356
Definition exception.h:47
Definition integral_limits.h:516
~queue()
Destructor.
Definition queue.h:654
size_type in
Where to input new data.
Definition queue.h:221
reference emplace(const T1 &value1, const T2 &value2)
Definition queue.h:391
queue & operator=(const queue &rhs)
Assignment operator.
Definition queue.h:662
const_reference front() const
Definition queue.h:281
ETL_DECLARE_DEBUG_COUNT
For internal debugging purposes.
Definition queue.h:225
const T * const_pointer
A const pointer to the type used in the queue.
Definition queue.h:256
void push(const_reference value)
Definition queue.h:309
reference emplace(const T1 &value1, const T2 &value2, const T3 &value3)
Definition queue.h:410
const_reference back() const
Definition queue.h:299
reference front()
Definition queue.h:272
size_type current_size
The number of items in the queue.
Definition queue.h:223
queue()
Default constructor.
Definition queue.h:626
void pop_into(reference destination)
Definition queue.h:482
etl::size_type_lookup< MEMORY_MODEL >::type size_type
The type used for determining the size of queue.
Definition queue.h:110
iqueue & operator=(const iqueue &rhs)
Assignment operator.
Definition queue.h:504
reference emplace(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition queue.h:430
T value_type
The type stored in the queue.
Definition queue.h:249
void pop()
Definition queue.h:469
void index_clear()
Clears the indexes.
Definition queue.h:213
size_type out
Where to get the oldest data.
Definition queue.h:222
~queue_base()
Destructor.
Definition queue.h:179
bool full() const
Definition queue.h:149
reference back()
Definition queue.h:290
size_type available() const
Definition queue.h:158
void del_out()
Increments (and wraps) the 'out' index value to record a queue deletion.
Definition queue.h:200
void add_in()
Increments (and wraps) the 'in' index value to record a queue addition.
Definition queue.h:186
~iqueue()
Destructor.
Definition queue.h:593
const size_type CAPACITY
The maximum number of items in the queue.
Definition queue.h:224
reference emplace()
Definition queue.h:356
base_t::size_type size_type
The type used for determining the size of the queue.
Definition queue.h:257
iqueue(T *p_buffer_, size_type max_size_)
The constructor that is called from derived classes.
Definition queue.h:570
queue_base(size_type max_size_)
The constructor that is called from derived classes.
Definition queue.h:168
void clone(const iqueue &other)
Make this a clone of the supplied queue.
Definition queue.h:536
queue(const queue &rhs)
Copy constructor.
Definition queue.h:634
size_type size() const
Returns the current number of items in the queue.
Definition queue.h:115
const T & const_reference
A const reference to the type used in the queue.
Definition queue.h:251
void pop_into(TContainer &destination)
Definition queue.h:495
size_type capacity() const
Returns the maximum number of items that can be queued.
Definition queue.h:131
T & reference
A reference to the type used in the queue.
Definition queue.h:250
size_type max_size() const
Returns the maximum number of items that can be queued.
Definition queue.h:123
reference emplace(const T1 &value1)
Definition queue.h:373
bool empty() const
Definition queue.h:140
T * pointer
A pointer to the type used in the queue.
Definition queue.h:255
void clear()
Clears the queue to the empty state.
Definition queue.h:445
This is the base for all queues that contain a particular type.
Definition queue.h:242
Definition queue.h:609
Definition queue.h:106
Definition queue.h:91
Definition queue.h:63
Definition queue.h:77
add_rvalue_reference
Definition type_traits_generator.h:1366
bitset_ext
Definition absolute.h:38
ETL_NODISCARD ETL_CONSTEXPR14 T round_half_even_unscaled(T value) ETL_NOEXCEPT
Definition scaled_rounding.h:314
Definition alignment.h:247
Definition type_traits_generator.h:2190
Definition memory_model.h:50