stack revision 1.1 1 // -*- C++ -*-
2 //===---------------------------- stack -----------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef _LIBCPP_STACK
11 #define _LIBCPP_STACK
12
13 /*
14 stack synopsis
15
16 namespace std
17 {
18
19 template <class T, class Container = deque<T>>
20 class stack
21 {
22 public:
23 typedef Container container_type;
24 typedef typename container_type::value_type value_type;
25 typedef typename container_type::reference reference;
26 typedef typename container_type::const_reference const_reference;
27 typedef typename container_type::size_type size_type;
28
29 protected:
30 container_type c;
31
32 public:
33 stack() = default;
34 ~stack() = default;
35
36 stack(const stack& q) = default;
37 stack(stack&& q) = default;
38
39 stack& operator=(const stack& q) = default;
40 stack& operator=(stack&& q) = default;
41
42 explicit stack(const container_type& c);
43 explicit stack(container_type&& c);
44 template <class Alloc> explicit stack(const Alloc& a);
45 template <class Alloc> stack(const container_type& c, const Alloc& a);
46 template <class Alloc> stack(container_type&& c, const Alloc& a);
47 template <class Alloc> stack(const stack& c, const Alloc& a);
48 template <class Alloc> stack(stack&& c, const Alloc& a);
49
50 bool empty() const;
51 size_type size() const;
52 reference top();
53 const_reference top() const;
54
55 void push(const value_type& x);
56 void push(value_type&& x);
57 template <class... Args> reference emplace(Args&&... args); // reference in C++17
58 void pop();
59
60 void swap(stack& c) noexcept(is_nothrow_swappable_v<Container>)
61 };
62
63 template<class Container>
64 stack(Container) -> stack<typename Container::value_type, Container>; // C++17
65
66 template<class Container, class Allocator>
67 stack(Container, Allocator) -> stack<typename Container::value_type, Container>; // C++17
68
69 template <class T, class Container>
70 bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
71 template <class T, class Container>
72 bool operator< (const stack<T, Container>& x, const stack<T, Container>& y);
73 template <class T, class Container>
74 bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y);
75 template <class T, class Container>
76 bool operator> (const stack<T, Container>& x, const stack<T, Container>& y);
77 template <class T, class Container>
78 bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
79 template <class T, class Container>
80 bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
81
82 template <class T, class Container>
83 void swap(stack<T, Container>& x, stack<T, Container>& y)
84 noexcept(noexcept(x.swap(y)));
85
86 } // std
87
88 */
89
90 #include <__config>
91 #include <deque>
92
93 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
94 #pragma GCC system_header
95 #endif
96
97 _LIBCPP_BEGIN_NAMESPACE_STD
98
99 template <class _Tp, class _Container = deque<_Tp> > class _LIBCPP_TEMPLATE_VIS stack;
100
101 template <class _Tp, class _Container>
102 _LIBCPP_INLINE_VISIBILITY
103 bool
104 operator==(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y);
105
106 template <class _Tp, class _Container>
107 _LIBCPP_INLINE_VISIBILITY
108 bool
109 operator< (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y);
110
111 template <class _Tp, class _Container /*= deque<_Tp>*/>
112 class _LIBCPP_TEMPLATE_VIS stack
113 {
114 public:
115 typedef _Container container_type;
116 typedef typename container_type::value_type value_type;
117 typedef typename container_type::reference reference;
118 typedef typename container_type::const_reference const_reference;
119 typedef typename container_type::size_type size_type;
120 static_assert((is_same<_Tp, value_type>::value), "" );
121
122 protected:
123 container_type c;
124
125 public:
126 _LIBCPP_INLINE_VISIBILITY
127 stack()
128 _NOEXCEPT_(is_nothrow_default_constructible<container_type>::value)
129 : c() {}
130
131 _LIBCPP_INLINE_VISIBILITY
132 stack(const stack& __q) : c(__q.c) {}
133
134 _LIBCPP_INLINE_VISIBILITY
135 stack& operator=(const stack& __q) {c = __q.c; return *this;}
136
137
138 #ifndef _LIBCPP_CXX03_LANG
139 _LIBCPP_INLINE_VISIBILITY
140 stack(stack&& __q)
141 _NOEXCEPT_(is_nothrow_move_constructible<container_type>::value)
142 : c(_VSTD::move(__q.c)) {}
143
144 _LIBCPP_INLINE_VISIBILITY
145 stack& operator=(stack&& __q)
146 _NOEXCEPT_(is_nothrow_move_assignable<container_type>::value)
147 {c = _VSTD::move(__q.c); return *this;}
148
149 _LIBCPP_INLINE_VISIBILITY
150 explicit stack(container_type&& __c) : c(_VSTD::move(__c)) {}
151 #endif // _LIBCPP_CXX03_LANG
152
153 _LIBCPP_INLINE_VISIBILITY
154 explicit stack(const container_type& __c) : c(__c) {}
155
156 template <class _Alloc>
157 _LIBCPP_INLINE_VISIBILITY
158 explicit stack(const _Alloc& __a,
159 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0)
160 : c(__a) {}
161 template <class _Alloc>
162 _LIBCPP_INLINE_VISIBILITY
163 stack(const container_type& __c, const _Alloc& __a,
164 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0)
165 : c(__c, __a) {}
166 template <class _Alloc>
167 _LIBCPP_INLINE_VISIBILITY
168 stack(const stack& __s, const _Alloc& __a,
169 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0)
170 : c(__s.c, __a) {}
171 #ifndef _LIBCPP_CXX03_LANG
172 template <class _Alloc>
173 _LIBCPP_INLINE_VISIBILITY
174 stack(container_type&& __c, const _Alloc& __a,
175 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0)
176 : c(_VSTD::move(__c), __a) {}
177 template <class _Alloc>
178 _LIBCPP_INLINE_VISIBILITY
179 stack(stack&& __s, const _Alloc& __a,
180 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0)
181 : c(_VSTD::move(__s.c), __a) {}
182 #endif // _LIBCPP_CXX03_LANG
183
184 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
185 bool empty() const {return c.empty();}
186 _LIBCPP_INLINE_VISIBILITY
187 size_type size() const {return c.size();}
188 _LIBCPP_INLINE_VISIBILITY
189 reference top() {return c.back();}
190 _LIBCPP_INLINE_VISIBILITY
191 const_reference top() const {return c.back();}
192
193 _LIBCPP_INLINE_VISIBILITY
194 void push(const value_type& __v) {c.push_back(__v);}
195 #ifndef _LIBCPP_CXX03_LANG
196 _LIBCPP_INLINE_VISIBILITY
197 void push(value_type&& __v) {c.push_back(_VSTD::move(__v));}
198
199 template <class... _Args>
200 _LIBCPP_INLINE_VISIBILITY
201 #if _LIBCPP_STD_VER > 14
202 decltype(auto) emplace(_Args&&... __args)
203 { return c.emplace_back(_VSTD::forward<_Args>(__args)...);}
204 #else
205 void emplace(_Args&&... __args)
206 { c.emplace_back(_VSTD::forward<_Args>(__args)...);}
207 #endif
208 #endif // _LIBCPP_CXX03_LANG
209
210 _LIBCPP_INLINE_VISIBILITY
211 void pop() {c.pop_back();}
212
213 _LIBCPP_INLINE_VISIBILITY
214 void swap(stack& __s)
215 _NOEXCEPT_(__is_nothrow_swappable<container_type>::value)
216 {
217 using _VSTD::swap;
218 swap(c, __s.c);
219 }
220
221 template <class T1, class _C1>
222 friend
223 bool
224 operator==(const stack<T1, _C1>& __x, const stack<T1, _C1>& __y);
225
226 template <class T1, class _C1>
227 friend
228 bool
229 operator< (const stack<T1, _C1>& __x, const stack<T1, _C1>& __y);
230 };
231
232 #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
233 template<class _Container,
234 class = _EnableIf<!__is_allocator<_Container>::value>
235 >
236 stack(_Container)
237 -> stack<typename _Container::value_type, _Container>;
238
239 template<class _Container,
240 class _Alloc,
241 class = _EnableIf<!__is_allocator<_Container>::value>,
242 class = _EnableIf<__is_allocator<_Alloc>::value>
243 >
244 stack(_Container, _Alloc)
245 -> stack<typename _Container::value_type, _Container>;
246 #endif
247
248 template <class _Tp, class _Container>
249 inline _LIBCPP_INLINE_VISIBILITY
250 bool
251 operator==(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
252 {
253 return __x.c == __y.c;
254 }
255
256 template <class _Tp, class _Container>
257 inline _LIBCPP_INLINE_VISIBILITY
258 bool
259 operator< (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
260 {
261 return __x.c < __y.c;
262 }
263
264 template <class _Tp, class _Container>
265 inline _LIBCPP_INLINE_VISIBILITY
266 bool
267 operator!=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
268 {
269 return !(__x == __y);
270 }
271
272 template <class _Tp, class _Container>
273 inline _LIBCPP_INLINE_VISIBILITY
274 bool
275 operator> (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
276 {
277 return __y < __x;
278 }
279
280 template <class _Tp, class _Container>
281 inline _LIBCPP_INLINE_VISIBILITY
282 bool
283 operator>=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
284 {
285 return !(__x < __y);
286 }
287
288 template <class _Tp, class _Container>
289 inline _LIBCPP_INLINE_VISIBILITY
290 bool
291 operator<=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
292 {
293 return !(__y < __x);
294 }
295
296 template <class _Tp, class _Container>
297 inline _LIBCPP_INLINE_VISIBILITY
298 _EnableIf<__is_swappable<_Container>::value, void>
299 swap(stack<_Tp, _Container>& __x, stack<_Tp, _Container>& __y)
300 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
301 {
302 __x.swap(__y);
303 }
304
305 template <class _Tp, class _Container, class _Alloc>
306 struct _LIBCPP_TEMPLATE_VIS uses_allocator<stack<_Tp, _Container>, _Alloc>
307 : public uses_allocator<_Container, _Alloc>
308 {
309 };
310
311 _LIBCPP_END_NAMESPACE_STD
312
313 #endif // _LIBCPP_STACK
314