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