diff options
Diffstat (limited to 'List.hpp')
| -rw-r--r-- | List.hpp | 319 |
1 files changed, 264 insertions, 55 deletions
@@ -6,7 +6,7 @@ /* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/01 09:31:07 by cacharle #+# #+# */ -/* Updated: 2020/04/24 19:16:46 by charles ### ########.fr */ +/* Updated: 2020/04/26 12:50:59 by charles ### ########.fr */ /* */ /* ************************************************************************** */ @@ -32,33 +32,41 @@ namespace ft typedef size_t size_type; explicit List(const allocator_type& alloc = allocator_type()) - : m_front(NULL), m_back(NULL), m_size(0) {} + : m_front(NULL), m_back(NULL), m_size(0), m_alloc(alloc) {} - List(const List& other) { *this = other; } + List(const List& other) : m_front(NULL), m_back(NULL) { *this = other; } List& operator=(const List& other) { - if (*this == other) + if (this == &other) return *this; - delete m_front; - m_front = NULL; - m_back = NULL; - // use iterator + clear(); + for (iterator it = other.begin(); it != other.end(); ++it) + push_back(*it); + m_alloc = other.m_alloc; return *this; } - ~List() { - clear(); - } + ~List() { delete m_front; } explicit List(size_type n, const value_type& val = value_type(), - const allocator_type& alloc = allocator_type()) {} + const allocator_type& alloc = allocator_type()) + : m_front(NULL), m_back(NULL), m_size(0), m_alloc(alloc) + { + while (n-- > 0) + push_back(val); + } template<typename InputIterator> List(InputIterator first, InputIterator last, - const allocator_type& alloc = allocator_type()) {} + const allocator_type& alloc = allocator_type()) + : m_front(NULL), m_back(NULL), m_size(0), m_alloc(alloc) + { + for (; first != last; ++first) + push_back(*first); + } private: class ListNode @@ -66,14 +74,12 @@ namespace ft public: ListNode() : m_next(NULL), m_prev(NULL), m_data(value_type()) {} - ListNode(const ListNode& other) - { - if (*this != other) - *this = other; - } + ListNode(const ListNode& other) { *this = other; } ListNode& operator=(const ListNode& other) { + if (this == &other) + return *this; m_next = other.m_next; m_prev = other.m_prev; m_data = other.m_data; @@ -92,11 +98,15 @@ namespace ft } } - ListNode(value_type& data) : m_next(NULL), m_prev(NULL), m_data(data) {} + ListNode(const value_type& data) : m_next(NULL), m_prev(NULL), m_data(data) {} ListNode* getNext() const { return m_next; } ListNode* getPrev() const { return m_prev; } - value_type& getData() const { return m_data; } + value_type& getData() { return m_data; } + + void setNext(ListNode* val) { m_next = val; } + void setPrev(ListNode* val) { m_prev = val; } + void setData(const value_type& val) { m_data = val; } private: ListNode* m_next; @@ -107,42 +117,30 @@ namespace ft public: class iterator { + friend class List<T, Alloc>; public: iterator() : m_current(NULL) {} + iterator(const iterator& other) { *this = other; } + ~iterator() {} - iterator(const iterator& other) { - *this = other; - } - - iterator& operator=(const iterator& other) { - if (*this == other) + iterator& operator=(const iterator& other) + { + if (this == &other) return *this; m_current = other.m_current; return *this; } - ~iterator() {} - - value_type& operator*() { return m_current->getData(); } - value_type& operator->() { return m_current->getData(); } + value_type& operator*() { return m_current->getData(); } + value_type* operator->() { return &m_current->getData(); } - bool operator==(const iterator& other) { return m_current == other.m_current; } - bool operator!=(const iterator& other) { return !(operator==(other)); } + bool operator==(const iterator& other) const { return m_current == other.m_current; } + bool operator!=(const iterator& other) const { return !(*this == other); } - iterator& operator++(int) - { - m_current = m_current->getNext(); - return *this; - } - - iterator& operator--(int) - { - m_current = m_current->getPrev(); - return *this; - } - - iterator& operator++() { return operator++; } - iterator& operator--() { return operator--; } + iterator& operator++() { m_current = m_current->getNext(); return *this; } + iterator& operator--() { m_current = m_current->getPrev(); return *this; } + iterator operator++(int) { iterator copy(*this); operator++(); return copy; } + iterator operator--(int) { iterator copy(*this); operator--(); return copy; } private: iterator(ListNode* current) : m_current(current) {} @@ -150,46 +148,176 @@ namespace ft List::ListNode* m_current; }; - iterator begin() { return iterator(m_front); } - iterator end() { return iterator(NULL); } + class const_iterator : public iterator + { + public: + const_iterator() : iterator() {} + const_iterator(const iterator& other) : iterator(other) {} + ~const_iterator() {} + const value_type& operator*() const { return iterator::m_current->getData(); } + const value_type* operator->() const { return &iterator::m_current->getData(); } + }; + + iterator begin() { return iterator(m_front); } + iterator end() { return iterator(NULL); } + const_iterator begin() const { return const_iterator(m_front); } + const_iterator end() const { return const_iterator(NULL); } + + bool empty() const { return m_size == 0; } + size_type size() const { return m_size; } + size_type max_size() const { return UINT_MAX; } - bool empty() const { return m_front == NULL; } - size_type size() const { return m_size; } - size_type max_size() const { return m_size; } + reference front() { return m_front->getData(); } + reference back() { return m_back->getData(); } + const_reference front() const { return m_front->getData(); } + const_reference back() const { return m_back->getData(); } - reference front() { return m_front->getData(); } - reference back() { return m_back->getData(); } + template <typename InputIterator> + void assign(InputIterator first, InputIterator last) + { + clear(); + for (; first != last; ++first) + push_back(*first); + } + + void assign(size_type n, const value_type& val) + { + clear(); + while (n-- > 0) + push_back(val); + } void push_front(const value_type& val) { ListNode* new_front = new ListNode(val); new_front->setNext(m_front); - m_front->setPrev(new_front); + if (m_front != NULL) + m_front->setPrev(new_front); + else + m_back = new_front; m_front = new_front; + m_size++; } void push_back(const value_type& val) { ListNode* new_back = new ListNode(val); new_back->setPrev(m_back); - m_back->setNext(new_back); + if (m_back != NULL) + m_back->setNext(new_back); + else + m_front = new_back; m_back = new_back; + m_size++; } void pop_front() { ListNode* tmp = m_front->getNext(); tmp->setPrev(NULL); + m_front->setNext(NULL); delete m_front; m_front = tmp; + m_size--; } void pop_back() { ListNode* tmp = m_back->getPrev(); tmp->setNext(NULL); + m_back->setPrev(NULL); delete m_back; m_back = tmp; + m_size--; + } + + iterator insert(iterator position, const value_type& val) + { + ListNode* inserted = new ListNode(val); + + if (position.m_current->m_prev != NULL) + position.m_current->m_prev->m_next = inserted; + else + m_front = inserted; + if (position.m_current->m_next != NULL) + position.m_current->m_next->m_prev = inserted; + else + m_back = inserted; + m_size++; + return iterator(inserted); + } + + void insert(iterator position, size_type n, const value_type& val) + { + while (n-- > 0) + insert(position, val); + } + + template <typename InputIterator> + void insert(iterator position, InputIterator first, InputIterator last) + { + if (first == last) + return; + --last; + for (; last != first; --last) + insert(position, *last); + insert(position, *last); + } + + iterator erase(iterator position) + { + iterator ret(position.m_current->m_next); + + if (position.m_current->m_prev != NULL) + position.m_current->m_prev->m_next = position.m_current->m_next; + if (position.m_current->m_next != NULL) + position.m_current->m_next->m_prev = position.m_current->m_prev; + delete position.m_current; + m_size--; + return ret; + } + + iterator erase(iterator first, iterator last) + { + iterator tmp(first); + + while (first != last) + { + ++tmp; + erase(first); + first = tmp; + } + return last; + } + + void swap(List& x) + { + ListNode* tmp_front = x.m_front; + ListNode* tmp_back = x.m_back; + size_type tmp_size = x.m_size; + allocator_type tmp_alloc = x.m_alloc; + + x.m_front = m_front; + x.m_back = m_back; + x.m_size = m_size; + x.m_alloc = m_alloc; + + m_front = tmp_front; + m_back = tmp_back; + m_size = tmp_size; + m_alloc = tmp_alloc; + } + + void resize(size_type n, value_type val = value_type()) + { + if (n == m_size) + return; + if (n < m_size) + while (n-- > 0) + pop_back(); + else + while (n-- > 0) + push_back(val); } void clear() @@ -200,11 +328,92 @@ namespace ft m_size = 0; } + void remove(const value_type& val) { remove_if(EqualPredicate(val)); } + + template <typename Predicate> + void remove_if(Predicate pred) + { + for (iterator it = begin(); it != end(); ++it) + if (pred(*it)) + erase(it); + } + + void merge(List& x) { merge(x, &compar); } + + template <typename Compare> + void merge(List& x, Compare comp) + { + iterator it = begin(); + while (!x.empty()) + { + while (it != end() && comp(*it, x.front())) + ++it; + insert(it, x.front()); + x.pop_front(); + } + } + + void sort() { sort(&compar); } + + template <typename Compare> + void sort(Compare comp) + { + (void)comp; + // for (iterator it = begin(); it != end(); ++it) + // { + // for (iterator it2(it); it2 != end(); ++it) + // } + } + + void reverse() + { + + } + + bool operator==(const List& other) const + { + if (m_size != other.m_size) + return false; + iterator it1 = begin(); + iterator it2 = begin(); + for (; it1 != end(); ++it1, ++it2) + if (*it1 != *it2) + return false; + return true; + } + + bool operator!=(const List& other) const { return !(*this == other); } + + bool operator<(const List& other) const + { + iterator it1 = begin(); + iterator it2 = begin(); + for (; it1 != end() && it2 != end() && *it1 == *it2; ++it1, ++it2); + + if (it1 == end() && it2 == other.end()) + return false; + if (it1 == end() || it2 == other.end()) + return it1 == end(); + return *it1 < *it2; + } + + bool operator>(const List& other) const { return other < *this; } + bool operator<=(const List& other) const { return !(*this > other); } + bool operator>=(const List& other) const { return !(*this < other); } private: ListNode* m_front; ListNode* m_back; size_type m_size; + allocator_type m_alloc; + + static bool compar(const value_type& a, const value_type& b) { return a < b; } + + struct EqualPred + { + bool operator()(const value_type& other) const { return val == other; } + const value_type& val; + }; }; } |
