Changeset 959

Show
Ignore:
Timestamp:
05/19/10 11:22:45 (14 years ago)
Author:
mido
Message:

another patch of UI AND L_Levels

Location:
library/bdm
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • library/bdm/base/bdmbase.h

    r956 r959  
    296296RV concat ( const RV &rv1, const RV &rv2 ); 
    297297 
     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.  
     306template<class T> class log_level_intermediate : public log_level_base { 
     307protected: 
     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        } 
     321public: 
     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 
    298379/*! 
    299380@brief Class for storing results (and semi-results) of an experiment 
     
    351432        //!  
    352433        //! 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 ) 
    354435        { 
    355436                if( !log_level.registered_logger ) 
     
    373454        //! It also sets a pointer to logger or justify it is correctly assigned from previous call to this procedure  
    374455        //! 
    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. 
    376457        //! This way we check compatibility of the passed log_level and log_level_enum, which would be impossible using just log_level_base class 
    377458        //! here.  
     
    379460        //! 
    380461        //! 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 ) { 
    382463                if( !log_level.registered_logger ) 
    383464                        log_level.registered_logger = this; 
     
    405486 
    406487//! 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         } 
     488template<class T> class log_level_template : public log_level_intermediate<T> { 
     489public: 
    429490 
    430491        //! Set log_levels according to the Setting element 
     
    512573  \ref ui 
    513574*/ 
    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; } 
    515576 
    516577 
  • library/bdm/base/user_info.cpp

    r952 r959  
    192192 
    193193        call_to_setting( instance, set ); 
     194} 
     195 
     196void 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] ); 
    194206} 
    195207 
     
    286298} 
    287299 
    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         } 
     300void 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 
     305void 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} 
    303310 
    304311void UI::from_setting ( mat& matrix, const Setting &element ) { 
  • library/bdm/base/user_info.h

    r952 r959  
    319319        //! method is necessary here to avoid the default call of "const SettingResolver link ( element );",  
    320320        //! 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 ); 
    326322        //! This method converts a Setting into a dynamically allocated root descendant 
    327323        template<class T> static void from_setting ( T* &instance, const Setting &element ) { 
     
    575571        // possible that more instances of log_level_base  (templated with different classes) 
    576572        // 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 ); 
    588574 
    589575        //!@} 
  • library/bdm/bdmroot.h

    r950 r959  
    194194}; 
    195195 
    196 //! This class stores the details which will be logged to a logger 
     196//! base class for all log_levels 
    197197//! 
    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 
     200class log_level_base : public root { 
    203201private: 
    204202        //! this is necessary to allow logger to set ids vector appropriately and also to set registered_logger 
    205203        friend class logger;  
    206  
    207  
    208         //! this method adds new id to its proper position and return the name of this position 
    209         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                 else  
    221                         stream << name_with_prefix; 
    222  
    223                 // add number to name only in the case there are more registered vectors with the same log_level_enum 
    224                 if( ids(log_level_enum).length() > 1 ) 
    225                         stream << "_" << enum_subindex; 
    226                  
    227                 return stream.str(); 
    228         } 
    229204 
    230205protected: 
     
    237212        Vec<ivec> ids; 
    238213 
    239         //! string equivalents of the used enumerations which are filled with a help of #LOG_LEVEL macro within class T 
    240         const Array<string> &names() const 
    241         { 
    242                 return T::log_level_names(); 
    243         } 
    244214 
    245215        //! default constructor�which is intentionaly declared as protected 
    246216        log_level_base( ) { 
    247217                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 + " }" ); 
    266218        } 
    267219};