| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -9,6 +9,7 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#define SETTINGS_H_ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <iostream> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <sstream> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <list> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <utility> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <memory> | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -25,14 +26,9 @@ namespace mrmc { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					namespace settings { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						namespace bpo = boost::program_options; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						/* | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	Sorry for very long comment at this point (for the class), but all | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	methods are private, hence there is no other place to explain the | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	inner workings of this class that are necessary to understand the | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	callback concept... | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	@brief	Simple wrapper around boost::program_options to handle configuration options. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	@brief	Wrapper around boost::program_options to handle configuration options. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	This class uses boost::program_options to read options from the | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	commandline and additionally load options from a file. | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -44,36 +40,15 @@ namespace settings { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	@code mrmc::settings::instance() @endcode | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	This class can be customized by other parts of the software using | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	callbacks. There are three types of callbacks: register, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	intermediate and checker. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	The (private) constructor will start with filling the internal | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	options_description object. There are a few generic options like | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	--help or --verbose. Then if calls all register callbacks that may | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	add more options. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	Then, it will start with a sloppy parsing run, allowing unregistered  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	options and ignoring further constraints from the options_description  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	objects. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	After that, it will call all intermediate callbacks. They can | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	inspect the options from the first run and add more options, e.g. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	enable more options for a specific component that has been enabled. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	Using the new options_description objects, the constructor performs | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	a second run. This time, it will not allow unregistered options and | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	will check for required and positional arguments. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	Finally, all checker callbacks will be called. They can check the | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	final options for more complex requirements. If any of those checker | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	callbacks returns false, a InvalidSettings exception will be thrown. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	option modules. An option module can be anything that implements the | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	interface specified by registerModule(). | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						class Settings | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							public: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief Get value of a generic option. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	Get value of a generic option. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								template <typename T> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								const T& get(const std::string &name) const { | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -82,18 +57,68 @@ namespace settings { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief Get value of string option | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	Get value of string option | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								const std::string& getString(const std::string &name) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									return this->get<std::string>(name); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief Check if an option is set | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	Check if an option is set | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								const bool isSet(const std::string &name) const { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									return this->vm.count(name) > 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	Register a new module. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	A new settings module can be registered via | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@code | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	mrmc::settings::Settings::registerModule<mrmc::ModuleClass>(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@endcode | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	This has to be done before any parsing takes place, i.e. before newInstance() is called. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	This function implicitly defines the following interface for any SettingsModule: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@code | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	static std::string getModuleName(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	static std::pair< std::string, std::string > getOptionTrigger(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	static void putOptions(boost::program_options::options_description*); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@endcode | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	The semantic is the following: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	If the trigger <a,b> is true, i.e. if option a is set to b, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	the options_description object will be added to the internal | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	option object. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	Furthermore, it will generate the option specified by the | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	trigger. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	The functions could look like this: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@code | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	static std::string getModuleName() { return "Backend A"; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	static std::pair<std::string, std::string> getOptionTrigger() { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *		return std::pair<std::string, std::string>("backend", "a"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	static void putOptions(boost::program_options::options_description* desc) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *		desc->add_options()("foo", "bar"); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@endcode | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								template <typename T> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								static void registerModule() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									// get trigger | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									std::pair< std::string, std::string > trigger = T::getOptionTrigger(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									// build description name | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									std::stringstream str; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									str << T::getModuleName() << " (" << trigger.first << " = " << trigger.second << ")"; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									bpo::options_description* desc = new bpo::options_description(str.str()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									// but options | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									T::putOptions(desc); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									// store | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									Settings::modules[ trigger ] = desc; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								friend std::ostream& help(std::ostream& os); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								friend std::ostream& helpConfigfile(std::ostream& os); | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -121,31 +146,20 @@ namespace settings { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								void secondRun(const int argc, const char* argv[], const char* filename); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	Option descriptions for config file. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								bpo::options_description configfile; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	Option descriptions for config file and command line. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								bpo::options_description generic; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	Option descriptions for command line. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								bpo::options_description commandline; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	Option description for positional arguments on command line. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								bpo::positional_options_description positional; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	Collecting option descriptions for command line. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	Collecting option descriptions. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								static std::unique_ptr<bpo::options_description> cli; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								static std::unique_ptr<bpo::options_description> desc; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	Collecting option descriptions for config file. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	Contains option descriptions for all modules. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								static std::unique_ptr<bpo::options_description> conf; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								static std::map< std::pair< std::string, std::string >, bpo::options_description* > modules; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	option mapping. | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -160,7 +174,7 @@ namespace settings { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	actual instance of this class. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								static Settings* inst; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					 			static Settings* inst; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						/*! | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -168,11 +182,6 @@ namespace settings { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						std::ostream& help(std::ostream& os); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	@brief	Print help for config file options. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						std::ostream& helpConfigfile(std::ostream& os); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	@brief	Return current instance. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 * | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -199,195 +208,7 @@ namespace settings { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							Settings::inst = new Settings(argc, argv, filename); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							return Settings::inst; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	@brief	Function type for functions registering new options. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						typedef void(*RegisterCallback)(bpo::options_description&); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	@brief	Function type for functions changing the parser state | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	between the first and second run. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						typedef void(*IntermediateCallback)(bpo::options_description*, bpo::variables_map&); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	@brief	Function type for function checking constraints on settings. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						typedef bool(*CheckerCallback)(bpo::variables_map&); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	@brief	This enums specifies the three types of options. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						enum CallbackType { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							//! Option can be set in config file | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							CB_CONFIG, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							//! Option can be set on command line | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							CB_CLI,  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							//! Option can be set in config file and command line | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							CB_GENERIC | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	@brief This class handles callbacks for registering new options and | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	checking constraints on them afterwards. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	As it should never be used directly, but only through the Register | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	class, it does not provide any public methods. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	This class is also a singleton (like Settings) and is implemented much | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	simpler as we don't need any custom initialization code. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						class Callbacks | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							public: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								inline void put(const CallbackType type, const RegisterCallback ptr) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									if (this->disabled) throw mrmc::exceptions::InvalidSettings(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									this->registerList.push_back(std::pair<CallbackType, RegisterCallback>(type, ptr)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								inline void put(const CallbackType type, const IntermediateCallback ptr) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									if (this->disabled) throw mrmc::exceptions::InvalidSettings(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									this->intermediateList.push_back(std::pair<CallbackType, IntermediateCallback>(type, ptr)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								inline void put(const CheckerCallback ptr) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									if (this->disabled) throw mrmc::exceptions::InvalidSettings(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									this->checkerList.push_back(ptr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							private: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	Stores register callbacks. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								std::list<std::pair<CallbackType, RegisterCallback>> registerList; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	Stores intermediate callbacks. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								std::list<std::pair<CallbackType, IntermediateCallback>> intermediateList; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	Stores check callbacks. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								std::list<CheckerCallback> checkerList; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief	Stores if we already loaded the settings. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								bool disabled; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief Private constructor. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								Callbacks() : disabled(false) {} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief Private copy constructor. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								Callbacks(const Callbacks&) {} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief Private destructor. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								~Callbacks() {}			 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief Returns current instance to create singleton. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@return current instance | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								inline static Callbacks* instance() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									static Callbacks inst; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									return &inst; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							 *	@brief Register class needs access to lists. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							friend class Register; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							 *	@brief Settings class need access to lists. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							friend class Settings; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	@brief Wrapper class to allow for registering callbacks during | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	static initialization. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	To use this class, use the following includes: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	@code | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	#include "src/utility/settings.h" | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	#include <boost/program_options.hpp> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	namespace bpo = boost::program_options;	 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 *	@endcode | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						class Register | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							public: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief Registers given function as register callback. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 * | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	This constructor registers a callback routine that might add | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	new options for the Settings class. It should be used like | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	this: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@code | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	void register(bpo::options_description& desc) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *		// do something with desc here | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	mrmc::settings::Register reg(mrmc::settings::CB_CLI, ®ister); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@endcode | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	This code should be executed during static initialization, i.e. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	it should be somewhere in the cpp-file. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								Register(const CallbackType type, const RegisterCallback ptr) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									mrmc::settings::Callbacks::instance()->put(type, ptr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief Registers given function as intermediate callback. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	This constructor registers a callback routine that can check | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	the option assignment after the first run and change the | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	options description before the second run. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	It should be used like this: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@code | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	void intermediate(bpo::options_description& desc, bpo::variables_map& map) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *		// check contents of map and maybe change desc | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	mrmc::settings::Register reg(mrmc::settings::CB_CLI, &intermediate); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@endcode | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	This code should be executed during static initialization, i.e. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	it should be somewhere in the cpp-file. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								Register(const CallbackType type, const IntermediateCallback ptr) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									mrmc::settings::Callbacks::instance()->put(type, ptr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								/*! | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@brief Registers given function as check callback. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	This constructor registers a callback routine that can check | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	the option assignment after the Settings class has loaded | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	them. It should be used like this: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@code | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	void check(bpo::variables_map& map) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *		// check contents of map | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	mrmc::settings::Register reg(&check); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	@endcode | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	This code should be executed during static initialization, i.e. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 *	it should be somewhere in the cpp-file. | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								 */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								Register(const CheckerCallback ptr) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
									mrmc::settings::Callbacks::instance()->put(ptr); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} // namespace settings | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} // namespace mrmc | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
					 | 
				
				 | 
				
					
  |