1 // This is brl/bpro/bprb/bprb_parameters.h
2 #ifndef bprb_parameters_h_
3 #define bprb_parameters_h_
4 //:
5 // \file
6 // \brief classes to represent parameters to bprb processes
7 // \author Matt Leotta, (mleotta@lems.brown.edu)
8 // \date July 1, 2004
9 //
10 // \verbatim
11 //  Modifications
12 //    Matt Leotta   Dec 15, 2004  Migrated from vidpro
13 //    Amir Tamrakar Sep 19, 2006  Added a parameter type for multiple choice options (bprb_choice_param_type)
14 //    J.L. Mundy    Jan 30, 2007  Migrated from breye
15 // \endverbatim
16 
17 #include <string>
18 #include <iostream>
19 #include <typeinfo>
20 #include <utility>
21 #include <vector>
22 #include <map>
23 #ifdef _MSC_VER
24 #  include <vcl_msvc_warnings.h>
25 #endif
26 #include <cassert>
27 #include <vbl/vbl_ref_count.h>
28 #include <bxml/bxml_document.h>
29 #include <bprb/bprb_parameters_sptr.h>
30 
31 //: The abstract base class for a process parameter
32 class bprb_param
33 {
34  public:
35 
36   //: Destructor
37   virtual ~bprb_param() = default;
38 
39   //: Clone this parameter
40   virtual bprb_param * clone() const = 0;
41 
42   //: Return the parameter name
name()43   std::string name() const { return name_; }
44   //: Return the parameter description
description()45   std::string description() const { return description_; }
46   //: Returns true if the valid range of parameter values is bounded
has_bounds()47   bool has_bounds() const { return has_bounds_; }
48 
49   //: Reset the value to its default
50   virtual void reset() = 0;
51   //: Attempt to set the value from the temporary reference
52   virtual bool set_from_temp() = 0;
53 
54   //: Return a string representation of the current value
55   virtual std::string value_str() const = 0;
56   //: Return a string representation of the default value
57   virtual std::string default_str() const = 0;
58   //: Return a string representation of the type
59   virtual std::string type_str() const = 0;
60 
61   //: Return a string representation of the minimum value
62   virtual std::string min_str() const = 0;
63   //: Return a string representation of the maximum value
64   virtual std::string max_str() const = 0;
65 
66   //: Set the current value by parsing a string
67   virtual bool parse_value_str(const std::string& input) = 0;
68 
69  protected:
70   //: Constructor
bprb_param(bool has_bounds,std::string name,std::string desc)71   bprb_param(bool has_bounds, std::string  name, std::string  desc)
72    : has_bounds_(has_bounds), name_(std::move(name)), description_(std::move(desc)) {}
73 
74 
75   //: Describes whether or not the parameter has bounds
76   const bool has_bounds_;
77   //: Name of the parameter
78   const std::string name_;
79   //: Description of the parameter
80   const std::string description_;
81 };
82 
83 //: Output stream operator for bprb_params
84 std::ostream& operator<<(std::ostream& os, const bprb_param& p);
85 
86 //===========================================================================================
87 
88 //: A Templated parameter class
89 template< class T >
90 class bprb_param_type : public bprb_param
91 {
92  public:
93   // Constructor - with bounds
94   bprb_param_type<T>(const std::string& name, const std::string& desc, const T& dflt, T  min, T  max)
bprb_param(true,name,desc)95    : bprb_param(true, name, desc), value_(dflt), default_(dflt), temp_value_(dflt),
96      min_value_(std::move(min)), max_value_(std::move(max)) { assert( min_value_ <= value_ && value_ <= max_value_ ); }
97 
98   // Constructor - without bounds
99   bprb_param_type<T>(const std::string& name, const std::string& desc, const T& dflt)
bprb_param(false,name,desc)100    : bprb_param(false, name, desc), value_(dflt), default_(dflt), temp_value_(dflt),
101      min_value_(dflt), max_value_(dflt) {}
102 
103   //: Accessor for the default value;
default_value()104   T default_value() const { return default_; }
105   //: Accessor for the default value;
min_value()106   T min_value() const { return min_value_; }
107   //: Accessor for the default value;
max_value()108   T max_value() const { return max_value_; }
109 
110   //: Accessor for the current value;
value()111   T value() const { return value_; }
112   //: A reference for temporary storage of values
temp_ref()113   T& temp_ref() { temp_value_ = value_; return temp_value_; }
114   //: Attempt to set the value from the temporary reference
set_from_temp()115   bool set_from_temp() override { return set_value(temp_value_); }
116   //: Set the current value to \p val
117   bool set_value( const T& val );
118 
119   //: Reset the value to its default
reset()120   void reset() override { value_ = default_; }
121 
122   //: Clone the parameter
clone()123   bprb_param * clone() const override { return new bprb_param_type<T>(*this); }
124 
125   //: Return a string representation of the current value
value_str()126   std::string value_str() const override { return create_string(value_); }
127   //: Return a string representation of the default value
default_str()128   std::string default_str() const override { return create_string(default_); }
129   //: Return a string representation of the default value
type_str()130   std::string type_str() const override { return typeid(std::string("dummy")) == typeid(default_) ? "string" : typeid(default_).name(); }
131 
132   //: Return a string representation of the minimum value
min_str()133   std::string min_str() const override { return has_bounds_? create_string(min_value_) : ""; }
134   //: Return a string representation of the maximum value
max_str()135   std::string max_str() const override { return has_bounds_? create_string(max_value_) : ""; }
136 
137   //: Set the current value by parsing a string
parse_value_str(const std::string & input)138   bool parse_value_str(const std::string& input) override { return set_value(parse_string(input)); }
139 
140  private:
141   //: Create a string representation of the value
142   std::string create_string(const T& val) const;
143 
144   //: Parse a string representation of the value
145   T parse_string(const std::string& input) const;
146 
147   //: The current parameter value
148   T value_;
149   //: The default parameter value
150   const T default_;
151   //: A temporary value for assignments by reference
152   T temp_value_;
153   //: The minimum allowed parameter value
154   const T min_value_;
155   //: The maximum allowed parameter value
156   const T max_value_;
157 };
158 
159 //===========================================================================================
160 
161 //: A parameter class for handling multiple choice parameters
162 class bprb_choice_param_type : public bprb_param_type<unsigned>
163 {
164  public:
165   // Constructor
bprb_choice_param_type(const std::string & name,const std::string & desc,const std::vector<std::string> & choices,const unsigned def_val)166   bprb_choice_param_type(const std::string& name, const std::string& desc,
167                          const std::vector<std::string>& choices, const unsigned def_val)
168    : bprb_param_type<unsigned>(name, desc, def_val, 0, static_cast<unsigned>(choices.size()-1)), choices_(choices) {}
169 
170   //: Clone the parameter
clone()171   bprb_param * clone() const override { return new bprb_choice_param_type(*this); }
172 
173   //: Accessor for the choice list;
choices()174   std::vector<std::string> & choices() { return choices_; }
175 
176  private:
177 
178   //: Multiple choice list
179   std::vector<std::string> choices_;
180 };
181 
182 //===========================================================================================
183 
184 //: This class maintains all parameters for a process
185 class bprb_parameters : public vbl_ref_count
186 {
187  public:
188 
189   //: Constructor
190   bprb_parameters();
191   //: Destructor
192   ~bprb_parameters() override;
193 
194   //: Deep pseudo copy constructor
195   bprb_parameters(const bprb_parameters_sptr& old_params);
196   //: Returns true if a parameter exists with \p name
197   bool valid_parameter( const std::string& name ) const;
198 
199   //: Returns true if a parameter exists with \p name and type \p T
200   template<class T>
valid_parameter_type(const std::string & name,const T &)201   bool valid_parameter_type( const std::string& name, const T&) const
202   {
203     std::map< std::string, bprb_param* >::const_iterator
204       itr = name_param_map_.find( name );
205     if ( itr == name_param_map_.end() ) {
206       return false; // Not Found
207     }
208     return dynamic_cast<bprb_param_type<T> *>(itr->second) != NULL;
209   }
210 
211   //: Add a new parameter with no bounds
212   template<class T>
add(const std::string & desc,const std::string & name,const T & default_val)213   bool add( const std::string& desc, const std::string& name, const T& default_val )
214   { return add(new bprb_param_type<T>(name, desc, default_val)); }
215 
216   //: Add a new parameter with bounds
217   template<class T>
add(const std::string & desc,const std::string & name,const T & default_val,const T & min_val,const T & max_val)218   bool add( const std::string& desc, const std::string& name, const T& default_val,
219             const T& min_val, const T& max_val )
220   { return add(new bprb_param_type<T>(name, desc, default_val, min_val, max_val)); }
221 
222   //: Add a new parameter for multiple choice options
223   template<class T>
add(const std::string & desc,const std::string & name,const std::vector<std::string> & choices,const T & default_val)224   bool add( const std::string& desc, const std::string& name,
225             const std::vector<std::string>& choices, const T& default_val )
226   { return add(new bprb_choice_param_type(name, desc, choices, default_val)); }
227 
228   //: Set the value of the existing parameter named \p name
229   template<class T>
set_value(const std::string & name,const T & value)230   bool set_value( const std::string& name , const T& value )
231   {
232     bprb_param_type<T> * param = NULL;
233     if ( get_param(name, param) && param ){
234       return param->set_value(value);
235     }
236     return false;
237   }
238 
239   //: Return the value of the parameter named \p name by reference
240   template<class T>
get_value(const std::string & name,T & value)241   bool get_value( const std::string& name , T& value ) const
242   {
243     bprb_param_type<T> * param = nullptr;
244     if ( get_param(name, param) && param ){
245       value = param->value();
246       return true;
247     }
248     return false;
249   }
250 
251   //: Return the value of the parameter
252   //  Be careful when using this method, if the parameter DOES NOT EXIST --> returns 0
253   //  so MAKE SURE that a parameter with the given name EXISTS in the parameter list of the process
254   template<class T>
value(const std::string & name)255   T value( const std::string& name )
256   {
257     bprb_param_type<T> * param = NULL;
258     T val = 0;
259     if ( get_param(name, param) && param ){
260       val = param->value();
261     }
262     return val;
263   }
264 
265   //: Return the default value of the parameter named \p name by reference
266   template<class T>
get_default(const std::string & name,T & deflt)267   bool get_default( const std::string& name , T& deflt ) const
268   {
269     bprb_param_type<T> * param = NULL;
270     if ( get_param(name, param) && param ){
271       deflt = param->default_value();
272       return true;
273     }
274     return false;
275   }
276 
277   //: Return the bounds of the parameter named \p name by reference
278   template<class T>
get_bounds(const std::string & name,T & min,T & max)279   bool get_bounds( const std::string& name, T & min, T & max ) const
280   {
281     bprb_param_type<T> * param = NULL;
282     if ( get_param(name, param) && param ){
283       min = param->min_value();
284       max = param->max_value();
285       return true;
286     }
287     return false;
288   }
289 
290   //: reads the parameters and their values from an XML document
291   bool parse_XML(std::string const& xml_fname, const std::string& root_tag="");
292 
293   //: prints the default parameter values to an XML document
294   void print_def_XML(const std::string& root_tag,
295                      const std::string& xml_path);
296 
297   //: prints the currently used parameter values to an XML document
298   void print_current_XML(const std::string& root_tag,
299                          const std::string& xml_path);
300 
301   //: Reset all parameters to their default values
302   bool reset_all();
303   //: Reset the parameter named \p name to its default value
304   bool reset( const std::string& name );
305 
306   //: Return a vector of base class pointers to the parameters
307   std::vector< bprb_param* > get_param_list() const;
308   //: Return the description of the parameter named \p name
309   std::string get_desc( const std::string& name ) const;
310   //: Print all parameters to \p os
311   void print_all(std::ostream& os) const;
312 
313  //private:
314   //: Add parameter helper function
315   bool add( bprb_param* param );
316  private:
317   template<class T>
get_param(const std::string & name,bprb_param_type<T> * & param)318   bool get_param( const std::string& name,
319                   bprb_param_type<T> * &param) const
320   {
321     std::map< std::string, bprb_param* >::const_iterator
322       itr = name_param_map_.find( name );
323     if ( itr == name_param_map_.end() ) {
324       return false; // Not Found
325     }
326     param = dynamic_cast<bprb_param_type<T> *>(itr->second);
327     if ( !param )
328       std::cerr << "WARNING: parameter \""<< name
329                << "\" was found but has incorrect type\n";
330     return true;
331   }
332 
333   //: The map from names to parameters
334   std::map< std::string , bprb_param* > name_param_map_;
335   //: The vector of parameters in order of declaration
336   std::vector< bprb_param* > param_list_;
337 
338   bxml_document xml_doc_;
339 };
340 
341 
342 //===========================================================================================
343 
344 
345 //: A simple class to represent a file (for use with parameters)
346 class bprb_filepath
347 {
348  public:
349   //: Constructor
350   bprb_filepath(std::string  p = "", std::string  e = "*")
path(std::move (p))351    : path(std::move(p)), ext(std::move(e)) {}
352 
353   std::string path;
354   std::string ext;
355 };
356 
357 //: Less than operator for bprb_filepath objects
358 bool operator<( const bprb_filepath& lhs, const bprb_filepath& rhs );
359 //: Less than or equal to operator for bprb_filepath objects
360 bool operator<=( const bprb_filepath& lhs, const bprb_filepath& rhs );
361 //: Output stream operator for bprb_filepath objects
362 std::ostream& operator<<( std::ostream& strm, const bprb_filepath& fp );
363 //: Input stream operator for bprb_filepath objects
364 std::istream& operator>>( std::istream& strm, bprb_filepath& fp );
365 
366 
367 #endif // bprb_parameters_h_
368