tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
stack.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch
3
4#ifndef TETL_STACK_STACK_HPP
5#define TETL_STACK_STACK_HPP
6
7#include <etl/_iterator/begin.hpp>
8#include <etl/_iterator/data.hpp>
9#include <etl/_iterator/end.hpp>
10#include <etl/_iterator/rbegin.hpp>
11#include <etl/_iterator/rend.hpp>
12#include <etl/_iterator/size.hpp>
13#include <etl/_type_traits/declval.hpp>
14#include <etl/_type_traits/is_nothrow_swappable.hpp>
15#include <etl/_type_traits/is_swappable.hpp>
16#include <etl/_utility/forward.hpp>
17#include <etl/_utility/move.hpp>
18
19namespace etl {
20
21/// The stack class is a container adapter that gives the programmer
22/// the functionality of a stack - specifically, a LIFO (last-in, first-out)
23/// data structure.
24///
25/// The class template acts as a wrapper to the underlying container -
26/// only a specific set of functions is provided. The stack pushes and pops the
27/// element from the back of the underlying container, known as the top of the
28/// stack.
29///
30/// \ingroup stack
31template <typename T, typename Container>
32struct stack {
33 using value_type = typename Container::value_type;
34 using reference = typename Container::reference;
35 using const_reference = typename Container::const_reference;
36 using size_type = typename Container::size_type;
37 using container_type = Container;
38
39 /// \brief Default constructor. Value-initializes the container.
40 constexpr stack()
41 : stack{Container{}}
42 {
43 }
44
45 /// \brief Copy-constructs the underlying container c with the contents of
46 /// cont.
47 constexpr explicit stack(Container const& cont)
48 : c{cont}
49 {
50 }
51
52 /// \brief Move-constructs the underlying container c with cont .
53 constexpr explicit stack(Container&& cont)
54 : c{etl::move(cont)}
55 {
56 }
57
58 /// \brief Copy constructor.
59 constexpr stack(stack const& other) = default;
60
61 /// \brief Move constructor.
62 constexpr stack(stack&& other) noexcept = default;
63
64 /// \brief Checks if the underlying container has no elements.
65 [[nodiscard]] constexpr auto empty() const noexcept(noexcept(declval<Container>().empty())) -> bool
66 {
67 return c.empty();
68 }
69
70 /// \brief Returns the number of elements in the underlying container.
71 [[nodiscard]] constexpr auto size() const noexcept(noexcept(declval<Container>().size())) -> size_type
72 {
73 return c.size();
74 }
75
76 /// \brief Returns reference to the top element in the stack. This is the
77 /// most recently pushed element. This element will be removed on a call to
78 /// pop().
79 [[nodiscard]] constexpr auto top() noexcept(noexcept(declval<Container>().back())) -> reference
80 {
81 return c.back();
82 }
83
84 /// \brief Returns reference to the top element in the stack. This is the
85 /// most recently pushed element. This element will be removed on a call to
86 /// pop().
87 [[nodiscard]] constexpr auto top() const noexcept(noexcept(declval<Container>().back())) -> const_reference
88 {
89 return c.back();
90 }
91
92 /// \brief Pushes the given element value to the top of the stack.
93 constexpr auto push(value_type const& x) noexcept(noexcept(declval<Container>().push_back(x))) -> void
94 {
95 c.push_back(x);
96 }
97
98 /// \brief Pushes the given element value to the top of the stack.
99 constexpr auto push(value_type&& x) noexcept(noexcept(declval<Container>().push_back(etl::move(x)))) -> void
100 {
101 c.push_back(etl::move(x));
102 }
103
104 /// \brief Pushes a new element on top of the stack. The element is
105 /// constructed in-place, i.e. no copy or move operations are performed. The
106 /// constructor of the element is called with exactly the same arguments as
107 /// supplied to the function.
108 template <typename... Args>
109 constexpr auto
110 emplace(Args&&... args) noexcept(noexcept(declval<Container>().emplace_back(etl::forward<Args>(args)...)))
111 -> decltype(auto)
112 {
113 return c.emplace_back(etl::forward<Args>(args)...);
114 }
115
116 /// \brief Removes the top element from the stack.
117 constexpr auto pop() noexcept(noexcept(declval<Container>().pop_back())) -> void
118 {
119 c.pop_back();
120 }
121
122 /// \brief Exchanges the contents of the container adaptor with those of
123 /// other.
124 constexpr auto swap(stack& s) noexcept(is_nothrow_swappable_v<Container>) -> void
125 {
126 using etl::swap;
127 swap(c, s.c);
128 }
129
130 /// \brief Compares the contents of the underlying containers of two
131 /// container adaptors. The comparison is done by applying the corresponding
132 /// operator to the underlying containers.
133 [[nodiscard]] friend constexpr auto
134 operator==(stack const& lhs, stack const& rhs) noexcept(noexcept(declval<Container>() == declval<Container>()))
135 -> bool
136 {
137 return lhs.c == rhs.c;
138 }
139
140 /// \brief Compares the contents of the underlying containers of two
141 /// container adaptors. The comparison is done by applying the corresponding
142 /// operator to the underlying containers.
143 [[nodiscard]] friend constexpr auto
144 operator!=(stack const& lhs, stack const& rhs) noexcept(noexcept(declval<Container>() != declval<Container>()))
145 -> bool
146 {
147 return lhs.c != rhs.c;
148 }
149
150 /// \brief Compares the contents of the underlying containers of two
151 /// container adaptors. The comparison is done by applying the corresponding
152 /// operator to the underlying containers.
153 [[nodiscard]] friend constexpr auto
154 operator<(stack const& lhs, stack const& rhs) noexcept(noexcept(declval<Container>() < declval<Container>()))
155 -> bool
156 {
157 return lhs.c < rhs.c;
158 }
159
160 /// \brief Compares the contents of the underlying containers of two
161 /// container adaptors. The comparison is done by applying the corresponding
162 /// operator to the underlying containers.
163 [[nodiscard]] friend constexpr auto
164 operator<=(stack const& lhs, stack const& rhs) noexcept(noexcept(declval<Container>() <= declval<Container>()))
165 -> bool
166 {
167 return lhs.c <= rhs.c;
168 }
169
170 /// \brief Compares the contents of the underlying containers of two
171 /// container adaptors. The comparison is done by applying the corresponding
172 /// operator to the underlying containers.
173 [[nodiscard]] friend constexpr auto
174 operator>(stack const& lhs, stack const& rhs) noexcept(noexcept(declval<Container>() > declval<Container>()))
175 -> bool
176 {
177 return lhs.c > rhs.c;
178 }
179
180 /// \brief Compares the contents of the underlying containers of two
181 /// container adaptors. The comparison is done by applying the corresponding
182 /// operator to the underlying containers.
183 [[nodiscard]] friend constexpr auto
184 operator>=(stack const& lhs, stack const& rhs) noexcept(noexcept(declval<Container>() >= declval<Container>()))
185 -> bool
186 {
187 return lhs.c >= rhs.c;
188 }
189
190protected:
191 Container c;
192};
193
194// These deduction guides are provided for stack to allow deduction from
195// underlying container type.
196template <typename Container>
197stack(Container) -> stack<typename Container::value_type, Container>;
198
199/// \brief Specializes the swap algorithm for stack. Swaps the contents of lhs
200/// and rhs. This overload only participates in overload resolution if
201/// is_swappable<C>::value is true.
202template <typename T, typename C>
203 requires(is_swappable_v<C>)
204constexpr auto swap(stack<T, C>& lhs, stack<T, C>& rhs) noexcept(noexcept(lhs.swap(rhs))) -> void
205{
206 lhs.swap(rhs);
207}
208
209} // namespace etl
210
211#endif // TETL_STACK_STACK_HPP
Definition adjacent_find.hpp:9
constexpr auto swap(stack< T, C > &lhs, stack< T, C > &rhs) noexcept(noexcept(lhs.swap(rhs))) -> void
Specializes the swap algorithm for stack. Swaps the contents of lhs and rhs. This overload only parti...
Definition stack.hpp:204
stack(Container) -> stack< typename Container::value_type, Container >
The stack class is a container adapter that gives the programmer the functionality of a stack - speci...
Definition stack.hpp:32
constexpr auto swap(stack &s) noexcept(is_nothrow_swappable_v< Container >) -> void
Exchanges the contents of the container adaptor with those of other.
Definition stack.hpp:124
friend constexpr auto operator>=(stack const &lhs, stack const &rhs) noexcept(noexcept(declval< Container >() >=declval< Container >())) -> bool
Compares the contents of the underlying containers of two container adaptors. The comparison is done ...
Definition stack.hpp:184
constexpr auto emplace(Args &&... args) noexcept(noexcept(declval< Container >().emplace_back(etl::forward< Args >(args)...))) -> decltype(auto)
Pushes a new element on top of the stack. The element is constructed in-place, i.e....
Definition stack.hpp:110
Container c
Definition stack.hpp:191
friend constexpr auto operator==(stack const &lhs, stack const &rhs) noexcept(noexcept(declval< Container >()==declval< Container >())) -> bool
Compares the contents of the underlying containers of two container adaptors. The comparison is done ...
Definition stack.hpp:134
constexpr auto top() noexcept(noexcept(declval< Container >().back())) -> reference
Returns reference to the top element in the stack. This is the most recently pushed element....
Definition stack.hpp:79
constexpr stack(Container &&cont)
Move-constructs the underlying container c with cont .
Definition stack.hpp:53
constexpr stack(stack const &other)=default
Copy constructor.
constexpr auto empty() const noexcept(noexcept(declval< Container >().empty())) -> bool
Checks if the underlying container has no elements.
Definition stack.hpp:65
constexpr auto push(value_type const &x) noexcept(noexcept(declval< Container >().push_back(x))) -> void
Pushes the given element value to the top of the stack.
Definition stack.hpp:93
friend constexpr auto operator<=(stack const &lhs, stack const &rhs) noexcept(noexcept(declval< Container >()<=declval< Container >())) -> bool
Compares the contents of the underlying containers of two container adaptors. The comparison is done ...
Definition stack.hpp:164
constexpr auto top() const noexcept(noexcept(declval< Container >().back())) -> const_reference
Returns reference to the top element in the stack. This is the most recently pushed element....
Definition stack.hpp:87
constexpr auto pop() noexcept(noexcept(declval< Container >().pop_back())) -> void
Removes the top element from the stack.
Definition stack.hpp:117
constexpr stack()
Default constructor. Value-initializes the container.
Definition stack.hpp:40
constexpr auto push(value_type &&x) noexcept(noexcept(declval< Container >().push_back(etl::move(x)))) -> void
Pushes the given element value to the top of the stack.
Definition stack.hpp:99
constexpr stack(stack &&other) noexcept=default
Move constructor.
constexpr stack(Container const &cont)
Copy-constructs the underlying container c with the contents of cont.
Definition stack.hpp:47
friend constexpr auto operator<(stack const &lhs, stack const &rhs) noexcept(noexcept(declval< Container >()< declval< Container >())) -> bool
Compares the contents of the underlying containers of two container adaptors. The comparison is done ...
Definition stack.hpp:154
friend constexpr auto operator>(stack const &lhs, stack const &rhs) noexcept(noexcept(declval< Container >() > declval< Container >())) -> bool
Compares the contents of the underlying containers of two container adaptors. The comparison is done ...
Definition stack.hpp:174
friend constexpr auto operator!=(stack const &lhs, stack const &rhs) noexcept(noexcept(declval< Container >() !=declval< Container >())) -> bool
Compares the contents of the underlying containers of two container adaptors. The comparison is done ...
Definition stack.hpp:144
constexpr auto size() const noexcept(noexcept(declval< Container >().size())) -> size_type
Returns the number of elements in the underlying container.
Definition stack.hpp:71