semf
linkedlist.h
Go to the documentation of this file.
1
10#ifndef SEMF_UTILS_CORE_LISTS_LINKEDLIST_H_
11#define SEMF_UTILS_CORE_LISTS_LINKEDLIST_H_
12
13#include <iterator>
14#include <cstdint>
15#include <cstddef>
16
17namespace semf
18{
41template <class T>
43{
44public:
51 class Node
52 {
53 public:
54 virtual ~Node() = default;
55
61 T* next() const
62 {
63 return m_next;
64 }
70 void setNext(T* next)
71 {
72 m_next = next;
73 }
79 T* previous() const
80 {
81 return m_previous;
82 }
89 {
90 m_previous = previous;
91 }
97 bool isInAList()
98 {
99 if (m_previous != nullptr || m_next != nullptr)
100 return true;
101 else
102 return false;
103 }
104
105 private:
107 T* m_next = nullptr;
109 T* m_previous = nullptr;
110 };
111
116 {
117 public:
118 using iterator_category = std::bidirectional_iterator_tag;
119 using value_type = T;
120 using difference_type = std::ptrdiff_t;
121 using pointer = T*;
122 using refernce = T&;
123
124 Iterator() = default;
129 explicit Iterator(T* element)
130 : m_node(element)
131 {
132 }
133 virtual ~Iterator() = default;
134
141 T& operator*() const
142 {
143 return *m_node;
144 }
151 T* operator->() const
152 {
153 return m_node;
154 }
162 {
163 m_node = m_node->LinkedList::Node::next();
164 return *this;
165 }
173 {
174 Iterator temp = *this;
175 m_node = m_node->LinkedList::Node::next();
176 return temp;
177 }
185 {
186 m_node = m_node->LinkedList::Node::previous();
187 return *this;
188 }
196 {
197 Iterator temp = *this;
198 temp.m_node = temp.m_node->LinkedList::Node::previous();
199 return temp;
200 }
207 bool operator==(const Iterator& that) const
208 {
209 return m_node == that.m_node;
210 }
217 bool operator!=(const Iterator& that) const
218 {
219 return m_node != that.m_node;
220 }
221
222 private:
224 T* m_node = nullptr;
225 };
226
231 {
232 public:
233 using iterator_category = std::bidirectional_iterator_tag;
234 using value_type = T;
235 using difference_type = std::ptrdiff_t;
236 using pointer = T*;
237 using refernce = T&;
238
239 ConstIterator() = default;
244 explicit ConstIterator(const T* element)
245 : m_node(element)
246 {
247 }
252 explicit ConstIterator(const Iterator& iterator)
253 : m_node(iterator.m_node)
254 {
255 }
256 virtual ~ConstIterator() = default;
257
264 const T& operator*() const
265 {
266 return *m_node;
267 }
274 const T* operator->() const
275 {
276 return m_node;
277 }
285 {
286 m_node = m_node->LinkedList::Node::next();
287 return *this;
288 }
296 {
297 ConstIterator temp = *this;
298 m_node = m_node->LinkedList::Node::next();
299 return temp;
300 }
308 {
309 m_node = m_node->LinkedList::Node::previous();
310 return *this;
311 }
319 {
320 ConstIterator temp = *this;
321 m_node = m_node->LinkedList::Node::previous();
322 return temp;
323 }
330 bool operator==(const ConstIterator& other) const
331 {
332 return m_node == other.m_node;
333 }
340 bool operator!=(const ConstIterator& other) const
341 {
342 return m_node != other.m_node;
343 }
344
345 private:
347 const T* m_node = nullptr;
348 };
361 T& front();
370 const T& front() const;
379 T& back();
388 const T& back() const;
396 Iterator begin();
404 ConstIterator begin() const;
412 ConstIterator cbegin() const;
423 Iterator end();
434 ConstIterator end() const;
445 ConstIterator cend() const;
453 bool empty() const;
458 size_t size() const;
463 void clear();
470 Iterator insert(Iterator position, T& element);
479 Iterator erase(Iterator position);
490 Iterator erase(Iterator first, Iterator last);
498 void pushBack(T& element);
507 void pushFront(T& element);
512 void popBack();
517 void popFront();
526
527private:
532 void pushEmpty(T& element);
534 T* m_front = nullptr;
536 Node m_end;
538 size_t m_size = 0;
539};
540
541template <class T>
543{
544 clear();
545}
546
547template <class T>
549{
550 return *m_front;
551}
552
553template <class T>
554const T& LinkedList<T>::front() const
555{
556 return *m_front;
557}
558
559template <class T>
561{
562 return *m_end.previous();
563}
564
565template <class T>
566const T& LinkedList<T>::back() const
567{
568 return *m_end.previous();
569}
570
571template <class T>
573{
574 return m_front ? Iterator(m_front) : end();
575}
576
577template <class T>
579{
580 return m_front ? ConstIterator(m_front) : end();
581}
582
583template <class T>
585{
586 return m_front ? ConstIterator(m_front) : cend();
587}
588
589template <class T>
591{
592 return Iterator(reinterpret_cast<T*>(&m_end));
593}
594
595template <class T>
597{
598 return ConstIterator(reinterpret_cast<const T*>(&m_end));
599}
600
601template <class T>
603{
604 return ConstIterator(reinterpret_cast<const T*>(&m_end));
605}
606
607template <class T>
609{
610 return m_size == 0;
611}
612
613template <class T>
615{
616 return m_size;
617}
618
619template <class T>
621{
622 m_front = nullptr;
623 m_end.setPrevious(m_front);
624 m_size = 0;
625}
626
627template <class T>
629{
630 Iterator ret = position;
631 if (&(*position) == m_front)
632 {
633 pushFront(element);
634 ret = Iterator(m_front);
635 }
636 else if (m_size == 0)
637 {
638 m_front = &element;
639 m_end.setPrevious(&element);
640 m_size++;
641 ret = Iterator(m_front);
642 }
643 else
644 {
645 T* nex = &(*position);
646 nex->LinkedList::Node::setPrevious(&element);
647 T* pre = &(*position--);
648 pre->LinkedList::Node::setNext(&element);
649 }
650 return ret;
651}
652
653template <class T>
655{
656 if (&(*position) == m_front)
657 {
658 popFront();
659 return begin();
660 }
661 else if (&(*position) == m_end.previous())
662 {
663 popBack();
664 return end();
665 }
666 else if (m_size > 0)
667 {
668 T* pre = (&(*position))->LinkedList::Node::previous();
669 T* nex = (&(*position))->LinkedList::Node::next();
670 pre->LinkedList::Node::setNext(nex);
671 nex->LinkedList::Node::setPrevious(pre);
672 m_size--;
673 return ++position;
674 }
675 return Iterator();
676}
677
678template <class T>
680{
681 while (first != last)
682 {
683 first = erase(first);
684 }
685 return erase(first);
686}
687
688template <class T>
690{
691 element.LinkedList::Node::setNext(nullptr);
692
693 if (m_size >= 1)
694 {
695 back().LinkedList::Node::setNext(&element);
696 element.LinkedList::Node::setPrevious(m_end.previous());
697 element.LinkedList::Node::setNext(reinterpret_cast<T*>(&m_end));
698 m_end.setPrevious(&element);
699 }
700 else // m_size == 0
701 {
702 pushEmpty(element);
703 }
704 m_size++;
705}
706
707template <class T>
709{
710 element.LinkedList::Node::setPrevious(nullptr);
711 if (m_size >= 1)
712 {
713 element.LinkedList::Node::setNext(m_front);
714 m_front->LinkedList::Node::setPrevious(element);
715 m_front = &element;
716 }
717 else // m_size == 0
718 {
719 pushEmpty(element);
720 }
721 m_size++;
722}
723
724template <class T>
726{
727 if (m_size == 1)
728 {
729 clear();
730 }
731 else if (m_size > 1)
732 {
733 Iterator newPrev = (end()--)--;
734 m_end.setPrevious(&(*newPrev));
735 newPrev->LinkedList::Node::setNext(reinterpret_cast<T*>(&m_end));
736 m_size--;
737 }
738}
739
740template <class T>
742{
743 if (m_size == 1)
744 {
745 clear();
746 }
747 else
748 {
749 m_front = m_front->LinkedList::Node::next();
750 m_size--;
751 }
752}
753
754template <class T>
756{
757 this->m_front = list.m_front;
758 this->m_end = list.m_end;
759 this->m_size = list.m_size;
760 return *this;
761}
762template <class T>
763void semf::LinkedList<T>::pushEmpty(T& element)
764{
765 element.LinkedList::Node::setPrevious(nullptr);
766 element.LinkedList::Node::setNext(reinterpret_cast<T*>(&m_end));
767 m_end.setPrevious(&element);
768 m_front = &element;
769}
770} /* namespace semf */
771#endif /* SEMF_UTILS_CORE_LISTS_LINKEDLIST_H_ */
Implementation of a bidirectional constant iterator for LinkedList.
Definition: linkedlist.h:231
ConstIterator(const Iterator &iterator)
Copy constructor.
Definition: linkedlist.h:252
ConstIterator & operator--()
Iterates to the previous element in the list.
Definition: linkedlist.h:307
const T * operator->() const
Returns the pointer into the element the iterator's position.
Definition: linkedlist.h:274
std::bidirectional_iterator_tag iterator_category
Definition: linkedlist.h:233
const T & operator*() const
Returns the reference of the element the iterator's position.
Definition: linkedlist.h:264
ConstIterator operator--(int)
Iterates to the previous element in the list.
Definition: linkedlist.h:318
bool operator==(const ConstIterator &other) const
Compares this element with that element.
Definition: linkedlist.h:330
ConstIterator(const T *element)
Constructor with member variable initialization.
Definition: linkedlist.h:244
ConstIterator & operator++()
Iterates to the next element in the list.
Definition: linkedlist.h:284
ConstIterator operator++(int)
Iterates to the next element in the list.
Definition: linkedlist.h:295
bool operator!=(const ConstIterator &other) const
Compares this element with that element.
Definition: linkedlist.h:340
virtual ~ConstIterator()=default
Implementation of a bidirectional iterator for LinkedList.
Definition: linkedlist.h:116
Iterator operator++(int)
Iterates to the next element in the list.
Definition: linkedlist.h:172
std::ptrdiff_t difference_type
Definition: linkedlist.h:120
T & operator*() const
Returns the reference of the element the iterator's position.
Definition: linkedlist.h:141
std::bidirectional_iterator_tag iterator_category
Definition: linkedlist.h:118
Iterator(T *element)
Constructor with member variable initialization.
Definition: linkedlist.h:129
bool operator!=(const Iterator &that) const
Compares this element with that element.
Definition: linkedlist.h:217
virtual ~Iterator()=default
Iterator & operator++()
Iterates to the next element in the list.
Definition: linkedlist.h:161
T * operator->() const
Returns the pointer into the element the iterator's position.
Definition: linkedlist.h:151
Iterator operator--(int)
Iterates to the previous element in the list.
Definition: linkedlist.h:195
Iterator & operator--()
Iterates to the previous element in the list.
Definition: linkedlist.h:184
bool operator==(const Iterator &that) const
Compares this element with that element.
Definition: linkedlist.h:207
Implements the previous() and next() functionality for every element in a list.
Definition: linkedlist.h:52
bool isInAList()
Returns if a node is part of a LinkedList.
Definition: linkedlist.h:97
void setPrevious(T *previous)
Sets a pointer to the previous element in a list.
Definition: linkedlist.h:88
virtual ~Node()=default
T * previous() const
Returns a pointer to the previous element in a list.
Definition: linkedlist.h:79
void setNext(T *next)
Sets a pointer to the next element in a list.
Definition: linkedlist.h:70
T * next() const
Returns a pointer to the next element in a list.
Definition: linkedlist.h:61
LinkedList is an managed double linked list implementation.
Definition: linkedlist.h:43
void popFront()
Removes the first element in the list, effectively reducing the list size by one.
Definition: linkedlist.h:741
void clear()
Removes all elements from the list and leaving the list with a size of 0.
Definition: linkedlist.h:620
LinkedList()
Creates an empty List.
Definition: linkedlist.h:542
ConstIterator end() const
Returns an iterator referring to the past-the-end element in the list.
Definition: linkedlist.h:596
size_t size() const
Returns the number of elements in the list.
Definition: linkedlist.h:614
bool empty() const
Returns whether the list is empty (i.e. whether its size is 0).
Definition: linkedlist.h:608
Iterator begin()
Returns an iterator pointing to the first element in the list.
Definition: linkedlist.h:572
T & front()
Returns a reference to the first element in the list.
Definition: linkedlist.h:548
void popBack()
Removes the last element in the list, effectively reducing the list size by one.
Definition: linkedlist.h:725
LinkedList< T > & operator=(const LinkedList< T > &list)
Assigns new contents to the list, replacing its current contents, and modifying its size accordingly.
Definition: linkedlist.h:755
Iterator insert(Iterator position, T &element)
The list is extended by inserting new elements before the element at the specified position.
Definition: linkedlist.h:628
const T & front() const
Returns a reference to the first element in the list.
Definition: linkedlist.h:554
void pushFront(T &element)
Adds a new element to the beginning of the list, before its current first element.
Definition: linkedlist.h:708
ConstIterator cbegin() const
Returns an iterator pointing to the first element in the list.
Definition: linkedlist.h:584
const T & back() const
Returns a reference to the last element in the list.
Definition: linkedlist.h:566
T & back()
Returns a reference to the last element in the list.
Definition: linkedlist.h:560
Iterator erase(Iterator first, Iterator last)
Removes multiple elements from the list.
Definition: linkedlist.h:679
ConstIterator cend() const
Returns an iterator referring to the past-the-end element in the list.
Definition: linkedlist.h:602
void pushBack(T &element)
Adds a new element to the end of the list, after its current last element.
Definition: linkedlist.h:689
Iterator erase(Iterator position)
Removes a single element from the list.
Definition: linkedlist.h:654
Iterator end()
Returns an iterator referring to the past-the-end element in the list.
Definition: linkedlist.h:590
ConstIterator begin() const
Returns an iterator pointing to the first element in the list.
Definition: linkedlist.h:578