- Main Page
- Related Pages
- Modules
- Classes
- Files

- File List
- File Members

# user_info.h

    00001 #ifndef USER_INFO_H
    00002 #define USER_INFO_H
    00003
    00004 #include <stdio.h>
    00005 #include <string>
    00006 #include <typeinfo>
    00007 #include <map>
    00008
    00009 #include "libconfig/libconfig.h++"
    00010 #include "bdmroot.h"
    00011 #include "itpp/itbase.h"
    00012
    00013
    00014 using std::string;
    00015 using namespace std;
    00016 using namespace libconfig;
    00017
    00018 #ifndef BDMLIB
    00019 #define UIREGISTER(class_name) template<> const Particular_UI<class_name>& Particular_UI<class_name>::ui = Particular_UI<class_name>(#class_name)
    00020 #else
    00021 #define UIREGISTER(class_name)
    00022 #endif
    00023
    00024 #define ASSERT_UITYPE(S,Type) it_assert_debug(S.getType()==Setting::Type, string("Wrong setting type, see input path \"")+string(S.getPath())+string("\""))
    00025
    00026 namespace bdm
    00027 {
    00028 class UI_File : public Config
    00029 {
    00030 private:
    00031         const string file_name;
    00032
    00033 public:
    00035         UI_File();
    00036
    00038         UI_File( const string &file_name );
    00039
    00041         void save(const string &file_name);
    00042
    00043         operator Setting&();
    00044 };
    00045
    00077 class UI
    00078 {
    00079 private:
    00084         class Mapped_UI
    00085         {
    00086         private:
    00088                 typedef map< const string, const UI* const > String_To_UI_Map;
    00089
    00091                 typedef map< const type_info * const, const string > Type_Info_To_String_Map;
    00092
    00094                 static String_To_UI_Map& mapped_strings();
    00095
    00097                 static Type_Info_To_String_Map& mapped_type_infos();
    00098
    00099         public:
    00101                 static void add_class( const string &class_name, const type_info * const class_type_info, const UI* const ui );
    00102
    00104                 static const UI& retrieve_ui( const string &class_name );
    00105
    00107                 static const string& retrieve_class_name( const type_info* const class_type_info );
    00108         };
    00109
    00110
    00111
    00112
    00114         virtual bdmroot* new_instance() const = 0;
    00115
    00119         static const Setting& to_child_setting( const Setting &element, const int index );
    00120
    00121         static const Setting& to_child_setting( const Setting &element, const string &name );
    00122
    00123
    00126
    00128         static void from_setting( mat& matrix, const Setting &element );
    00130         static void from_setting( ivec &vector, const Setting &element );
    00131         // jednak kvuli pretypovani, apak taky proto, ze na string nefunguje link_expander..
    00132         static void from_setting( string &str, const Setting &element );
    00134
    00135         static void from_setting( vec &vector, const Setting &element );
    00136
    00137         template<class T> static void from_setting( T* &instance, const Setting &element )
    00138         {
    00139                 const SettingsResolver link_expander( element );
    00140                 const Setting &root = link_expander.root();
    00141
    00142                 ASSERT_UITYPE(root,TypeGroup);
    00143
    00144                 // we get a velue stored in the "class" attribute
    00145                 string class_name;
    00146                 if( !root.lookupValue( "class", class_name ) )
    00147                         ui_error( "the obligatory ""class"" identifier is missing", root );
    00148
    00149                 // and finally we find a UserInfo related to this type
    00150                 const UI& related_UI = Mapped_UI::retrieve_ui( class_name );
    00151
    00152                 bdmroot* typeless_instance = related_UI.new_instance();
    00153
    00154                 instance = NULL;
    00155                 try
    00156                 {
    00157                         instance = (T*) typeless_instance ;
    00158                 }
    00159                 catch(...)
    00160                 {
    00161                         it_error ( "UI error: class " + class_name + " is not a descendant of the desired output class. Try to call the UI::build function with a different type parameter." );
    00162                 }
    00163
    00164                 try
    00165                 {
    00166                         instance->from_setting( root );
    00167                 }
    00168                 catch(SettingException xcptn)
    00169                 {
    00170                         it_error ( "UI error: the method " + class_name + ".from_setting(Setting&) has thrown an exception when parsing the setting " + xcptn.getPath() + ". Try to correct this method." );
    00171                 }
    00172         }
    00173
    00174
    00176         // efektivne jen pro vect, mat a string, pro dalsi je nutne pridat from_setting metodu.. ale to asi necceme
    00177         template<class T> static void from_setting( Array<T> &array_to_load, const Setting &element )
    00178         {
    00179                 const SettingsResolver link_expander( element );
    00180                 const Setting &root = link_expander.root();
    00181
    00182                 ASSERT_UITYPE(root,TypeList);
    00183
    00184                 int len = root.getLength();
    00185                 array_to_load.set_length( len );
    00186                 if( len == 0 ) return;
    00187
    00188                 for( int i=0; i < len; i++ )
    00189                         from_setting( array_to_load(i), root[i] );
    00190         }
    00191
    00193
    00194
    00195         static void ui_error( string message, const Setting &element );
    00196
    00197 protected:
    00199         UI( const string& class_name, const type_info * const class_type_info )
    00200         {
    00201                 Mapped_UI::add_class( class_name, class_type_info, this );
    00202         }
    00203
    00205         virtual ~UI(){};
    00206
    00207 public:
    00211
    00212         // vraci true, kdyz to byl platny link, jinak false.. v pripade chyby konci it_errorem..
    00213         // do elementu vrati setting prislusny po rozbaleni linku, jinak ponecha beze zmeny
    00214         class SettingsResolver
    00215         {
    00216         private:
    00217                 UI_File *file;
    00218                 const Setting *result;
    00219
    00220         public:
    00221
    00222                 SettingsResolver( const Setting &potential_link );
    00223
    00224                 ~SettingsResolver();
    00225
    00226                 const Setting& root() const;
    00227         };
    00228
    00229
    00230
    00232         template<class T> static T* build( const Setting &element, const int index )
    00233         {
    00234                 T* instance;
    00235                 from_setting<T>( to_child_setting( element, index ) );
    00236                 return instance;
    00237         }
    00238
    00239         template<class T> static T* build( const Setting &element, const string &name )
    00240         {
    00241                 T* instance;
    00242                 from_setting<T>( instance, to_child_setting( element, name ) );
    00243                 return instance;
    00244         }
    00245
    00247         template<class T> static void get( T &instance, const Setting &element, const string &name )
    00248         {
    00249                 from_setting( instance, to_child_setting( element, name ) );
    00250         }
    00251
    00253         template<class T> static void get( T &instance, const Setting &element, const int index )
    00254         {
    00255                 from_setting( instance, to_child_setting( element, index ) );
    00256         }
    00257
    00259         template<class T> static void get( Array<T> &array_to_load, const Setting &element, const string &name )
    00260         {
    00261                 from_setting( array_to_load, to_child_setting( element, name ) );
    00262         }
    00263
    00265         template<class T> static void get( Array<T> &array_to_load, const Setting &element, const int index )
    00266         {
    00267                 from_setting( array_to_load, to_child_setting( element, index ) );
    00268         }
    00269
    00270         template< class T> static void save( const T * const instance, Setting &element, const string &name = "")
    00271         {
    00272                 Setting &root = (name == "") ? element.add( Setting::TypeGroup )
    00273                                                                          : element.add( name, Setting::TypeGroup );
    00274
    00275                 const string &class_name = Mapped_UI::retrieve_class_name( &typeid(*instance) );
    00276
    00277                 // add attribute "class"
    00278                 Setting &type = root.add( "class", Setting::TypeString );
    00279                 type = class_name;
    00280
    00281                 try
    00282                 {
    00283                         instance->to_setting( root );
    00284                 }
    00285                 catch(SettingException xcptn)
    00286                 {
    00287                         it_error ( "UI error: the method " + class_name + ".to_setting(Setting&) has thrown an exception when filling the setting " + xcptn.getPath() + ". Try to correct this method." );
    00288                 }
    00289         }
    00290
    00292         template<class T> static void save( const Array<T> &array_to_save, Setting &element, const string &name = "" )
    00293         {
    00294                 ASSERT_UITYPE(element,TypeGroup);
    00295                 Setting &list = (name == "") ? element.add( Setting::TypeList )
    00296                                                                          : element.add( name, Setting::TypeList );
    00297                 for( int i=0; i<array_to_save.length(); i++ )
    00298                         save( array_to_save(i), list );
    00299         }
    00300
    00301
    00303         static void save( const mat &matrix, Setting &element, const string &name = "" );
    00304
    00306         static void save( const ivec &vec, Setting &element, const string &name = "" );
    00307
    00308         static void save( const vec &vector, Setting &element, const string &name);
    00309
    00310         private:
    00312         static void save( const string &str, Setting &element);
    00313
    00314 };
    00315
    00316
    00322 template<typename T> class Particular_UI : private UI
    00323 {
    00324         public:
    00325
    00327         Particular_UI<T>( const string &class_name) : UI( class_name, &typeid(T) )
    00328         {       cout << class_name << endl;
    00329         };
    00330
    00333         static const Particular_UI<T>& ui;
    00334
    00335         bdmroot* new_instance() const
    00336         {
    00337                 return new T();
    00338         }
    00339 };
    00340
    00341
    00342
    00343
    00344 }
    00345
    00369 #endif // #ifndef USER_INFO_H