Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An iterator for AList #205

Merged
merged 1 commit into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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