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