2222
2323#include < cstdlib>
2424#include < cstdio>
25- #include < cstring>
26- #include < cmath>
2725#include < iterator>
2826#include < cstddef>
27+ #include " Container.h"
28+
29+
30+ template <class T >
31+ class LinkedList ;
2932
3033
3134template <class T >
3235class linkedlist_value_container_t {
3336public:
34- explicit inline linkedlist_value_container_t (const T& value) : value(value) {}
37+ explicit inline linkedlist_value_container_t (const T& value) : value(value), next(nullptr ), previous(nullptr ) {}
38+
3539 T value;
3640 linkedlist_value_container_t * next;
3741 linkedlist_value_container_t * previous;
38- };
39-
40-
41- template <class T >
42- class LinkedList {
43- public:
4442
45- class iterator {
43+ class Iterator {
4644 public:
45+ // Needed for reverse_iterator
4746 typedef std::bidirectional_iterator_tag iterator_category;
4847 typedef T value_type;
4948 typedef std::ptrdiff_t difference_type;
5049 typedef T* pointer;
5150 typedef T& reference;
5251
53- iterator () : node(nullptr ), list(nullptr ) {}
54- iterator (linkedlist_value_container_t <T>* node, LinkedList<T>* list) : node(node), list(list) {}
52+ Iterator () : node(nullptr ), atEnd(true ) {}
53+ Iterator (linkedlist_value_container_t * node, bool atEnd) : node(node), atEnd(atEnd) {}
54+
55+ T& operator *() const {
56+ return node->value ;
57+ }
5558
56- reference operator *() const { return node->value ; }
57- pointer operator ->() const { return &node->value ; }
59+ T* operator ->() const {
60+ if (atEnd)
61+ return nullptr ;
62+ return &node->value ;
63+ }
5864
59- iterator& operator ++() {
60- if (node) node = node->next ;
65+ Iterator& operator ++() {
66+ if (!atEnd && node) {
67+ if (node->next )
68+ node = node->next ;
69+ else
70+ atEnd = true ;
71+ }
6172 return *this ;
6273 }
6374
64- iterator operator ++(int ) {
65- iterator tmp = *this ;
75+ Iterator operator ++(int ) {
76+ Iterator tmp = *this ;
6677 ++(*this );
6778 return tmp;
6879 }
6980
70- iterator& operator --() {
71- node = node ? node->previous : (list ? list->last : nullptr );
81+ Iterator& operator --() {
82+ if (atEnd)
83+ atEnd = false ;
84+ else
85+ node = node ? node->previous : nullptr ;
7286 return *this ;
7387 }
7488
75- iterator operator --(int ) {
76- iterator tmp = *this ;
89+ Iterator operator --(int ) {
90+ Iterator tmp = *this ;
7791 --(*this );
7892 return tmp;
7993 }
8094
81- bool operator ==(const iterator& other) const { return node == other.node ; }
82- bool operator !=(const iterator& other) const { return node != other.node ; }
95+ bool operator ==(const Iterator& other) const {
96+ if (atEnd != other.atEnd ) return false ;
97+ if (atEnd) return true ; // Both are at end, node doesn't matter (or should both be last)
98+ return node == other.node ;
99+ }
100+ bool operator !=(const Iterator& other) const { return !(*this == other); }
83101
84102 private:
85- linkedlist_value_container_t <T>* node;
86- LinkedList<T>* list;
87- friend class LinkedList ;
88- friend class const_iterator ;
103+ linkedlist_value_container_t * node;
104+ bool atEnd;
89105 };
90106
91- class const_iterator {
107+ class ConstIterator {
92108 public:
109+ // Needed for reverse_iterator
93110 typedef std::bidirectional_iterator_tag iterator_category;
94111 typedef const T value_type;
95112 typedef std::ptrdiff_t difference_type;
96113 typedef const T* pointer;
97114 typedef const T& reference;
98115
99- const_iterator () : node(nullptr ), list( nullptr ) {}
100- const_iterator (const linkedlist_value_container_t <T> * node, const LinkedList<T>* list ) : node(node), list(list ) {}
101- const_iterator (const iterator & other) : node(other.node), list (other.list ) {}
116+ ConstIterator () : node(nullptr ), atEnd( true ) {}
117+ ConstIterator (const linkedlist_value_container_t * node, bool atEnd ) : node(node), atEnd(atEnd ) {}
118+ ConstIterator (const Iterator & other) : node(other.node), atEnd (other.atEnd ) {}
102119
103- reference operator *() const { return node->value ; }
104- pointer operator ->() const { return &node->value ; }
120+ const T& operator *() const { return node->value ; }
121+ const T* operator ->() const {
122+ if (atEnd)
123+ return nullptr ;
124+ return &node->value ;
125+ }
105126
106- const_iterator& operator ++() {
107- if (node) node = node->next ;
127+ ConstIterator& operator ++() {
128+ if (!atEnd && node) {
129+ if (node->next )
130+ node = node->next ;
131+ else
132+ atEnd = true ;
133+ }
108134 return *this ;
109135 }
110136
111- const_iterator operator ++(int ) {
112- const_iterator tmp = *this ;
137+ ConstIterator operator ++(int ) {
138+ ConstIterator tmp = *this ;
113139 ++(*this );
114140 return tmp;
115141 }
116142
117- const_iterator& operator --() {
118- node = node ? node->previous : (list ? list->last : nullptr );
143+ ConstIterator& operator --() {
144+ if (atEnd)
145+ atEnd = false ;
146+ else
147+ node = node ? node->previous : nullptr ;
119148 return *this ;
120149 }
121150
122- const_iterator operator --(int ) {
123- const_iterator tmp = *this ;
151+ ConstIterator operator --(int ) {
152+ ConstIterator tmp = *this ;
124153 --(*this );
125154 return tmp;
126155 }
127156
128- bool operator ==(const const_iterator& other) const { return node == other.node ; }
129- bool operator !=(const const_iterator& other) const { return node != other.node ; }
157+ bool operator ==(const ConstIterator& other) const {
158+ if (atEnd != other.atEnd ) return false ;
159+ if (atEnd) return true ;
160+ return node == other.node ;
161+ }
162+ bool operator !=(const ConstIterator& other) const { return !(*this == other); }
130163
131164 private:
132- const linkedlist_value_container_t <T>* node;
133- const LinkedList<T>* list;
134- friend class LinkedList ;
165+ const linkedlist_value_container_t * node;
166+ bool atEnd;
135167 };
168+ };
136169
137- iterator begin () { return iterator (first, this ); }
138- iterator end () { return iterator (nullptr , this ); }
139- const_iterator begin () const { return const_iterator (first, this ); }
140- const_iterator end () const { return const_iterator (nullptr , this ); }
141- const_iterator cbegin () const { return const_iterator (first, this ); }
142- const_iterator cend () const { return const_iterator (nullptr , this ); }
143170
144- typedef std::reverse_iterator<iterator> reverse_iterator;
145- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
171+ template <class T >
172+ class LinkedList : public Container <T, typename linkedlist_value_container_t <T>::Iterator, typename linkedlist_value_container_t <T>::ConstIterator> {
173+ public:
174+
175+ typedef typename linkedlist_value_container_t <T>::Iterator iterator;
176+ typedef typename linkedlist_value_container_t <T>::ConstIterator const_iterator;
146177
147- reverse_iterator rbegin () { return reverse_iterator ( end () ); }
148- reverse_iterator rend () { return reverse_iterator ( begin () ); }
149- const_reverse_iterator rbegin () const { return const_reverse_iterator ( end () ); }
150- const_reverse_iterator rend () const { return const_reverse_iterator ( begin () ); }
151- const_reverse_iterator crbegin () const { return const_reverse_iterator ( end () ); }
152- const_reverse_iterator crend () const { return const_reverse_iterator ( begin () ); }
178+ iterator begin () override { return iterator (first, first == nullptr ); }
179+ iterator end () override { return iterator (last, true ); }
180+ const_iterator begin () const override { return const_iterator (first, first == nullptr ); }
181+ const_iterator end () const override { return const_iterator (last, true ); }
182+ const_iterator cbegin () const { return const_iterator (first, first == nullptr ); }
183+ const_iterator cend () const { return const_iterator (last, true ); }
153184
154185 /* *
155186 * Creates an empty LinkedList.
@@ -394,6 +425,12 @@ class LinkedList {
394425 inline linkedlist_value_container_t <T>* getRawCursor () { return cursor; }
395426 inline void setRawCursor (linkedlist_value_container_t <T>* newCursor) { cursor = newCursor; }
396427
428+ public:
429+ int length;
430+ linkedlist_value_container_t <T>* first = nullptr ;
431+ linkedlist_value_container_t <T>* last = nullptr ;
432+ linkedlist_value_container_t <T>* cursor = nullptr ;
433+
397434private:
398435 T removeRaw (linkedlist_value_container_t <T>* containerToRemove) {
399436 if (containerToRemove == last)
@@ -415,11 +452,6 @@ class LinkedList {
415452 delete containerToRemove;
416453 return value;
417454 }
418-
419- int length;
420- linkedlist_value_container_t <T>* first = nullptr ;
421- linkedlist_value_container_t <T>* last = nullptr ;
422- linkedlist_value_container_t <T>* cursor = nullptr ;
423455};
424456
425457#endif // EXCESSIVE_LINKEDLIST_H
0 commit comments