1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
| #include <algorithm>
#include <list>
#include <map>
struct machine_error{};
template <typename T, typename Id=int>
class machine {
public:
typedef Id (*selecteur)(T const&);
private:
typedef std::map<Id, selecteur> etats_t;
public:
machine(Id id, selecteur initialstate, bool final = false) : courant(id) {
etat(id, initialstate, final);
}
~machine(){}
void etat(Id id, selecteur f, bool final = false) {
etats.insert( typename etats_t::value_type(id, f) );
if(final) finaux.push_back(id);
}
void avancer(T const& t) const {
typename etats_t::const_iterator it = etats.find(courant);
if (it==etats.end()) throw machine_error();
courant = (it->second)(t);
}
bool final() const {
return std::count(finaux.begin(), finaux.end(), courant) != 0;
}
private:
std::map<Id, selecteur> etats;
std::list<Id> finaux;
mutable Id courant;
};
template <typename Id>
class machine<void, Id> {
public:
typedef Id (*selecteur)();
private:
typedef std::map<Id, selecteur> etats_t;
public:
machine(Id id, selecteur initialstate, bool final = false) : courant(id) {
etat(id, initialstate, final);
}
~machine(){}
void etat(Id id, selecteur f, bool final = false) {
etats.insert( typename etats_t::value_type(id, f) );
if(final) finaux.push_back(id);
}
void avancer() const {
typename etats_t::const_iterator it = etats.find(courant);
if (it==etats.end()) throw machine_error();
courant = (it->second)();
}
bool final() const {
return std::count(finaux.begin(), finaux.end(), courant) != 0;
}
private:
std::map<Id, selecteur> etats;
std::list<Id> finaux;
mutable Id courant;
};
#include <iostream>
using namespace std;
namespace states {
int todo;
int begin() {
todo = 10;
cout<<"start"<<endl;
return 1;
}
int etat1() {
cout<<"exercise"<<endl;
return 2;
}
int etat2() {
cout<<"done"<<endl;
return --todo ? 1 : 3;
}
int close() {
cout<<"finish"<<endl;
return 3;
}
}
int main() {
machine<void> m(0, states::begin);
m.etat(1, states::etat1);
m.etat(2, states::etat2);
m.etat(3, states::close, true);
try {
while (!m.final()) {
m.avancer();
}
} catch (machine_error& e) {
cerr << "machine error" << endl;
}
} |
Partager