- 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
    00020 #define UIREGISTER(class_name) template<> const Particular_UI<class_name>& Particular_UI<class_name>::ui = Particular_UI<class_name>(#class_name)
    00021 #else
    00022 #define UIREGISTER(class_name)
    00023 #endif
    00024
    00025 #define ASSERT_UITYPE(S,Type) it_assert_debug(S.getType()==Setting::Type, string("Wrong setting type, see input path \"")+string(S.getPath())+string("\""))
    00026
    00027 namespace bdm
    00028 {
    00029 class UI_File : public Config
    00030 {
    00031 private:
    00032         const string file_name;
    00033
    00034 public:
    00036         UI_File();
    00037
    00039         UI_File( const string &file_name );
    00040
    00042         void save(const string &file_name);
    00043
    00044         operator Setting&();
    00045 };
    00046
    00078 class UI
    00079 {
    00080 private:
    00085         class Mapped_UI
    00086         {
    00087         private:
    00089                 typedef map< const string, const UI* const > String_To_UI_Map;
    00090
    00092                 typedef map< const type_info * const, const string > Type_Info_To_String_Map;
    00093
    00095                 static String_To_UI_Map& mapped_strings();
    00096
    00098                 static Type_Info_To_String_Map& mapped_type_infos();
    00099
    00100         public:
    00102                 static void add_class( const string &class_name, const type_info * const class_type_info, const UI* const ui );
    00103
    00105                 static const UI& retrieve_ui( const string &class_name );
    00106
    00108                 static const string& retrieve_class_name( const type_info* const class_type_info );
    00109         };
    00110
    00111
    00112
    00113
    00115         virtual bdmroot* new_instance() const = 0;
    00116
    00120         static const Setting& to_child_setting( const Setting &element, const int index );
    00121
    00122         static const Setting& to_child_setting( const Setting &element, const string &name );
    00123
    00124
    00127
    00129         static void from_setting( mat& matrix, const Setting &element );
    00131         static void from_setting( ivec &vector, const Setting &element );
    00132         // jednak kvuli pretypovani, apak taky proto, ze na string nefunguje link_expander..
    00133         static void from_setting( string &str, const Setting &element );
    00135
    00136         static void from_setting( vec &vector, const Setting &element );
    00137
    00138         template<class T> static void from_setting( T* &instance, const Setting &element )
    00139         {
    00140                 const SettingsResolver link_expander( element );
    00141                 const Setting &root = link_expander.root();
    00142
    00143                 ASSERT_UITYPE(root,TypeGroup);
    00144
    00145                 // we get a velue stored in the "class" attribute
    00146                 string class_name;
    00147                 if( !root.lookupValue( "class", class_name ) )
    00148                         ui_error( "the obligatory ""class"" identifier is missing", root );
    00149
    00150                 // and finally we find a UserInfo related to this type
    00151                 const UI& related_UI = Mapped_UI::retrieve_ui( class_name );
    00152
    00153                 bdmroot* typeless_instance = related_UI.new_instance();
    00154
    00155                 instance = NULL;
    00156                 try
    00157                 {
    00158                         instance = (T*) typeless_instance ;
    00159                 }
    00160                 catch(...)
    00161                 {
    00162                         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." );
    00163                 }
    00164
    00165                 try
    00166                 {
    00167                         instance->from_setting( root );
    00168                 }
    00169                 catch(SettingException xcptn)
    00170                 {
    00171                         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." );
    00172                 }
    00173         }
    00174
    00175
    00177         // efektivne jen pro vect, mat a string, pro dalsi je nutne pridat from_setting metodu.. ale to asi necceme
    00178         template<class T> static void from_setting( Array<T> &array_to_load, const Setting &element )
    00179         {
    00180                 const SettingsResolver link_expander( element );
    00181                 const Setting &root = link_expander.root();
    00182
    00183                 ASSERT_UITYPE(root,TypeList);
    00184
    00185                 int len = root.getLength();
    00186                 array_to_load.set_length( len );
    00187                 if( len == 0 ) return;
    00188
    00189                 for( int i=0; i < len; i++ )
    00190                         from_setting( array_to_load(i), root[i] );
    00191         }
    00192
    00194
    00195
    00196         static void ui_error( string message, const Setting &element );
    00197
    00198 protected:
    00200         UI( const string& class_name, const type_info * const class_type_info )
    00201         {
    00202                 Mapped_UI::add_class( class_name, class_type_info, this );
    00203         }
    00204
    00206         virtual ~UI(){};
    00207
    00208 public:
    00212
    00213         // vraci true, kdyz to byl platny link, jinak false.. v pripade chyby konci it_errorem..
    00214         // do elementu vrati setting prislusny po rozbaleni linku, jinak ponecha beze zmeny
    00215         class SettingsResolver
    00216         {
    00217         private:
    00218                 UI_File *file;
    00219                 const Setting *result;
    00220
    00221         public:
    00222
    00223                 SettingsResolver( const Setting &potential_link );
    00224
    00225                 ~SettingsResolver();
    00226
    00227                 const Setting& root() const;
    00228         };
    00229
    00230
    00231
    00233         template<class T> static T* build( const Setting &element, const int index )
    00234         {
    00235                 T* instance;
    00236                 from_setting<T>( to_child_setting( element, index ) );
    00237                 return instance;
    00238         }
    00239
    00240         template<class T> static T* build( const Setting &element, const string &name )
    00241         {
    00242                 T* instance;
    00243                 from_setting<T>( instance, to_child_setting( element, name ) );
    00244                 return instance;
    00245         }
    00246
    00248         template<class T> static void get( T &instance, const Setting &element, const string &name )
    00249         {
    00250                 from_setting( instance, to_child_setting( element, name ) );
    00251         }
    00252
    00254         template<class T> static void get( T &instance, const Setting &element, const int index )
    00255         {
    00256                 from_setting( instance, to_child_setting( element, index ) );
    00257         }
    00258
    00260         template<class T> static void get( Array<T> &array_to_load, const Setting &element, const string &name )
    00261         {
    00262                 from_setting( array_to_load, to_child_setting( element, name ) );
    00263         }
    00264
    00266         template<class T> static void get( Array<T> &array_to_load, const Setting &element, const int index )
    00267         {
    00268                 from_setting( array_to_load, to_child_setting( element, index ) );
    00269         }
    00270
    00271         template< class T> static void save( const T * const instance, Setting &element, const string &name = "")
    00272         {
    00273                 Setting &root = (name == "") ? element.add( Setting::TypeGroup )
    00274                                                                          : element.add( name, Setting::TypeGroup );
    00275
    00276                 const string &class_name = Mapped_UI::retrieve_class_name( &typeid(*instance) );
    00277
    00278                 // add attribute "class"
    00279                 Setting &type = root.add( "class", Setting::TypeString );
    00280                 type = class_name;
    00281
    00282                 try
    00283                 {
    00284                         instance->to_setting( root );
    00285                 }
    00286                 catch(SettingException xcptn)
    00287                 {
    00288                         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." );
    00289                 }
    00290         }
    00291
    00293         template<class T> static void save( const Array<T> &array_to_save, Setting &element, const string &name = "" )
    00294         {
    00295                 ASSERT_UITYPE(element,TypeGroup);
    00296                 Setting &list = (name == "") ? element.add( Setting::TypeList )
    00297                                                                          : element.add( name, Setting::TypeList );
    00298                 for( int i=0; i<array_to_save.length(); i++ )
    00299                         save( array_to_save(i), list );
    00300         }
    00301
    00302
    00304         static void save( const mat &matrix, Setting &element, const string &name = "" );
    00305
    00307         static void save( const ivec &vec, Setting &element, const string &name = "" );
    00308
    00309         static void save( const vec &vector, Setting &element, const string &name);
    00310
    00311         private:
    00313         static void save( const string &str, Setting &element);
    00314
    00315 };
    00316
    00317
    00323 template<typename T> class Particular_UI : private UI
    00324 {
    00325         public:
    00326
    00328         Particular_UI<T>( const string &class_name) : UI( class_name, &typeid(T) )
    00329         {       cout << class_name << endl;
    00330         };
    00331
    00334         static const Particular_UI<T>& ui;
    00335
    00336         bdmroot* new_instance() const
    00337         {
    00338                 return new T();
    00339         }
    00340 };
    00341
    00342
    00343
    00344
    00345 }
    00346
    00370 #endif // #ifndef USER_INFO_H