Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

iter.h File Reference

@@ NEED TO RATIONALIZE WITH LoopState.h. More...

This graph shows which files directly or indirectly include this file:

Included by dependency graph

Go to the source code of this file.




Detailed Description


Why an abstraction?

Because I don't know if I'm going to switch to dynamic arrays or something tomorrow, and I don't want all the code using my code to have to be changed.

Why this abstraction?

It's lightweight, doesn't need macros, and is typesafe in user land.

It's missing ways of going backwards or peeking ahead, but you can do those in userland (see \Ref{Buffering}). I don't believe it's possible to layer them between the user and the provider in C in a typesafe way.

[ You can provide peek(..., iter, offset) if you want... ]

Simple example usage:

(these are in iter_demo.c).

   void simple_example()
       iter i={0,0};
       char *s;

       while (( s=get_next_string_in_sequence(&i) )) {
           printf("s is 's'
", s); } }

More complex usage, with iteration being abandoned in the middle:

   void medium_example()
       iter i={0,0};
       char *s;

       while (( s=get_next_string_in_sequence(&i) )) {
           if (!strcmp(s, "special terminate value")) {
               iter_reset(&i);  / * free any resources * /
           printf("s is 's'
", s); } }


What do you do if you want to peer ahead in the sequence? You have to keep that state yourself.

There are two examples in iter_demo.c.

There's probably a way to factor this better, but I'm not sure how.


If your internal structure is an array or a linked list, where the iterator can just be a pointer, then just user iter.state as that pointer. Something like this:

   void get_next_string_in_sequence(iter *i)
      static char **strings = { "john", "jacob", "jingleheimer", 0 };
      char *result;

      result = strings[i->state++];
      if (!result) i->state = 0;
      return result;

If your internal structure is something where you need more than a single pointer to traverse it, such as a tree structure with only downward links, then you'll need to allocate that traversal-management structure when called with i->state == 0, and set i->reset to a function which frees the structure and sets the state to 0. Before you return 0 on the last call, you should call that reset function yourself.

\URL[Sandro Hawke]{} (
iter.h,v 1.4 2001/07/11 13:37:00 sandro Exp
@name Using Iterators To GIVE Many Results (Writing Collections) @memo

Definition in file iter.h.

Define Documentation

#define iter_reset  


if ((i)->state) {               \
    if ((i)->reset) (*((i)->reset))(i); \
    } else {                    \
    (i)->state = 0;             \
Implement iter_reset as a macro.

(Otherwise some implementations will hold onto resources.)

Definition at line 147 of file iter.h.

Typedef Documentation

typedef struct iter_s iter

Declare as "iter" each iterator you want to use, in the caller's memory.

Be sure to initialize it to {0,0} like:

   iter x = {0,0};

Definition at line 132 of file iter.h.

Home to blindfold. This page generated via doxygen Wed Oct 10 16:40:35 2001.