// stack standard header -*-c++-*-
// Copyright 2003-2020 IAR Systems AB. 
#ifndef _DLIB5_STACK_
#define _DLIB5_STACK_

#ifndef _SYSTEM_BUILD
#pragma system_include
#endif

#include <dlib5/deque>
_DLIB5_BEGIN

#pragma language = save
#pragma language = extended
// TEMPLATE CLASS stack
template<class _Ty,
         class _Container = deque<_Ty> >
class __memory_of(_Ty) stack
{       // LIFO queue implemented with a container
public:
  typedef _Container container_type;
  typedef typename _Container::value_type value_type;
  typedef typename _Container::size_type size_type;
  typedef typename _TypeUtil::_ParameterType<value_type>::_Type _ParamTy;

  stack()
    : c()
  {}      // construct with empty container

  explicit stack(const _Container& _Cont)
    : c(_Cont)
  {}      // construct by copying specified container

  bool empty() const
  {       // test if stack is empty
    return (c.empty()); 
  }

  size_type size() const
  {       // test length of stack
    return (c.size()); 
  }

  value_type& top()
  {       // return last element of mutable stack
    return (c.back()); 
  }

  const value_type& top() const
  {       // return last element of nonmutable stack
    return (c.back()); 
  }

  void push(_ParamTy _Val)
  {       // insert element at end
    c.push_back(_Val); 
  }

  void pop()
  {       // erase last element
    c.pop_back(); 
  }

//protected:
  _Container c;   // the underlying container
};
#pragma language = restore

// stack TEMPLATE FUNCTIONS
template<class _Ty,
         class _Container> inline
bool operator==(const stack<_Ty, _Container>& _Left,
                const stack<_Ty, _Container>& _Right)
{       // test for stack equality
  return (_Left.c == _Right.c); 
}

template<class _Ty,
         class _Container> inline
bool operator!=(const stack<_Ty, _Container>& _Left,
                const stack<_Ty, _Container>& _Right)
{       // test for stack inequality
  return (!(_Left == _Right)); 
}

template<class _Ty,
         class _Container> inline
bool operator<(const stack<_Ty, _Container>& _Left,
               const stack<_Ty, _Container>& _Right)
{       // test if _Left < _Right for stacks
  return (_Left.c < _Right.c); 
}

template<class _Ty,
         class _Container> inline
bool operator>(const stack<_Ty, _Container>& _Left,
               const stack<_Ty, _Container>& _Right)
{       // test if _Left > _Right for stacks
  return (_Right < _Left); 
}

template<class _Ty,
         class _Container> inline
bool operator<=(const stack<_Ty, _Container>& _Left,
                const stack<_Ty, _Container>& _Right)
{       // test if _Left <= _Right for stacks
  return (!(_Right < _Left)); 
}

template<class _Ty,
         class _Container> inline
bool operator>=(const stack<_Ty, _Container>& _Left,
                const stack<_Ty, _Container>& _Right)
{       // test if _Left >= _Right for stacks
  return (!(_Left < _Right)); 
}

_DLIB5_END
#endif /* _STACK_ */

/*
 * This file is derived from software bearing the following
 * restrictions:
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Permission to use, copy, modify, distribute and sell this
 * software and its documentation for any purpose is hereby
 * granted without fee, provided that the above copyright notice
 * appear in all copies and that both that copyright notice and
 * this permission notice appear in supporting documentation.
 * Hewlett-Packard Company makes no representations about the
 * suitability of this software for any purpose. It is provided
 * "as is" without express or implied warranty.
 */

/*
 * Copyright (c) 1992-2009 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
 V5.04:0576 */
