Home | History | Annotate | Download | only in include
      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 
     17 namespace std
     18 {
     19 
     20 template <class T, class Container = deque<T>>
     21 class stack
     22 {
     23 public:
     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 
     30 protected:
     31     container_type c;
     32 
     33 public:
     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> reference emplace(Args&&... args); // reference in C++17
     59     void pop();
     60 
     61     void swap(stack& c) noexcept(is_nothrow_swappable_v<Container>)
     62 };
     63 
     64 template <class T, class Container>
     65   bool operator==(const stack<T, Container>& x, const stack<T, Container>& y);
     66 template <class T, class Container>
     67   bool operator< (const stack<T, Container>& x, const stack<T, Container>& y);
     68 template <class T, class Container>
     69   bool operator!=(const stack<T, Container>& x, const stack<T, Container>& y);
     70 template <class T, class Container>
     71   bool operator> (const stack<T, Container>& x, const stack<T, Container>& y);
     72 template <class T, class Container>
     73   bool operator>=(const stack<T, Container>& x, const stack<T, Container>& y);
     74 template <class T, class Container>
     75   bool operator<=(const stack<T, Container>& x, const stack<T, Container>& y);
     76 
     77 template <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 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
     89 #pragma GCC system_header
     90 #endif
     91 
     92 _LIBCPP_BEGIN_NAMESPACE_STD
     93 
     94 template <class _Tp, class _Container = deque<_Tp> > class _LIBCPP_TEMPLATE_VIS stack;
     95 
     96 template <class _Tp, class _Container>
     97 _LIBCPP_INLINE_VISIBILITY
     98 bool
     99 operator==(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y);
    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 /*= deque<_Tp>*/>
    107 class _LIBCPP_TEMPLATE_VIS stack
    108 {
    109 public:
    110     typedef _Container                               container_type;
    111     typedef typename container_type::value_type      value_type;
    112     typedef typename container_type::reference       reference;
    113     typedef typename container_type::const_reference const_reference;
    114     typedef typename container_type::size_type       size_type;
    115     static_assert((is_same<_Tp, value_type>::value), "" );
    116     
    117 protected:
    118     container_type c;
    119 
    120 public:
    121     _LIBCPP_INLINE_VISIBILITY
    122     stack()
    123         _NOEXCEPT_(is_nothrow_default_constructible<container_type>::value)
    124         : c() {}
    125 
    126     _LIBCPP_INLINE_VISIBILITY
    127     stack(const stack& __q) : c(__q.c) {}
    128 
    129 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
    130     _LIBCPP_INLINE_VISIBILITY
    131     stack(stack&& __q)
    132         _NOEXCEPT_(is_nothrow_move_constructible<container_type>::value)
    133         : c(_VSTD::move(__q.c)) {}
    134 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
    135 
    136     _LIBCPP_INLINE_VISIBILITY
    137     stack& operator=(const stack& __q) {c = __q.c; return *this;}
    138 
    139 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
    140     _LIBCPP_INLINE_VISIBILITY
    141     stack& operator=(stack&& __q)
    142         _NOEXCEPT_(is_nothrow_move_assignable<container_type>::value)
    143         {c = _VSTD::move(__q.c); return *this;}
    144 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
    145 
    146     _LIBCPP_INLINE_VISIBILITY
    147     explicit stack(const container_type& __c) : c(__c) {}
    148 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
    149     _LIBCPP_INLINE_VISIBILITY
    150     explicit stack(container_type&& __c) : c(_VSTD::move(__c)) {}
    151 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
    152     template <class _Alloc>
    153         _LIBCPP_INLINE_VISIBILITY
    154         explicit stack(const _Alloc& __a,
    155                        typename enable_if<uses_allocator<container_type,
    156                                                          _Alloc>::value>::type* = 0)
    157             : c(__a) {}
    158     template <class _Alloc>
    159         _LIBCPP_INLINE_VISIBILITY
    160         stack(const container_type& __c, const _Alloc& __a,
    161               typename enable_if<uses_allocator<container_type,
    162                                                 _Alloc>::value>::type* = 0)
    163             : c(__c, __a) {}
    164     template <class _Alloc>
    165         _LIBCPP_INLINE_VISIBILITY
    166         stack(const stack& __s, const _Alloc& __a,
    167               typename enable_if<uses_allocator<container_type,
    168                                                 _Alloc>::value>::type* = 0)
    169             : c(__s.c, __a) {}
    170 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
    171     template <class _Alloc>
    172         _LIBCPP_INLINE_VISIBILITY
    173         stack(container_type&& __c, const _Alloc& __a,
    174               typename enable_if<uses_allocator<container_type,
    175                                                 _Alloc>::value>::type* = 0)
    176             : c(_VSTD::move(__c), __a) {}
    177     template <class _Alloc>
    178         _LIBCPP_INLINE_VISIBILITY
    179         stack(stack&& __s, const _Alloc& __a,
    180               typename enable_if<uses_allocator<container_type,
    181                                                 _Alloc>::value>::type* = 0)
    182             : c(_VSTD::move(__s.c), __a) {}
    183 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
    184 
    185     _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_HAS_NO_RVALUE_REFERENCES
    197     _LIBCPP_INLINE_VISIBILITY
    198     void push(value_type&& __v) {c.push_back(_VSTD::move(__v));}
    199 #ifndef _LIBCPP_HAS_NO_VARIADICS
    200     template <class... _Args>
    201         _LIBCPP_INLINE_VISIBILITY
    202 #if _LIBCPP_STD_VER > 14
    203         reference 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_HAS_NO_VARIADICS
    210 #endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
    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 template <class _Tp, class _Container>
    234 inline _LIBCPP_INLINE_VISIBILITY
    235 bool
    236 operator==(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
    237 {
    238     return __x.c == __y.c;
    239 }
    240 
    241 template <class _Tp, class _Container>
    242 inline _LIBCPP_INLINE_VISIBILITY
    243 bool
    244 operator< (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
    245 {
    246     return __x.c < __y.c;
    247 }
    248 
    249 template <class _Tp, class _Container>
    250 inline _LIBCPP_INLINE_VISIBILITY
    251 bool
    252 operator!=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
    253 {
    254     return !(__x == __y);
    255 }
    256 
    257 template <class _Tp, class _Container>
    258 inline _LIBCPP_INLINE_VISIBILITY
    259 bool
    260 operator> (const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
    261 {
    262     return __y < __x;
    263 }
    264 
    265 template <class _Tp, class _Container>
    266 inline _LIBCPP_INLINE_VISIBILITY
    267 bool
    268 operator>=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
    269 {
    270     return !(__x < __y);
    271 }
    272 
    273 template <class _Tp, class _Container>
    274 inline _LIBCPP_INLINE_VISIBILITY
    275 bool
    276 operator<=(const stack<_Tp, _Container>& __x, const stack<_Tp, _Container>& __y)
    277 {
    278     return !(__y < __x);
    279 }
    280 
    281 template <class _Tp, class _Container>
    282 inline _LIBCPP_INLINE_VISIBILITY
    283 typename enable_if<
    284     __is_swappable<_Container>::value,
    285     void
    286 >::type
    287 swap(stack<_Tp, _Container>& __x, stack<_Tp, _Container>& __y)
    288     _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y)))
    289 {
    290     __x.swap(__y);
    291 }
    292 
    293 template <class _Tp, class _Container, class _Alloc>
    294 struct _LIBCPP_TEMPLATE_VIS uses_allocator<stack<_Tp, _Container>, _Alloc>
    295     : public uses_allocator<_Container, _Alloc>
    296 {
    297 };
    298 
    299 _LIBCPP_END_NAMESPACE_STD
    300 
    301 #endif  // _LIBCPP_STACK
    302