#include <iostream>
#include <memory>
#include <vector>

using namespace std;


/////////////////////////////////////////
// opengl_helper.h
// this is some manager class that knows what should be initialized later
struct OpenGLHelper
{
	typedef std::function<void()> function_type;
	
	static std::vector<function_type>& get_initialization_list();
	
	static void register_initializer(function_type fn);
	
	static void run_init();
};
// helper class that will register some function at construction time
struct OpenGLHelper_initializer
{
	OpenGLHelper_initializer(OpenGLHelper::function_type fn)
	{
		OpenGLHelper::register_initializer(fn);
	}
};
/////////////////////////////////////////
//opengl_helper.cpp

std::vector<OpenGLHelper::function_type>& OpenGLHelper::get_initialization_list()
{
	static std::vector<function_type> initializer_list;
	return initializer_list;	
}

// function that puts initializer into a list. 
void OpenGLHelper::register_initializer(OpenGLHelper::function_type fn)
{

	get_initialization_list().push_back(fn);
}

void OpenGLHelper::run_init()
{
	for (auto fn : get_initialization_list())
		fn();
}

/////////////////////////////////////////
// figure.h
// here is sample class that will be registered for initialization
struct Square
{
	static int to_be_initialized;
	
	// static member that will register Square class to be initialized
	static OpenGLHelper_initializer __initializer;
};

/////////////////////////////////////////
// Square.cpp
int Square::to_be_initialized = 0;
// this is the most interesting part - register square into initializer list
OpenGLHelper_initializer Square::__initializer([](){
	Square::to_be_initialized = 15; 
	std::cout << "Called Square::init: " << to_be_initialized << std::endl; 
});

int main() 
{
	std::cout << "Before initialization : " << Square::to_be_initialized << std::endl;
	OpenGLHelper::run_init();
	std::cout << "After  initialization : " << Square::to_be_initialized << std::endl;
	return 0;
}