Embedded Template Library 1.0
Loading...
Searching...
No Matches
stack.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_STACK_INCLUDED
32#define ETL_STACK_INCLUDED
33
34#include "platform.h"
35#include "algorithm.h"
36#include "utility.h"
37#include "iterator.h"
38#include "alignment.h"
39#include "array.h"
40#include "exception.h"
41#include "error_handler.h"
42#include "debug_count.h"
43#include "type_traits.h"
44#include "placement_new.h"
45
46#include <stddef.h>
47#include <stdint.h>
48
49//*****************************************************************************
54//*****************************************************************************
55
56namespace etl
57{
58 //***************************************************************************
61 //***************************************************************************
62 class stack_exception : public exception
63 {
64 public:
65
66 stack_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
67 : exception(reason_, file_name_, line_number_)
68 {
69 }
70 };
71
72 //***************************************************************************
75 //***************************************************************************
76 class stack_full : public stack_exception
77 {
78 public:
79
80 stack_full(string_type file_name_, numeric_type line_number_)
81 : stack_exception(ETL_ERROR_TEXT("stack:full", ETL_STACK_FILE_ID"A"), file_name_, line_number_)
82 {
83 }
84 };
85
86 //***************************************************************************
89 //***************************************************************************
90 class stack_empty : public stack_exception
91 {
92 public:
93
94 stack_empty(string_type file_name_, numeric_type line_number_)
95 : stack_exception(ETL_ERROR_TEXT("stack:empty", ETL_STACK_FILE_ID"B"), file_name_, line_number_)
96 {
97 }
98 };
99
100 //***************************************************************************
104 //***************************************************************************
106 {
107 public:
108
109 typedef size_t size_type;
110
111 //*************************************************************************
114 //*************************************************************************
115 bool empty() const
116 {
117 return current_size == 0;
118 }
119
120 //*************************************************************************
123 //*************************************************************************
124 bool full() const
125 {
126 return current_size == CAPACITY;
127 }
128
129 //*************************************************************************
131 //*************************************************************************
133 {
134 return current_size;
135 }
136
137 //*************************************************************************
139 //*************************************************************************
141 {
142 return CAPACITY;
143 }
144
145 //*************************************************************************
148 //*************************************************************************
149 size_t available() const
150 {
151 return max_size() - size();
152 }
153
154 protected:
155
156 //*************************************************************************
158 //*************************************************************************
160 : top_index(0),
161 current_size(0),
162 CAPACITY(max_size_)
163 {
164 }
165
166 //*************************************************************************
168 //*************************************************************************
170 {
171 }
172
173 //*************************************************************************
175 //*************************************************************************
176 void add_in()
177 {
179 ETL_INCREMENT_DEBUG_COUNT;
180 }
181
182 //*************************************************************************
184 //*************************************************************************
185 void del_out()
186 {
187 --top_index;
188 --current_size;
189 ETL_DECREMENT_DEBUG_COUNT;
190 }
191
192 //*************************************************************************
194 //*************************************************************************
196 {
197 top_index = 0;
198 current_size = 0;
199 ETL_RESET_DEBUG_COUNT;
200 }
201
206 };
207
208 //***************************************************************************
218 //***************************************************************************
219 template <typename T>
220 class istack : public etl::stack_base
221 {
222 public:
223
224 typedef T value_type;
225 typedef T& reference;
226 typedef const T& const_reference;
227#if ETL_USING_CPP11
228 typedef T&& rvalue_reference;
229#endif
230 typedef T* pointer;
231 typedef const T* const_pointer;
233
234 private:
235
236 typedef typename etl::stack_base base_t;
237
238 public:
239
240 //*************************************************************************
243 //*************************************************************************
245 {
246 return p_buffer[top_index];
247 }
248
249 //*************************************************************************
253 //*************************************************************************
255 {
256 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(stack_full));
257
259 ::new (&p_buffer[top_index]) T(value);
260 }
261
262#if ETL_USING_CPP11
263 //*************************************************************************
267 //*************************************************************************
268 void push(rvalue_reference value)
269 {
270 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(stack_full));
271
273 ::new (&p_buffer[top_index]) T(etl::move(value));
274 }
275#endif
276
277#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT
278 //*************************************************************************
282 //*************************************************************************
283 template <typename ... Args>
284 reference emplace(Args && ... args)
285 {
286 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
287
289 ::new (&p_buffer[top_index]) T(etl::forward<Args>(args)...);
290
291 return p_buffer[top_index];
292 }
293#else
294 //*************************************************************************
298 //*************************************************************************
300 {
301 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
302
304 ::new (&p_buffer[top_index]) T();
305
306 return p_buffer[top_index];
307 }
308
309 //*************************************************************************
313 //*************************************************************************
314 template <typename T1>
315 reference emplace(const T1& value1)
316 {
317 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
318
320 ::new (&p_buffer[top_index]) T(value1);
321
322 return p_buffer[top_index];
323 }
324
325 //*************************************************************************
329 //*************************************************************************
330 template <typename T1, typename T2>
331 reference emplace(const T1& value1, const T2& value2)
332 {
333 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
334
336 ::new (&p_buffer[top_index]) T(value1, value2);
337
338 return p_buffer[top_index];
339 }
340
341 //*************************************************************************
345 //*************************************************************************
346 template <typename T1, typename T2, typename T3>
347 reference emplace(const T1& value1, const T2& value2, const T3& value3)
348 {
349 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
350
352 ::new (&p_buffer[top_index]) T(value1, value2, value3);
353
354 return p_buffer[top_index];
355 }
356
357 //*************************************************************************
361 //*************************************************************************
362 template <typename T1, typename T2, typename T3, typename T4>
363 reference emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
364 {
365 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
366
368 ::new (&p_buffer[top_index]) T(value1, value2, value3, value4);
369
370 return p_buffer[top_index];
371 }
372#endif
373
374 //*************************************************************************
377 //*************************************************************************
379 {
380 return p_buffer[top_index];
381 }
382
383 //*************************************************************************
385 //*************************************************************************
386 void clear()
387 {
388 if ETL_IF_CONSTEXPR(etl::is_trivially_destructible<T>::value)
389 {
391 }
392 else
393 {
394 while (current_size > 0)
395 {
396 p_buffer[top_index].~T();
398 }
399 }
400 }
401
402 //*************************************************************************
404 //*************************************************************************
405 void pop()
406 {
407 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(stack_empty));
408
409 p_buffer[top_index].~T();
411 }
412
413 //*************************************************************************
415 //*************************************************************************
416 void pop_into(reference destination)
417 {
418 destination = ETL_MOVE(top());
419 pop();
420 }
421
422 //*************************************************************************
426 //*************************************************************************
427 template <typename TContainer>
428 void pop_into(TContainer& destination)
429 {
430 destination.push(ETL_MOVE(top()));
431 pop();
432 }
433
434 //*************************************************************************
436 //*************************************************************************
437 void reverse()
438 {
439 etl::reverse(p_buffer, p_buffer + current_size);
440 }
441
442 //*************************************************************************
444 //*************************************************************************
446 {
447 if (&rhs != this)
448 {
449 clear();
450 clone(rhs);
451 }
452
453 return *this;
454 }
455
456#if ETL_USING_CPP11
457 //*************************************************************************
459 //*************************************************************************
461 {
462 if (&rhs != this)
463 {
464 clone(etl::move(rhs));
465 }
466
467 return *this;
468 }
469#endif
470
471 protected:
472
473 //*************************************************************************
475 //*************************************************************************
476 void clone(const istack& other)
477 {
478 clear();
479
480 size_t index = 0UL;
481
482 for (size_t i = 0UL; i < other.size(); ++i)
483 {
484 push(other.p_buffer[index++]);
485 }
486 }
487
488#if ETL_USING_CPP11
489 //*************************************************************************
491 //*************************************************************************
492 void clone(istack&& other)
493 {
494 clear();
495
496 size_t index = 0UL;
497
498 for (size_t i = 0UL; i < other.size(); ++i)
499 {
500 push(etl::move(other.p_buffer[index++]));
501 }
502 }
503#endif
504
505 //*************************************************************************
507 //*************************************************************************
508 istack(T* p_buffer_, size_type max_size_)
509 : stack_base(max_size_),
510 p_buffer(p_buffer_)
511 {
512 }
513
514 private:
515
516 // Disable copy construction.
517 istack(const istack&);
518
519 T* p_buffer;
520
521 //*************************************************************************
523 //*************************************************************************
524#if defined(ETL_POLYMORPHIC_STACK) || defined(ETL_POLYMORPHIC_CONTAINERS)
525 public:
526 virtual ~istack()
527 {
528 }
529#else
530 protected:
532 {
533 }
534#endif
535 };
536
537 //***************************************************************************
543 //***************************************************************************
544 template <typename T, const size_t SIZE>
545 class stack : public etl::istack<T>
546 {
547 public:
548 typedef typename etl::aligned_storage<sizeof(T), etl::alignment_of<T>::value>::type container_type;
549
550 static ETL_CONSTANT size_t MAX_SIZE = SIZE;
551
552 //*************************************************************************
554 //*************************************************************************
556 : etl::istack<T>(reinterpret_cast<T*>(&buffer[0]), SIZE)
557 {
558 }
559
560 //*************************************************************************
562 //*************************************************************************
563 stack(const stack& rhs)
564 : etl::istack<T>(reinterpret_cast<T*>(&buffer[0]), SIZE)
565 {
567 }
568
569#if ETL_USING_CPP11
570 //*************************************************************************
572 //*************************************************************************
573 stack(stack&& rhs)
574 : etl::istack<T>(reinterpret_cast<T*>(&buffer[0]), SIZE)
575 {
576 etl::istack<T>::clone(etl::move(rhs));
577 }
578#endif
579
580 //*************************************************************************
582 //*************************************************************************
584 {
586 }
587
588 //*************************************************************************
590 //*************************************************************************
592 {
593 if (&rhs != this)
594 {
596 }
597
598 return *this;
599 }
600
601#if ETL_USING_CPP11
602 //*************************************************************************
604 //*************************************************************************
605 stack& operator = (stack&& rhs)
606 {
607 if (&rhs != this)
608 {
609 etl::istack<T>::clone(etl::move(rhs));
610 }
611
612 return *this;
613 }
614#endif
615
616 private:
617
619 container_type buffer[SIZE];
620 };
621
622 template <typename T, const size_t SIZE>
623 ETL_CONSTANT size_t stack<T, SIZE>::MAX_SIZE;
624}
625
626#endif
Definition alignment.h:246
ETL_CONSTEXPR exception(string_type reason_, string_type, numeric_type line_)
Constructor.
Definition exception.h:69
ETL_DECLARE_DEBUG_COUNT
For internal debugging purposes.
Definition stack.h:205
void del_out()
Decrements the indexes value to record a queue deletion.
Definition stack.h:185
stack & operator=(const stack &rhs)
Assignment operator.
Definition stack.h:591
reference top()
Definition stack.h:244
bool empty() const
Definition stack.h:115
~stack_base()
Destructor.
Definition stack.h:169
stack()
Default constructor.
Definition stack.h:555
stack_base(size_type max_size_)
The constructor that is called from derived classes.
Definition stack.h:159
bool full() const
Definition stack.h:124
const T * const_pointer
A const pointer to the type used in the stack.
Definition stack.h:231
const size_type CAPACITY
The maximum number of items in the stack.
Definition stack.h:204
void index_clear()
Clears all of the indexes.
Definition stack.h:195
size_type size() const
Returns the current number of items top the stack.
Definition stack.h:132
reference emplace(const T1 &value1, const T2 &value2)
Definition stack.h:331
reference emplace(const T1 &value1)
Definition stack.h:315
istack(T *p_buffer_, size_type max_size_)
The constructor that is called from derived classes.
Definition stack.h:508
size_type max_size() const
Returns the maximum number of items that can be stacked.
Definition stack.h:140
size_type current_size
The number of items in the stack.
Definition stack.h:203
reference emplace()
Definition stack.h:299
size_t available() const
Definition stack.h:149
void push(const_reference value)
Definition stack.h:254
void pop()
Removes the oldest item from the top of the stack.
Definition stack.h:405
istack & operator=(const istack &rhs)
Assignment operator.
Definition stack.h:445
size_type top_index
The index of the top of the stack.
Definition stack.h:202
size_t size_type
The type used for determining the size of stack.
Definition stack.h:109
reference emplace(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition stack.h:363
T & reference
A reference to the type used in the stack.
Definition stack.h:225
reference emplace(const T1 &value1, const T2 &value2, const T3 &value3)
Definition stack.h:347
T * pointer
A pointer to the type used in the stack.
Definition stack.h:230
~stack()
Destructor.
Definition stack.h:583
stack(const stack &rhs)
Copy constructor.
Definition stack.h:563
void pop_into(TContainer &destination)
Definition stack.h:428
void clone(const istack &other)
Make this a clone of the supplied stack.
Definition stack.h:476
~istack()
Destructor.
Definition stack.h:531
void pop_into(reference destination)
Removes the oldest item from the top of the stack and puts it in the destination.
Definition stack.h:416
const T & const_reference
A const reference to the type used in the stack.
Definition stack.h:226
void add_in()
Increments the indexes value to record a stack addition.
Definition stack.h:176
void clear()
Clears the stack to the empty state.
Definition stack.h:386
stack_base::size_type size_type
The type used for determining the size of the stack.
Definition stack.h:232
T value_type
The type stored in the stack.
Definition stack.h:224
void reverse()
Reverses the stack.
Definition stack.h:437
const_reference top() const
Definition stack.h:378
This is the base for all stacks that contain a particular type.
Definition stack.h:221
Definition stack.h:546
Definition stack.h:106
Definition stack.h:91
Definition stack.h:77
add_rvalue_reference
Definition type_traits_generator.h:1413
bitset_ext
Definition absolute.h:39