Show
Ignore:
Timestamp:
04/20/10 21:16:56 (14 years ago)
Author:
mido
Message:

patch of LOG LEVELS

Files:
1 modified

Legend:

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

    r907 r910  
    298298 
    299299//! This class stores a details that will be logged to a logger 
    300 template<class T> class log_level_template : public log_level_base { 
    301         //! this is necessary to allow logger to set ids vector appropriately and also to set registered_logger 
    302         friend class logger;  
    303  
    304         //! vector of log IDs - one element for each entry 
    305         ivec ids; 
    306  
    307         //! internal pointer to the logger to which this log_level is registered 
    308         //!  
    309         //! it is set to NULL at the beginning 
    310         logger * registered_logger; 
    311  
    312 public: 
    313         //! default constructor 
    314         log_level_template() { 
    315                 registered_logger = NULL; 
    316                 ids.set_size(  T::log_level_names().length() ); 
     300//! 
     301//! This is only the first part of the whole declaration, which has to be however separated into 
     302//! two different classes for allowing the compilation of source code. For more details 
     303//! 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 
     304//! method. For the reason the second one is templated, it was necessary to declare this whole class.  
     305template<class T> class log_level_intermediate : public log_level_base { 
     306public: 
     307        log_level_intermediate( ) { 
     308                ids.set_size( names().length() ); 
    317309                ids = -1; 
    318310        } 
    319  
    320         //! This method stores a vector to the proper place in registered logger  
    321         void store( const enum T::log_level_enums log_level_enum, const vec &vect ) const 
    322         { 
    323                 bdm_assert_debug( registered_logger != NULL, "You have to register instance to a logger first! Use root::log_register(...) method."); 
    324                 bdm_assert_debug( ids( log_level_enum ) >= 0, "This particular vector was not added to logger! Use logger::add_vector(...) method."); 
    325                 registered_logger->log_vector( ids( log_level_enum ), vect ); 
    326         } 
    327  
    328         //! This method stores a double to the proper place in registered logger  
    329         void store( const enum T::log_level_enums log_level_enum, const double &dbl ) const 
    330         { 
    331                 bdm_assert_debug( registered_logger != NULL, "You have to register instance to a logger first! See root::log_register(...) method."); 
    332                 bdm_assert_debug( ids( log_level_enum ) >= 0, "This particular double was not added to logger! Use logger::add_vector(...) method."); 
    333                 registered_logger->log_double( ids( log_level_enum ), dbl ); 
    334         } 
    335  
    336         //! This method stores a Setting obtained by call of UI::save( data, .. ) to the proper place in registered logger  
    337         template<class U> void store( const enum T::log_level_enums log_level_enum, const U data ) const 
    338         {                        
    339                 bdm_assert_debug( registered_logger != NULL, "You have to register instance to a logger first! See root::log_register(...) method."); 
    340                 bdm_assert_debug( ids( log_level_enum ) >= 0, "This particular vector was not added to logger! Use logger::add_setting(...) method."); 
    341                 registered_logger->log_setting( ids( log_level_enum ), data); 
    342         } 
    343  
    344311 
    345312        //! string equivalents of the used enumerations which are filled with a help of #LOG_LEVEL macro within class T 
     
    349316        } 
    350317 
    351         //! read only operator for testing  individual fields of log_level 
     318        //! read only operator for testing individual fields of log_level 
    352319        //! 
    353320        //! it is necessary to acces it with a proper enumeration type, thus this approach is type-safe 
     
    365332        } 
    366333}; 
    367  
    368 /*! 
    369   \def LOG_LEVEL(classname,...) 
    370   \brief Macro for defining a log_level attribute with a specific set of enumerations related to a specific class  
    371  
    372   This macro has to be called within a class declaration. Its argument \a classname has to correspond to that wrapping class. 
    373   This macro defines a log_level instance which can be modified either directly or by the means of #UI class. 
    374  
    375   One of the main purposes of this macro is to allow variability in using enumerations. By relating them to their names through 
    376   an array of strings, we are no more dependant on their precise ordering. What is more, we can add or remove any without harming  
    377   any applications which are using this library. 
    378  
    379   \todo Write a more detailed explanation including also examples 
    380  
    381   \ref ui 
    382 */ 
    383 #define LOG_LEVEL(classname,...) public: enum log_level_enums { __VA_ARGS__ }; log_level_template<classname> log_level; private: friend class log_level_template<classname>; static const Array<string> &log_level_names() { static const Array<string> log_level_names = log_level_base::string2Array( #__VA_ARGS__ ); return log_level_names; } 
    384334 
    385335 
     
    442392        //! It also sets a pointer to logger or justify it is correctly assigned from previous call to this procedure  
    443393        //! Entries with empty RV will be ignored  
    444         template<class T> void add_vector ( log_level_template<T> &log_level, enum T::log_level_enums const log_level_enum, const RV &rv, const string &prefix ) 
     394        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 ) 
    445395        { 
    446396                if( !log_level.registered_logger ) 
     
    448398                else 
    449399                        bdm_assert_debug ( log_level.registered_logger == this, "This log_level is already registered to another logger!"); 
    450  
    451400 
    452401                if ( rv._dsize() == 0 )  
     
    464413        //! 
    465414        //! It also sets a pointer to logger or justify it is correctly assigned from previous call to this procedure  
    466         template<class T> void add_setting ( log_level_template<T> &log_level, enum T::log_level_enums const log_level_enum,  const string &prefix ) { 
     415        //! 
     416        //! To allow both arguments log_level and log_level_enum be templated, it was necessary to declare log_level_intermediate<T> class. 
     417        //! This way we check compatibility of the passed log_level and log_level_enum, which would be impossible using just log_level_base class 
     418        //! here.  
     419        template<class T> void add_setting ( log_level_intermediate<T> &log_level, enum T::log_level_enums const log_level_enum,  const string &prefix ) { 
    467420                if( !log_level.registered_logger ) 
    468421                        log_level.registered_logger = this; 
     
    489442        virtual void init() {}; 
    490443}; 
     444 
     445//! This class stores a details that will be logged to a logger 
     446template<class T> class log_level_template : public log_level_intermediate<T> { 
     447public: 
     448        //! This method stores a vector to the proper place in registered logger  
     449        void store( const enum T::log_level_enums log_level_enum, const vec &vect ) const 
     450        { 
     451                bdm_assert_debug( registered_logger != NULL, "You have to register instance to a logger first! Use root::log_register(...) method."); 
     452                bdm_assert_debug( ids( log_level_enum ) >= 0, "This particular vector was not added to logger! Use logger::add_vector(...) method."); 
     453                registered_logger->log_vector( ids( log_level_enum ), vect ); 
     454        } 
     455 
     456        //! This method stores a double to the proper place in registered logger  
     457        void store( const enum T::log_level_enums log_level_enum, const double &dbl ) const 
     458        { 
     459                bdm_assert_debug( registered_logger != NULL, "You have to register instance to a logger first! See root::log_register(...) method."); 
     460                bdm_assert_debug( ids( log_level_enum ) >= 0, "This particular double was not added to logger! Use logger::add_vector(...) method."); 
     461                registered_logger->log_double( ids( log_level_enum ), dbl ); 
     462        } 
     463 
     464        //! This method stores a Setting obtained by call of UI::save( data, .. ) to the proper place in registered logger  
     465        //! 
     466        //! If this method was not templated, we could store whole body of this class in cpp file without explicitly touching registered_logger->log_setting(...) here. 
     467        //! (it would not be straightforward, though, still there are some enums which had to be converted into integers but it could be done without loosing type control) 
     468        //! This way, it would not be necessary to declare log_level_intermediate<T> class and we could declare log_level_template<T> 
     469        //! before the log_level class itself with a mere foroward declaration of log_level. In our case, however, touching of registered_logger->log_setting 
     470        //! implies that friend declaration is not enough and we are lost in a circle. And just by cutting this circle we obtains log_level_intermediate<T> class.  
     471        //! Howg.) 
     472        template<class U> void store( const enum T::log_level_enums log_level_enum, const U data ) const 
     473        {                        
     474                bdm_assert_debug( registered_logger != NULL, "You have to register instance to a logger first! See root::log_register(...) method."); 
     475                bdm_assert_debug( ids( log_level_enum ) >= 0, "This particular vector was not added to logger! Use logger::add_setting(...) method."); 
     476                registered_logger->log_setting( ids( log_level_enum ), data); 
     477        } 
     478}; 
     479 
     480/*! 
     481  \def LOG_LEVEL(classname,...) 
     482  \brief Macro for defining a log_level attribute with a specific set of enumerations related to a specific class  
     483 
     484  This macro has to be called within a class declaration. Its argument \a classname has to correspond to that wrapping class. 
     485  This macro defines a log_level instance which can be modified either directly or by the means of #UI class. 
     486 
     487  One of the main purposes of this macro is to allow variability in using enumerations. By relating them to their names through 
     488  an array of strings, we are no more dependant on their precise ordering. What is more, we can add or remove any without harming  
     489  any applications which are using this library. 
     490 
     491  \todo Write a more detailed explanation including also examples 
     492 
     493  \ref ui 
     494*/ 
     495#define LOG_LEVEL(classname,...) public: enum log_level_enums { __VA_ARGS__ }; log_level_template<classname> log_level; private: friend class log_level_template<classname>; friend class log_level_intermediate<classname>; static const Array<string> &log_level_names() { static const Array<string> log_level_names = log_level_base::string2Array( #__VA_ARGS__ ); return log_level_names; } 
     496 
    491497 
    492498//! Class representing function \f$f(x)\f$ of variable \f$x\f$ represented by \c rv