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 <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
|
||||||
|
@ -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_; }
|
||||||
|
Loading…
Reference in New Issue
Block a user