HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
stack.hpp
1// Copyright Take Vos 2020-2021.
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 "../utility/module.hpp"
8#include <type_traits>
9#include <memory>
10#include <initializer_list>
11
12namespace hi::inline v1 {
13
21template<typename T, std::size_t MaxSize>
22class stack {
23public:
24 using value_type = T;
25 using pointer = value_type *;
26 using const_pointer = value_type const *;
27 using reference_type = value_type &;
28 using const_reference_type = value_type const &;
29 using iterator = pointer;
30 using const_iterator = const_pointer;
31 using size_type = std::size_t;
32 using difference_type = ptrdiff_t;
33
36 stack() noexcept : _top(begin()) {}
37
41 stack(std::initializer_list<value_type> init) noexcept : _top(begin())
42 {
43 for (hilet &init_item : init) {
44 push_back(init_item);
45 }
46 }
47
48 ~stack() noexcept
49 {
50 clear();
51 }
52
53 [[nodiscard]] const_pointer data() const noexcept
54 {
55 return reinterpret_cast<const_pointer>(_buffer);
56 }
57
58 [[nodiscard]] pointer data() noexcept
59 {
60 return reinterpret_cast<pointer>(_buffer);
61 }
62
66 [[nodiscard]] iterator begin() noexcept
67 {
68 return data();
69 }
70
74 [[nodiscard]] const_iterator begin() const noexcept
75 {
76 return data();
77 }
78
82 [[nodiscard]] const_iterator cbegin() const noexcept
83 {
84 return data();
85 }
86
90 [[nodiscard]] iterator end() noexcept
91 {
92 return _top;
93 }
94
98 [[nodiscard]] const_iterator end() const noexcept
99 {
100 return _top;
101 }
102
106 [[nodiscard]] const_iterator cend() const noexcept
107 {
108 return _top;
109 }
110
114 [[nodiscard]] constexpr size_type max_size() const noexcept
115 {
116 return MaxSize;
117 }
118
122 [[nodiscard]] size_type size() const noexcept
123 {
124 return narrow_cast<size_type>(std::distance(begin(), end()));
125 }
126
130 [[nodiscard]] bool full() const noexcept
131 {
132 return _top == (data() + max_size());
133 }
134
138 [[nodiscard]] bool empty() const noexcept
139 {
140 return _top == data();
141 }
142
147 [[nodiscard]] reference_type operator[](std::size_t index) noexcept
148 {
149 hi_assert_bounds(index, *this);
150 return *(data() + index);
151 }
152
157 [[nodiscard]] const_reference_type operator[](std::size_t index) const noexcept
158 {
159 hi_assert_bounds(index, *this);
160 return *(data() + index);
161 }
162
167 [[nodiscard]] reference_type at(std::size_t index) noexcept
168 {
169 if (index >= size()) {
170 throw std::out_of_range("stack::at");
171 }
172 return (*this)[index];
173 }
174
179 [[nodiscard]] const_reference_type at(std::size_t index) const noexcept
180 {
181 if (index >= size()) {
182 throw std::out_of_range("stack::at");
183 }
184 return (*this)[index];
185 }
186
190 [[nodiscard]] reference_type back() noexcept
191 {
192 hi_axiom(not empty());
193 return *(_top - 1);
194 }
195
199 [[nodiscard]] const_reference_type back() const noexcept
200 {
201 hi_axiom(not empty());
202 return *(_top - 1);
203 }
204
209 template<typename... Args>
210 void emplace_back(Args &&...args) noexcept
211 {
212 hi_axiom(not full());
213 new (_top++) value_type(std::forward<Args>(args)...);
214 }
215
220 template<typename Arg>
221 requires(std::is_convertible_v<Arg, value_type>) void push_back(Arg &&arg) noexcept
222 {
223 emplace_back(std::forward<Arg>(arg));
224 }
225
229 void pop_back() noexcept
230 {
231 hi_axiom(not empty());
232 std::destroy_at(--_top);
233 }
234
239 void pop_back(iterator new_end) noexcept
240 {
241 while (_top != new_end) {
242 pop_back();
243 }
244 }
245
248 void clear() noexcept
249 {
250 std::destroy(data(), _top);
251 _top = data();
252 }
253
254private:
255 pointer _top;
256 alignas(T) std::byte _buffer[MaxSize * sizeof(T)];
257};
258
259} // namespace hi::inline v1
#define hi_assert_bounds(x,...)
Assert if a value is within bounds.
Definition assert.hpp:225
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:253
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:13
A static sized stack.
Definition stack.hpp:22
void pop_back() noexcept
Remove the value at the top of the stack.
Definition stack.hpp:229
size_type size() const noexcept
The number of elements that fit on the stack.
Definition stack.hpp:122
reference_type operator[](std::size_t index) noexcept
Get a reference to an element on the stack at an index.
Definition stack.hpp:147
void push_back(Arg &&arg) noexcept
Push a new value to after the current top of the stack.
Definition stack.hpp:221
void clear() noexcept
Remove all elements from the stack.
Definition stack.hpp:248
void pop_back(iterator new_end) noexcept
Pop elements of the stack through the given iterator.
Definition stack.hpp:239
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:179
const_iterator end() 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:190
bool full() const noexcept
Check if the stack is full.
Definition stack.hpp:130
stack() noexcept
Construct an empty stack.
Definition stack.hpp:36
reference_type at(std::size_t index) noexcept
Get a reference to an element on the stack at an index.
Definition stack.hpp:167
const_iterator begin() const noexcept
Get an iterator to the first element on the stack.
Definition stack.hpp:74
void emplace_back(Args &&...args) noexcept
Construct an object after the current top of the stack.
Definition stack.hpp:210
const_reference_type back() const noexcept
Get a reference to the element at the top of the stack.
Definition stack.hpp:199
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:157
iterator end() noexcept
Get an iterator to the last element on the stack.
Definition stack.hpp:90
stack(std::initializer_list< value_type > init) noexcept
Construct a stack with the given data.
Definition stack.hpp:41
bool empty() const noexcept
Check if the stack is empty.
Definition stack.hpp:138
const_iterator cend() const noexcept
Get an iterator to the last element on the stack.
Definition stack.hpp:106
constexpr size_type max_size() const noexcept
The maximum number of elements that fit on the stack.
Definition stack.hpp:114
const_iterator cbegin() const noexcept
Get an iterator to the first element on the stack.
Definition stack.hpp:82
iterator begin() noexcept
Get an iterator to the first element on the stack.
Definition stack.hpp:66
Definition concepts.hpp:36
T distance(T... args)