00001
00002
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00031
00032 #ifndef RCSC_PARAM_PARAM_MAP_H
00033 #define RCSC_PARAM_PARAM_MAP_H
00034
00035 #include <boost/shared_ptr.hpp>
00036 #include <boost/lexical_cast.hpp>
00037
00038 #include <vector>
00039 #include <map>
00040 #include <string>
00041 #include <iostream>
00042 #include <cassert>
00043
00044 namespace rcsc {
00045
00050 struct BoolSwitch {
00051 bool * ptr_;
00052
00057 explicit
00058 BoolSwitch( bool * ptr )
00059 : ptr_( ptr )
00060 {
00061 assert( ptr );
00062 }
00063 };
00064
00065
00070 class ParamEntity {
00071 private:
00073 std::string M_long_name;
00075 std::string M_short_name;
00077 std::string M_description;
00078
00080 ParamEntity();
00081
00082 protected:
00083
00090 ParamEntity( const std::string & long_name,
00091 const std::string & short_name,
00092 const char * description = "" )
00093 : M_long_name( long_name )
00094 , M_short_name( short_name )
00095 , M_description( description )
00096 { }
00097
00098 public:
00099
00103 virtual
00104 ~ParamEntity()
00105 { }
00106
00111 const
00112 std::string & longName() const
00113 {
00114 return M_long_name;
00115 }
00116
00121 const
00122 std::string & shortName() const
00123 {
00124 return M_short_name;
00125 }
00130 const
00131 std::string & description() const
00132 {
00133 return M_description;
00134 }
00135
00136
00141 virtual
00142 bool isString() const
00143 {
00144 return false;
00145 }
00146
00151 virtual
00152 bool isSwitch() const
00153 {
00154 return false;
00155 }
00156
00161 virtual
00162 bool analyze( const std::string & value_str ) = 0;
00163
00169 virtual
00170 std::ostream & printValue( std::ostream & os ) const = 0;
00171
00172 };
00173
00177 typedef boost::shared_ptr< ParamEntity > ParamPtr;
00178
00179
00180
00185 template < typename ValueType >
00186 class ParamGeneric
00187 : public ParamEntity {
00188 private:
00190 ValueType * M_value_ptr;
00191
00192 public:
00193
00201 ParamGeneric( const std::string & long_name,
00202 const std::string & short_name,
00203 ValueType * value_ptr,
00204 const char * description = "" )
00205 : ParamEntity( long_name, short_name, description )
00206 , M_value_ptr( value_ptr )
00207 {
00208 assert( value_ptr );
00209 }
00210
00215 bool isString() const
00216 {
00217 return ( typeid( ValueType ) == typeid( std::string ) );
00218 }
00219
00225 bool analyze( const std::string & value_str )
00226 {
00227 try
00228 {
00229 *M_value_ptr = boost::lexical_cast< ValueType >( value_str );
00230 return true;
00231 }
00232 catch ( boost::bad_lexical_cast & e )
00233 {
00234 std::cerr << e.what() << " [" << value_str << "]"
00235 << std::endl;
00236 return false;
00237 }
00238 }
00239
00245 std::ostream & printValue( std::ostream & os ) const
00246 {
00247 return os << *M_value_ptr;
00248 }
00249
00250 };
00251
00252
00256 template <>
00257 class ParamGeneric< bool >
00258 : public ParamEntity {
00259 private:
00261 bool * M_value_ptr;
00262
00263 public:
00264
00272 ParamGeneric( const std::string & long_name,
00273 const std::string & short_name,
00274 bool * value_ptr,
00275 const char * description = "" )
00276 : ParamEntity( long_name, short_name, description )
00277 , M_value_ptr( value_ptr )
00278 {
00279 assert( value_ptr );
00280 }
00281
00287 bool analyze( const std::string & value_str );
00288
00294 std::ostream & printValue( std::ostream & os ) const;
00295
00296 };
00297
00298
00303 class ParamSwitch
00304 : public ParamEntity {
00305 private:
00307 bool * M_value_ptr;
00308
00309 public:
00310
00318 ParamSwitch( const std::string & long_name,
00319 const std::string & short_name,
00320 bool * value_ptr,
00321 const char * description = "" )
00322 : ParamEntity( long_name, short_name, description )
00323 , M_value_ptr( value_ptr )
00324 {
00325 assert( value_ptr );
00326 }
00327
00332 virtual
00333 bool isSwitch() const
00334 {
00335 return true;
00336 }
00337
00343 bool analyze( const std::string & value_str );
00344
00350 std::ostream & printValue( std::ostream & os ) const;
00351
00352 };
00353
00354
00355
00360 class ParamMap {
00361 private:
00362
00367 class Registrar {
00368 private:
00370 ParamMap & M_param_map;
00372 Registrar();
00373 public:
00378 explicit
00379 Registrar( ParamMap & pmap )
00380 : M_param_map( pmap )
00381 { }
00382
00391 template < typename ValueType >
00392 Registrar & operator()( const std::string & long_name,
00393 const std::string & short_name,
00394 ValueType * value_ptr,
00395 const char * description = "" )
00396 {
00397 if ( value_ptr == static_cast< ValueType * >( 0 ) )
00398 {
00399 std::cerr << "***ERROR*** detected null pointer for the option "
00400 << long_name << std::endl;
00401 return *this;
00402 }
00403
00404 ParamPtr ptr( new ParamGeneric< ValueType >( long_name,
00405 short_name,
00406 value_ptr,
00407 description ) );
00408 M_param_map.add( ptr );
00409 return *this;
00410 }
00411
00412
00421 Registrar & operator()( const std::string & long_name,
00422 const std::string & short_name,
00423 const BoolSwitch & value,
00424 const char * description = "" );
00425
00426 };
00427
00429 Registrar M_registrar;
00430
00432 std::string M_option_name;
00433
00435 std::vector< ParamPtr > M_parameters;
00436
00438 std::map< std::string, ParamPtr > M_long_name_map;
00439
00441 std::map< std::string, ParamPtr > M_short_name_map;
00442
00443 public:
00444
00448 ParamMap()
00449 : M_registrar( *this )
00450 { }
00451
00456 explicit
00457 ParamMap( const std::string & option_name )
00458 : M_registrar( *this )
00459 , M_option_name( option_name )
00460 { }
00461
00465 ~ParamMap()
00466 { }
00467
00472 const
00473 std::string & optionName() const
00474 {
00475 return M_option_name;
00476 }
00477
00482 const
00483 std::vector< ParamPtr > & parameters() const
00484 {
00485 return M_parameters;
00486 }
00487
00492 const
00493 std::map< std::string, ParamPtr > & longNameMap() const
00494 {
00495 return M_long_name_map;
00496 }
00497
00502 const
00503 std::map< std::string, ParamPtr > & shortNameMap() const
00504 {
00505 return M_short_name_map;
00506 }
00507
00512 ParamMap & add( ParamMap & param_map );
00513
00518 Registrar & add()
00519 {
00520 return M_registrar;
00521 }
00522
00527 Registrar & add( ParamPtr param );
00528
00533 void remove( const std::string & long_name );
00534
00540 ParamPtr findLongName( const std::string & long_name );
00541
00547 ParamPtr findShortName( const std::string & short_name );
00548
00555 std::ostream & printHelp( std::ostream & os,
00556 const bool with_default = true ) const;
00557
00563 std::ostream & printValues( std::ostream & os ) const;
00564 };
00565
00566 }
00567
00568 #endif