update vector and list
This commit is contained in:
parent
512e118358
commit
23fac82112
Binary file not shown.
257
src/list.hh
257
src/list.hh
@ -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
|
||||
|
@ -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_; }
|
||||
|
Loading…
Reference in New Issue
Block a user