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 "alignment.h"
37#include "array.h"
38#include "debug_count.h"
39#include "error_handler.h"
40#include "exception.h"
41#include "iterator.h"
42#include "placement_new.h"
43#include "type_traits.h"
44#include "utility.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 //***************************************************************************
105 //***************************************************************************
107 {
108 public:
109
110 typedef size_t size_type;
111
112 //*************************************************************************
115 //*************************************************************************
116 bool empty() const
117 {
118 return current_size == 0;
119 }
120
121 //*************************************************************************
124 //*************************************************************************
125 bool full() const
126 {
127 return current_size == CAPACITY;
128 }
129
130 //*************************************************************************
132 //*************************************************************************
134 {
135 return current_size;
136 }
137
138 //*************************************************************************
140 //*************************************************************************
142 {
143 return CAPACITY;
144 }
145
146 //*************************************************************************
149 //*************************************************************************
150 size_t available() const
151 {
152 return max_size() - size();
153 }
154
155 protected:
156
157 //*************************************************************************
159 //*************************************************************************
161 : top_index(0)
162 , current_size(0)
163 , CAPACITY(max_size_)
164 {
165 }
166
167 //*************************************************************************
169 //*************************************************************************
171
172 //*************************************************************************
174 //*************************************************************************
175 void add_in()
176 {
178 ETL_INCREMENT_DEBUG_COUNT;
179 }
180
181 //*************************************************************************
183 //*************************************************************************
184 void del_out()
185 {
186 --top_index;
187 --current_size;
188 ETL_DECREMENT_DEBUG_COUNT;
189 }
190
191 //*************************************************************************
193 //*************************************************************************
195 {
196 top_index = 0;
197 current_size = 0;
198 ETL_RESET_DEBUG_COUNT;
199 }
200
205 };
206
207 //***************************************************************************
217 //***************************************************************************
218 template <typename T>
219 class istack : public etl::stack_base
220 {
221 public:
222
223 typedef T value_type;
224 typedef T& reference;
225 typedef const T& const_reference;
226#if ETL_USING_CPP11
227 typedef T&& rvalue_reference;
228#endif
229 typedef T* pointer;
230 typedef const T* const_pointer;
232
233 private:
234
235 typedef typename etl::stack_base base_t;
236
237 public:
238
239 //*************************************************************************
244 //*************************************************************************
246 {
247 ETL_ASSERT_CHECK_EXTRA(!empty(), ETL_ERROR(stack_empty));
248 return p_buffer[top_index];
249 }
250
251 //*************************************************************************
256 //*************************************************************************
258 {
259 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(stack_full));
260
262 ::new (&p_buffer[top_index]) T(value);
263 }
264
265#if ETL_USING_CPP11
266 //*************************************************************************
271 //*************************************************************************
272 void push(rvalue_reference value)
273 {
274 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(stack_full));
275
277 ::new (&p_buffer[top_index]) T(etl::move(value));
278 }
279#endif
280
281#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT
282 //*************************************************************************
287 //*************************************************************************
288 template <typename... Args>
289 reference emplace(Args&&... args)
290 {
291 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
292
294 ::new (&p_buffer[top_index]) T(etl::forward<Args>(args)...);
295
296 return p_buffer[top_index];
297 }
298#else
299 //*************************************************************************
304 //*************************************************************************
306 {
307 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
308
310 ::new (&p_buffer[top_index]) T();
311
312 return p_buffer[top_index];
313 }
314
315 //*************************************************************************
320 //*************************************************************************
321 template <typename T1>
322 reference emplace(const T1& value1)
323 {
324 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
325
327 ::new (&p_buffer[top_index]) T(value1);
328
329 return p_buffer[top_index];
330 }
331
332 //*************************************************************************
337 //*************************************************************************
338 template <typename T1, typename T2>
339 reference emplace(const T1& value1, const T2& value2)
340 {
341 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
342
344 ::new (&p_buffer[top_index]) T(value1, value2);
345
346 return p_buffer[top_index];
347 }
348
349 //*************************************************************************
354 //*************************************************************************
355 template <typename T1, typename T2, typename T3>
356 reference emplace(const T1& value1, const T2& value2, const T3& value3)
357 {
358 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
359
361 ::new (&p_buffer[top_index]) T(value1, value2, value3);
362
363 return p_buffer[top_index];
364 }
365
366 //*************************************************************************
371 //*************************************************************************
372 template <typename T1, typename T2, typename T3, typename T4>
373 reference emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
374 {
375 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
376
378 ::new (&p_buffer[top_index]) T(value1, value2, value3, value4);
379
380 return p_buffer[top_index];
381 }
382#endif
383
384 //*************************************************************************
389 //*************************************************************************
391 {
392 ETL_ASSERT_CHECK_EXTRA(!empty(), ETL_ERROR(stack_empty));
393 return p_buffer[top_index];
394 }
395
396 //*************************************************************************
398 //*************************************************************************
399 void clear()
400 {
401 if ETL_IF_CONSTEXPR (etl::is_trivially_destructible<T>::value)
402 {
404 }
405 else
406 {
407 while (current_size > 0)
408 {
409 p_buffer[top_index].~T();
411 }
412 }
413 }
414
415 //*************************************************************************
417 //*************************************************************************
418 void pop()
419 {
420 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(stack_empty));
421
422 p_buffer[top_index].~T();
424 }
425
426 //*************************************************************************
429 //*************************************************************************
430 void pop_into(reference destination)
431 {
432 destination = ETL_MOVE(top());
433 pop();
434 }
435
436 //*************************************************************************
440 //*************************************************************************
441 template <typename TContainer>
442 void pop_into(TContainer& destination)
443 {
444 destination.push(ETL_MOVE(top()));
445 pop();
446 }
447
448 //*************************************************************************
450 //*************************************************************************
451 void reverse()
452 {
453 etl::reverse(p_buffer, p_buffer + current_size);
454 }
455
456 //*************************************************************************
458 //*************************************************************************
460 {
461 if (&rhs != this)
462 {
463 clear();
464 clone(rhs);
465 }
466
467 return *this;
468 }
469
470#if ETL_USING_CPP11
471 //*************************************************************************
473 //*************************************************************************
474 istack& operator=(istack&& rhs)
475 {
476 if (&rhs != this)
477 {
478 clone(etl::move(rhs));
479 }
480
481 return *this;
482 }
483#endif
484
485 protected:
486
487 //*************************************************************************
489 //*************************************************************************
490 void clone(const istack& other)
491 {
492 clear();
493
494 size_t index = 0UL;
495
496 for (size_t i = 0UL; i < other.size(); ++i)
497 {
498 push(other.p_buffer[index++]);
499 }
500 }
501
502#if ETL_USING_CPP11
503 //*************************************************************************
505 //*************************************************************************
506 void clone(istack&& other)
507 {
508 clear();
509
510 size_t index = 0UL;
511
512 for (size_t i = 0UL; i < other.size(); ++i)
513 {
514 push(etl::move(other.p_buffer[index++]));
515 }
516 }
517#endif
518
519 //*************************************************************************
521 //*************************************************************************
522 istack(T* p_buffer_, size_type max_size_)
523 : stack_base(max_size_)
524 , p_buffer(p_buffer_)
525 {
526 }
527
528 private:
529
530 // Disable copy construction.
531 istack(const istack&);
532
533 T* p_buffer;
534
535 //*************************************************************************
537 //*************************************************************************
538#if defined(ETL_POLYMORPHIC_STACK) || defined(ETL_POLYMORPHIC_CONTAINERS)
539
540 public:
541
542 virtual ~istack() {}
543#else
544
545 protected:
546
548#endif
549 };
550
551 //***************************************************************************
557 //***************************************************************************
558 template <typename T, const size_t SIZE>
559 class stack : public etl::istack<T>
560 {
561 public:
562
563 typedef typename etl::aligned_storage< sizeof(T), etl::alignment_of<T>::value>::type container_type;
564
565 static ETL_CONSTANT size_t MAX_SIZE = SIZE;
566
567 //*************************************************************************
569 //*************************************************************************
571 : etl::istack<T>(reinterpret_cast<T*>(&buffer[0]), SIZE)
572 {
573 }
574
575 //*************************************************************************
577 //*************************************************************************
578 stack(const stack& rhs)
579 : etl::istack<T>(reinterpret_cast<T*>(&buffer[0]), SIZE)
580 {
582 }
583
584#if ETL_USING_CPP11
585 //*************************************************************************
587 //*************************************************************************
588 stack(stack&& rhs)
589 : etl::istack<T>(reinterpret_cast<T*>(&buffer[0]), SIZE)
590 {
591 etl::istack<T>::clone(etl::move(rhs));
592 }
593#endif
594
595 //*************************************************************************
597 //*************************************************************************
599 {
601 }
602
603 //*************************************************************************
605 //*************************************************************************
606 stack& operator=(const stack& rhs)
607 {
608 if (&rhs != this)
609 {
611 }
612
613 return *this;
614 }
615
616#if ETL_USING_CPP11
617 //*************************************************************************
619 //*************************************************************************
620 stack& operator=(stack&& rhs)
621 {
622 if (&rhs != this)
623 {
624 etl::istack<T>::clone(etl::move(rhs));
625 }
626
627 return *this;
628 }
629#endif
630
631 private:
632
634 container_type buffer[SIZE];
635 };
636
637 template <typename T, const size_t SIZE>
638 ETL_CONSTANT size_t stack<T, SIZE>::MAX_SIZE;
639} // namespace etl
640
641#endif
Definition alignment.h:251
ETL_EXCEPTION_CONSTEXPR exception(string_type reason_, string_type, numeric_type)
Constructor.
Definition exception.h:81
ETL_DECLARE_DEBUG_COUNT
For internal debugging purposes.
Definition stack.h:204
void del_out()
Decrements the indexes value to record a queue deletion.
Definition stack.h:184
stack & operator=(const stack &rhs)
Assignment operator.
Definition stack.h:606
reference top()
Definition stack.h:245
bool empty() const
Definition stack.h:116
~stack_base()
Destructor.
Definition stack.h:170
stack()
Default constructor.
Definition stack.h:570
stack_base(size_type max_size_)
The constructor that is called from derived classes.
Definition stack.h:160
bool full() const
Definition stack.h:125
const T * const_pointer
A const pointer to the type used in the stack.
Definition stack.h:230
const size_type CAPACITY
The maximum number of items in the stack.
Definition stack.h:203
void index_clear()
Clears all of the indexes.
Definition stack.h:194
size_type size() const
Returns the current number of items top the stack.
Definition stack.h:133
reference emplace(const T1 &value1, const T2 &value2)
Definition stack.h:339
reference emplace(const T1 &value1)
Definition stack.h:322
istack(T *p_buffer_, size_type max_size_)
The constructor that is called from derived classes.
Definition stack.h:522
size_type max_size() const
Returns the maximum number of items that can be stacked.
Definition stack.h:141
size_type current_size
The number of items in the stack.
Definition stack.h:202
reference emplace()
Definition stack.h:305
size_t available() const
Definition stack.h:150
void push(const_reference value)
Definition stack.h:257
void pop()
Removes the oldest item from the top of the stack.
Definition stack.h:418
istack & operator=(const istack &rhs)
Assignment operator.
Definition stack.h:459
size_type top_index
The index of the top of the stack.
Definition stack.h:201
size_t size_type
The type used for determining the size of stack.
Definition stack.h:110
reference emplace(const T1 &value1, const T2 &value2, const T3 &value3, const T4 &value4)
Definition stack.h:373
T & reference
A reference to the type used in the stack.
Definition stack.h:224
reference emplace(const T1 &value1, const T2 &value2, const T3 &value3)
Definition stack.h:356
T * pointer
A pointer to the type used in the stack.
Definition stack.h:229
~stack()
Destructor.
Definition stack.h:598
stack(const stack &rhs)
Copy constructor.
Definition stack.h:578
void pop_into(TContainer &destination)
Definition stack.h:442
void clone(const istack &other)
Make this a clone of the supplied stack.
Definition stack.h:490
~istack()
Destructor.
Definition stack.h:547
void pop_into(reference destination)
Definition stack.h:430
const T & const_reference
A const reference to the type used in the stack.
Definition stack.h:225
void add_in()
Increments the indexes value to record a stack addition.
Definition stack.h:175
void clear()
Clears the stack to the empty state.
Definition stack.h:399
stack_base::size_type size_type
The type used for determining the size of the stack.
Definition stack.h:231
T value_type
The type stored in the stack.
Definition stack.h:223
void reverse()
Reverses the stack.
Definition stack.h:451
const_reference top() const
Definition stack.h:390
This is the base for all stacks that contain a particular type.
Definition stack.h:220
Definition stack.h:560
Definition stack.h:107
Definition stack.h:91
Definition stack.h:77
bitset_ext
Definition absolute.h:40