// -*- C++ -*-
/***************************************************************************
 *
 * <stack> - definition of the C++ Standard Library stack class template
 *
 * $Id$
 *
 ***************************************************************************
 *
 * 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.
 *
 ***************************************************************************
 *
 * Licensed to the Apache Software  Foundation (ASF) under one or more
 * contributor  license agreements.  See  the NOTICE  file distributed
 * with  this  work  for  additional information  regarding  copyright
 * ownership.   The ASF  licenses this  file to  you under  the Apache
 * License, Version  2.0 (the  "License"); you may  not use  this file
 * except in  compliance with the License.   You may obtain  a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the  License is distributed on an  "AS IS" BASIS,
 * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
 * implied.   See  the License  for  the  specific language  governing
 * permissions and limitations under the License.
 *
 * Copyright 1994-2006 Rogue Wave Software.
 * 
 **************************************************************************/

#ifndef _RWSTD_STACK_INCLUDED
#define _RWSTD_STACK_INCLUDED

#include <deque>
#include <rw/_defs.h>


_RWSTD_NAMESPACE (std) { 


template <class _TypeT, class _Container = deque<_TypeT> > 
class stack;


template <class _TypeT, class _Container>
inline bool operator==(const stack<_TypeT, _Container>&, 
                       const stack<_TypeT, _Container>&);

template <class _TypeT, class _Container>
inline bool operator<(const stack<_TypeT, _Container>&, 
                      const stack<_TypeT, _Container>&);

template <class _TypeT, class _Container>
class stack
{
    friend bool _RWSTD_SPECIALIZED_FRIEND (operator==)
        (const stack&, const stack&);

    friend bool _RWSTD_SPECIALIZED_FRIEND (operator<)
        (const stack&, const stack&);

public:
    
    typedef _Container                                container_type;
    typedef typename container_type::value_type      value_type;
    typedef typename container_type::size_type       size_type;
    // lwg issue 307: additional typedefs
    typedef typename container_type::reference       reference;
    typedef typename container_type::const_reference const_reference;

protected:
    
    container_type c;

public:

    explicit
    stack (const container_type &__c = container_type ()) 
        : c (__c) { }

    bool empty () const {
        return c.empty ();
    }

    size_type size () const {
        return c.size ();
    }

    reference top () {
        return c.back ();
    }

    const_reference top () const {
        return c.back ();
    }

    void push (const value_type &__x) {
        c.push_back (__x);
    }

    void pop () {
        c.pop_back ();
    }
};


template <class _TypeT, class _Container>
inline bool operator== (const stack<_TypeT, _Container> &__x, 
                        const stack<_TypeT, _Container> &__y)
{
    return __x.c == __y.c;
}

template <class _TypeT, class _Container>
inline bool operator< (const stack<_TypeT, _Container> &__x, 
                       const stack<_TypeT, _Container> &__y)
{
    return __x.c < __y.c;
}

template <class _TypeT, class _Container>
inline bool operator!= (const stack<_TypeT, _Container> &__x, 
                        const stack<_TypeT, _Container> &__y)
{
    return !(__x == __y);
}

template <class _TypeT, class _Container>
inline bool operator> (const stack<_TypeT, _Container> &__x, 
                       const stack<_TypeT, _Container> &__y)
{
    return __y < __x;
}

template <class _TypeT, class _Container>
inline bool operator>= (const stack<_TypeT, _Container> &__x, 
                        const stack<_TypeT, _Container> &__y)
{
    return !(__x < __y);
}

template <class _TypeT, class _Container>
inline bool operator<= (const stack<_TypeT, _Container> &__x, 
                        const stack<_TypeT, _Container> &__y)
{
    return !(__y <  __x);
}


}   // namespace std

#endif   // _RWSTD_STACK_INCLUDED
