//: C16:IterStackTemplate.h // From Thinking in C++, 2nd Edition // Available at http://www.BruceEckel.com // (c) Bruce Eckel 2000 // Copyright notice in Copyright.txt // Simple stack template with nested iterator #ifndef ITERSTACKTEMPLATE_H #define ITERSTACKTEMPLATE_H #include "../require.h" #include template class StackTemplate { T stack[ssize]; int top; public: StackTemplate() : top(0) {} void push(const T& i) { require(top < ssize, "Too many push()es"); stack[top++] = i; } T pop() { require(top > 0, "Too many pop()s"); return stack[--top]; } class iterator; // Declaration required friend class iterator; // Make it a friend class iterator { // Now define it StackTemplate& s; int index; public: iterator(StackTemplate& st): s(st),index(0){} // To create the "end sentinel" iterator: iterator(StackTemplate& st, bool) : s(st), index(s.top) {} T operator*() const { return s.stack[index];} T operator++() { // Prefix form require(index < s.top, "iterator moved out of range"); return s.stack[++index]; } T operator++(int) { // Postfix form require(index < s.top, "iterator moved out of range"); return s.stack[index++]; } // Jump an iterator forward iterator& operator+=(int amount) { require(index + amount < s.top, " StackTemplate::iterator::operator+=() " "tried to move out of bounds"); index += amount; return *this; } // To see if you're at the end: bool operator==(const iterator& rv) const { return index == rv.index; } bool operator!=(const iterator& rv) const { return index != rv.index; } friend std::ostream& operator<<( std::ostream& os, const iterator& it) { return os << *it; } }; iterator begin() { return iterator(*this); } // Create the "end sentinel": iterator end() { return iterator(*this, true);} }; #endif // ITERSTACKTEMPLATE_H ///:~