template <class T> struct slist_node {
T val;
slist_node* next;
slist_node(const T& t, slist_node* p)
: val(t), next(p) { }
};
template <bool flag, class IsTrue, class IsFalse>
struct choose;
template <class IsTrue, class IsFalse>
struct choose<true, IsTrue, IsFalse> {
typedef IsTrue type;
};
template <class IsTrue, class IsFalse>
struct choose<false, IsTrue, IsFalse> {
typedef IsFalse type;
};
template <class T, bool isconst = false>
struct slist_iterator {
typedef std::forward_iterator_tag iterator_category;
typedef T value_type;
typedef std::ptrdiff_t difference_type;
typedef typename choose<isconst, const T&, T&>::type
reference;
typedef typename choose<isconst, const T*, T*>::type
pointer;
typedef typename choose<isconst, const slist_node<T>*,
slist_node<T>*>::type
nodeptr;
slist_iterator(nodeptr x = 0) : p(x) { }
slist_iterator(const slist_iterator<T, false>& i)
: p(i.p) { }
reference operator*() const { return p->val; }
pointer operator->() const { return &(p->val); }
slist_iterator& operator++() {
p = p->next;
return *this;
}
slist_iterator operator++(int) {
slist_iterator tmp(*this);
++*this;
return tmp;
}
friend bool operator==(const slist_iterator& x,
const slist_iterator& y) {
return x.p == y.p;
}
friend bool operator!=(const slist_iterator& x,
const slist_iterator& y) {
return x.p != y.p;
}
nodeptr p;
};
// This is not a complete container class. It is just
// enough to illustrate defining and using an iterator/
// const iterator pair.
template <class T> struct slist {
slist_node<T>* head;
typedef slist_iterator<T> iterator;
typedef slist_iterator<T, true> const_iterator;
iterator begin() { return iterator(head); }
iterator end() { return iterator(0); }
const_iterator begin() const {
return const_iterator(head);
}
const_iterator end() const {
return const_iterator(0);
}
slist() : head(0) { }
~slist() {
while (head) {
slist_node<T>* next = head->next;
delete head;
head = next;
}
}
void push_front(const T& t) {
head = new slist_node<T>(t, head);
}
...
};
End of Listing