1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
#ifndef NON_STL_SINGLY_LINK_LIST_HPP
#define NON_STL_SINGLY_LINK_LIST_HPP
#include<iterator>
#include<memory>
#include"stl_construct.hpp"
struct slist_node_base
{
slist_node_base *next;
};
template<typename T>
struct slist_node : public slist_node_base
{
T data;
};
struct slist_iterator_base
{
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef std::forward_iterator_tag iterator_category;
slist_iterator_base(slist_node_base *x) : node(x) {}
bool operator==(slist_iterator_base const x) const { return node == x.node; }
bool operator!=(slist_iterator_base const x) const { return node != x.node; }
slist_node_base *node;
};
//three template parameters are designed to
//discern the const iterator and non-const iterator
template<typename T, typename Ref, typename Ptr>
struct slist_iterator : public slist_iterator_base
{
typedef slist_iterator<T, T&, T*> iterator;
typedef slist_iterator<T, T const&, T const*> const_iterator;
typedef slist_iterator<T, Ref, Ptr> self;
typedef std::forward_iterator_tag iterator_tag;
typedef T value_type;
typedef Ptr pointer;
typedef Ref reference;
typedef slist_node<T> list_node;
slist_iterator(list_node *x) : slist_iterator_base(x) {}
slist_iterator() : slist_iterator_base(0) {}
slist_iterator(iterator const &x) : slist_iterator_base(x.node) {}
reference operator*() const { return static_cast<list_node*>(node)->data; }
pointer operator->() const { return &(operator()*); }
self& operator++()
{
node = node->next;
return *this;
}
self operator++(int)
{
iterator temp = *this;
++*this;
return temp;
}
};
inline slist_node_base* slist_make_link(slist_node_base *prev_node, slist_node_base *new_node)
{
new_node->next = prev_node->next;
prev_node->next = new_node;
return new_node;
}
size_t slist_size(slist_node_base *begin);
template<typename T, typename Alloc = std::allocator<T> >
class SList
{
public :
typedef T value_type;
typedef T* pointer;
typedef const pointer const_pointer;
typedef T& reference;
typedef const reference const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
public :
typedef slist_iterator<T, T&, T*> iterator;
typedef slist_iterator<T, T const&, T const*> const_iterator;
private :
typedef slist_node<T> list_node;
public :
SList() { head.next = 0; }
~SList() { clear(); }
public :
iterator begin() { return iterator(static_cast<list_node*>(head.next)); }
const_iterator begin() const { return const_iterator(static_cast<list_node*>(head.next)); }
iterator end() { return iterator(0); }
const_iterator end() const { return const_iterator(0); }
reference front () { return static_cast<slist_node*>(head.next)->data; }
void clear()
{
for(slist_node_base *begin = head.next; begin != 0; begin = head.next)
pop_front();
}
void pop_front()
{
list_node *node = static_cast<list_node*>(head.next);
head.next = node->next;
destroy_node(node);
}
void push_front(value_type const &x)
{
slist_make_link(&head, create_node(x) );
}
size_type size() { return slist_size(head.next); }
void swap(SList &list)
{
std::swap(list.head.next, head.next);
}
private :
list_node* create_node(value_type const &x)
{
list_node *node = alloc.allocate(1);
construct_(&node->data);
node->next = 0;
return node;
}
void destroy_node(list_node *node)
{
destroy_(&node->data);
alloc.deallocate(node, 1);
}
private :
slist_node_base head;
typename Alloc::rebind<list_node>::other alloc;
};
#endif
|