Elements  6.0.1
A C++ base framework for the Euclid Software.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ProgramExample.cpp
Go to the documentation of this file.
1 
21 #include <cstdint> // for int64_t
22 #include <map> // for map
23 #include <memory> // for unique_ptr
24 #include <string> // for string
25 #include <utility> // for move
26 #include <vector> // for vector
27 
29 #include <boost/current_function.hpp> // for BOOST_CURRENT_FUNCTION
30 #include <boost/program_options.hpp> // for program options from configuration file of command line arguments
31 
32 #include "ElementsKernel/Module.h" // for Module
33 #include "ElementsKernel/ProgramHeaders.h" // for including all Program/related headers
34 #include "ElementsKernel/Project.h" // for Project
35 #include "ElementsKernel/ThisModule.h" // for getThisExecutableInfo
36 
39 
40 using std::map;
41 using std::string;
42 using std::vector;
43 
44 using boost::program_options::bool_switch;
45 using boost::program_options::value;
46 
47 using std::int64_t;
48 
49 namespace Elements {
50 namespace Examples {
51 
60 
61  auto logger = Logging::getLogger();
62  logger.info("Test of Message");
63 
64  auto logger2 = Logging::getLogger(__func__);
65  logger2.info("Test2 of Message");
66 
67  auto logger3 = Logging::getLogger(BOOST_CURRENT_FUNCTION);
68  logger3.info("Test3 of Message");
69 }
70 
79 class ProgramExample : public Program {
80 
81 public:
92 
93  OptionsDescription config_options{"Example program options"};
94  auto add = config_options.add_options();
95 
96  bool flag = false;
97 
98  // Add the specific program options
99  add("int-option", value<int>()->default_value(int{111}), "An example int option");
100  add("int-option-with-default-and-default-in-conf", value<int>()->default_value(int{222}), "An example int option");
101  add("int-option-with-default-no-default-in-conf", value<int>()->default_value(int{444}), "An example int option");
102  add("int-option-no-default-not-defined-in-conf", value<int>(), "An example int option");
103  add("int-option-with-no-defaults-anywhere", value<int>(), "An example int option");
104  add("string-option", value<string>()->default_value(string{}), "An example string option");
105  add("boolean-option", value<bool>()->default_value(false), "An example boolean option");
106  add("flag,f", bool_switch(&flag), "An option to set to true");
107  add("string-option-no-default", value<string>(), "A string option without default value");
108  add("long-long-option", value<int64_t>()->default_value(int64_t{}), "An example long long option");
109  add("double-option", value<double>()->default_value(double{}), "An example double option");
110  add("int-vector-option", value<vector<int>>()->multitoken()->default_value(vector<int>{}, "Empty"),
111  "An example vector option");
112  add("threshold,t", value<double>()->default_value(double{0.5}), "An example double option");
113 
114  return config_options;
115  }
116 
129 
130  auto log = Logging::getLogger("ProgramExample");
131  log.info("Entering mainMethod()");
132  log.info("#");
133  /*
134  * Check availability of mandatory program arguments (or options)
135  *
136  * Arguments values may come from
137  * 1) the default value provided in above defineSpecificProgramOptions()
138  * 2) the configuration file
139  * 3) the command line
140  *
141  * If an none of the three options provide any values for a mandatory
142  * argument, you should check if your option has any values following the
143  * below example. Note that this may happen for all options without default
144  * values.
145  */
146  if (args["string-option-no-default"].empty()) {
147  log.info() << "No value are available for string-option-no-default";
148  /*
149  * An exception may be thrown her if the above option is mandatory and there
150  * is no way to continue without value
151  */
152  }
153  /*
154  * Get and log one of the program arguments (or options)
155  *
156  * The string-option has a default empty string value, so that it can always be
157  * printed event as an empty string
158  */
159  string string_example{args["string-option"].as<string>()};
160  log.info() << "String option value: " << string_example;
161 
162  log.info() << "The int-option value is " << args["int-option"].as<int>();
163  log.info() << "The threshold value is " << args["threshold"].as<double>();
164 
165  // Some initialization
166  double input_variable = 3.4756;
167  int64_t source_id = 12345;
168  double ra = 45.637;
169 
170  // Factory method example
171  ClassExample example_class_object = ClassExample::factoryMethod(source_id, ra);
172 
173  /*
174  * All fundamental type variables can be copied forth and back without significant
175  * cost in (almost) all cases
176  */
177  double method_result = example_class_object.fundamentalTypeMethod(input_variable);
178  log.info() << "Some result: " << method_result;
179 
180  double first = 1.0;
181  double division_result{};
182  try {
183  log.info("#");
184  log.info("# Calling a method throwing an exception ");
185  log.info("#");
186  double second = 0.0;
187  division_result = example_class_object.divideNumbers(first, second);
188  //
189  } catch (const Exception& e) {
190  log.info("#");
191  log.info() << e.what();
192  log.info("#");
193  log.info("# In this silly example we continue with a fake fix ");
194  log.info("#");
195  division_result = example_class_object.divideNumbers(first, 0.000001);
196  }
197  log.info() << "Second result is: " << division_result;
198 
199  /*
200  * Illustration on how best to use smart pointer (regular pointer should not
201  * be used anymore). The move() indicate that the ownership of the pointer is given to the
202  * method called. The vector_unique_ptr cannot be used in this method anymore after the
203  * call.
204  */
205  std::unique_ptr<vector<double>> vector_unique_ptr{new vector<double>{1.0, 2.3, 4.5}};
206  example_class_object.passingUniquePointer(std::move(vector_unique_ptr));
207 
208  /*
209  * Illustration on how best to pass any object. The passingObjectInGeneral() is taking
210  * a reference to this object.
211  */
212  vector<double> object_example{vector<double>{1.0, 2.3, 4.5}};
213  example_class_object.passingObjectInGeneral(object_example);
214 
215  log.info() << "Function Example: " << functionExample(3);
216 
217  log.info() << "This executable name: " << Elements::System::getThisExecutableInfo().name();
218 
220 
221  printProject();
222 
223  log.info() << Project();
224  log.info() << "Project Name: " << Project::name();
225  log.info() << "Project Version: " << Project::versionString();
226  log.info() << "Module Name: " << Module::name();
227  log.info() << "Module Version: " << Module::versionString();
228 
229  log.info("#");
230  log.info("Exiting mainMethod()");
231  return ExitCode::OK;
232  }
233 };
234 
235 } // namespace Examples
236 } // namespace Elements
237 
ExitCode
Strongly typed exit numbers.
Definition: Exit.h:97
double fundamentalTypeMethod(const double input_variable) const
Simple method example.
OptionsDescription defineSpecificProgramOptions() override
Allows to define the (command line and configuration file) options specific to this program...
static std::string name()
Definition: Project.h:42
Everything is OK.
Defines tools to describe the current project.
ELEMENTS_API const ModuleInfo & getThisExecutableInfo()
Definition: ThisModule.cpp:33
static std::string versionString()
Definition: Module.h:45
void myLocalLogTestFunc()
test function to demonstrate the logger
ELEMENTS_API int functionExample(const int j)
Abstract class for all Elements programs.
Definition: Program.h:52
STL class.
STL class.
constexpr double e
The base of the natural logarithm .
Definition: MathConstants.h:51
header to get the module info statically
#define MAIN_FOR(ELEMENTS_PROGRAM_NAME)
Definition: Main.h:113
static std::string name()
Definition: Module.h:42
const std::string name() const
Definition: ModuleInfo.cpp:71
ELEMENTS_API void printProject()
static std::string versionString()
Definition: Project.h:46
ExitCode mainMethod(map< string, VariableValue > &args) override
The &quot;main&quot; method.
void passingUniquePointer(std::unique_ptr< std::vector< double >> vector_unique_ptr) const
Example method with a unique pointer argument.
T move(T...args)
Defines tools to describe the current Elmeents module.
STL class.
STL class.
Elements base exception class.
Definition: Exception.h:47
options_description OptionsDescription
Definition: Program.h:62
constexpr double second
void passingObjectInGeneral(const std::vector< double > &input_object) const
Example method taking an object in input.
Simple example of an Elements program.
double divideNumbers(const double first, const double second) const
Divide two double variables.
const char * what() const noexceptoverride
Definition: Exception.h:98
static Logging getLogger(const std::string &name="")
Definition: Logging.cpp:63
static ClassExample factoryMethod(const std::int64_t source_id, const double ra)
Example factory method.