Skip to content

Commit 7847ae5

Browse files
committed
Fix mutability
1 parent 070efa4 commit 7847ae5

File tree

10 files changed

+54
-314
lines changed

10 files changed

+54
-314
lines changed

src/AbstractList.hpp

Lines changed: 45 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,38 @@ class AbstractList {
5050
*/
5151
class AbstractEntry {
5252
private:
53-
T value;/// The raw value.
53+
T immutableValue; /// The raw value, assigned for immutable lists.
54+
T *mutableValue = nullptr;/// A pointer to the raw value, assigned for mutable lists.
5455

5556
public:
5657
/*!
57-
* @brief Get a reference to the value.
58+
* @brief Get a pointer to the value (mutable or immutable).
59+
*
60+
* @param m Indicates, if the list is mutable or immutable.
5861
*
5962
* @return Pointer to the value of the entry.
6063
*/
61-
T *getValue() { return &value; };
64+
T *getValue(bool m) {
65+
if (m) {
66+
return mutableValue;
67+
} else {
68+
return &immutableValue;
69+
}
70+
}
6271

6372
/*!
64-
* @brief Set the value for the entry.
73+
* @brief Set the value.
6574
*
6675
* @param val Reference to the value.
76+
* @param m Indicates, if the list is mutable or immutable.
6777
*/
68-
void setValue(T &val) { value = val; }
78+
void setValue(T &val, bool m) {
79+
if (m) {
80+
mutableValue = &val;
81+
} else {
82+
immutableValue = val;
83+
}
84+
}
6985
};
7086

7187
/*!
@@ -120,13 +136,15 @@ class AbstractList {
120136
/*!
121137
* @copydoc AbstractList::addLast()
122138
* @note Alias of addLast().
139+
* @note If this list is mutable, ensure, that all variables added to the lists do not go out-of-scope during all operations of the list.
123140
* @see addLast()
124141
*/
125142
void add(T &value) { addLast(value); }
126143

127144
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
128145
/*!
129146
* @copydoc AbstractList::add()
147+
* @note If the list is mutable and the values saved in the list are not primitives, nothing happen.
130148
*/
131149
void add(T &&value) { addLast(value); }
132150
#endif
@@ -137,6 +155,7 @@ class AbstractList {
137155
* entry.
138156
* @note Allowed indices are 0 to getSize(). If the index is out of bounds,
139157
* nothing will happen.
158+
* @note If this list is mutable, ensure, that all variables added to the lists do not go out-of-scope during all operations of the list.
140159
*
141160
* @param index Index of the entry, where the value should be added.
142161
* @param value Value of the new entry.
@@ -146,15 +165,22 @@ class AbstractList {
146165
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
147166
/*!
148167
* @copydoc AbstractList::addAtIndex()
168+
* @note If the list is mutable nothing happen.
149169
*/
150-
virtual void addAtIndex(int index, T &&value) { addAtIndex(index, value); }
170+
virtual void addAtIndex(int index, T &&value) {
171+
if (this->isMutable()) {
172+
return;// Mutable lists cannot save rvalues!
173+
}
174+
addAtIndex(index, value);
175+
}
151176
#endif
152177

153178
/*!
154179
* @brief Add all entries from the given list to this list at a specified
155180
* index. The original entry at this index, and followings, will be placed
156181
* directly after the entries of the given list.
157182
* @note The elements from the other list, remain untouched.
183+
* @note If the other list is mutable and the values saved in the lists are primitives, nothing happens.
158184
*
159185
* @param index Index of this list, at which all entries should be added.
160186
* @param list Other list from where to copy the entries.
@@ -168,6 +194,7 @@ class AbstractList {
168194
/*!
169195
* @brief Add all entries from the given list at the end of the list.
170196
* @note The elements from the other list, remain untouched.
197+
* @note If the other list is mutable and the values saved in the lists are primitives, nothing happens.
171198
*
172199
* @param list Other list to copy from.
173200
*/
@@ -178,6 +205,7 @@ class AbstractList {
178205
* The original entry at this index, and followings, will be placed
179206
* directly after the entries of the given list.
180207
* @note The elements from the other list, remain untouched.
208+
* @note If this list is mutable, ensure, that the other lists do not go out-of-scope during all operations of this list. If the other list is mutable, all values added to this lists are immutable.
181209
*
182210
* @param index Index of this list, at which all entries should be added.
183211
* @param arr Array.
@@ -204,28 +232,32 @@ class AbstractList {
204232

205233
/*!
206234
* @brief Add a new entry at the beginning of the list.
207-
*
235+
* @note If this list is mutable, ensure, that all variables added to the lists do not go out-of-scope during all operations of the list.
236+
*
208237
* @param value Value to add.
209238
*/
210239
void addFirst(T &value) { addAtIndex(0, value); }
211240

212241
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
213242
/*!
214243
* @copydoc AbstractList::addFirst()
244+
* @note If the list is mutable and the values saved in the list are not primitives, nothing happen.
215245
*/
216246
void addFirst(T &&value) { addAtIndex(0, value); }
217247
#endif
218248

219249
/*!
220250
* @brief Add a new entry at the end of the list.
221-
*
251+
* @note If this list is mutable, ensure, that all variables added to the lists do not go out-of-scope during all operations of the list.
252+
*
222253
* @param value Value to add.
223254
*/
224255
void addLast(T &value) { addAtIndex(getSize(), value); }
225256

226257
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
227258
/*!
228259
* @copydoc AbstractList::addLast()
260+
* @note If the list is mutable and the values saved in the list are not primitives, nothing happen.
229261
*/
230262
void addLast(T &&value) { addAtIndex(getSize(), value); }
231263
#endif
@@ -318,73 +350,6 @@ class AbstractList {
318350
*/
319351
bool isEmpty() { return getSize() == 0; }
320352

321-
//
322-
// @brief Get an array which represent the list.
323-
//
324-
// @note If this list is empty, a nullptr will be returned.
325-
// @note The memory for the array is dynamically allocated. the returned
326-
// pointer has to be free'd with free() in order to prevent memory leaks. For
327-
// further processing of the array, e.g. inserting new elements, the other
328-
// method toArray(T* arr) is preferred!
329-
// @note The array contains always immutable representations of the elements,
330-
// saved in the list.
331-
//
332-
// @return Array representation of the list or nullptr if the list is
333-
// empty.
334-
//
335-
// T *toArray() {
336-
// if (getSize() == 0) {
337-
// return nullptr;
338-
// }
339-
//
340-
// T *arr = static_cast<T *>(malloc(getSize() * sizeof(T)));
341-
// this->toArray(arr);
342-
//
343-
// return arr;
344-
// }
345-
//
346-
//
347-
// @brief Fill the passed array with immutable objects.
348-
//
349-
// @note The array contains always immutable representations of the elements,
350-
// saved in the list.
351-
// @note Be sure, that the array has enough free space for all elements of the
352-
// list.
353-
//
354-
// @param arr Array to fill.
355-
//
356-
// void toArray(T *arr) {
357-
// for (int i = 0; i < getSize(); i++) {
358-
// arr[i] = get(i);
359-
// }
360-
// }
361-
//
362-
//
363-
// @brief Create the list from given array.
364-
// @note Removes all entries in current list.
365-
//
366-
// @param arr Array
367-
// @param arrSize Size of Array
368-
//
369-
// void fromArray(T *arr, size_t arrSize) {
370-
// this->clear();
371-
// addAll(arr, arrSize);
372-
// }
373-
374-
//
375-
// @brief Sort the entries in the list with Quicksort.
376-
//
377-
// @param compFunc Comparator Method
378-
//
379-
// void sort(int (*compFunc)(const void *, const void *)) {
380-
// T *arr = this->toArray();
381-
//
382-
// qsort(arr, getSize(), sizeof(*arr), compFunc);
383-
//
384-
// this->fromArray(arr, getSize());
385-
// free(arr);
386-
// }
387-
388353
/*!
389354
* @brief Compare two lists whether their attributes and entries are equal.
390355
* @note If you use this list for non-primitive data types, check if the
@@ -439,6 +404,7 @@ class AbstractList {
439404

440405
/*!
441406
* @copydoc AbstractList::add()
407+
* @note If this list is mutable, ensure, that all variables added to the lists do not go out-of-scope during all operations of the list.
442408
* @see add()
443409
*/
444410
void operator+(T &value) { this->add(value); }
@@ -447,13 +413,15 @@ class AbstractList {
447413
/*!
448414
* @copydoc AbstractList::add()
449415
* @see add()
450-
*/
416+
* @note If the list is mutable and the values saved in the list are not primitives, nothing happen.
417+
*/
451418
void operator+(T &&value) { this->add(value); }
452419
#endif
453420

454421
/*!
455422
* @copydoc AbstractList::addAll(AbstractList<T>&)
456-
* @see addAll(AbstractList<T>&)
423+
* @note If the other list is mutable and the values saved in the lists are primitives, nothing happens.
424+
* @see addAll(AbstractList<T>&)
457425
*/
458426
void operator+(AbstractList<T> &list) { this->addAll(list); }
459427
};

src/DoubleLinkedList.hpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class DoubleLinkedList : public AbstractList<T> {
108108
}
109109
}
110110

111-
return current->getValue();
111+
return current->getValue(this->isMutable());
112112
}
113113

114114
public:
@@ -140,16 +140,8 @@ class DoubleLinkedList : public AbstractList<T> {
140140
return;
141141
}
142142

143-
Entry *entry;
144-
145-
if (this->isMutable()) {
146-
// TODO: change for mutable
147-
entry = new Entry();
148-
entry->setValue(value);
149-
} else {
150-
entry = new Entry();
151-
entry->setValue(value);
152-
}
143+
Entry *entry = new Entry();
144+
entry->setValue(value, this->isMutable());
153145

154146
if (index == 0) {
155147
if (this->getSize() == 0) {
@@ -234,7 +226,7 @@ class DoubleLinkedList : public AbstractList<T> {
234226
int i = this->getSize() - 1;
235227
while (i > index - 1) {
236228
current = current->getPrev();
237-
i--;
229+
--i;
238230
}
239231
}
240232
} else {

src/List.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ class List : public SingleLinkedList<T> {
5858
*
5959
* @param mutableList true if the list should be mutable; false otherwise
6060
* (default).
61+
* @note Mutable lists only work as expected, if the values, that are added, are
62+
* only lvalues and you can ensure, that the variables do not go out-of-scope during all operations of the list.
6163
*/
6264
explicit List<T>(bool mutableList = false)
6365
: SingleLinkedList<T>(mutableList) {}

src/SingleLinkedList.hpp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class SingleLinkedList : public AbstractList<T> {
8282
current = current->getNext();
8383
i++;
8484
}
85-
return current->getValue();
85+
return current->getValue(this->isMutable());
8686
}
8787

8888
public:
@@ -116,14 +116,8 @@ class SingleLinkedList : public AbstractList<T> {
116116

117117
Entry *entry;
118118

119-
if (this->isMutable()) {
120-
// TODO: change for mutable
121-
entry = new Entry();
122-
entry->setValue(value);
123-
} else {
124-
entry = new Entry();
125-
entry->setValue(value);
126-
}
119+
entry = new Entry();
120+
entry->setValue(value, this->isMutable());
127121

128122
if (index == 0) {
129123
if (this->getSize() == 0) {

test/test_immutable_doublelinkedlist_array/test_immutable_doublelinkedlist_array.cpp

Lines changed: 0 additions & 72 deletions
This file was deleted.

test/test_immutable_doublelinkedlist_sort/test_immutable_doublelinkedlist_sort.cpp

Whitespace-only changes.

0 commit comments

Comments
 (0)