Skip to content

Commit ed4fa99

Browse files
committed
[container] Implement LinkedList as std::list
1 parent 56e4b2a commit ed4fa99

File tree

4 files changed

+61
-615
lines changed

4 files changed

+61
-615
lines changed

src/modm/container/doubly_linked_list.hpp

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ namespace modm
3535
public:
3636
using const_iterator = std::list<T>::const_iterator;
3737
using iterator = std::list<T>::iterator;
38+
using Size = std::size_t;
3839

3940
DoublyLinkedList(const Allocator& allocator = Allocator())
4041
: data_{std::move(allocator)}
@@ -63,10 +64,11 @@ namespace modm
6364
}
6465

6566
/// Insert at the end of the list
66-
void
67+
bool
6768
append(const T& value)
6869
{
6970
data_.push_back(value);
71+
return true;
7072
}
7173

7274
/// Remove the first entry
@@ -82,6 +84,12 @@ namespace modm
8284
data_.pop_back();
8385
}
8486

87+
T&
88+
getFront()
89+
{
90+
return data_.front();
91+
}
92+
8593
/**
8694
* \return the first node in the list
8795
*/
@@ -91,6 +99,12 @@ namespace modm
9199
return data_.front();
92100
}
93101

102+
T&
103+
getBack()
104+
{
105+
return data_.back();
106+
}
107+
94108
/**
95109
* \return the last node in the list
96110
*/
@@ -100,7 +114,6 @@ namespace modm
100114
return data_.back();
101115
}
102116

103-
public:
104117
/**
105118
* Returns a read/write iterator that points to the first element in the
106119
* list. Iteration is done in ordinary element order.
@@ -153,8 +166,33 @@ namespace modm
153166
iterator
154167
erase(iterator position)
155168
{
156-
return data_.erase(position);
169+
if (position != data_.end()) {
170+
return data_.erase(position);
171+
} else {
172+
return data_.end();
173+
}
174+
}
175+
176+
/**
177+
* Insert data after position iterator.
178+
*
179+
* This behavior is compatible with modm::LinkedList but different
180+
* compared to std::list which inserts before the position iterator
181+
* argument.
182+
*/
183+
bool
184+
insert(iterator position, const T& value)
185+
{
186+
if (position == data_.end()) {
187+
data_.push_back(value);
188+
} else {
189+
data_.insert(std::next(position), value);
190+
}
191+
return true;
157192
}
193+
194+
private:
195+
std::list<T, Allocator> data_;
158196
};
159197
}
160198

src/modm/container/linked_list.hpp

Lines changed: 20 additions & 200 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Copyright (c) 2012, Niklas Hauser
55
* Copyright (c) 2013-2014, Sascha Schade
66
* Copyright (c) 2015, Kevin Läufer
7+
* Copyright (c) 2023, Christopher Durand
78
*
89
* This file is part of the modm project.
910
*
@@ -16,9 +17,7 @@
1617
#ifndef MODM_LINKED_LIST_HPP
1718
#define MODM_LINKED_LIST_HPP
1819

19-
#include <stdint.h>
20-
#include <iterator>
21-
#include <modm/utils/allocator.hpp>
20+
#include <modm/container/doubly_linked_list.hpp>
2221

