14.04.2015, 19:45
(
Last edited by Ada32; 14/04/2015 at 08:29 PM.
)
Contents
First Post
Information on the internal implementation of various parts of "y_iterate".
Introduction - A brief word on what this tutorial is about and a recap.
Multi-Dimensional Iterators - A review of multi-dimensional iterators required for later.
Macros - How the "Iterator:" macro works.
Linked Lists - An explanation of the data type used by iterators.
Start Point - How "foreach" loops over arbitrary arrays.
Improvements - Why "foreach" is better than "for" in most cases.
Generic Loop Functions - Using iterators without "foreach".
Reverse Iteration - Going backwards through iterators.
Second Post
Function list.
Functions - A list of all the functions provided by "y_iterate".
Third Post
An introduction to "special iterators" - those that are defined by functions and
not by using "Iterator:".
Special Iterators - An introduction to writing special iterator functions.
Example 1 - Writing an iterator for every positive even integer.
Explanation - A more detailed look at the code for Example 1.
Example 2 - Writing an iterator for every positive even integer.
Example 3 - Writing an iterator for RCON admins, which can be done multiple ways.
Fourth Post
More advanced special iterators.
Iterators In Iterators - Using iterators to create new iterators.
Multi-Dimensional Special Iterators - Special iterators that look like multi-dimensional iterators.
More Parameters - Passing more than one parameter to a special iterator.
Function-Like Iterators - Special iterators that look like regular functions.
Fifth Post
A detailed look at the macros that make up "y_iterate" and make all these
different iterator types work together.
"foreach" Types - A review of all the "foreach" syntax forms.
Redefining "new" - "y_iterate"'s dirty little secret.
Y_FOREACH_SECOND - Detecting one syntax form.
Y_FOREACH_THIRD - Detecting a second syntax form.
Why Redefine "new"? - Why the "#define new" hack is required.
The Remainder - All the other syntax form detections.
Functions
Beside the well known functions and those listed above, there are many more
available in "y_iterate". These are all documented in the main "foreach"
release topic, but are duplicated here for additional information.
First Post
Information on the internal implementation of various parts of "y_iterate".
Introduction - A brief word on what this tutorial is about and a recap.
Multi-Dimensional Iterators - A review of multi-dimensional iterators required for later.
Macros - How the "Iterator:" macro works.
Linked Lists - An explanation of the data type used by iterators.
Start Point - How "foreach" loops over arbitrary arrays.
Improvements - Why "foreach" is better than "for" in most cases.
Generic Loop Functions - Using iterators without "foreach".
Reverse Iteration - Going backwards through iterators.
Second Post
Function list.
Functions - A list of all the functions provided by "y_iterate".
Third Post
An introduction to "special iterators" - those that are defined by functions and
not by using "Iterator:".
Special Iterators - An introduction to writing special iterator functions.
Example 1 - Writing an iterator for every positive even integer.
Explanation - A more detailed look at the code for Example 1.
Example 2 - Writing an iterator for every positive even integer.
Example 3 - Writing an iterator for RCON admins, which can be done multiple ways.
Fourth Post
More advanced special iterators.
Iterators In Iterators - Using iterators to create new iterators.
Multi-Dimensional Special Iterators - Special iterators that look like multi-dimensional iterators.
More Parameters - Passing more than one parameter to a special iterator.
Function-Like Iterators - Special iterators that look like regular functions.
Fifth Post
A detailed look at the macros that make up "y_iterate" and make all these
different iterator types work together.
"foreach" Types - A review of all the "foreach" syntax forms.
Redefining "new" - "y_iterate"'s dirty little secret.
Y_FOREACH_SECOND - Detecting one syntax form.
Y_FOREACH_THIRD - Detecting a second syntax form.
Why Redefine "new"? - Why the "#define new" hack is required.
The Remainder - All the other syntax form detections.
Functions
Beside the well known functions and those listed above, there are many more
available in "y_iterate". These are all documented in the main "foreach"
release topic, but are duplicated here for additional information.
- Iter_Add(Iterator, value); - Add an in-range value from an iterator:
pawn Code:// Assume "4, 9, 11" already added:
foreach (new i : MyIter)
{
printf("%d", i);
}
printf("Adding 16...");
Iter_Add(MyIter, 16);
foreach (new i : MyIter)
{
printf("%d", i);
}
pawn Code:4
9
11
Adding 16...
4
9
11
16 - Iter_Remove(Iterator, value); - Remove an in-range value from an
iterator:
pawn Code:// Assume "4, 9, 11" already added:
foreach (new i : MyIter)
{
printf("%d", i);
}
printf("Removing 9...");
Iter_Remove(MyIter, 9);
foreach (new i : MyIter)
{
printf("%d", i);
}
pawn Code:4
9
11
Removing 9...
4
11 - Iter_Contains(Iterator, value); - Check if the given value is in the
given iterator:
pawn Code:// Assume "4, 9, 11" already added:
printf("%d", Iter_Contains(MyIter, 6));
Iter_Add(MyIter, 6);
printf("%d", Iter_Contains(MyIter, 6));
pawn Code:0
1 - Iter_Free(Iterator); - Get the first INVALID value in the iterator.
Useful for finding empty slots. Returns "-1" on failure (i.e. when there are
no free slots).
pawn Code:// Assume "0, 1, 3" already added:
printf("%d", Iter_Free(MyIter));
Iter_Add(MyIter, 2);
printf("%d", Iter_Free(MyIter));
pawn Code:2
4 - Iter_Count(Iterator); - Get the number of UNIQUE elements already
added to the iterator:
pawn Code:new
Iterator:MyIter<12>;
Iter_Add(MyIter, 4);
Iter_Add(MyIter, 5);
Iter_Add(MyIter, 9);
Iter_Add(MyIter, 9);
printf("%d", Iter_Count(MyIter));
pawn Code:3 - Iter_Clear(Iterator); - Reset the iterator entirely:
pawn Code:// Assume "7, 10, 15" already added:
foreach (new i : MyIter)
{
printf("%d", i);
}
printf("Resetting...");
Iter_Clear(MyIter);
foreach (new i : MyIter)
{
printf("%d", i);
}
pawn Code:7
10
15
Resetting... - Iter_Random(Iterator); - Select a random added element from the
iterator. This is vastly more efficient than most other implementations:
pawn Code:// Assume "0, 1, 3, 4, 6, 7, 8" already added:
printf("Random: %d", Iter_Random(MyIter));
pawn Code:4
pawn Code:8 - Iter_Init(MDIterator); - Normal iterators set themselves up with the
"{2 * s, 2 * s - 1, ...}" code shown above. However, you can't use that syntax
with multi-dimensional iterators, so they need explicitly initiating:
pawn Code:new
Iterator:MyIters[4]<11>;
Iter_Init(MyIters);
inside a loop that uses that iterator or it may crash:
pawn Code:foreach (new i : MyIter)
{
if (i == 5)
{
Iter_Remove(MyIter, i);
}
}
the next slot, but we just removed the current slot so it is no longer valid for
getting the next slot. Instead, we use "Iter_SafeRemove", which takes an
additional parameter to store the next slot in BEFORE the current slot is
removed:
pawn Code:foreach (new i : MyIter)
{
new
cur = i;
if (cur == 5)
{
Iter_SafeRemove(MyIter, cur, i);
}
}
pawn Code:new i = Iter_First(MyIter);
while (i != Iter_End(MyIter))
{
new
cur = i,
nxt = Iter_Next(MyIter, cur);
if (cur == 5)
{
Iter_Remove(MyIter, cur);
}
i = nxt;
} - Iter_Begin(Iterator); - A technically invalid slot that comes before
the first valid slot of an iterator. Doing "Iter_Next" on this value will give
the first valid slot (if there is one at all).
- Iter_End(Iterator); - A value that comes after the last valid slot, to
check for having reached the end of an array.
- Iter_Next(Iterator, cur); - Get the iterator value after the current
one. Will return "Iter_End" when called on the very last valid value.
- Iter_Prev(Iterator, cur); - Get the iterator value before the current
one. Will return "Iter_Begin" when called on the very first valid value.
- Iter_First(Iterator); - Returns the first VALID value of the iterator,
unlike "Iter_Begin" which returns a value BEFORE the first valid value.
- Iter_Last(Iterator); - Returns the last valid value of the iterator,
unlike "Iter_End" which returns a value AFTER the last valid value.
- Iter_Size(Iterator); - Returns the declared size of the iterator:
pawn Code:new
Iterator:MyIter<101>;
printf("%d", Iter_Size(MyIter));
pawn Code:101 - Iter_InternalSize(Iterator); - Returns the internal size of the
iterator. This includes the additional slot at the end of the array added on by
the "Iterator:" macro:
pawn Code:new
Iterator:MyIter<101>;
printf("%d", Iter_Size(MyIter));
pawn Code:102