#include <iostream>
#include <vector>
#include <utility>

void A() {
	std::cout << "I'm an A" << std::endl;
}

void B() {
	std::cout << "I'm a B" << std::endl;
}

void C() {
	std::cout << "I'm a C" << std::endl;
}

class processor {
private:
	std::vector<void (*)()> funcs;
	std::vector<std::pair<int, int>> links;
public:
	void add_func(void (*func)()) { funcs.push_back(func); }
	void link(int from, int to) { links.push_back({from, to}); }
	void call(int indx) {
		// Make the call
		std::cout << "generic preprocessing" << std::endl;
		funcs.at(indx)();
		std::cout << "generic postprocessing" << std::endl;
		
		// Call any links
		for(auto it : links) {
			if(it.first == indx) { call(it.second); }
		}
	}
};

int main() {
	processor p;
	p.add_func(A);
	p.add_func(B);
	p.add_func(C);
	
	p.link(0, 1); // A -> B
	p.link(1, 2); // B -> C
	
	p.call(0); // Call A
	
	return 0;
}