Elements  5.10
A C++ base framework for the Euclid Software.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ElementsExamples/src/program/SimpleProgramExample.cpp

These are examples of how to create a executable program using the Program class.

#include <map> // for map
#include <string> // for string
#include <vector> // for vector
#include <utility> // for move
#include <memory> // for unique_ptr
#include <boost/current_function.hpp> // for BOOST_CURRENT_FUNCTION
#include "ElementsKernel/ProgramHeaders.h" // for including all Program/related headers
#include "ElementsKernel/ThisModule.h" // for getThisExecutableInfo
using std::map;
using boost::program_options::options_description;
using boost::program_options::value;
using boost::program_options::variable_value;
using boost::program_options::bool_switch;
namespace Elements {
namespace Examples {
auto logger = Logging::getLogger();
logger.info("Test of Message");
auto logger2 = Logging::getLogger(__func__);
logger2.info("Test2 of Message");
auto logger3 = Logging::getLogger(BOOST_CURRENT_FUNCTION);
logger3.info("Test3 of Message");
}
class ProgramExample: public Program {
public:
options_description defineSpecificProgramOptions() override {
options_description config_options { "Example program options" };
bool flag = false;
// Add the specific program options
config_options.add_options()
("int-option", value<int>()->default_value(int {111}),
"An example int option")
("int-option-with-default-and-default-in-conf", value<int>()->default_value(int {222}),
"An example int option")
("int-option-with-default-no-default-in-conf", value<int>()->default_value(int {444}),
"An example int option")
("int-option-no-default-not-defined-in-conf", value<int>(),
"An example int option")
("int-option-with-no-defaults-anywhere", value<int>(),
"An example int option")
("string-option", value<string>()->default_value(string { }),
"An example string option")
("boolean-option", value<bool>()->default_value(false),
"An example boolean option")
("flag,f", bool_switch(&flag),
"An option to set to true")
("string-option-no-default", value<string>(),
"A string option without default value")
("long-long-option", value<int64_t>()->default_value(int64_t { }),
"An example long long option")
("double-option", value<double>()->default_value(double { }),
"An example double option")
("int-vector-option",
value<vector<int>>()->multitoken()->default_value(vector<int> { }, "Empty"),
"An example vector option")
("threshold,t", value<double>()->default_value(double {0.5}),
"An example double option");
return config_options;
}
ExitCode mainMethod(map<string, variable_value>& args) override {
auto log = Logging::getLogger("ProgramExample");
log.info("Entering mainMethod()");
log.info("#");
/*
* Check availability of mandatory program arguments (or options)
*
* Arguments values may come from
* 1) the default value provided in above defineSpecificProgramOptions()
* 2) the configuration file
* 3) the command line
*
* If an none of the three options provide any values for a mandatory
* argument, you should check if your option has any values following the
* below example. Note that this may happen for all options without default
* values.
*/
if (args["string-option-no-default"].empty()) {
log.info() << "No value are available for string-option-no-default";
/*
* An exception may be thrown her if the above option is mandatory and there
* is no way to continue without value
*/
}
/*
* Get and log one of the program arguments (or options)
*
* The string-option has a default empty string value, so that it can always be
* printed event as an empty string
*/
string string_example { args["string-option"].as<string>() };
log.info() << "String option value: " << string_example;
log.info() << "The int-option value is " << args["int-option"].as<int>();
log.info() << "The threshold value is " << args["threshold"].as<double>();
// Some initialization
double input_variable = 3.4756;
int64_t source_id = 12345;
double ra = 45.637;
// Factory method example
ClassExample example_class_object = ClassExample::factoryMethod(
source_id, ra);
/*
* All fundamental type variables can be copied forth and back without significant
* cost in (almost) all cases
*/
double method_result = example_class_object.fundamentalTypeMethod(
input_variable);
log.info() << "Some result: " << method_result;
double first = 1.0;
double division_result{};
try {
log.info("#");
log.info("# Calling a method throwing an exception ");
log.info("#");
double second = 0.0;
division_result = example_class_object.divideNumbers(first, second);
//
} catch (const Exception & e) {
log.info("#");
log.info() << e.what();
log.info("#");
log.info("# In this silly example we continue with a fake fix ");
log.info("#");
division_result = example_class_object.divideNumbers(first, 0.000001);
}
log.info() << "Second result is: " << division_result;
/*
* Illustration on how best to use smart pointer (regular pointer should not
* be used anymore). The move() indicate that the ownership of the pointer is given to the
* method called. The vector_unique_ptr cannot be used in this method anymore after the
* call.
*/
std::unique_ptr<vector<double>> vector_unique_ptr {
new vector<double> { 1.0, 2.3, 4.5 } };
example_class_object.passingUniquePointer(std::move(vector_unique_ptr));
/*
* Illustration on how best to pass any object. The passingObjectInGeneral() is taking
* a reference to this object.
*/
vector<double> object_example { vector<double> { 1.0, 2.3, 4.5 } };
example_class_object.passingObjectInGeneral(object_example);
log.info() << "Function Example: " << functionExample(3);
log.info() << "This executable name: " << Elements::System::getThisExecutableInfo().name();
log.info("#");
log.info("Exiting mainMethod()");
return ExitCode::OK;
}
};
} // namespace Examples
} // namespace Elements
#include <iostream> // for cout, endl
#include <map> // for map
#include <string> // for string
#include "ElementsKernel/Sleep.h" // for nanoSleep
namespace po = boost::program_options;
using std::map;
using boost::program_options::variable_value;
namespace Elements {
namespace Examples {
class SimpleProgramExample: public Program {
public:
ExitCode mainMethod(ELEMENTS_UNUSED map<string, variable_value>& args) override {
// Get logger and log the entry into the mainMethod
log.info("This Works");
std::cout << "This Works too!" << std::endl;
return ExitCode::OK;
}
};
} // namespace Examples
} // namespace Elements