update vector and list

This commit is contained in:
Lucien Cartier-Tilet 2017-10-10 16:30:42 +02:00
parent 512e118358
commit 23fac82112
3 changed files with 224 additions and 60 deletions

Binary file not shown.

View File

@ -1,4 +1,5 @@
#include <cstdlib> #include <cstdlib>
#include <algorithm>
#include <memory> #include <memory>
#include <utility> #include <utility>
@ -7,37 +8,48 @@ 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 {
private: private:
struct cell { struct cell {
cell() = default; cell() = default;
explicit cell(const T& value) : x{value}, p{nullptr}, n{nullptr} {}
explicit cell(T&& value) : x{value}, p{nullptr}, n{nullptr} {}
cell *p; cell *p;
cell *n; cell *n;
T x; T x;
}; };
cell *sentry; cell *sentry;
const Allocator alloc_;
public: public:
class iterator; class iterator;
class const_iterator; class const_iterator;
class reverse_iterator;
class const_reverse_iterator;
// Member types ////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Member functions //
/////////////////////////////////////////////////////////////////////////////
// Constructors /////////////////////////////////////////////////////////////
list() : list{Allocator()}, sentry{new cell} {} list() : list{Allocator()}, sentry{new cell} {}
explicit list(const Allocator &alloc) { explicit list(const Allocator &alloc) : alloc_(alloc) {
sentry = new cell; sentry = new cell{};
sentry->p = sentry; sentry->p = sentry;
sentry->n = sentry; sentry->n = sentry;
} }
list(size_type count, const T &value, const Allocator &alloc = Allocator()) list(size_type count, const T &value, const Allocator &alloc = Allocator())
: list(alloc) { : list(alloc), alloc_{alloc} {
while (size() < count) while (size() < count)
push_back(value); push_back(value);
} }
explicit list(size_type count, const Allocator &alloc = Allocator()) explicit list(size_type count, const Allocator &alloc = Allocator())
: list(alloc) { : list(alloc), alloc_{alloc} {
while (size() < count) while (size() < count)
push_back(T()); push_back(T());
} }
@ -59,7 +71,10 @@ public:
push_back(elem); push_back(elem);
} }
list(list &&other) : list() { std::swap(other.sentry, sentry); } list(list &&other) : list() {
std::swap(other.sentry, sentry);
std::swap(other.alloc_, alloc_);
}
list(list &&other, const Allocator &alloc) : list(alloc) { list(list &&other, const Allocator &alloc) : list(alloc) {
std::swap(other.sentry, sentry); std::swap(other.sentry, sentry);
@ -67,43 +82,18 @@ public:
list(std::initializer_list<T> init, const Allocator &alloc = Allocator()) list(std::initializer_list<T> init, const Allocator &alloc = Allocator())
: list(alloc) { : list(alloc) {
for (auto elem : init) for (const T &elem : init)
push_back(elem); push_back(elem);
} }
// Destructor ///////////////////////////////////////////////////////////////
virtual ~list() { virtual ~list() {
clear(); clear();
delete sentry; delete sentry;
} }
// Element access //////////////////////////////////////////////////////////// // operator= ////////////////////////////////////////////////////////////////
T &front() const { return sentry->n->x; }
T &back() const { return sentry->p->x; }
// Iterators /////////////////////////////////////////////////////////////////
iterator begin() noexcept { return iterator{sentry->n}; }
const_iterator begin() const noexcept { return const_iterator{sentry->n}; }
const_iterator cbegin() const noexcept { return const_iterator{sentry->n}; }
iterator end() noexcept { return iterator{sentry}; }
const_iterator end() const noexcept { return const_iterator{sentry}; }
const_iterator cend() const noexcept { return const_iterator{sentry}; }
// Capacity //////////////////////////////////////////////////////////////////
// Modifiers /////////////////////////////////////////////////////////////////
void clear() {
cell *it = sentry->n;
while (it != sentry) {
cell *todel = it;
it = it->n;
delete todel;
}
}
list &operator=(const list &other) { list &operator=(const list &other) {
cell *it = other.sentry->n; cell *it = other.sentry->n;
@ -120,12 +110,84 @@ public:
} }
list &operator=(std::initializer_list<T> ilist) { list &operator=(std::initializer_list<T> ilist) {
for (auto elem : ilist) for (const T &elem : ilist)
push_back(elem); push_back(elem);
return *this; return *this;
} }
bool empty() { return sentry->p == sentry; } // Assign ///////////////////////////////////////////////////////////////////
void assign(size_type count, const T &value) {
clear();
for (int i = 0; i < count; ++i)
push_front(value);
}
template <class InputIt> void assign(InputIt first, InputIt last) {
clear();
for (; first != last; ++first)
push_back(*first);
}
void assign(std::initializer_list<T> ilist) {
clear();
for (const T &elem : ilist)
push_back(elem);
}
// get_allocator ////////////////////////////////////////////////////////////
std::allocator<T> get_allocator() { return alloc_; }
/////////////////////////////////////////////////////////////////////////////
// Element access //
/////////////////////////////////////////////////////////////////////////////
T &front() { return sentry->n->x; }
const T &front() const { return sentry->n->x; }
T &back() { return sentry->p->x; }
const T &back() const { return sentry->p->x; }
/////////////////////////////////////////////////////////////////////////////
// Iterators //
/////////////////////////////////////////////////////////////////////////////
// iterators ////////////////////////////////////////////////////////////////
iterator begin() noexcept { return iterator{sentry->n}; }
const_iterator begin() const noexcept { return const_iterator{sentry->n}; }
const_iterator cbegin() const noexcept { return const_iterator{sentry->n}; }
iterator end() noexcept { return iterator{sentry}; }
const_iterator end() const noexcept { return const_iterator{sentry}; }
const_iterator cend() const noexcept { return const_iterator{sentry}; }
// reverse iterators ////////////////////////////////////////////////////////
reverse_iterator rbegin() noexcept { return reverse_iterator{sentry->p}; }
const_reverse_iterator rbegin() const noexcept {
return const_reverse_iterator{sentry->p};
}
const_reverse_iterator crbegin() const noexcept {
return const_reverse_iterator{sentry->p};
}
reverse_iterator rend() noexcept { return reverse_iterator{sentry}; }
const_reverse_iterator rend() const noexcept {
return const_reverse_iterator{sentry};
}
const_reverse_iterator crend() const noexcept {
return const_reverse_iterator{sentry};
}
/////////////////////////////////////////////////////////////////////////////
// Capacity //
/////////////////////////////////////////////////////////////////////////////
bool empty() const noexcept {
return sentry->p == sentry;
}
size_type size() const { size_type size() const {
cell *it = sentry->n; cell *it = sentry->n;
@ -137,6 +199,48 @@ public:
return n; return n;
} }
/////////////////////////////////////////////////////////////////////////////
// Modifiers //
/////////////////////////////////////////////////////////////////////////////
void clear() {
cell *it = sentry->n;
while (it != sentry) {
cell *todel = it;
it = it->n;
delete todel;
}
}
iterator insert(const_iterator pos, const T &value) {
cell *elem = new cell{value};
elem->n = pos;
elem->p = pos->p;
pos->p->n = elem;
pos->p = elem;
return iterator{pos};
}
iterator insert(const_iterator pos, T &&value) {
cell *elem = new cell{value};
elem->n = pos;
elem->p = pos->p;
pos->p->n = elem;
pos->p = elem;
return iterator{pos};
}
template<class InputIt>
iterator insert(const_iterator pos, InputIt first, InputIt last) {
for(; first != last; ++first)
insert(pos, *first);
return iterator{pos};
}
bool empty() { return sentry->p == sentry; }
void push_front(const T &v) { void push_front(const T &v) {
cell *c = new cell; cell *c = new cell;
c->x = v; c->x = v;
@ -170,6 +274,10 @@ public:
} }
class iterator { class iterator {
protected:
cell *it;
public: public:
iterator() : it{nullptr} {} iterator() : it{nullptr} {}
explicit iterator(cell *point) : it{point} {} explicit iterator(cell *point) : it{point} {}
@ -197,10 +305,10 @@ public:
it = it->n; it = it->n;
return *this; return *this;
} }
iterator &operator++(int) { // i++ iterator operator++(int) { // i++
iterator t; // iterator t;
t.it = it; // t.it = it;
// iterator t{*this}; iterator t{*this};
it = it->n; it = it->n;
return t; return t;
} }
@ -210,9 +318,10 @@ public:
return *this; return *this;
} }
iterator &operator--(int) { // i-- iterator operator--(int) { // i--
iterator t; // iterator t;
t.it = it; // t.it = it;
iterator t{it};
it = it->n; it = it->n;
return t; return t;
} }
@ -226,9 +335,6 @@ public:
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; }
protected:
cell *it;
}; };
class const_iterator : protected iterator { class const_iterator : protected iterator {
@ -243,12 +349,65 @@ public:
const_iterator(const_iterator &&other) : iterator(std::move(other)) {} const_iterator(const_iterator &&other) : iterator(std::move(other)) {}
const_iterator &operator++() = delete; const_iterator &operator++() = delete;
const_iterator &operator++(int) = delete; const_iterator operator++(int) = delete;
const_iterator &operator--() = delete; const_iterator &operator--() = delete;
const_iterator &operator--(int) = delete; const_iterator operator--(int) = delete;
~const_iterator() {} ~const_iterator() {}
}; };
class reverse_iterator : protected iterator {
public:
reverse_iterator() : iterator() {}
explicit reverse_iterator(T *point) : iterator(point) {}
reverse_iterator(const reverse_iterator &other) : iterator(other) {}
reverse_iterator(reverse_iterator &&other) : iterator(std::move(other)) {}
reverse_iterator &operator++() {
this->it = this->it->p;
return *this;
}
reverse_iterator operator++(int) {
reverse_iterator t{*this};
this->it = this->it->p;
return t;
}
reverse_iterator &operator--() {
this->it = this->it->n;
return *this;
}
reverse_iterator operator--(int) {
reverse_iterator t{*this};
this->it = this->it->p;
return t;
}
~reverse_iterator() {}
};
class const_reverse_iterator : protected iterator {
public:
const_reverse_iterator() : iterator() {}
explicit const_reverse_iterator(T *point) : iterator(point) {}
const_reverse_iterator(const const_reverse_iterator &other)
: iterator(other) {}
const_reverse_iterator(const_reverse_iterator &&other)
: iterator(std::move(other)) {}
const_reverse_iterator &operator++() = delete;
const_reverse_iterator &operator++(int) = delete;
const_reverse_iterator &operator--() = delete;
const_reverse_iterator &operator--(int) = delete;
~const_reverse_iterator() {}
};
}; };
} // namespace phundrak } // namespace phundrak

