root/bdm/uibuilder.h @ 281

Revision 281, 5.9 kB (checked in by smidl, 15 years ago)

new version of mpf_test for TR2245

  • Property svn:eol-style set to native
Line 
1#ifndef UIBUILD
2#define UIBUILD
3
4#include <itpp/itbase.h>
5#include "stat/libBM.h"
6#include "libconfig/libconfig.h++"
7
8namespace bdm {
9
10using namespace libconfig;
11using namespace std;
12
13#define CHECK_UITYPE(S,Type) it_assert_debug(S.getType()==Setting::Type, string("Wrong input path \"")+string(S.getPath())+string("\""));
14#define UIREGISTER(UI) UI* UI##_global_instance = new UI();
15
16//!Standard catches for UIs, use as: catch UICATCH
17#define UICATCH  ( SettingTypeException e ) {it_error ( "Setting " +string ( e.getPath() ) +" is of incorrect Type" );} catch ( SettingNotFoundException e ) {it_error ( "Setting " + string ( e.getPath() ) +" was not found" );}
18
19////////// GLOBAL VAriables
20
21class UIbuilder;
22//! Internal structure mapping strings to UIBuilder objects
23typedef map<const string, const UIbuilder*> UImap;
24extern UImap __uimap__;
25
26class UIFile : public Config {
27public:
28        UIFile ( const char * fname ) :Config() {
29                try{Config::readFile ( fname );}
30                catch ( FileIOException f ) {it_error ( "File " + string ( fname ) + " not found" );}
31                catch ( ParseException& P ) {
32                        char msg[200];
33                        sprintf ( msg,"Error in file %s  on line %d.", fname, P.getLine() );
34                        it_error ( msg );
35                }
36        }
37};
38
39//! \name elem Elementary build functions
40//!@{
41
42//! construct itpp::vec from Setting of type Array
43inline vec getvec ( Setting& S ) {
44        CHECK_UITYPE ( S,TypeArray );
45        vec tmp;
46        tmp.set_size ( S.getLength() );
47        for ( int i=0;i<S.getLength();i++ ) {
48                switch ( S[i].getType() ) {
49                        case Setting::TypeFloat :
50                                tmp[i]=double ( S[i] );break;
51                        case Setting::TypeInt :
52                                tmp[i]=int ( S[i] );break;
53                        case Setting::TypeBoolean :
54                                tmp[i]=bool ( S[i] );break;
55                        default: it_error ( "libconfig error?" );
56                }
57        }
58        return tmp;
59};
60
61//! construct itpp::mat from Setting of type Array, number of columns must be given
62inline mat getmat ( Setting& S , int ncols ) {
63        CHECK_UITYPE ( S,TypeArray );
64        mat tmp;
65        int nrows=S.getLength() /ncols;
66        int r=0,c=0;
67        tmp.set_size ( nrows, ncols );
68        // Build matrix row-wise
69        for ( int i=0;i<S.getLength();i++ ) {
70                switch ( S[i].getType() ) {
71                        case Setting::TypeFloat :
72                                tmp ( r,c ) =double ( S[i] );break;
73                        case Setting::TypeInt :
74                                tmp ( r,c ) =int ( S[i] );break;
75                        case Setting::TypeBoolean :
76                                tmp ( r,c ) =bool ( S[i] );break;
77                        default: it_error ( "libconfig error?" );
78                }
79                c++; if ( c==ncols ) {c=0;r++;}
80        }
81        return tmp;
82};
83
84//! construct itpp::ivec from Setting of type Array
85
86inline ivec getivec ( Setting& S ) {
87        CHECK_UITYPE ( S,TypeArray );
88        ivec tmp;
89        tmp.set_size ( S.getLength() );
90        for ( int i=0;i<S.getLength();i++ ) {
91                switch ( S[i].getType() ) {
92                        case Setting::TypeFloat :
93                                tmp[i]=double ( S[i] );break;
94                        case Setting::TypeInt :
95                                tmp[i]=int ( S[i] );break;
96                        case Setting::TypeBoolean :
97                                tmp[i]=bool ( S[i] );break;
98                        default: it_error ( "libconfig error?" );
99                }
100        }
101        return tmp;
102};
103
104//! construct itpp::Array<string> from Setting of type Array
105
106inline Array<string> get_as ( Setting& S ) {
107        CHECK_UITYPE ( S,TypeArray );
108        Array<string> tmp;
109        tmp.set_size ( S.getLength() );
110        for ( int i=0;i<S.getLength();i++ ) {tmp ( i ) = ( const char* ) S[i];}
111        return tmp;
112};
113
114//!@}
115
116/*!\brief Builds computational object from a UserInfo structure
117
118Return value is a pointer to the created object (memory management issue?)
119*/
120class UIbuilder {
121protected:
122public:
123        //!Constructor needs to be run only once macro UIREGISTER
124        UIbuilder ( const string &typ ) {__uimap__.insert ( make_pair ( typ,this ) );}
125        //! Function building the computational object
126        virtual bdmroot* build ( Setting &S ) const =0;
127};
128
129/*! Recursive build of objects defined in external file
130
131\code
132{type="external";
133filename="my_file.cfg";       // name of file from which to read
134path="system.profile.[0]";    // Path in the external file
135};
136\endcode
137*/
138class UIexternal:public UIbuilder {
139public:
140        UIexternal() :UIbuilder ( "external" ) {}
141        bdmroot* build ( Setting &S ) const;
142};
143
144/*! Recursive build of objects defined in the same file
145
146\code
147{type="internal";
148path="system.profile.[0]";    // Path from the root
149};
150\endcode
151 */
152class UIinternal:public UIbuilder {
153public:
154        UIinternal() :UIbuilder ( "internal" ) {}
155        bdmroot* build ( Setting &S ) const;
156};
157
158//! [Debugging] Print values in current S to cout
159void UI_DBG ( Setting &S, const string &spc );
160
161//! Prototype of a UI builder. Return value is by the second argument since it type checking via \c dynamic_cast.
162template<class T>
163void UIbuild ( Setting &S, T* &ret ) {
164        CHECK_UITYPE ( S,TypeGroup );
165        // Check if field "type" is present, if not it is not a valid UI
166        it_assert_debug ( S.exists ( "type" ), string ( S.getPath() ) +" is not a valid UI!" );
167
168        const string typ=S["type"];
169        // Find "type" in list of registred UI builders
170        UImap::const_iterator iter = __uimap__.find ( typ );
171        if ( iter == __uimap__.end() ) {
172                it_error ( "UI of type \"" + typ + "\" is not registered!" );
173        }
174
175        //BUILD the result
176        try {
177                ret = dynamic_cast<T*> ( iter->second->build ( S ) );
178        }
179        catch UICATCH
180};
181
182//! Auxiliary function allowing recursivity in S (too complex, remove?)
183template<class T>
184void UIcall ( Setting &S, void ( *func ) ( Setting&, T ), T Tmp ) {
185        CHECK_UITYPE ( S,TypeGroup );
186        // Check if field "type" is present, if not it is not a valid UI
187        it_assert_debug ( S.exists ( "type" ), string ( S.getPath() ) +" is not a valid UI!" );
188
189        const string typ=S["type"];
190        if ( typ=="internal" ) {
191                try {
192                        Setting* Stmp = &S;
193                        do {Stmp=& ( Stmp->getParent() );}
194                        while ( !Stmp->isRoot() );
195                        Setting& intS=Stmp->lookup ( ( const char* ) S["path"] );
196                        func ( intS, Tmp ); // <======== calling func
197                        return;
198                }
199                catch ( ... ) {
200                        it_error ( "Internal field " + string ( S.getPath() ) + " not valid" );
201                }
202        }
203        if ( typ=="external" ) {
204                UIFile C ( S["filename"] );
205                try {
206                        func ( C.lookup ( ( const char* ) S["path"] ), Tmp );
207                }
208                catch ( ... ) {
209                        it_error ( "External field " + string ( S.getPath() ) + " not valid" );
210                }
211                return;
212        }
213
214        // v======================= calling final func
215        func ( S, Tmp );
216};
217
218}
219#endif //UIBUILD
Note: See TracBrowser for help on using the browser.