Control structures in programming languages: from goto to algebraic effects

Xavier Leroy

Generators in C++ (chapter 4)

/* Section 4.2: Compiling generators */

#include <iostream>
using namespace std;

/* Compiled generator, using GNU extensions (first-class labels) */

class Generator1 {
  int n;
  void * pc = NULL;
public:
  int next(void) {
    if (pc) goto *pc;
    n = 0;
    while (1) {
      pc = &&next1; return n; next1:
      pc = &&next2; return (-n); next2:
      n += 1;
    }
  }
};

/* Compiled generator, using Duff's device */

class Generator2 {
  int n;
  enum { START, NEXT1, NEXT2 } pc = START;
public:
  int next(void) {
    switch (pc) {
    case START:
      n = 0;
      while (1) {
        pc = NEXT1; return n; case NEXT1:
        pc = NEXT2; return (-n); case NEXT2:
        n += 1;
      }
    }
  }
};

int main() {
  Generator1 g1 = Generator1();
  for (int i = 0; i < 20; i++) {
    cout << g1.next(); cout << ' ';
  }
  cout << '\n';
  Generator2 g2 = Generator2();
  for (int i = 0; i < 20; i++) {
    cout << g2.next(); cout << ' ';
  }
  cout << '\n';
  return 0;
}