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