| 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 | typename enable_if<uses_allocator<container_type, | 
|---|
| 160 | _Alloc>::value>::type* = 0) | 
|---|
| 161 | : c(__a) {} | 
|---|
| 162 | template <class _Alloc> | 
|---|
| 163 | _LIBCPP_INLINE_VISIBILITY | 
|---|
| 164 | stack(const container_type& __c, const _Alloc& __a, | 
|---|
| 165 | typename enable_if<uses_allocator<container_type, | 
|---|
| 166 | _Alloc>::value>::type* = 0) | 
|---|
| 167 | : c(__c, __a) {} | 
|---|
| 168 | template <class _Alloc> | 
|---|
| 169 | _LIBCPP_INLINE_VISIBILITY | 
|---|
| 170 | stack(const stack& __s, const _Alloc& __a, | 
|---|
| 171 | typename enable_if<uses_allocator<container_type, | 
|---|
| 172 | _Alloc>::value>::type* = 0) | 
|---|
| 173 | : c(__s.c, __a) {} | 
|---|
| 174 | #ifndef _LIBCPP_CXX03_LANG | 
|---|
| 175 | template <class _Alloc> | 
|---|
| 176 | _LIBCPP_INLINE_VISIBILITY | 
|---|
| 177 | stack(container_type&& __c, const _Alloc& __a, | 
|---|
| 178 | typename enable_if<uses_allocator<container_type, | 
|---|
| 179 | _Alloc>::value>::type* = 0) | 
|---|
| 180 | : c(_VSTD::move(__c), __a) {} | 
|---|
| 181 | template <class _Alloc> | 
|---|
| 182 | _LIBCPP_INLINE_VISIBILITY | 
|---|
| 183 | stack(stack&& __s, const _Alloc& __a, | 
|---|
| 184 | typename enable_if<uses_allocator<container_type, | 
|---|
| 185 | _Alloc>::value>::type* = 0) | 
|---|
| 186 | : c(_VSTD::move(__s.c), __a) {} | 
|---|
| 187 | #endif  // _LIBCPP_CXX03_LANG | 
|---|
| 188 |  | 
|---|
| 189 | _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY | 
|---|
| 190 | bool empty()     const      {return c.empty();} | 
|---|
| 191 | _LIBCPP_INLINE_VISIBILITY | 
|---|
| 192 | size_type size() const      {return c.size();} | 
|---|
| 193 | _LIBCPP_INLINE_VISIBILITY | 
|---|
| 194 | reference top()             {return c.back();} | 
|---|
| 195 | _LIBCPP_INLINE_VISIBILITY | 
|---|
| 196 | const_reference top() const {return c.back();} | 
|---|
| 197 |  | 
|---|
| 198 | _LIBCPP_INLINE_VISIBILITY | 
|---|
| 199 | void push(const value_type& __v) {c.push_back(__v);} | 
|---|
| 200 | #ifndef _LIBCPP_CXX03_LANG | 
|---|
| 201 | _LIBCPP_INLINE_VISIBILITY | 
|---|
| 202 | void push(value_type&& __v) {c.push_back(_VSTD::move(__v));} | 
|---|
| 203 |  | 
|---|
| 204 | template <class... _Args> | 
|---|
| 205 | _LIBCPP_INLINE_VISIBILITY | 
|---|
| 206 | #if _LIBCPP_STD_VER > 14 | 
|---|
| 207 | decltype(auto) emplace(_Args&&... __args) | 
|---|
| 208 | { return c.emplace_back(_VSTD::forward<_Args>(__args)...);} | 
|---|
| 209 | #else | 
|---|
| 210 | void      emplace(_Args&&... __args) | 
|---|
| 211 | {        c.emplace_back(_VSTD::forward<_Args>(__args)...);} | 
|---|
| 212 | #endif | 
|---|
| 213 | #endif  // _LIBCPP_CXX03_LANG | 
|---|
| 214 |  | 
|---|
| 215 | _LIBCPP_INLINE_VISIBILITY | 
|---|
| 216 | void pop() {c.pop_back();} | 
|---|
| 217 |  | 
|---|
| 218 | _LIBCPP_INLINE_VISIBILITY | 
|---|
| 219 | void swap(stack& __s) | 
|---|
| 220 | _NOEXCEPT_(__is_nothrow_swappable<container_type>::value) | 
|---|
| 221 | { | 
|---|
| 222 | using _VSTD::swap; | 
|---|
| 223 | swap(c, __s.c); | 
|---|
| 224 | } | 
|---|
| 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 | template <class T1, class _C1> | 
|---|
| 232 | friend | 
|---|
| 233 | bool | 
|---|
| 234 | operator< (const stack<T1, _C1>& __x, const stack<T1, _C1>& __y); | 
|---|
| 235 | }; | 
|---|
| 236 |  | 
|---|
| 237 | #ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES | 
|---|
| 238 | template<class _Container, | 
|---|
| 239 | class = typename enable_if<!__is_allocator<_Container>::value, nullptr_t>::type | 
|---|
| 240 | > | 
|---|
| 241 | stack(_Container) | 
|---|
| 242 | -> stack<typename _Container::value_type, _Container>; | 
|---|
| 243 |  | 
|---|
| 244 | template<class _Container, | 
|---|
| 245 | class _Alloc, | 
|---|
| 246 | class = typename enable_if<!__is_allocator<_Container>::value, nullptr_t>::type, | 
|---|
| 247 | class = typename enable_if< __is_allocator<_Alloc>::value, nullptr_t>::type | 
|---|
| 248 | > | 
|---|
| 249 | stack(_Container, _Alloc) | 
|---|
| 250 | -> stack<typename _Container::value_type, _Container>; | 
|---|
| 251 | #endif | 
|---|
| 252 |  | 
|---|
| 253 | template <class _Tp, class _Container> | 
|---|
| 254 | inline _LIBCPP_INLINE_VISIBILITY | 
|---|
| 255 | bool | 
|---|
| 256 | operator==(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) | 
|---|
| 257 | { | 
|---|
| 258 | return __x.c == __y.c; | 
|---|
| 259 | } | 
|---|
| 260 |  | 
|---|
| 261 | template <class _Tp, class _Container> | 
|---|
| 262 | inline _LIBCPP_INLINE_VISIBILITY | 
|---|
| 263 | bool | 
|---|
| 264 | operator< (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) | 
|---|
| 265 | { | 
|---|
| 266 | return __x.c < __y.c; | 
|---|
| 267 | } | 
|---|
| 268 |  | 
|---|
| 269 | template <class _Tp, class _Container> | 
|---|
| 270 | inline _LIBCPP_INLINE_VISIBILITY | 
|---|
| 271 | bool | 
|---|
| 272 | operator!=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) | 
|---|
| 273 | { | 
|---|
| 274 | return !(__x == __y); | 
|---|
| 275 | } | 
|---|
| 276 |  | 
|---|
| 277 | template <class _Tp, class _Container> | 
|---|
| 278 | inline _LIBCPP_INLINE_VISIBILITY | 
|---|
| 279 | bool | 
|---|
| 280 | operator> (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) | 
|---|
| 281 | { | 
|---|
| 282 | return __y < __x; | 
|---|
| 283 | } | 
|---|
| 284 |  | 
|---|
| 285 | template <class _Tp, class _Container> | 
|---|
| 286 | inline _LIBCPP_INLINE_VISIBILITY | 
|---|
| 287 | bool | 
|---|
| 288 | operator>=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) | 
|---|
| 289 | { | 
|---|
| 290 | return !(__x < __y); | 
|---|
| 291 | } | 
|---|
| 292 |  | 
|---|
| 293 | template <class _Tp, class _Container> | 
|---|
| 294 | inline _LIBCPP_INLINE_VISIBILITY | 
|---|
| 295 | bool | 
|---|
| 296 | operator<=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) | 
|---|
| 297 | { | 
|---|
| 298 | return !(__y < __x); | 
|---|
| 299 | } | 
|---|
| 300 |  | 
|---|
| 301 | template <class _Tp, class _Container> | 
|---|
| 302 | inline _LIBCPP_INLINE_VISIBILITY | 
|---|
| 303 | typename enable_if< | 
|---|
| 304 | __is_swappable<_Container>::value, | 
|---|
| 305 | void | 
|---|
| 306 | >::type | 
|---|
| 307 | swap(stack<_Tp, _Container>& __x, stack<_Tp, _Container>& __y) | 
|---|
| 308 | _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) | 
|---|
| 309 | { | 
|---|
| 310 | __x.swap(__y); | 
|---|
| 311 | } | 
|---|
| 312 |  | 
|---|
| 313 | template <class _Tp, class _Container, class _Alloc> | 
|---|
| 314 | struct _LIBCPP_TEMPLATE_VIS uses_allocator<stack<_Tp, _Container>, _Alloc> | 
|---|
| 315 | : public uses_allocator<_Container, _Alloc> | 
|---|
| 316 | { | 
|---|
| 317 | }; | 
|---|
| 318 |  | 
|---|
| 319 | _LIBCPP_END_NAMESPACE_STD | 
|---|
| 320 |  | 
|---|
| 321 | #endif  // _LIBCPP_STACK | 
|---|
| 322 |  | 
|---|