#ifndef REFSTACK_H #define REFSTACK_H #include <iostream> template <typename T> class stack; template <typename T> std::ostream &operator<<( std::ostream &os, const stack<T> &s); template <typename T> class stack { friend std::ostream &operator<< <>( std::ostream &os, const stack &s); public: stack() : cap(ibs), sp(0), v(new T[ibs]), cnt(new int(1)) { } stack( const stack &other) { attach(other); } ~stack() { detach(); } stack& operator=( const stack &other); void push( const T &t); const T &pop() { return v[--sp]; } bool empty() const { return 0 == sp; } void *test_address() const { return v; } private: int cap; int sp; double *v; int *cnt; static const int ibs = 8; void detach(); void attach( const stack &other); void copy( const T *ov); void grow(); }; template <typename T> void stack<T>::detach() { // Nem thread-safe! if ( 0 == --*cnt ) { delete cnt; delete [] v; } } template <typename T> void stack<T>::attach( const stack &other) { // Nem thread-safe! cap = other.cap; sp = other.sp; v = other.v; cnt = other.cnt; ++*cnt; } template <typename T> stack<T>& stack<T>::operator=( const stack &other) { if ( this != &other ) // x = x { detach(); attach(other); } return *this; } template <typename T> void stack<T>::push( const T &t) { // Nem thread-safe! if ( 1 < *cnt ) { --*cnt; if ( cap == sp ) cap *= 2; copy(v); cnt = new int(1); } if ( cap == sp ) grow(); v[sp++] = t; } template <typename T> void stack<T>::copy( const T *oldv) { v = new T[cap]; for ( int i = 0 ; i < sp; ++i) v[i] = oldv[i]; } template <typename T> void stack<T>::grow() { T* oldv = v; cap *= 2; copy(oldv); delete [] oldv; } template <typename T> std::ostream &operator<<( std::ostream &os, const stack<T> &s) { os << "[ "; for ( int i = 0; i < s.sp-1; ++i ) os << s.v[i] << ", "; if ( s.sp > 0 ) os << s.v[s.sp-1]; os << " ]"; return os; } #endif /* REFSTACK_H */