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