Solution
This implementation of Stack is only
slightly different from the last. For example, Count()
returns impl_.vused_ instead of just an inherited
vused_.
Here's the complete code:
template <class T>
class Stack
{
public:
Stack(size_t size=0)
: impl_(size)
{
}
Stack(const Stack& other)
: impl_(other.impl_.vused_)
{
while( impl_.vused_ < other.impl_.vused_ )
{
construct( impl_.v_+impl_.vused_,
other.impl_.v_[impl_.vused_] );
++impl_.vused_;
}
}
Stack& operator=(const Stack& other)
{
Stack temp(other);
impl_.Swap(temp.impl_); // this can't throw
return *this;
}
size_t Count() const
{
return impl_.vused_;
}
void Push( const T& t )
{
if( impl_.vused_ == impl_.vsize_ )
{
Stack temp( impl_.vsize_*2+1 );
while( temp.Count() < impl_.vused_ )
{
temp.Push( impl_.v_[temp.Count()] );
}
temp.Push( t );
impl_.Swap( temp.impl_ );
}
else
{
construct( impl_.v_+impl_.vused_, t );
++impl_.vused_;
}
}
T& Top()
{
if( impl_.vused_ == 0 )
{
throw "empty stack";
}
return impl_.v_[impl_.vused_-1];
}
void Pop()
{
if( impl_.vused_ == 0 )
{
throw "pop from empty stack";
}
else
{
--impl_.vused_;
destroy( impl_.v_+impl_.vused_ );
}
}
private:
StackImpl<T> impl_; // private implementation
};
Whew. That's a lot of impl_'s. Which
brings us to the final question in this miniseries.
|