Project Euler Solutions
Public Attributes | Related Functions | List of all members
c::include::iterator::Iterator Struct Reference

An implementation of Python-like iterators and generators in C. More...

#include <iterator.h>

Inheritance diagram for c::include::iterator::Iterator:
Inheritance graph
[legend]

Public Attributes

bool exhausted: 1
 An indicator that the iterator has stopped. More...
 
bool started: 1
 An indicator that the iterator has started. More...
 
bool phase: 1
 An indicator that changes each time the iterator moves. More...
 

Related Functions

(Note that these are not member functions.)

#define IteratorTail(return_type, struct_type)
 The base definition macro for all iterators in this project. More...
 
#define IterationHead(it)
 The base macro for all iteration functions in this project. More...
 
#define IteratorInitHead(advance, ...)   {.iterator_function = &advance, AddDestructor(no_destructor), __VA_ARGS__}
 The base macro for all iterator initialization functions in this project. More...
 
#define AddDestructor(func)   ExtendInit(destructor, (void (*const)(void *)) &func)
 The extension macro for initializing Iterators with a destructor. More...
 
#define ExtendInit(name, value)   .name = value
 The extension macro for initializing more complicated Iterators. More...
 
#define next(state)   (*(state.iterator_function))(&state)
 The macro to advance generic iterators. More...
 
#define next_p(state)   (*(state->iterator_function))(state)
 The macro to advance generic iterator pointers. More...
 
#define free_iterator(it)   (*(it.destructor))(&it)
 The generic destructor for iterators. More...
 
#define free_iterator_p(it)   (*(it->destructor))(it)
 The generic destructor for iterator pointers. More...
 

Detailed Description

An implementation of Python-like iterators and generators in C.

See also
counter For an example implementation

Friends And Related Function Documentation

#define AddDestructor (   func)    ExtendInit(destructor, (void (*const)(void *)) &func)
related

The extension macro for initializing Iterators with a destructor.

Parameters
funcThe destructor function of your iterator
Attention
When adding a destructor to an Iterator subclass it MUST have the following signature:
void function_name(iterator_subclass *is)
Note, however, that it will be cast to
void (*)(void *)
for compatibility with the default destructor. This means that you may not see a type error if you enter it incorrectly.

Assignment example:

counter counter0() {
return ct; // note all other values are initialized to 0
}

Direct return example:

counter counter0() {
}
#define ExtendInit (   name,
  value 
)    .name = value
related

The extension macro for initializing more complicated Iterators.

Parameters
nameThe name you would like to assign to in the struct (do not include the struct name or initial .)
valueThe value you would like to assign

Assignment example:

counter counter0() {
return ct; // note all other values are initialized to 0
}

Direct return example:

counter counter0() {
}
#define free_iterator (   it)    (*(it.destructor))(&it)
related

The generic destructor for iterators.

Parameters
itThe iterator you wish to destruct
See also
free_iterator_p For a version that deals with pointers
counter for an example implementation
Note
Any given subclass might not include a destructor if nothing needs cleaning. That does not mean you should not call this function, as that may change in the future, and on most compilers it typically adds very little overhead (order of 3 instructions).
#define free_iterator_p (   it)    (*(it->destructor))(it)
related

The generic destructor for iterator pointers.

Parameters
itA pointer to the iterator you wish to destruct
See also
free_iterator For a version that deals with direct objects
counter for an example implementation
Note
Any given subclass might not include a destructor if nothing needs cleaning. That does not mean you should not call this function, as that may change in the future, and on most compilers it typically adds very little overhead (order of 3 instructions).
#define IterationHead (   it)
related
Value:
it->started = 1; \
it->phase = !(it->phase)

The base macro for all iteration functions in this project.

Parameters
itThe pointer to the iterator you are advancing
See also
counter for an example implementation

Example:

static uintmax_t iterate_counter(counter *ct) {
if (!ct->exhausted) {
const uintmax_t ret = ct->idx;
ct->idx += ct->step;
ct->exhausted = (ct->idx >= ct->stop);
return ret;
}
return -1; // error
}
#define IteratorInitHead (   advance,
  ... 
)    {.iterator_function = &advance, AddDestructor(no_destructor), __VA_ARGS__}
related

The base macro for all iterator initialization functions in this project.

Parameters
advanceThe function this iterator uses to advance
...Additional things to initialize wrapped in ExtendInit()
Returns
A compound literal that initializes the Iterator-defined portions of your subclass
See also
counter for an example implementation
Note
All values not directly related to the Iterator class will be initialized according to the C99 rules for compound literals. This means:
  • Numeric types are initialized to 0
  • Pointer types are initialized to NULL
  • Composite types are initialized recursively by these rules
Attention
The iterator function you give it MUST take in ONLY a pointer to the declared struct
Because the pointer to the iteration function is constant, any nested Iterators must be initialized in the original assigning expression, and Iterators cannot be reassigned to entierely. It is often recommended to provide a "reset" function as an alternative to the standard constructor if you want these objects to be reused.

Example:

counter counter0() {
ct.step = 1;
ct.stop = 100;
return ct; // note all other values are initialized to 0
}
#define IteratorTail (   return_type,
  struct_type 
)
related
Value:
return_type (*const iterator_function)(struct_type *it); \
void (*const destructor)(void *it); \
bool exhausted : 1;\
bool started : 1;\
bool phase : 1;

The base definition macro for all iterators in this project.

Parameters
return_typeThe type that your iterator will yield
struct_typeThe type that your iterator state is stored in
See also
counter for an example implementation
Remarks
It is recommended that you put this at the end of your struct for better packing, but if you are going to use bitfield elements, it should go before that.
Attention
When you are declaring an Iterator struct, you MUST DECLARE IT FIRST in order to feed it to this macro

Example:

typedef struct counter counter;
struct counter {
uintmax_t idx;
uintmax_t stop;
intmax_t step;
IteratorTail(uintmax_t, counter)
bool example_bit : 1;
};
#define next (   state)    (*(state.iterator_function))(&state)
related

The macro to advance generic iterators.

Parameters
stateThe iterator you wish to advance
Returns
The next item generated by the given iterator
See also
next_p For a version that deals with pointers
counter for an example implementation
#define next_p (   state)    (*(state->iterator_function))(state)
related

The macro to advance generic iterator pointers.

Parameters
stateThe pointer to the iterator you wish to advance
Returns
The next item generated by the given iterator
See also
next For a version that deals with direct objects
counter for an example implementation

Member Data Documentation

bool c::include::iterator::Iterator::exhausted

An indicator that the iterator has stopped.

bool c::include::iterator::Iterator::phase

An indicator that changes each time the iterator moves.

bool c::include::iterator::Iterator::started

An indicator that the iterator has started.


The documentation for this struct was generated from the following file: