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> * ¶m) 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