Skip to content

Commit

Permalink
An iterator for AList
Browse files Browse the repository at this point in the history
  • Loading branch information
valdisz committed Aug 20, 2024
1 parent 675583e commit ee04e99
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 6 deletions.
23 changes: 23 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Editor configuration, see http://editorconfig.org
root = true

[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
max_line_length = off
trim_trailing_whitespace = false

[package.json]
indent_size = 2

[*.yaml]
indent_size = 2

[*.yml]
indent_size = 2
10 changes: 10 additions & 0 deletions alist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,13 @@ int AList::NextLive(AListElem **copy, int size, int pos)
}
return pos;
}

AList::iterator AList::begin() const
{
return AList::iterator(this->list);
}

AList::iterator AList::end() const
{
return AList::iterator();
}
96 changes: 90 additions & 6 deletions alist.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class AListElem;
class AList;

/// This represents an element of a list.
/**
/**
AListElem is a virtual class, which will be set to whatever the right type is.
It has a 'next' variable, and all the rest of the usual list stuff.
*/
Expand All @@ -40,9 +40,77 @@ class AListElem {
AListElem * next; ///< The next element in the list
};

/**
* A forward iterator for AList. To replace the old forlist macro while
* AList is still in use.
*
* @tparam T The type of the element to iterate over.
*/
template <class T = AListElem>
class AListIterator {
public:
using node = T *;

AListIterator() : current(nullptr) {}
AListIterator(T *current) : current(current) {}

node& operator*() {
return this->current;
}

AListIterator& operator++() {
this->current = static_cast<T*>(current->next);
return *this;
}

AListIterator operator++(int) {
AListIterator tmp = *this;
++(*this);
return tmp;
}

bool operator==(const AListIterator<T>& rhs) {
return this->current == rhs.current;
}

bool operator!=(const AListIterator<T>& rhs) {
return this->current != rhs.current;
}

private:
T* current;
};

/**
* A proxy class to allow typed iteration over an AList.
*
* @tparam T The type of the element to iterate over.
*/
template <class T = AListElem>
class ATypedListProxy {
public:
ATypedListProxy(T *head) : head(head) {}

using iterator = AListIterator<T>;

iterator begin() const {
return iterator(head);
}

iterator end() const {
return iterator();
}

private:
T *head;
};

/// A standard list
class AList {
public:
/// An iterator for the list.
using iterator = AListIterator<AListElem>;

AList();
~AList();

Expand All @@ -56,16 +124,32 @@ class AList {
AListElem * First();
int Num();

/* Helper function for forlist_safe */
/// Helper function for forlist_safe
int NextLive(AListElem **copy, int size, int pos);

private:
/// Get an iterator to the beginning of the list.
iterator begin() const;

/// Get an iterator to the end of the list.
iterator end() const;

/**
* Get a typed proxy for this list. This allows typed iteration over the list.
*
* @tparam T The type of the element to iterate over. Defaults to AListElem.
* @return ATypedListProxy<T> A proxy object for iterating over the list.
*/
template <typename T = AListElem> ATypedListProxy<T> iter() {
return ATypedListProxy<T>(static_cast<T*>(this->list));
}

private:
AListElem *list; ///< The first element of the list
AListElem *lastelem; ///< The last element of the list
int num;
};

/// Iterate over a list
/// (OBSOLETE) Iterate over a list. Use the iterator instead.
#define forlist(l) \
AListElem * elem, * _elem2; \
for (elem=(l)->First(), \
Expand All @@ -74,15 +158,15 @@ class AList {
elem = _elem2, \
_elem2 = (_elem2 ? ((l)->Next(_elem2)) : 0))

/// Iterate over a list, if we've already done so.
/// (OBSOLETE) Iterate over a list, if we've already done so. Use the iterator instead.
#define forlist_reuse(l) \
for (elem=(l)->First(), \
_elem2 = (elem ? (l)->Next(elem) : 0); \
elem; \
elem = _elem2, \
_elem2 = (_elem2 ? ((l)->Next(_elem2)) : 0))

/// Iterate over a list (without messing it up?)
/// (OBSOLETE) Iterate over a list (without messing it up?). Use the iterator instead.
#define forlist_safe(l) \
int size = (l)->Num(); \
AListElem **copy = new AListElem*[size]; \
Expand Down

0 comments on commit ee04e99

Please sign in to comment.