SIRF  3.4.0
ParserKey.h
Go to the documentation of this file.
1 /*
2 SyneRBI Synergistic Image Reconstruction Framework (SIRF)
3 Copyright 2017 - 2019 University College London
4 
5 This is software developed for the Collaborative Computational
6 Project in Synergistic Reconstruction for Biomedical Imaging (formerly CCP PETMR)
7 (http://www.ccpsynerbi.ac.uk/).
8 
9 Licensed under the Apache License, Version 2.0 (the "License");
10 you may not use this file except in compliance with the License.
11 You may obtain a copy of the License at
12 http://www.apache.org/licenses/LICENSE-2.0
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18 
19 */
20 
30 #pragma once
31 
32 #include <string>
33 #include <iostream>
34 #include <algorithm>
35 
36 namespace sirf {
38 template<class A>
39 std::string get_typename(A)
40 {
41  if (typeid(A) == typeid(const char *)) return "const char *";
42  else if (typeid(A) == typeid(int)) return "int";
43  else if (typeid(A) == typeid(float)) return "float";
44  else if (typeid(A) == typeid(double)) return "double";
45  else if (typeid(A) == typeid(unsigned int)) return "unsigned int";
46  else if (typeid(A) == typeid(bool)) return "bool";
47  else return typeid(A).name();
48 }
49 
57 template<class Z>
59 {
60 public:
61 
64 
66  virtual ~ParserKeyBase() {}
67 
69  void set_object(std::shared_ptr<Z> object) { _object = object; }
70 
72  virtual void get_arguments(const std::string &line) = 0;
73 
75  virtual void call_function() const = 0;
76 
78  virtual void print_num_arguments_expected() const = 0;
79 
80 protected:
81 
83  void check_num_arguments(const std::string &line, const int num_args_expected) const
84  {
85  int num_args;
86 
87  // If last character is "=", then num args == 0
88  if (line.back() == '=') num_args = 0;
89 
90  // If not... Parameters are separated by commas. so num parameters is num commas + 1
91  else {
92  num_args = int(std::count(line.begin(), line.end(), ',')) + 1;
93  }
94 
95  if (num_args != num_args_expected) {
96  throw std::runtime_error("Error. Num arguments expected: " + std::to_string(num_args_expected) + ", num arguments found: " + std::to_string(num_args) + ".");
97  }
98 
100  std::cout << "\tNumber arguments found: " << num_args << "\n";
101  }
102 
103 
105  std::string get_arg_as_string(const std::string &line, const int arg_num) const
106  {
107  // Start index is always to right of the ":="
108  // End index is up to ","
109  auto index_start = line.find(":=") + 2;
110  auto index_end = line.find(",");
111 
112  // For subsequent arguments
113  for (int i=0; i<arg_num; i++) {
114  index_start = line.find(",",index_start) + 1; // add 1 to go to right of ","
115  index_end = line.find(",",index_start);
116  }
117 
118  // Error check
119  if (index_end == index_start) {
120  throw std::runtime_error("Error. Argument number " + std::to_string(arg_num) + " was not found.");
121  }
122 
123  std::string arg_as_string = line.substr(index_start, index_end-index_start);
124  std::cout << "\t\tArg as string: " << arg_as_string << "\n";
125 
126  // Return the substring
127  return arg_as_string;
128  }
129 
131  void get_argument(const std::string &line, const int arg_num, const char *&arg ) const { arg = get_arg_as_string(line, arg_num).c_str(); }
132 
134  void get_argument(const std::string &line, const int arg_num, bool &arg ) const { arg = std::stoi(get_arg_as_string(line, arg_num)); }
135 
137  void get_argument(const std::string &line, const int arg_num, int &arg ) const { arg = std::stoi(get_arg_as_string(line, arg_num)); }
138 
140  void get_argument(const std::string &line, const int arg_num, unsigned int &arg ) const { arg = static_cast<unsigned>(std::stoul(get_arg_as_string(line, arg_num))); }
141 
143  void get_argument(const std::string &line, const int arg_num, float &arg ) const { arg = std::stof(get_arg_as_string(line, arg_num)); }
144 
146  void get_argument(const std::string &line, const int arg_num, double &arg ) const { arg = std::stod(get_arg_as_string(line, arg_num)); }
147 
149  void get_argument(const std::string &line, const int arg_num, unsigned long &arg) const { arg = std::stoul(get_arg_as_string(line, arg_num)); }
150 
151 #ifdef _WIN32
152  void get_argument(const std::string &line, const int arg_num, std::size_t &arg) const { arg = std::stoul(get_arg_as_string(line, arg_num)); }
154 #endif
155  std::shared_ptr<Z> _object;
157 };
158 
166 template<class Z>
167 class ParserKey0Arg : public ParserKeyBase<Z>
168 {
169 public:
170 
173 
175  virtual ~ParserKey0Arg() {}
176 
178  void set_function(void (Z::*function)()) { _function = function; }
179 
181  virtual void get_arguments(const std::string &line)
182  {
183  this->check_num_arguments(line,0);
184  }
185 
187  virtual void call_function() const
188  {
189  std::cout << "\tCalling function with no arguments..." << std::flush;
190  (this->_object.get()->*_function)();
191  std::cout << "done." << std::endl;
192  }
193 
195  virtual void print_num_arguments_expected() const { std::cout << "\tNumber arguments expected: 0\n"; }
196 
197 
198 protected:
199 
201  void (Z::*_function)();
202 };
203 
211 template<class Z, class A>
212 class ParserKey1Arg : public ParserKeyBase<Z>
213 {
214 public:
215 
218 
220  virtual ~ParserKey1Arg() {}
221 
223  void set_function(void (Z::*function)(A)) { _function = function; }
224 
226  virtual void get_arguments(const std::string &line)
227  {
228  this->check_num_arguments(line, 1);
229 
230  // Set the argument
231  std::cout << "\tSetting argument...\n";
232  this->get_argument(line, 0, _arg1);
233  std::cout << "\t\tExpected type: " << get_typename(_arg1) << "\n";
234  std::cout << "\t\tValue: " << _arg1 << "\n";
235  }
236 
238  virtual void call_function() const
239  {
240  std::cout << "\tCalling function with one argument..." << std::flush;
241  (this->_object.get()->*_function)(_arg1);
242  std::cout << "done." << std::endl;
243  }
244 
246  virtual void print_num_arguments_expected() const { std::cout << "\tNumber arguments expected: 1 (" << get_typename(_arg1) << ")\n"; }
247 
248 protected:
249 
251  void (Z::*_function)(A);
253  A _arg1;
254 };
255 
263 template<class Z, class A, class B>
264 class ParserKey2Arg : public ParserKeyBase<Z>
265 {
266 public:
267 
270 
272  virtual ~ParserKey2Arg() {}
273 
275  void set_function(void (Z::*function)(A,B)) { _function = function; }
276 
278  virtual void get_arguments(const std::string &line)
279  {
280  this->check_num_arguments(line, 2);
281 
282  // Set the first argument
283  std::cout << "\tSetting first argument...\n";
284  this->get_argument(line, 0, _arg1);
285  std::cout << "\t\tExpected type: " << get_typename(_arg1) << "\n";
286  std::cout << "\t\tValue: " << _arg1 << "\n";
287 
288  // Set the second argument
289  std::cout << "\tSetting second argument...\n";
290  this->get_argument(line, 1, _arg2);
291  std::cout << "\t\tExpected type: " << get_typename(_arg2) << "\n";
292  std::cout << "\t\tValue: " << _arg2 << "\n";
293  }
294 
296  virtual void call_function() const
297  {
298  std::cout << "\tCalling function with two arguments..." << std::flush;
299  (this->_object.get()->*_function)(_arg1,_arg2);
300  std::cout << "done." << std::endl;
301  }
302 
304  virtual void print_num_arguments_expected() const { std::cout << "\tNumber arguments expected: 2 (" << get_typename(_arg1) << " and " << get_typename(_arg2) << ")\n"; }
305 
306 protected:
307 
309  void (Z::*_function)(A,B);
311  A _arg1;
313  B _arg2;
314 };
315 }
virtual void get_arguments(const std::string &line)
Get arguments.
Definition: ParserKey.h:278
virtual ~ParserKey1Arg()
Destructor.
Definition: ParserKey.h:220
virtual void call_function() const =0
Call function.
virtual ~ParserKey0Arg()
Destructor.
Definition: ParserKey.h:175
virtual void print_num_arguments_expected() const =0
Print number of arguments expected.
virtual void get_arguments(const std::string &line)
Get arguments - don&#39;t need to do anything.
Definition: ParserKey.h:181
void get_argument(const std::string &line, const int arg_num, double &arg) const
Get argument - double.
Definition: ParserKey.h:146
void get_argument(const std::string &line, const int arg_num, unsigned long &arg) const
Get argument - unsigned long.
Definition: ParserKey.h:149
A _arg1
Argument.
Definition: ParserKey.h:253
virtual void get_arguments(const std::string &line)=0
Get arguments.
Class for parser keys with 1 argument.
Definition: ParserKey.h:212
ParserKeyBase()
Constructor.
Definition: ParserKey.h:63
void get_argument(const std::string &line, const int arg_num, const char *&arg) const
Get argument - const char *.
Definition: ParserKey.h:131
A _arg1
First argument.
Definition: ParserKey.h:311
virtual void print_num_arguments_expected() const
Print number of arguments expected.
Definition: ParserKey.h:304
virtual ~ParserKeyBase()
Destructor.
Definition: ParserKey.h:66
virtual void get_arguments(const std::string &line)
Get arguments.
Definition: ParserKey.h:226
void set_function(void(Z::*function)(A, B))
Set function.
Definition: ParserKey.h:275
virtual ~ParserKey2Arg()
Destructor.
Definition: ParserKey.h:272
Base for parser keys.
Definition: ParserKey.h:58
void get_argument(const std::string &line, const int arg_num, bool &arg) const
Get argument - bool.
Definition: ParserKey.h:134
Class for parser keys with 0 arguments.
Definition: ParserKey.h:167
void set_object(std::shared_ptr< Z > object)
Set object.
Definition: ParserKey.h:69
void get_argument(const std::string &line, const int arg_num, float &arg) const
Get argument - float.
Definition: ParserKey.h:143
Abstract data container.
Definition: GeometricalInfo.cpp:141
ParserKey0Arg()
Constructor.
Definition: ParserKey.h:172
ParserKey1Arg()
Constructor.
Definition: ParserKey.h:217
void set_function(void(Z::*function)())
Set function.
Definition: ParserKey.h:178
virtual void call_function() const
Call the function.
Definition: ParserKey.h:238
std::shared_ptr< Z > _object
Object to call the function on.
Definition: ParserKey.h:156
Class for parser keys with 2 arguments.
Definition: ParserKey.h:264
std::string get_arg_as_string(const std::string &line, const int arg_num) const
Get the nth argument as a string.
Definition: ParserKey.h:105
ParserKey2Arg()
Constructor.
Definition: ParserKey.h:269
virtual void call_function() const
Call the function.
Definition: ParserKey.h:296
std::string get_typename(A)
Get template type as human-readable name.
Definition: ParserKey.h:39
void get_argument(const std::string &line, const int arg_num, unsigned int &arg) const
Get argument - unsigned int.
Definition: ParserKey.h:140
void get_argument(const std::string &line, const int arg_num, int &arg) const
Get argument - int.
Definition: ParserKey.h:137
virtual void call_function() const
Call the function.
Definition: ParserKey.h:187
void set_function(void(Z::*function)(A))
Set function.
Definition: ParserKey.h:223
virtual void print_num_arguments_expected() const
Print number of arguments expected.
Definition: ParserKey.h:246
B _arg2
Second argument.
Definition: ParserKey.h:313
void check_num_arguments(const std::string &line, const int num_args_expected) const
Check that the number of arguments matches the expected amount.
Definition: ParserKey.h:83
virtual void print_num_arguments_expected() const
Print number of arguments expected.
Definition: ParserKey.h:195