Changeset 959
- Timestamp:
- 05/19/10 11:22:45 (15 years ago)
- Location:
- library/bdm
- Files:
-
- 4 modified
Legend:
- Unmodified
- Added
- Removed
-
library/bdm/base/bdmbase.h
r956 r959 296 296 RV concat ( const RV &rv1, const RV &rv2 ); 297 297 298 299 300 //! This class stores a details that will be logged to a logger 301 //! 302 //! This is only the first part of the whole declaration, which has to be however separated into 303 //! two different classes for allowing the compilation of source code. For more details 304 //! see logger::add_setting(...) method and mainly log_level_template<T>::template<class U> void store( const enum T::log_level_enums log_level_enum, const U data ) const 305 //! method. For the reason the second one is templated, it was necessary to declare this whole class. 306 template<class T> class log_level_intermediate : public log_level_base { 307 protected: 308 //! boolean flags related indicating which details will be logged to a logger 309 bitset<32> values; 310 311 //! default constructor is protected to prevent creating instances elsewhere than in log_level_template descendant class 312 log_level_intermediate( ) { 313 int len = names().length(); 314 ids.set_size( len ); 315 for( int i = 0; i<len; i++ ) 316 { 317 ids(i).set_size ( 1 ); 318 ids(i) = -1; 319 } 320 } 321 public: 322 //! a general utility transforming a comma-separated sequence of strings into an instance of Array<strings> 323 static Array<string> string2Array( const string &input ) 324 { 325 string result = input; 326 string::size_type loc; 327 while( loc = result.find( ',' ), loc != string::npos ) 328 result[loc] = ' '; 329 return Array<string>("{ " + result + " }" ); 330 } 331 332 //! this method adds new id to its proper position and return the name of this position 333 string store_id_and_give_name( enum T::log_level_enums const log_level_enum, int enum_subindex, int id ) { 334 if( ids(log_level_enum).length() <= enum_subindex ) 335 ids(log_level_enum).set_size( enum_subindex+1, true ); 336 ids(log_level_enum)(enum_subindex) = id; 337 338 // here we remove a "log" prefix from name, i.e., for instance it transforms "logevidence" to "evidence" 339 ostringstream stream; 340 string name_with_prefix = names()(log_level_enum); 341 string possible_log_prefix = name_with_prefix.substr(0,3); 342 if( possible_log_prefix == "log" ) 343 stream << name_with_prefix.substr(3,name_with_prefix.length()-3); 344 else 345 stream << name_with_prefix; 346 347 // add number to name only in the case there are more registered vectors with the same log_level_enum 348 if( ids(log_level_enum).length() > 1 ) 349 stream << "_" << enum_subindex; 350 351 return stream.str(); 352 } 353 354 //! string equivalents of the used enumerations which are filled with a help of #LOG_LEVEL macro within class T 355 const Array<string> &names() const 356 { 357 return T::log_level_names(); 358 } 359 360 //! read only operator for testing individual fields of log_level 361 //! 362 //! it is necessary to acces it with a proper enumeration type, thus this approach is type-safe 363 bool operator [] (const enum T::log_level_enums &log_level_enum ) const 364 { 365 return values[log_level_enum]; 366 } 367 368 //! operator for setting an individual field of log_level 369 //! 370 //! it is necessary to acces it with a proper enumeration type, thus this approach is type-safe 371 bitset<32>::reference operator [] (const enum T::log_level_enums &log_level_enum ) 372 { 373 return values[log_level_enum]; 374 } 375 }; 376 //UIREGISTER IS FORBIDDEN FOR THIS CLASS, AS IT SHOULD BE LOADED ONLY THROUGH THE SPECIALIZED UI::GET(...) METHOD 377 378 298 379 /*! 299 380 @brief Class for storing results (and semi-results) of an experiment … … 351 432 //! 352 433 //! passing the last parameter \c enum_subindex one can store multiple vectors in the position of one enum 353 template<class T> void add_vector ( log_level_ base<T> &log_level, enum T::log_level_enums const log_level_enum, const RV &rv, const string &prefix, int enum_subindex = 0 )434 template<class T> void add_vector ( log_level_intermediate<T> &log_level, enum T::log_level_enums const log_level_enum, const RV &rv, const string &prefix, int enum_subindex = 0 ) 354 435 { 355 436 if( !log_level.registered_logger ) … … 373 454 //! It also sets a pointer to logger or justify it is correctly assigned from previous call to this procedure 374 455 //! 375 //! To allow both arguments log_level and log_level_enum be templated, it was necessary to declare log_level_ base<T> class.456 //! To allow both arguments log_level and log_level_enum be templated, it was necessary to declare log_level_intermediate<T> class. 376 457 //! This way we check compatibility of the passed log_level and log_level_enum, which would be impossible using just log_level_base class 377 458 //! here. … … 379 460 //! 380 461 //! passing the last parameter \c enum_subindex one can store multiple settings in the position of one enum 381 template<class T> void add_setting ( log_level_ base<T> &log_level, enum T::log_level_enums const log_level_enum, const string &prefix, int enum_subindex = 0 ) {462 template<class T> void add_setting ( log_level_intermediate<T> &log_level, enum T::log_level_enums const log_level_enum, const string &prefix, int enum_subindex = 0 ) { 382 463 if( !log_level.registered_logger ) 383 464 log_level.registered_logger = this; … … 405 486 406 487 //! This class stores a details that will be logged to a logger 407 template<class T> class log_level_template : public log_level_base<T> { 408 protected: 409 //! boolean flags related indicating which details will be logged to a logger 410 bitset<32> values; 411 412 public: 413 414 //! read only operator for testing individual fields of log_level 415 //! 416 //! it is necessary to acces it with a proper enumeration type, thus this approach is type-safe 417 bool operator [] (const enum T::log_level_enums &log_level_enum ) const 418 { 419 return values[log_level_enum]; 420 } 421 422 //! operator for setting an individual field of log_level 423 //! 424 //! it is necessary to acces it with a proper enumeration type, thus this approach is type-safe 425 bitset<32>::reference operator [] (const enum T::log_level_enums &log_level_enum ) 426 { 427 return values[log_level_enum]; 428 } 488 template<class T> class log_level_template : public log_level_intermediate<T> { 489 public: 429 490 430 491 //! Set log_levels according to the Setting element … … 512 573 \ref ui 513 574 */ 514 #define LOG_LEVEL(classname,...) public: enum log_level_enums { __VA_ARGS__ }; log_level_template<classname> log_level; private: friend class log_level_ base<classname>; static const Array<string> &log_level_names() { static const Array<string> log_level_names = log_level_template<classname>::string2Array( #__VA_ARGS__ ); return log_level_names; }575 #define LOG_LEVEL(classname,...) public: enum log_level_enums { __VA_ARGS__ }; log_level_template<classname> log_level; private: friend class log_level_intermediate<classname>; static const Array<string> &log_level_names() { static const Array<string> log_level_names = log_level_template<classname>::string2Array( #__VA_ARGS__ ); return log_level_names; } 515 576 516 577 -
library/bdm/base/user_info.cpp
r952 r959 192 192 193 193 call_to_setting( instance, set ); 194 } 195 196 void UI::save ( const log_level_base &log_level, Setting &element ) { 197 assert_type ( element, Setting::TypeGroup ); 198 string name = "log_level"; 199 200 if( element.exists( name ) ) 201 assert_type ( element[name], Setting::TypeString ); 202 else 203 element.add ( name, Setting::TypeString ); 204 205 call_to_setting( log_level, element[name] ); 194 206 } 195 207 … … 286 298 } 287 299 288 void UI::from_setting ( root &instance, const Setting &element ) { 289 if (element.getType()==Setting::TypeString){ 290 const type_info *ti=&typeid(instance); 291 size_t strc=string(ti->name()).find("log_level_template"); 292 if (strc!=string::npos){ // loglevel 293 call_from_setting( instance, element ); 294 } else { 295 const SettingResolver link ( element ); 296 assert_type( link.result, Setting::TypeGroup ); 297 call_from_setting( instance, link.result); 298 } 299 }else{ 300 call_from_setting( instance, element ); 301 } 302 } 300 void UI::from_setting ( log_level_base &log_level, const Setting &element ) { 301 assert_type( element, Setting::TypeString ); 302 call_from_setting( log_level, element ); 303 } 304 305 void UI::from_setting ( root &instance, const Setting &element ) { 306 const SettingResolver link ( element ); 307 assert_type( link.result, Setting::TypeGroup ); 308 call_from_setting( instance, link.result); 309 } 303 310 304 311 void UI::from_setting ( mat& matrix, const Setting &element ) { -
library/bdm/base/user_info.h
r952 r959 319 319 //! method is necessary here to avoid the default call of "const SettingResolver link ( element );", 320 320 //! which would lead to erroneous behaviour in this case 321 // template<class T> static void from_setting ( log_level_base<T> &log_level, const Setting &element ) { 322 // assert_type( element, Setting::TypeString ); 323 // call_from_setting( log_level, element ); 324 // } 325 321 static void from_setting ( log_level_base &log_level, const Setting &element ); 326 322 //! This method converts a Setting into a dynamically allocated root descendant 327 323 template<class T> static void from_setting ( T* &instance, const Setting &element ) { … … 575 571 // possible that more instances of log_level_base (templated with different classes) 576 572 // can be stored in only one line in a configuration file 577 template<class T> static void save ( const log_level_base<T> &log_level, Setting &element ) { 578 assert_type ( element, Setting::TypeGroup ); 579 string name = "log_level"; 580 581 if( element.exists( name ) ) 582 assert_type ( element[name], Setting::TypeString ); 583 else 584 element.add ( name, Setting::TypeString ); 585 586 log_level.to_setting( element[name] ); 587 } 573 static void save ( const log_level_base &log_level, Setting &element ); 588 574 589 575 //!@} -
library/bdm/bdmroot.h
r950 r959 194 194 }; 195 195 196 //! This class stores the details which will be logged to a logger196 //! base class for all log_levels 197 197 //! 198 //! This is only the first part of the whole declaration, which has to be however separated into 199 //! two different classes for allowing the compilation of source code. For more details 200 //! see logger::add_setting(...) method and mainly log_level_template<T>::template<class U> void store( const enum T::log_level_enums log_level_enum, const U data ) const 201 //! method. For the reason the second one is templated, it was necessary to declare this whole class. 202 template<class T> class log_level_base : public root { 198 //! the existence of this class is forced by the necessity of passing log_levels to user_info methods, however, the main functionality 199 //! is located in \c log_level_template class 200 class log_level_base : public root { 203 201 private: 204 202 //! this is necessary to allow logger to set ids vector appropriately and also to set registered_logger 205 203 friend class logger; 206 207 208 //! this method adds new id to its proper position and return the name of this position209 string store_id_and_give_name( enum T::log_level_enums const log_level_enum, int enum_subindex, int id ) {210 if( ids(log_level_enum).length() <= enum_subindex )211 ids(log_level_enum).set_size( enum_subindex+1, true );212 ids(log_level_enum)(enum_subindex) = id;213 214 // here we remove a "log" prefix from name, i.e., for instance it transforms "logevidence" to "evidence"215 ostringstream stream;216 string name_with_prefix = names()(log_level_enum);217 string possible_log_prefix = name_with_prefix.substr(0,3);218 if( possible_log_prefix == "log" )219 stream << name_with_prefix.substr(3,name_with_prefix.length()-3);220 else221 stream << name_with_prefix;222 223 // add number to name only in the case there are more registered vectors with the same log_level_enum224 if( ids(log_level_enum).length() > 1 )225 stream << "_" << enum_subindex;226 227 return stream.str();228 }229 204 230 205 protected: … … 237 212 Vec<ivec> ids; 238 213 239 //! string equivalents of the used enumerations which are filled with a help of #LOG_LEVEL macro within class T240 const Array<string> &names() const241 {242 return T::log_level_names();243 }244 214 245 215 //! default constructor�which is intentionaly declared as protected 246 216 log_level_base( ) { 247 217 registered_logger = NULL; 248 int len = names().length();249 ids.set_size( len );250 for( int i = 0; i<len; i++ )251 {252 ids(i).set_size ( 1 );253 ids(i) = -1;254 }255 }256 257 public:258 //! a general utility transforming a comma-separated sequence of strings into an instance of Array<strings>259 static Array<string> string2Array( const string &input )260 {261 string result = input;262 string::size_type loc;263 while( loc = result.find( ',' ), loc != string::npos )264 result[loc] = ' ';265 return Array<string>("{ " + result + " }" );266 218 } 267 219 };