2322
namespace modm
2423
{
@@ -34,210 +33,31 @@ namespace modm
3433
*
3534
* \author Fabian Greif
3635
* \ingroup modm_container
36+
*
37+
* \todo TODO: implementated as doubly-linked list
38+
* std::forward_list does not save both front and back pointers.
39+
* This would make operations in xpcc very inefficient.
3740
*/
38-
template <typename T, typename Allocator = allocator::Dynamic<T> >
39-
class LinkedList
41+
template <typename T, typename Allocator = std::allocator<T>>
42+
class LinkedList : public DoublyLinkedList<T, Allocator>
4043
{
4144
public:
42-
typedef std::size_t Size;
43-
44-
public:
45-
LinkedList(const Allocator& allocator = Allocator());
46-
47-
~LinkedList();
48-
49-
/// check if there are any nodes in the list
50-
inline bool
51-
isEmpty() const;
52-
53-
/**
54-
* \brief Get number of elements
55-
*
56-
* \warning This method is slow because it has to iterate through
57-
* all elements.
58-
*/
59-
std::size_t
60-
getSize() const;
61-
62-
/// Insert in front
63-
bool
64-
prepend(const T& value);
65-
66-
/// Insert at the end of the list
67-
bool
68-
append(const T& value);
69-
70-
/// Remove the first entry
71-
void
72-
removeFront();
73-
74-
/**
75-
* \return the first node in the list
76-
*/
77-
inline const T&
78-
getFront() const;
79-
80-
inline T&
81-
getFront();
45+
using DoublyLinkedList<T, Allocator>::DoublyLinkedList;
46+
using iterator = DoublyLinkedList<T, Allocator>::iterator;
8247

83-
/**
84-
* \return the last node in the list
85-
*/
86-
inline const T&
87-
getBack() const;
88-
89-
inline T&
90-
getBack();
91-
92-
/**
93-
* \brief Remove all elements form the list
94-
*/
95-
void
96-
removeAll();
97-
98-
protected:
99-
struct Node
100-
{
101-
T value;
102-
Node *next;
103-
};
104-
105-
// The stored instance is not actually of type Allocator. Instead we
106-
// rebind the type to Allocator<Node<T>>. Node<T> is not the same
107-
// size as T (it's one pointer larger), and specializations on T may go
108-
// unused because Node<T> is being bound instead.
109-
typedef typename Allocator::template rebind< Node >::other NodeAllocator;
110-
111-
NodeAllocator nodeAllocator;
112-
113-
Node *front;
114-
Node *back;
115-
116-
public:
117-
#pragma GCC diagnostic push
118-
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
119-
/**
120-
* \brief Forward iterator
121-
*/
122-
class iterator : public std::iterator<std::forward_iterator_tag, T>
48+
iterator
49+
remove(const iterator& position)
12350
{
124-
friend class LinkedList;
125-
friend class const_iterator;
126-
127-
public:
128-
/// Default constructor
129-
iterator();
130-
iterator(const iterator& other);
51+
return this->erase(position);
52+
}
13153

132-
iterator& operator = (const iterator& other);
133-
iterator& operator ++ ();
134-
bool operator == (const iterator& other) const;
135-
bool operator != (const iterator& other) const;
136-
T& operator * ();
137-
T* operator -> ();
138-
139-
private:
140-
iterator(Node* node);
141-
142-
Node* node;
143-
};
144-
145-
/**
146-
* \brief forward const iterator
147-
*/
148-
class const_iterator : public std::iterator<std::forward_iterator_tag, T>
54+
void
55+
removeAll()
14956
{
150-
friend class LinkedList;
151-
152-
public:
153-
/// Default constructor
154-
const_iterator();
155-
156-
/**
157-
* \brief Copy construtor
158-
*
159-
* Used to convert a normal iterator to a const iterator.
160-
* The other way is not possible.
161-
*/
162-
const_iterator(const iterator& other);
163-
164-
/**
165-
* \brief Copy construtor
166-
*/
167-
const_iterator(const const_iterator& other);
168-
169-
const_iterator& operator = (const const_iterator& other);
170-
const_iterator& operator ++ ();
171-
bool operator == (const const_iterator& other) const;
172-
bool operator != (const const_iterator& other) const;
173-
const T& operator * () const;
174-
const T* operator -> () const;
175-
176-
private:
177-
const_iterator(Node* node);
178-
// TODO: this should acutally be a node that points to a const
179-
// value, but since all access is const, this does not really make
180-
// a difference
181-
Node* node;
182-
};
183-
#pragma GCC diagnostic pop
184-
185-
/**
186-
* Returns a read/write iterator that points to the first element in the
187-
* list. Iteration is done in ordinary element order.
188-
*/
189-
iterator
190-
begin();
191-
192-
/**
193-
* Returns a read-only (constant) iterator that points to the
194-
* first element in the list. Iteration is done in ordinary
195-
* element order.
196-
*/
197-
const_iterator
198-
begin() const;
199-
200-
/**
201-
* Returns a read/write iterator that points one past the last
202-
* element in the list. Iteration is done in ordinary element
203-
* order.
204-
*/
205-
iterator
206-
end();
207-
208-
/**
209-
* Returns a read-only (constant) iterator that points one past
210-
* the last element in the list. Iteration is done in ordinary
211-
* element order.
212-
*/
213-
const_iterator
214-
end() const;
215-
216-
/**
217-
* \brief Erase element
218-
*
219-
* Removes a single element from the list container.
220-
* This effectively reduces the list size by one, calling the element's
221-
* destructor before.
222-
*/
223-
iterator
224-
remove(const iterator& position);
225-
226-
bool
227-
insert(const_iterator pos, const T& value);
228-
229-
private:
230-
friend class const_iterator;
231-
friend class iterator;
232-
233-
LinkedList(const LinkedList& other);
234-
235-
LinkedList&
236-
operator = (const LinkedList& other);
57+
while (!this->isEmpty()) {
58+
this->removeFront();
59+
}
60+
}
23761
};
23862
}
239-
240-
#include "linked_list_impl.hpp"
241-
#include "linked_list_iterator_impl.hpp"
242-
24363
#endif // MODM_LINKED_LIST_HPP

0 commit comments

Comments
 (0)