diff --git a/debug/PhundrakSTL b/debug/PhundrakSTL index 8ee3a1e..db2daf9 100755 Binary files a/debug/PhundrakSTL and b/debug/PhundrakSTL differ diff --git a/src/list.hh b/src/list.hh index 1ec587d..12ffe7f 100644 --- a/src/list.hh +++ b/src/list.hh @@ -1,4 +1,5 @@ #include +#include #include #include @@ -7,37 +8,48 @@ namespace phundrak { using size_type = size_t; template > 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 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 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 void assign(InputIt first, InputIt last) { + clear(); + for (; first != last; ++first) + push_back(*first); + } + + void assign(std::initializer_list ilist) { + clear(); + for (const T &elem : ilist) + push_back(elem); + } + + // get_allocator //////////////////////////////////////////////////////////// + + std::allocator 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 + 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 diff --git a/src/vector.hh b/src/vector.hh index 9b599b9..166f9c3 100644 --- a/src/vector.hh +++ b/src/vector.hh @@ -3,6 +3,7 @@ #include #include #include +#include namespace phundrak { @@ -63,22 +64,26 @@ namespace phundrak { push_back(value); } - template 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::value, InputIt>* = nullptr> + + + // template 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_; }