//***** For documentation, see Figure 6.3. *****//

#ifndef STACK_DEQUE
#define STACK_DEQUE

#include <iostream>
#include <deque>
using namespace std;

template<typename StackElement>

class Stack
{
/***** Function Members *****/
public:
bool empty() const;
void push(const StackElement & value);
void display(ostream & out) const;
StackElement top() const;
void pop();

/***** Data Members *****/
private:
  deque<StackElement> myDeque;   // deque to store elements

}; // end of class declaration

//--- Definition of empty operation
template <typename StackElement>
inline bool Stack<StackElement>::empty() const
{
  return myDeque.empty();
}


//--- Definition of push operation
template <typename StackElement>
void Stack<StackElement>::push(const StackElement & value)
{
  myDeque.push_back(value);
}


//--- Definition of display operation
template <typename StackElement>
void Stack<StackElement>::display(ostream & out) const
{
  for (int pos = myDeque.size() - 1; pos >= 0; pos--)
    out << myDeque[pos] << endl;
}

//--- Definition of top operation
template <typename StackElement>
StackElement Stack<StackElement>:: top() const
{
  if (!myDeque.empty())
    return myDeque.back();
  //else
  cerr << "*** Stack is empty ***\n";
  return StackElement();
}


//--- Definition of pop operation
template <typename StackElement>
void Stack<StackElement>:: pop()
{
  if (!myDeque.empty())
    myDeque.pop_back();
  else
    cerr << "*** Stack is empty -- can't remove a value ***\n";
}

#endif

