#ifndef cathlibcpp_stack_H
#define cathlibcpp_stack_H

// File:       stack.h
// Author:     (c) Miles Sabin, 1997
// Purpose:    approximation to ANSI C++ stack template


#ifndef included_stddef_H
#define included_stddef_H
#include <stddef.h>           // for size_t
#endif

#ifndef cathlibcpp_bool_H
#include "bool.h"
#endif

#ifndef cathlibcpp_config_H
#include "config.h"
#endif


template<class Container, class value_type>
class stack
{
  friend bool operator==(stack<Container, value_type> const& lhs, stack<Container, value_type> const& rhs);
  friend bool operator< (stack<Container, value_type> const& lhs, stack<Container, value_type> const& rhs);

  public:

#   define size_type   size_t

    // accessors
    inline bool empty() const;
    inline size_type size() const;

    inline value_type const& top() const;

    // mutators
    inline value_type& top();

    inline void push(value_type const& x);
    inline void pop();

  protected:

    Container c;

#   undef size_type
};


template<class Container, class value_type>
bool operator==(stack<Container, value_type> const& lhs, stack<Container, value_type> const& rhs);

template<class Container, class value_type>
bool operator< (stack<Container, value_type> const& lhs, stack<Container, value_type> const& rhs);


// Implementation of stack<Container, value_type>

#define size_type   size_t

template<class Container, class value_type>
inline bool stack<Container, value_type>::empty() const
  { return c.empty(); }

template<class Container, class value_type>
inline size_type stack<Container, value_type>::size() const
  { return c.size(); }

template<class Container, class value_type>
inline value_type const& stack<Container, value_type>::top() const
  { return c.back(); }

template<class Container, class value_type>
inline value_type& stack<Container, value_type>::top()
  { return c.back(); }

template<class Container, class value_type>
inline void stack<Container, value_type>::push(value_type const& x)
  { c.push_back(x); }

template<class Container, class value_type>
inline void stack<Container, value_type>::pop()
  { c.pop_back(); }

#undef size_type


// Implementation of stack<Container, value_type> free fns

template<class Container, class value_type>
inline bool operator==(stack<Container, value_type> const& lhs, stack<Container, value_type> const& rhs)
{
  return lhs.c == rhs.c;
}

template<class Container, class value_type>
inline bool operator< (stack<Container, value_type> const& lhs, stack<Container, value_type> const& rhs)
{
  return lhs.c < rhs.c;
}

#endif