View File

@ -3,6 +3,7 @@
#include <iterator> #include <iterator>
#include <stdexcept> #include <stdexcept>
#include <iostream> #include <iostream>
#include <type_traits>
namespace phundrak { namespace phundrak {
@ -63,22 +64,26 @@ namespace phundrak {
push_back(value); push_back(value);
} }
template <class InputIt> void assign(InputIt first, InputIt last) { template<typename InputIt,
clear(); typename std::enable_if_t<!std::is_integral<InputIt>::value, InputIt>* = nullptr>
capacity_ = std::distance(first, last);
size_ = std::distance(first, last);
data_ = new T[size_]; // template <class InputIt> void assign(InputIt first, InputIt last) {
for (int i = 0; first != last; ++first, ++i) // clear();
data_[i] = *first; // capacity_ = std::distance(first, last);
} // size_ = std::distance(first, last);
// data_ = new T[size_];
// for (int i = 0; first != last; ++first, ++i)
// data_[i] = *first;
// }
// Element access ///////////////////////////////////////////////////////// // Element access /////////////////////////////////////////////////////////
T &at(size_t pos) { T &at(size_t pos) {
try { try {
if (pos >= size_ || pos < 0) if (pos >= size_)
throw std::out_of_range("Out of range"); throw std::out_of_range("Out of range");
} catch (std::out_of_range e) { } catch (const std::out_of_range& e) {
std::cout << e.what() << " in phundrak::vector " << this << '\n'; std::cout << e.what() << " in phundrak::vector " << this << '\n';
std::terminate(); std::terminate();
} }
@ -116,7 +121,7 @@ namespace phundrak {
// Capacity /////////////////////////////////////////////////////////////// // Capacity ///////////////////////////////////////////////////////////////
bool empty() const noexcept { bool empty() const noexcept {
return (size_ <= 0 || data_ == nullptr) ? true : false; return (data_ == nullptr) ? true : false;
} }
size_t size() const noexcept { return size_; } size_t size() const noexcept { return size_; }