Home | History | Annotate | Line # | Download | only in include
      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