fixed iterators and iterator usage

This commit is contained in:
Phuntsok Drak-pa 2017-10-20 19:25:56 +02:00
parent 907377e32f
commit 6037ce30a7
2 changed files with 753 additions and 716 deletions

View File

@ -8,11 +8,21 @@
namespace phundrak { namespace phundrak {
using size_type = size_t; using size_type = size_t;
template <class T, class Allocator = std::allocator<T>> class list { template <class T, class Allocator = std::allocator<T>> class list {
public:
class iterator;
class reverse_iterator;
class const_iterator;
class const_reverse_iterator;
// using const_iterator = const iterator;
// using const_reverse_iterator = const reverse_iterator;
private:
// data structure ///////////////////////////////////////////////////////////
private:
struct cell { struct cell {
cell() = default; cell() = default;
explicit cell(const T &value) : x{value}, p{nullptr}, n{nullptr} {} explicit cell(const T &value) : x{value}, p{nullptr}, n{nullptr} {}
@ -31,7 +41,7 @@ private:
} }
cell &operator=(cell &&other) { cell &operator=(cell &&other) {
std::swap(x, other.x); std::swap(x, other.x);
std::swap(other.n, n); std::swap(n, other.n);
std::swap(p, other.p); std::swap(p, other.p);
return *this; return *this;
} }
@ -40,25 +50,21 @@ private:
T x; T x;
}; };
// members //////////////////////////////////////////////////////////////////
cell *sentry; cell *sentry;
const Allocator alloc_; const Allocator alloc_;
public: public:
class iterator;
class reverse_iterator;
using const_iterator = const iterator;
using const_reverse_iterator = const reverse_iterator;
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Member functions // // Member functions //
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Constructors ///////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////
list() : list{Allocator()}, sentry{new cell} {} list() : list{Allocator()}, sentry{new cell{}} {}
explicit list(const Allocator &alloc) : alloc_(alloc) { explicit list(const Allocator &alloc) : sentry{new cell{}}, alloc_{alloc} {
sentry = new cell{};
sentry->p = sentry; sentry->p = sentry;
sentry->n = sentry; sentry->n = sentry;
} }
@ -270,11 +276,11 @@ public:
// erase //////////////////////////////////////////////////////////////////// // erase ////////////////////////////////////////////////////////////////////
iterator erase(const_iterator pos) { iterator erase(const_iterator pos) {
pos->p->n = pos->n; pos.it->p->n = pos.it->n;
pos->n->p = pos->p; pos.it->n->p = pos.it->p;
pos->n = nullptr; pos.it->n = nullptr;
pos->p = nullptr; pos.it->p = nullptr;
cell *todel = pos; cell *todel = pos.it;
++pos; ++pos;
delete todel; delete todel;
return pos; return pos;
@ -638,14 +644,14 @@ public:
// unique /////////////////////////////////////////////////////////////////// // unique ///////////////////////////////////////////////////////////////////
void unique() { void unique() {
for(auto elem = sentry->n; elem->n != sentry; elem = elem->n) for (auto elem = sentry->n; elem->n != sentry; elem = elem->n)
if(elem->x == elem->n->x) while (elem->x == elem->n->x)
erase(iterator{elem->n}); erase(const_iterator{elem->n});
} }
template<class BinaryPredicate> void unique(BinaryPredicate p) { template <class BinaryPredicate> void unique(BinaryPredicate p) {
for(auto elem = sentry->n; elem->n != sentry; elem = elem->n) for (auto elem = sentry->n; elem->n != sentry; elem = elem->n)
if(p(elem, elem->n)) while (p(elem, elem->n))
erase(iterator{elem->n}); erase(iterator{elem->n});
} }
@ -679,7 +685,9 @@ public:
return *this; return *this;
} }
~iterator() {} ~iterator() {
// delete it;
}
iterator &operator++() { // ++i iterator &operator++() { // ++i
it = it->n; it = it->n;
@ -714,16 +722,28 @@ public:
bool operator!=(const iterator &other) { return other.it != it; } bool operator!=(const iterator &other) { return other.it != it; }
bool operator!=(iterator &&other) { return other.it != it; } bool operator!=(iterator &&other) { return other.it != it; }
T& operator*() { return it->x; } T &operator*() { return it->x; }
friend class list;
}; };
class reverse_iterator : protected iterator { class const_iterator : public iterator {
public:
const_iterator() : iterator() {}
explicit const_iterator(cell *point) : iterator{point} {}
explicit const_iterator(const iterator &other) : iterator{other} {}
const_iterator(const const_iterator &other) : iterator{other} {}
explicit const_iterator(iterator &&other) : iterator{std::move(other)} {}
const_iterator(const_iterator &&other) : iterator{std::move(other)} {}
const T &operator*() { return this->it->x; }
};
class reverse_iterator : public iterator {
public: public:
reverse_iterator() : iterator() {} reverse_iterator() : iterator() {}
explicit reverse_iterator(T *point) : iterator(point) {} explicit reverse_iterator(cell *point) : iterator(point) {}
reverse_iterator(const reverse_iterator &other) : iterator(other) {} reverse_iterator(const reverse_iterator &other) : iterator(other) {}
reverse_iterator(reverse_iterator &&other) : iterator(std::move(other)) {} reverse_iterator(reverse_iterator &&other) : iterator(std::move(other)) {}
reverse_iterator &operator++() { reverse_iterator &operator++() {
@ -750,6 +770,19 @@ public:
~reverse_iterator() {} ~reverse_iterator() {}
}; };
};
class const_reverse_iterator : public reverse_iterator {
public:
const_reverse_iterator() : reverse_iterator() {}
explicit const_reverse_iterator(cell *point) : reverse_iterator{point} {}
explicit const_reverse_iterator(const reverse_iterator &other)
: reverse_iterator{other} {}
const_reverse_iterator(const const_reverse_iterator &other)
: reverse_iterator{other} {}
explicit const_reverse_iterator(reverse_iterator &&other)
: reverse_iterator{other} {}
virtual ~const_reverse_iterator() { ~reverse_iterator(); }
};
};
} // namespace phundrak } // namespace phundrak

View File

@ -1,25 +1,29 @@
#include "list.hh" #include "list.hh"
#include "vector.hh" #include "vector.hh"
#include <cstdio> #include <iostream>
using namespace phundrak; using namespace phundrak;
using std::cout;
int main(void) { int main(void) {
printf("Hello 1!\n");
list<char> test {'C', 'a', 'r', 't', 'i', 'e', 'r'}; list<char> test {'C', 'a', 'r', 't', 'i', 'e', 'r'};
printf("Hello !\n");
for(auto c : test) { for(auto c : test)
printf("%c\n", c); cout << c << " ";
}
cout << "\n";
list<int> test_unique {1,1,1,1,1,2,2,2,3,3,3,4,4,1,1,5,1,2,1,1,3,3,3}; list<int> test_unique {1,1,1,1,1,2,2,2,3,3,3,4,4,1,1,5,1,2,1,1,3,3,3};
printf("Elements before unique():\n"); printf("Elements before unique():\n");
for(const auto& elem : test_unique) for(const auto& elem : test_unique)
printf("%2d,", elem); cout << elem << " ";
cout << "\n";
test_unique.unique(); test_unique.unique();
for(const auto& elem : test_unique)
cout << elem << " ";
cout << "\n";
return 0; return 0;
} }