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 <algorithm>
#include <memory>
#include <utility>
@ -7,37 +8,48 @@ namespace phundrak {
using size_type = size_t;
template <class T, class Allocator = std::allocator<T>> class list {
private:
struct cell {
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 *n;
T x;
};
cell *sentry;
const Allocator alloc_;
public:
class iterator;
class const_iterator;
class reverse_iterator;
class const_reverse_iterator;
// Member types //////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Member functions //
/////////////////////////////////////////////////////////////////////////////
// Constructors /////////////////////////////////////////////////////////////
list() : list{Allocator()}, sentry{new cell} {}
explicit list(const Allocator &alloc) {
sentry = new cell;
explicit list(const Allocator &alloc) : alloc_(alloc) {
sentry = new cell{};
sentry->p = sentry;
sentry->n = sentry;
}
list(size_type count, const T &value, const Allocator &alloc = Allocator())
: list(alloc) {
: list(alloc), alloc_{alloc} {
while (size() < count)
push_back(value);
}
explicit list(size_type count, const Allocator &alloc = Allocator())
: list(alloc) {
: list(alloc), alloc_{alloc} {
while (size() < count)
push_back(T());
}
@ -59,7 +71,10 @@ public:
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) {
std::swap(other.sentry, sentry);
@ -67,43 +82,18 @@ public:
list(std::initializer_list<T> init, const Allocator &alloc = Allocator())
: list(alloc) {
for (auto elem : init)
for (const T &elem : init)
push_back(elem);
}
// Destructor ///////////////////////////////////////////////////////////////
virtual ~list() {
clear();
delete sentry;
}
// Element access ////////////////////////////////////////////////////////////
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;
}
}
// operator= ////////////////////////////////////////////////////////////////
list &operator=(const list &other) {
cell *it = other.sentry->n;
@ -120,12 +110,84 @@ public:
}
list &operator=(std::initializer_list<T> ilist) {
for (auto elem : ilist)
for (const T &elem : ilist)
push_back(elem);
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 {
cell *it = sentry->n;
@ -137,6 +199,48 @@ public:
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) {
cell *c = new cell;
c->x = v;
@ -170,6 +274,10 @@ public:
}
class iterator {
protected:
cell *it;
public:
iterator() : it{nullptr} {}
explicit iterator(cell *point) : it{point} {}
@ -197,10 +305,10 @@ public:
it = it->n;
return *this;
}
iterator &operator++(int) { // i++
iterator t;
t.it = it;
// iterator t{*this};
iterator operator++(int) { // i++
// iterator t;
// t.it = it;
iterator t{*this};
it = it->n;
return t;
}
@ -210,9 +318,10 @@ public:
return *this;
}
iterator &operator--(int) { // i--
iterator t;
t.it = it;
iterator operator--(int) { // i--
// iterator t;
// t.it = it;
iterator t{it};
it = it->n;
return t;
}
@ -226,9 +335,6 @@ public:
bool operator!=(iterator &&other) { return other.it != it; }
T operator*() { return it->x; }
protected:
cell *it;
};
class const_iterator : protected iterator {
@ -243,12 +349,65 @@ public:
const_iterator(const_iterator &&other) : iterator(std::move(other)) {}
const_iterator &operator++() = delete;
const_iterator &operator++(int) = delete;
const_iterator operator++(int) = delete;
const_iterator &operator--() = delete;
const_iterator &operator--(int) = delete;
const_iterator operator--(int) = delete;
~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

View File

@ -3,6 +3,7 @@
#include <iterator>
#include <stdexcept>
#include <iostream>
#include <type_traits>
namespace phundrak {
@ -63,22 +64,26 @@ namespace phundrak {
push_back(value);
}
template <class InputIt> void assign(InputIt first, InputIt last) {
clear();
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;
}
template<typename InputIt,
typename std::enable_if_t<!std::is_integral<InputIt>::value, InputIt>* = nullptr>
// template <class InputIt> void assign(InputIt first, InputIt last) {
// clear();
// 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 /////////////////////////////////////////////////////////
T &at(size_t pos) {
try {
if (pos >= size_ || pos < 0)
if (pos >= size_)
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::terminate();
}
@ -116,7 +121,7 @@ namespace phundrak {
// Capacity ///////////////////////////////////////////////////////////////
bool empty() const noexcept {
return (size_ <= 0 || data_ == nullptr) ? true : false;
return (data_ == nullptr) ? true : false;
}
size_t size() const noexcept { return size_; }