/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* List.hpp :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/01 09:31:07 by cacharle #+# #+# */ /* Updated: 2020/04/24 19:16:46 by charles ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef LIST_HPP # define LIST_HPP # include # include namespace ft { template < typename T, typename Alloc = std::allocator > class List { public: typedef T value_type; typedef Alloc allocator_type; typedef typename allocator_type::reference reference; typedef typename allocator_type::const_reference const_reference; typedef typename allocator_type::pointer pointer; typedef typename allocator_type::const_pointer const_pointer; typedef ptrdiff_t difference_type; typedef size_t size_type; explicit List(const allocator_type& alloc = allocator_type()) : m_front(NULL), m_back(NULL), m_size(0) {} List(const List& other) { *this = other; } List& operator=(const List& other) { if (*this == other) return *this; delete m_front; m_front = NULL; m_back = NULL; // use iterator return *this; } ~List() { clear(); } explicit List(size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type()) {} template List(InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()) {} private: class ListNode { public: ListNode() : m_next(NULL), m_prev(NULL), m_data(value_type()) {} ListNode(const ListNode& other) { if (*this != other) *this = other; } ListNode& operator=(const ListNode& other) { m_next = other.m_next; m_prev = other.m_prev; m_data = other.m_data; return *this; } ~ListNode() { if (m_next != NULL) { m_next->m_prev = NULL; delete m_next; } if (m_prev != NULL) { m_prev->m_next = NULL; delete m_prev; } } ListNode(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; } private: ListNode* m_next; ListNode* m_prev; value_type m_data; }; public: class iterator { public: iterator() : m_current(NULL) {} iterator(const iterator& other) { *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(); } bool operator==(const iterator& other) { return m_current == other.m_current; } bool operator!=(const iterator& other) { return !(operator==(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--; } private: iterator(ListNode* current) : m_current(current) {} List::ListNode* m_current; }; iterator begin() { return iterator(m_front); } iterator end() { return iterator(NULL); } 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(); } void push_front(const value_type& val) { ListNode* new_front = new ListNode(val); new_front->setNext(m_front); m_front->setPrev(new_front); m_front = new_front; } void push_back(const value_type& val) { ListNode* new_back = new ListNode(val); new_back->setPrev(m_back); m_back->setNext(new_back); m_back = new_back; } void pop_front() { ListNode* tmp = m_front->getNext(); tmp->setPrev(NULL); delete m_front; m_front = tmp; } void pop_back() { ListNode* tmp = m_back->getPrev(); tmp->setNext(NULL); delete m_back; m_back = tmp; } void clear() { delete m_front; m_front = NULL; m_back = NULL; m_size = 0; } private: ListNode* m_front; ListNode* m_back; size_type m_size; }; } #endif