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 hi::inline v1 {
14
22template<typename T, std::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 = std::size_t;
33 using difference_type = ptrdiff_t;
34
37 stack() noexcept : _top(begin()) {}
38
42 stack(std::initializer_list<value_type> init) noexcept : _top(begin())
43 {
44 for (hilet &init_item : init) {
45 push_back(init_item);
46 }
47 }
48
49 ~stack() noexcept
50 {
51 clear();
52 }
53
57 [[nodiscard]] iterator_type begin() noexcept
58 {
59 return std::launder(reinterpret_cast<pointer_type>(&_buffer[0]));
60 }
61
65 [[nodiscard]] const_iterator_type begin() const noexcept
66 {
67 return std::launder(reinterpret_cast<const_pointer_type>(&_buffer[0]));
68 }
69
73 [[nodiscard]] const_iterator_type cbegin() const noexcept
74 {
75 return std::launder(reinterpret_cast<const_pointer_type>(&_buffer[0]));
76 }
77
81 [[nodiscard]] iterator_type end() noexcept
82 {
83 return _top;
84 }
85
89 [[nodiscard]] const_iterator_type end() const noexcept
90 {
91 return _top;
92 }
93
97 [[nodiscard]] const_iterator_type cend() const noexcept
98 {
99 return _top;
100 }
101
105 [[nodiscard]] constexpr size_type max_size() const noexcept
106 {
107 return MaxSize;
108 }
109
113 [[nodiscard]] size_type size() const noexcept
114 {
115 return narrow_cast<size_type>(end() - begin());
116 }
117
121 [[nodiscard]] bool full() const noexcept
122 {
123 return _top == (begin() + max_size());
124 }
125
129 [[nodiscard]] bool empty() const noexcept
130 {
131 return _top == begin();
132 }
133
138 [[nodiscard]] reference_type operator[](std::size_t index) noexcept
139 {
140 hi_axiom(index < size());
141 return *std::launder(reinterpret_cast<pointer_type>(&_buffer[index]));
142 }
143
148 [[nodiscard]] const_reference_type operator[](std::size_t index) const noexcept
149 {
150 hi_axiom(index < size());
151 return *std::launder(reinterpret_cast<pointer_type>(&_buffer[index]));
152 }
153
158 [[nodiscard]] reference_type at(std::size_t index) noexcept
159 {
160 if (index >= size()) {
161 throw std::out_of_range("stack::at");
162 }
163 return (*this)[index];
164 }
165
170 [[nodiscard]] const_reference_type at(std::size_t index) const noexcept
171 {
172 if (index >= size()) {
173 throw std::out_of_range("stack::at");
174 }
175 return (*this)[index];
176 }
177
181 [[nodiscard]] reference_type back() noexcept
182 {
183 hi_axiom(!empty());
184 return *std::launder(reinterpret_cast<pointer_type>(_top - 1));
185 }
186
190 [[nodiscard]] const_reference_type back() const noexcept
191 {
192 hi_axiom(!empty());
193 return *std::launder(reinterpret_cast<pointer_type>(_top - 1));
194 }
195
200 template<typename... Args>
201 void emplace_back(Args &&...args) noexcept
202 {
203 hi_axiom(!full());
204 new (end()) value_type(std::forward<Args>(args)...);
205 ++_top;
206 }
207
212 template<typename Arg>
213 requires(std::is_convertible_v<Arg, value_type>) void push_back(Arg &&arg) noexcept
214 {
215 emplace_back(std::forward<Arg>(arg));
216 }
217
221 void pop_back() noexcept
222 {
223 hi_axiom(!empty());
224 auto *old_item = std::launder(--_top);
225 std::destroy_at(old_item);
226 }
227
232 void pop_back(iterator_type new_end) noexcept
233 {
234 while (_top != new_end) {
235 pop_back();
236 }
237 }
238
241 void clear() noexcept
242 {
243 std::destroy(begin(), end());
244 _top = begin();
245 }
246
247private:
248 std::aligned_storage_t<sizeof(T), std::alignment_of_v<T>> _buffer[MaxSize];
249 pointer_type _top;
250};
251
252} // namespace hi::inline v1
This file includes required definitions.
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23
A static sized stack.
Definition stack.hpp:23
void pop_back() noexcept
Remove the value at the top of the stack.
Definition stack.hpp:221
size_type size() const noexcept
The number of elements that fit on the stack.
Definition stack.hpp:113
reference_type operator[](std::size_t index) noexcept
Get a reference to an element on the stack at an index.
Definition stack.hpp:138
const_iterator_type cbegin() const noexcept
Get an iterator to the first element on the stack.
Definition stack.hpp:73
void push_back(Arg &&arg) noexcept
Push a new value to after the current top of the stack.
Definition stack.hpp:213
void clear() noexcept
Remove all elements from the stack.
Definition stack.hpp:241
const_reference_type at(std::size_t index) const noexcept
Get a reference to an element on the stack at an index.
Definition stack.hpp:170
void pop_back(iterator_type new_end) noexcept
Pop elements of the stack through the given iterator.
Definition stack.hpp:232
reference_type back() noexcept
Get a reference to the element at the top of the stack.
Definition stack.hpp:181
const_iterator_type begin() const noexcept
Get an iterator to the first element on the stack.
Definition stack.hpp:65
bool full() const noexcept
Check if the stack is full.
Definition stack.hpp:121
stack() noexcept
Construct an empty stack.
Definition stack.hpp:37
iterator_type begin() noexcept
Get an iterator to the first element on the stack.
Definition stack.hpp:57
reference_type at(std::size_t index) noexcept
Get a reference to an element on the stack at an index.
Definition stack.hpp:158
const_iterator_type end() const noexcept
Get an iterator to the last element on the stack.
Definition stack.hpp:89
void emplace_back(Args &&...args) noexcept
Construct an object after the current top of the stack.
Definition stack.hpp:201
const_reference_type back() const noexcept
Get a reference to the element at the top of the stack.
Definition stack.hpp:190
const_reference_type operator[](std::size_t index) const noexcept
Get a reference to an element on the stack at an index.
Definition stack.hpp:148
stack(std::initializer_list< value_type > init) noexcept
Construct a stack with the given data.
Definition stack.hpp:42
bool empty() const noexcept
Check if the stack is empty.
Definition stack.hpp:129
constexpr size_type max_size() const noexcept
The maximum number of elements that fit on the stack.
Definition stack.hpp:105
const_iterator_type cend() const noexcept
Get an iterator to the last element on the stack.
Definition stack.hpp:97
iterator_type end() noexcept
Get an iterator to the last element on the stack.
Definition stack.hpp:81