Elements 6.1.2
A C++ base framework for the Euclid Software.
Loading...
Searching...
No Matches
ElementsExamples/src/program/SimpleProgram.cpp

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

#include <cstdint> // for int64_t
#include <map> // for map
#include <memory> // for unique_ptr
#include <string> // for string
#include <utility> // for move
#include <vector> // for vector
#include <boost/current_function.hpp> // for BOOST_CURRENT_FUNCTION
#include <boost/program_options.hpp> // for program options from configuration file of command line arguments
#include "ElementsKernel/Module.h" // for Module
#include "ElementsKernel/ProgramHeaders.h" // for including all Program/related headers
#include "ElementsKernel/Project.h" // for Project
#include "ElementsKernel/ThisModule.h" // for getThisExecutableInfo
using std::map;
using boost::program_options::bool_switch;
using boost::program_options::value;
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 Program : public Elements::Program {
public:
OptionsDescription config_options{"Example program options"};
auto add = config_options.add_options();
bool flag = false;
// Add the specific program options
add("int-option", value<int>()->default_value(int{111}), "An example int option");
add("int-option-with-default-and-default-in-conf", value<int>()->default_value(int{222}), "An example int option");
add("int-option-with-default-no-default-in-conf", value<int>()->default_value(int{444}), "An example int option");
add("int-option-no-default-not-defined-in-conf", value<int>(), "An example int option");
add("int-option-with-no-defaults-anywhere", value<int>(), "An example int option");
add("string-option", value<string>()->default_value(string{}), "An example string option");
add("boolean-option", value<bool>()->default_value(false), "An example boolean option");
add("flag,f", bool_switch(&flag), "An option to set to true");
add("string-option-no-default", value<string>(), "A string option without default value");
add("long-long-option", value<int64_t>()->default_value(int64_t{}), "An example long long option");
add("double-option", value<double>()->default_value(double{}), "An example double option");
add("int-vector-option", value<vector<int>>()->multitoken()->default_value(vector<int>{}, "Empty"),
"An example vector option");
add("threshold,t", value<double>()->default_value(double{0.5}), "An example double option");
return config_options;
}
ExitCode mainMethod(map<string, VariableValue>& args) override {
auto log = Logging::getLogger("Program");
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() << Project();
log.info() << "Project Name: " << Project::name();
log.info() << "Project Version: " << Project::versionString();
log.info() << "Module Name: " << Module::name();
log.info() << "Module Version: " << Module::versionString();
log.info("#");
log.info("Exiting mainMethod()");
return ExitCode::OK;
}
};
} // namespace Examples
} // namespace Elements
Defines tools to describe the current Elmeents module.
Defines tools to describe the current project.
header to get the module info statically
static ClassExample factoryMethod(const std::int64_t source_id, const double ra)
Example factory method.
Simple example of an Elements program.
Definition: Program.cpp:79
OptionsDescription defineSpecificProgramOptions() override
Allows to define the (command line and configuration file) options specific to this program.
Definition: Program.cpp:91
ExitCode mainMethod(map< string, VariableValue > &args) override
The "main" method.
Definition: Program.cpp:128
static Logging getLogger(const std::string &name="")
Definition: Logging.cpp:63
Abstract class for all Elements programs.
Definition: Program.h:52
options_description OptionsDescription
Definition: Program.h:62
Elements::ExitCode ExitCode
Definition: Program.h:67
const std::string name() const
Definition: ModuleInfo.cpp:72
#define MAIN_FOR(ELEMENTS_PROGRAM_NAME)
Definition: Main.h:113
@ OK
Everything is OK.
T move(T... args)
ELEMENTS_API void printProject()
ELEMENTS_API int functionExample(const int j)
void myLocalLogTestFunc()
test function to demonstrate the logger
Definition: Program.cpp:59
ELEMENTS_API const ModuleInfo & getThisExecutableInfo()
Definition: ThisModule.cpp:33
static std::string name()
Definition: Module.h:42
static std::string versionString()
Definition: Module.h:45
static std::string versionString()
Definition: Project.h:46
static std::string name()
Definition: Project.h:42
#include <iostream> // for cout, endl
#include <map> // for map
#include <string> // for string
#include "ElementsKernel/Sleep.h" // for nanoSleep
using std::map;
namespace Elements {
namespace Examples {
class SimpleProgram : public Program {
public:
ExitCode mainMethod(ELEMENTS_UNUSED map<string, VariableValue>& 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
Macro to silence unused variables warnings from the compiler.
Example of an Elements program.
ExitCode mainMethod(ELEMENTS_UNUSED map< string, VariableValue > &args) override
The "main" method.
T endl(T... args)
#define ELEMENTS_UNUSED
Definition: Unused.h:39
ELEMENTS_API void nanoSleep(std::int64_t nsec)
Small variation on the sleep function for nanoseconds sleep.
Definition: Sleep.cpp:39