<commit_before>// Title       : Implementation of Coroutine in Cpp, Version 2.0
// Author      : <EMAIL>
// Date        : 11-22-2020
// License     : MIT License

#include <cstdlib>
#include <ctime>
#include <iostream>
#include <functional>
#include <memory>
#include <string>
#include <tuple>
#include <typeinfo>
#include <utility>
#include <vector>

using namespace std;

template<typename T>
class Generator : public std::enable_shared_from_this<Generator<T>> {
public:
    int state;
    Generator() : state(0) {}
    virtual bool next(T& output) = 0;
    bool operator()(T& output) {
        return next(output);
    }
    shared_ptr<Generator<T>> getPtr() { return this->shared_from_this(); }
};

template<typename T>
class IteratorHelper : public std::enable_shared_from_this<IteratorHelper<T>> {
public:
    shared_ptr<Generator<T>> gen;
    T output;
    bool pending;
    IteratorHelper(Generator<T> &_gen) : gen(_gen.getPtr()),  pending(false) {}
    IteratorHelper(shared_ptr<Generator<T>> _gen) : gen(_gen),  pending(false) {}
    T next() {
        if(!pending) hasNext();
        if(pending) {
            pending = false;
        } else {
            // Error, Iterator is done.
        }
        return output;
    }
    bool hasNext() {
        if(pending) return pending;
        return pending = gen->next(output);
    }
    shared_ptr<IteratorHelper<T>> getPtr() { return this->shared_from_this(); }
};

template<typename S, typename T>
class Coroutine : public std::enable_shared_from_this<Coroutine<S,T>> {
public:
    int state;
    Coroutine() : state(0) {}
    virtual ~Coroutine() {}
    virtual bool next(S& input, T &output) = 0;
    bool operator()(S& input, T &output) {
        return next(input, output);
    }
    shared_ptr<Coroutine<S,T>> getPtr() { return this->shared_from_this(); }
};


#define PRG_BEG \
switch(state) { \
case 0:;

#define PRG_END \
case -1:; \
default: { return false; } }

#define YIELD() \
do { state = __LINE__; return true; case __LINE__:; } while(0)

#define RETURN() \
do { state = -1; return false; } while(0)

/* Examples */

class FibGen : public Generator<int> {
public:
    int a, b;
    FibGen() : a(1), b(1) {}
    bool next(int &output) {
        PRG_BEG
        while(true) {
            output = a;
            a = b;
            b = output + a;
            YIELD();
        }
        PRG_END
    }
};<commit_msg>Update macro_v2.cpp<commit_after>// Title       : Implementation of Coroutine in Cpp, Version 2.0
// Author      : <EMAIL>
// Date        : 11-22-2020
// License     : MIT License

#include <cstdlib>
#include <ctime>
#include <iostream>
#include <functional>
#include <memory>
#include <string>
#include <tuple>
#include <typeinfo>
#include <utility>
#include <vector>

#define PRG_BEG \
switch(state) { \
case 0:;

#define PRG_END \
case -1:; \
default: { return false; } }

#define YIELD() \
do { state = __LINE__; return true; case __LINE__:; } while(0)

#define YIELD_ALL(iter,output) \
do { while((iter)->next((output))) { YIELD(); } } while(0)

#define RETURN() \
do { state = -1; return false; } while(0)

using namespace std;

template<typename T>
class Generator : public std::enable_shared_from_this<Generator<T>> {
public:
    int state;
    Generator() : state(0) {}
    virtual bool next(T& output) = 0;
    bool operator()(T& output) {
        return next(output);
    }
    shared_ptr<Generator<T>> getPtr() { return this->shared_from_this(); }
};

template<typename T>
class GenIter : public std::enable_shared_from_this<GenIter<T>> {
public:
    shared_ptr<Generator<T>> gen;
    T output;
    bool pending;
    GenIter(Generator<T> &_gen) : gen(_gen.getPtr()),  pending(false) {}
    GenIter(shared_ptr<Generator<T>> _gen) : gen(_gen),  pending(false) {}
    T next() {
        if(!pending) hasNext();
        if(pending) {
            pending = false;
        } else {
            // Error, Iterator is done.
        }
        return output;
    }
    bool hasNext() {
        if(pending) return pending;
        return pending = gen->next(output);
    }
    shared_ptr<GenIter<T>> getPtr() { return this->shared_from_this(); }
};

template<typename S, typename T>
class Coroutine : public std::enable_shared_from_this<Coroutine<S,T>> {
public:
    int state;
    Coroutine() : state(0) {}
    virtual ~Coroutine() {}
    virtual bool next(S& input, T &output) = 0;
    bool operator()(S& input, T &output) {
        return next(input, output);
    }
    shared_ptr<Coroutine<S,T>> getPtr() { return this->shared_from_this(); }
};


/* Examples */

class FibGen : public Generator<int> {
public:
    int a, b;
    FibGen() : a(1), b(1) {}
    bool next(int &output) {
        PRG_BEG
        while(true) {
            output = a;
            a = b;
            b = output + a;
            YIELD();
        }
        PRG_END
    }
};
{'fraction_non_alphanumeric': 0.14902852418354692, 'fraction_numerical': 0.009094667217858619, 'mean_word_length': 2.8012568735271013, 'pattern_counts': {'":': 0, '<': 67, '<?xml version=': 0, '>': 76, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '637443', 'n_tokens_mistral': 1665, 'n_tokens_neox': 1640, 'n_words': 409}