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
48//*****************************************************************************
53//*****************************************************************************
54
55namespace etl
56{
57 //***************************************************************************
60 //***************************************************************************
61 class stack_exception : public exception
62 {
63 public:
64
65 stack_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
66 : exception(reason_, file_name_, line_number_)
67 {
68 }
69 };
70
71 //***************************************************************************
74 //***************************************************************************
75 class stack_full : public stack_exception
76 {
77 public:
78
79 stack_full(string_type file_name_, numeric_type line_number_)
80 : stack_exception(ETL_ERROR_TEXT("stack:full", ETL_STACK_FILE_ID"A"), file_name_, line_number_)
81 {
82 }
83 };
84
85 //***************************************************************************
88 //***************************************************************************
89 class stack_empty : public stack_exception
90 {
91 public:
92
93 stack_empty(string_type file_name_, numeric_type line_number_)
94 : stack_exception(ETL_ERROR_TEXT("stack:empty", ETL_STACK_FILE_ID"B"), file_name_, line_number_)
95 {
96 }
97 };
98
99 //***************************************************************************
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 //*************************************************************************
173 //*************************************************************************
174 void add_in()
175 {
177 ETL_INCREMENT_DEBUG_COUNT;
178 }
179
180 //*************************************************************************
182 //*************************************************************************
183 void del_out()
184 {
185 --top_index;
186 --current_size;
187 ETL_DECREMENT_DEBUG_COUNT;
188 }
189
190 //*************************************************************************
192 //*************************************************************************
194 {
195 top_index = 0;
196 current_size = 0;
197 ETL_RESET_DEBUG_COUNT;
198 }
199
204 };
205
206 //***************************************************************************
216 //***************************************************************************
217 template <typename T>
218 class istack : public etl::stack_base
219 {
220 public:
221
222 typedef T value_type;
223 typedef T& reference;
224 typedef const T& const_reference;
225#if ETL_USING_CPP11
226 typedef T&& rvalue_reference;
227#endif
228 typedef T* pointer;
229 typedef const T* const_pointer;
231
232 private:
233
234 typedef typename etl::stack_base base_t;
235
236 public:
237
238 //*************************************************************************
243 //*************************************************************************
245 {
246 ETL_ASSERT_CHECK_EXTRA(!empty(), ETL_ERROR(stack_empty));
247 return p_buffer[top_index];
248 }
249
250 //*************************************************************************
255 //*************************************************************************
257 {
258 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(stack_full));
259
261 ::new (&p_buffer[top_index]) T(value);
262 }
263
264#if ETL_USING_CPP11
265 //*************************************************************************
270 //*************************************************************************
271 void push(rvalue_reference value)
272 {
273 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!full(), ETL_ERROR(stack_full));
274
276 ::new (&p_buffer[top_index]) T(etl::move(value));
277 }
278#endif
279
280#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT
281 //*************************************************************************
286 //*************************************************************************
287 template <typename... Args>
288 reference emplace(Args&&... args)
289 {
290 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
291
293 ::new (&p_buffer[top_index]) T(etl::forward<Args>(args)...);
294
295 return p_buffer[top_index];
296 }
297#else
298 //*************************************************************************
303 //*************************************************************************
305 {
306 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
307
309 ::new (&p_buffer[top_index]) T();
310
311 return p_buffer[top_index];
312 }
313
314 //*************************************************************************
319 //*************************************************************************
320 template <typename T1>
321 reference emplace(const T1& value1)
322 {
323 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
324
326 ::new (&p_buffer[top_index]) T(value1);
327
328 return p_buffer[top_index];
329 }
330
331 //*************************************************************************
336 //*************************************************************************
337 template <typename T1, typename T2>
338 reference emplace(const T1& value1, const T2& value2)
339 {
340 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
341
343 ::new (&p_buffer[top_index]) T(value1, value2);
344
345 return p_buffer[top_index];
346 }
347
348 //*************************************************************************
353 //*************************************************************************
354 template <typename T1, typename T2, typename T3>
355 reference emplace(const T1& value1, const T2& value2, const T3& value3)
356 {
357 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
358
360 ::new (&p_buffer[top_index]) T(value1, value2, value3);
361
362 return p_buffer[top_index];
363 }
364
365 //*************************************************************************
370 //*************************************************************************
371 template <typename T1, typename T2, typename T3, typename T4>
372 reference emplace(const T1& value1, const T2& value2, const T3& value3, const T4& value4)
373 {
374 ETL_ASSERT_CHECK_PUSH_POP(!full(), ETL_ERROR(stack_full));
375
377 ::new (&p_buffer[top_index]) T(value1, value2, value3, value4);
378
379 return p_buffer[top_index];
380 }
381#endif
382
383 //*************************************************************************
388 //*************************************************************************
390 {
391 ETL_ASSERT_CHECK_EXTRA(!empty(), ETL_ERROR(stack_empty));
392 return p_buffer[top_index];
393 }
394
395 //*************************************************************************
397 //*************************************************************************
398 void clear()
399 {
400 if ETL_IF_CONSTEXPR (etl::is_trivially_destructible<T>::value)
401 {
403 }
404 else
405 {
406 while (current_size > 0)
407 {
408 p_buffer[top_index].~T();
410 }
411 }
412 }
413
414 //*************************************************************************
416 //*************************************************************************
417 void pop()
418 {
419 ETL_ASSERT_CHECK_PUSH_POP_OR_RETURN(!empty(), ETL_ERROR(stack_empty));
420
421 p_buffer[top_index].~T();
423 }
424
425 //*************************************************************************
428 //*************************************************************************
429 void pop_into(reference destination)
430 {
431 destination = ETL_MOVE(top());
432 pop();
433 }
434
435 //*************************************************************************
439 //*************************************************************************
440 template <typename TContainer>
441 void pop_into(TContainer& destination)
442 {
443 destination.push(ETL_MOVE(top()));
444 pop();
445 }
446
447 //*************************************************************************
449 //*************************************************************************
450 void reverse()
451 {
452 etl::reverse(p_buffer, p_buffer + current_size);
453 }
454
455 //*************************************************************************
457 //*************************************************************************
459 {
460 if (&rhs != this)
461 {
462 clear();
463 clone(rhs);
464 }
465
466 return *this;
467 }
468
469#if ETL_USING_CPP11
470 //*************************************************************************
472 //*************************************************************************
473 istack& operator=(istack&& rhs)
474 {
475 if (&rhs != this)
476 {
477 clone(etl::move(rhs));
478 }
479
480 return *this;
481 }
482#endif
483
484 protected:
485
486 //*************************************************************************
488 //*************************************************************************
489 void clone(const istack& other)
490 {
491 clear();
492
493 size_t index = 0UL;
494
495 for (size_t i = 0UL; i < other.size(); ++i)
496 {
497 push(other.p_buffer[index++]);
498 }
499 }
500
501#if ETL_USING_CPP11
502 //*************************************************************************
504 //*************************************************************************
505 void clone(istack&& other)
506 {
507 clear();
508
509 size_t index = 0UL;
510
511 for (size_t i = 0UL; i < other.size(); ++i)
512 {
513 push(etl::move(other.p_buffer[index++]));
514 }
515 }
516#endif
517
518 //*************************************************************************
520 //*************************************************************************
521 istack(T* p_buffer_, size_type max_size_)
522 : stack_base(max_size_)
523 , p_buffer(p_buffer_)
524 {
525 }
526
527 private:
528
529 // Disable copy construction.
530 istack(const istack&);
531
532 T* p_buffer;
533
534 //*************************************************************************
536 //*************************************************************************
537#if defined(ETL_POLYMORPHIC_STACK) || defined(ETL_POLYMORPHIC_CONTAINERS)
538
539 public:
540
541 virtual ~istack() {}
542#else
543
544 protected:
545
547#endif
548 };
549
550 //***************************************************************************
556 //***************************************************************************
557 template <typename T, const size_t SIZE>
558 class stack : public etl::istack<T>
559 {
560 public:
561
562 typedef typename etl::aligned_storage< sizeof(T), etl::alignment_of<T>::value>::type container_type;
563
564 static ETL_CONSTANT size_t MAX_SIZE = SIZE;
565
566 //*************************************************************************
568 //*************************************************************************
570 : etl::istack<T>(reinterpret_cast<T*>(&buffer[0]), SIZE)
571 {
572 }
573
574 //*************************************************************************
576 //*************************************************************************
577 stack(const stack& rhs)
578 : etl::istack<T>(reinterpret_cast<T*>(&buffer[0]), SIZE)
579 {
581 }
582
583#if ETL_USING_CPP11
584 //*************************************************************************
586 //*************************************************************************
587 stack(stack&& rhs)
588 : etl::istack<T>(reinterpret_cast<T*>(&buffer[0]), SIZE)
589 {
590 etl::istack<T>::clone(etl::move(rhs));
591 }
592#endif
593
594 //*************************************************************************
596 //*************************************************************************
598 {
600 }
601
602 //*************************************************************************
604 //*************************************************************************
605 stack& operator=(const stack& rhs)
606 {
607 if (&rhs != this)
608 {
610 }
611
612 return *this;
613 }
614
615#if ETL_USING_CPP11
616 //*************************************************************************
618 //*************************************************************************
619 stack& operator=(stack&& rhs)
620 {
621 if (&rhs != this)
622 {
623 etl::istack<T>::clone(etl::move(rhs));
624 }
625
626 return *this;
627 }
628#endif
629
630 private:
631
633 container_type buffer[SIZE];
634 };
635
636 template <typename T, const size_t SIZE>
637 ETL_CONSTANT size_t stack<T, SIZE>::MAX_SIZE;
638} // namespace etl
639
640#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:203
void del_out()
Decrements the indexes value to record a queue deletion.
Definition stack.h:183
stack & operator=(const stack &rhs)
Assignment operator.
Definition stack.h:605
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:569
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:229
const size_type CAPACITY
The maximum number of items in the stack.
Definition stack.h:202
void index_clear()
Clears all of the indexes.
Definition stack.h:193
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:338
reference emplace(const T1 &value1)
Definition stack.h:321
istack(T *p_buffer_, size_type max_size_)
The constructor that is called from derived classes.
Definition stack.h:521
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:201
reference emplace()
Definition stack.h:304
size_t available() const
Definition stack.h:149
void push(const_reference value)
Definition stack.h:256
void pop()
Removes the oldest item from the top of the stack.
Definition stack.h:417
istack & operator=(const istack &rhs)
Assignment operator.
Definition stack.h:458
size_type top_index
The index of the top of the stack.
Definition stack.h:200
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:372
T & reference
A reference to the type used in the stack.
Definition stack.h:223
reference emplace(const T1 &value1, const T2 &value2, const T3 &value3)
Definition stack.h:355
T * pointer
A pointer to the type used in the stack.
Definition stack.h:228
~stack()
Destructor.
Definition stack.h:597
stack(const stack &rhs)
Copy constructor.
Definition stack.h:577
void pop_into(TContainer &destination)
Definition stack.h:441
void clone(const istack &other)
Make this a clone of the supplied stack.
Definition stack.h:489
~istack()
Destructor.
Definition stack.h:546
void pop_into(reference destination)
Definition stack.h:429
const T & const_reference
A const reference to the type used in the stack.
Definition stack.h:224
void add_in()
Increments the indexes value to record a stack addition.
Definition stack.h:174
void clear()
Clears the stack to the empty state.
Definition stack.h:398
stack_base::size_type size_type
The type used for determining the size of the stack.
Definition stack.h:230
T value_type
The type stored in the stack.
Definition stack.h:222
void reverse()
Reverses the stack.
Definition stack.h:450
const_reference top() const
Definition stack.h:389
This is the base for all stacks that contain a particular type.
Definition stack.h:219
Definition stack.h:559
Definition stack.h:106
Definition stack.h:90
Definition stack.h:76
Definition absolute.h:40