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 16namespace std 17{ 18 19template <class T, class Container = deque<T>> 20class stack 21{ 22public: 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 29protected: 30 container_type c; 31 32public: 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 63template<class Container> 64 stack(Container) -> stack<typename Container::value_type, Container>; // C++17 65 66template<class Container, class Allocator> 67 stack(Container, Allocator) -> stack<typename Container::value_type, Container>; // C++17 68 69template <class T, class Container> 70 bool operator==(const stack<T, Container>& x, const stack<T, Container>& y); 71template <class T, class Container> 72 bool operator< (const stack<T, Container>& x, const stack<T, Container>& y); 73template <class T, class Container> 74 bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y); 75template <class T, class Container> 76 bool operator> (const stack<T, Container>& x, const stack<T, Container>& y); 77template <class T, class Container> 78 bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y); 79template <class T, class Container> 80 bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y); 81 82template <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 <__utility/forward.h> 92#include <deque> 93 94#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 95#pragma GCC system_header 96#endif 97 98_LIBCPP_BEGIN_NAMESPACE_STD 99 100template <class _Tp, class _Container = deque<_Tp> > class _LIBCPP_TEMPLATE_VIS stack; 101 102template <class _Tp, class _Container> 103_LIBCPP_INLINE_VISIBILITY 104bool 105operator==(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y); 106 107template <class _Tp, class _Container> 108_LIBCPP_INLINE_VISIBILITY 109bool 110operator< (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y); 111 112template <class _Tp, class _Container /*= deque<_Tp>*/> 113class _LIBCPP_TEMPLATE_VIS stack 114{ 115public: 116 typedef _Container container_type; 117 typedef typename container_type::value_type value_type; 118 typedef typename container_type::reference reference; 119 typedef typename container_type::const_reference const_reference; 120 typedef typename container_type::size_type size_type; 121 static_assert((is_same<_Tp, value_type>::value), "" ); 122 123protected: 124 container_type c; 125 126public: 127 _LIBCPP_INLINE_VISIBILITY 128 stack() 129 _NOEXCEPT_(is_nothrow_default_constructible<container_type>::value) 130 : c() {} 131 132 _LIBCPP_INLINE_VISIBILITY 133 stack(const stack& __q) : c(__q.c) {} 134 135 _LIBCPP_INLINE_VISIBILITY 136 stack& operator=(const stack& __q) {c = __q.c; return *this;} 137 138 139#ifndef _LIBCPP_CXX03_LANG 140 _LIBCPP_INLINE_VISIBILITY 141 stack(stack&& __q) 142 _NOEXCEPT_(is_nothrow_move_constructible<container_type>::value) 143 : c(_VSTD::move(__q.c)) {} 144 145 _LIBCPP_INLINE_VISIBILITY 146 stack& operator=(stack&& __q) 147 _NOEXCEPT_(is_nothrow_move_assignable<container_type>::value) 148 {c = _VSTD::move(__q.c); return *this;} 149 150 _LIBCPP_INLINE_VISIBILITY 151 explicit stack(container_type&& __c) : c(_VSTD::move(__c)) {} 152#endif // _LIBCPP_CXX03_LANG 153 154 _LIBCPP_INLINE_VISIBILITY 155 explicit stack(const container_type& __c) : c(__c) {} 156 157 template <class _Alloc> 158 _LIBCPP_INLINE_VISIBILITY 159 explicit stack(const _Alloc& __a, 160 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0) 161 : c(__a) {} 162 template <class _Alloc> 163 _LIBCPP_INLINE_VISIBILITY 164 stack(const container_type& __c, const _Alloc& __a, 165 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0) 166 : c(__c, __a) {} 167 template <class _Alloc> 168 _LIBCPP_INLINE_VISIBILITY 169 stack(const stack& __s, const _Alloc& __a, 170 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0) 171 : c(__s.c, __a) {} 172#ifndef _LIBCPP_CXX03_LANG 173 template <class _Alloc> 174 _LIBCPP_INLINE_VISIBILITY 175 stack(container_type&& __c, const _Alloc& __a, 176 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0) 177 : c(_VSTD::move(__c), __a) {} 178 template <class _Alloc> 179 _LIBCPP_INLINE_VISIBILITY 180 stack(stack&& __s, const _Alloc& __a, 181 _EnableIf<uses_allocator<container_type, _Alloc>::value>* = 0) 182 : c(_VSTD::move(__s.c), __a) {} 183#endif // _LIBCPP_CXX03_LANG 184 185 _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY 186 bool empty() const {return c.empty();} 187 _LIBCPP_INLINE_VISIBILITY 188 size_type size() const {return c.size();} 189 _LIBCPP_INLINE_VISIBILITY 190 reference top() {return c.back();} 191 _LIBCPP_INLINE_VISIBILITY 192 const_reference top() const {return c.back();} 193 194 _LIBCPP_INLINE_VISIBILITY 195 void push(const value_type& __v) {c.push_back(__v);} 196#ifndef _LIBCPP_CXX03_LANG 197 _LIBCPP_INLINE_VISIBILITY 198 void push(value_type&& __v) {c.push_back(_VSTD::move(__v));} 199 200 template <class... _Args> 201 _LIBCPP_INLINE_VISIBILITY 202#if _LIBCPP_STD_VER > 14 203 decltype(auto) emplace(_Args&&... __args) 204 { return c.emplace_back(_VSTD::forward<_Args>(__args)...);} 205#else 206 void emplace(_Args&&... __args) 207 { c.emplace_back(_VSTD::forward<_Args>(__args)...);} 208#endif 209#endif // _LIBCPP_CXX03_LANG 210 211 _LIBCPP_INLINE_VISIBILITY 212 void pop() {c.pop_back();} 213 214 _LIBCPP_INLINE_VISIBILITY 215 void swap(stack& __s) 216 _NOEXCEPT_(__is_nothrow_swappable<container_type>::value) 217 { 218 using _VSTD::swap; 219 swap(c, __s.c); 220 } 221 222 template <class T1, class _C1> 223 friend 224 bool 225 operator==(const stack<T1, _C1>& __x, const stack<T1, _C1>& __y); 226 227 template <class T1, class _C1> 228 friend 229 bool 230 operator< (const stack<T1, _C1>& __x, const stack<T1, _C1>& __y); 231}; 232 233#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES 234template<class _Container, 235 class = _EnableIf<!__is_allocator<_Container>::value> 236> 237stack(_Container) 238 -> stack<typename _Container::value_type, _Container>; 239 240template<class _Container, 241 class _Alloc, 242 class = _EnableIf<!__is_allocator<_Container>::value>, 243 class = _EnableIf<uses_allocator<_Container, _Alloc>::value> 244 > 245stack(_Container, _Alloc) 246 -> stack<typename _Container::value_type, _Container>; 247#endif 248 249template <class _Tp, class _Container> 250inline _LIBCPP_INLINE_VISIBILITY 251bool 252operator==(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) 253{ 254 return __x.c == __y.c; 255} 256 257template <class _Tp, class _Container> 258inline _LIBCPP_INLINE_VISIBILITY 259bool 260operator< (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) 261{ 262 return __x.c < __y.c; 263} 264 265template <class _Tp, class _Container> 266inline _LIBCPP_INLINE_VISIBILITY 267bool 268operator!=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) 269{ 270 return !(__x == __y); 271} 272 273template <class _Tp, class _Container> 274inline _LIBCPP_INLINE_VISIBILITY 275bool 276operator> (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) 277{ 278 return __y < __x; 279} 280 281template <class _Tp, class _Container> 282inline _LIBCPP_INLINE_VISIBILITY 283bool 284operator>=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) 285{ 286 return !(__x < __y); 287} 288 289template <class _Tp, class _Container> 290inline _LIBCPP_INLINE_VISIBILITY 291bool 292operator<=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y) 293{ 294 return !(__y < __x); 295} 296 297template <class _Tp, class _Container> 298inline _LIBCPP_INLINE_VISIBILITY 299_EnableIf<__is_swappable<_Container>::value, void> 300swap(stack<_Tp, _Container>& __x, stack<_Tp, _Container>& __y) 301 _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) 302{ 303 __x.swap(__y); 304} 305 306template <class _Tp, class _Container, class _Alloc> 307struct _LIBCPP_TEMPLATE_VIS uses_allocator<stack<_Tp, _Container>, _Alloc> 308 : public uses_allocator<_Container, _Alloc> 309{ 310}; 311 312_LIBCPP_END_NAMESPACE_STD 313 314#endif // _LIBCPP_STACK 315