HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
stack.hpp
1// Copyright Take Vos 2020.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include <type_traits>
8#include <memory>
9#include <initializer_list>
10#include "required.hpp"
11#include "cast.hpp"
12
13namespace tt {
14
22template<typename T, size_t MaxSize>
23class stack {
24public:
25 using value_type = T;
26 using pointer_type = value_type *;
27 using const_pointer_type = value_type const *;
28 using reference_type = value_type &;
29 using const_reference_type = value_type const &;
30 using iterator_type = pointer_type;
31 using const_iterator_type = const_pointer_type;
32 using size_type = size_t;
33 using difference_type = ptrdiff_t;
34
37 stack() noexcept : _top(begin()) {}
38
43 _top(begin())
44 {
45 for (ttlet &init_item : init) {
46 push_back(init_item);
47 }
48 }
49
50 ~stack() noexcept
51 {
52 clear();
53 }
54
58 [[nodiscard]] iterator_type begin() noexcept
59 {
60 return std::launder(reinterpret_cast<pointer_type>(&_buffer[0]));
61 }
62
66 [[nodiscard]] const_iterator_type begin() const noexcept
67 {
68 return std::launder(reinterpret_cast<const_pointer_type>(&_buffer[0]));
69 }
70
74 [[nodiscard]] const_iterator_type cbegin() const noexcept
75 {
76 return std::launder(reinterpret_cast<const_pointer_type>(&_buffer[0]));
77 }
78
82 [[nodiscard]] iterator_type end() noexcept
83 {
84 return _top;
85 }
86
90 [[nodiscard]] const_iterator_type end() const noexcept
91 {
92 return _top;
93 }
94
98 [[nodiscard]] const_iterator_type cend() const noexcept
99 {
100 return _top;
101 }
102
106 [[nodiscard]] constexpr size_type max_size() const noexcept
107 {
108 return MaxSize;
109 }
110
114 [[nodiscard]] size_type size() const noexcept
115 {
116 return narrow_cast<size_type>(end() - begin());
117 }
118
122 [[nodiscard]] bool full() const noexcept
123 {
124 return _top == (begin() + max_size());
125 }
126
130 [[nodiscard]] bool empty() const noexcept
131 {
132 return _top == begin();
133 }
134
139 [[nodiscard]] reference_type operator[](size_t index) noexcept
140 {
141 tt_axiom(index < size());
142 return *std::launder(reinterpret_cast<pointer_type>(&_buffer[index]));
143 }
144
149 [[nodiscard]] const_reference_type operator[](size_t index) const noexcept
150 {
151 tt_axiom(index < size());
152 return *std::launder(reinterpret_cast<pointer_type>(&_buffer[index]));
153 }
154
159 [[nodiscard]] reference_type at(size_t index) noexcept
160 {
161 if (index >= size()) {
162 throw std::out_of_range("stack::at");
163 }
164 return (*this)[index];
165 }
166
171 [[nodiscard]] const_reference_type at(size_t index) const noexcept
172 {
173 if (index >= size()) {
174 throw std::out_of_range("stack::at");
175 }
176 return (*this)[index];
177 }
178
182 [[nodiscard]] reference_type back() noexcept
183 {
184 tt_axiom(!empty());
185 return *std::launder(reinterpret_cast<pointer_type>(_top - 1));
186 }
187
191 [[nodiscard]] const_reference_type back() const noexcept
192 {
193 tt_axiom(!empty());
194 return *std::launder(reinterpret_cast<pointer_type>(_top - 1));
195 }
196
201 template<typename... Args>
202 [[nodiscard]] void emplace_back(Args &&... args) noexcept
203 {
204 tt_axiom(!full());
205 new (end()) value_type(std::forward<Args>(args)...);
206 ++_top;
207 }
208
213 template<typename Arg> requires (std::is_convertible_v<Arg,value_type>)
214 [[nodiscard]] void push_back(Arg &&arg) noexcept
215 {
216 emplace_back(std::forward<Arg>(arg));
217 }
218
222 void pop_back() noexcept
223 {
224 tt_axiom(!empty());
225 auto *old_item = std::launder(--_top);
226 std::destroy_at(old_item);
227 }
228
233 void pop_back(iterator_type new_end) noexcept
234 {
235 while (_top != new_end) {
236 pop_back();
237 }
238 }
239
242 void clear() noexcept
243 {
244 std::destroy(begin(), end());
245 _top = begin();
246 }
247
248private:
249 std::aligned_storage_t<sizeof(T), std::alignment_of_v<T>> _buffer[MaxSize];
250 pointer_type _top;
251};
252
253}
A static sized stack.
Definition stack.hpp:23
reference_type operator[](size_t index) noexcept
Get a reference to an element on the stack at an index.
Definition stack.hpp:139
const_iterator_type end() const noexcept
Get an iterator to the last element on the stack.
Definition stack.hpp:90
const_iterator_type cend() const noexcept
Get an iterator to the last element on the stack.
Definition stack.hpp:98
reference_type back() noexcept
Get a reference to the element at the top of the stack.
Definition stack.hpp:182
const_reference_type back() const noexcept
Get a reference to the element at the top of the stack.
Definition stack.hpp:191
void emplace_back(Args &&... args) noexcept
Construct an object after the current top of the stack.
Definition stack.hpp:202
bool empty() const noexcept
Check if the stack is empty.
Definition stack.hpp:130
reference_type at(size_t index) noexcept
Get a reference to an element on the stack at an index.
Definition stack.hpp:159
stack() noexcept
Construct an empty stack.
Definition stack.hpp:37
void pop_back(iterator_type new_end) noexcept
Pop elements of the stack through the given iterator.
Definition stack.hpp:233
stack(std::initializer_list< value_type > init) noexcept
Construct a stack with the given data.
Definition stack.hpp:42
void push_back(Arg &&arg) noexcept
Push a new value to after the current top of the stack.
Definition stack.hpp:214
void clear() noexcept
Remove all elements from the stack.
Definition stack.hpp:242
bool full() const noexcept
Check if the stack is full.
Definition stack.hpp:122
size_type size() const noexcept
The number of elements that fit on the stack.
Definition stack.hpp:114
const_iterator_type cbegin() const noexcept
Get an iterator to the first element on the stack.
Definition stack.hpp:74
iterator_type end() noexcept
Get an iterator to the last element on the stack.
Definition stack.hpp:82
constexpr size_type max_size() const noexcept
The maximum number of elements that fit on the stack.
Definition stack.hpp:106
void pop_back() noexcept
Remove the value at the top of the stack.
Definition stack.hpp:222
const_reference_type at(size_t index) const noexcept
Get a reference to an element on the stack at an index.
Definition stack.hpp:171
const_reference_type operator[](size_t index) const noexcept
Get a reference to an element on the stack at an index.
Definition stack.hpp:149
const_iterator_type begin() const noexcept
Get an iterator to the first element on the stack.
Definition stack.hpp:66
iterator_type begin() noexcept
Get an iterator to the first element on the stack.
Definition stack.hpp:58