00001 #ifndef NMWR_GB_READ_PARAMETERS_H 00002 #define NMWR_GB_READ_PARAMETERS_H 00003 00004 00005 00006 // $LICENSE 00007 00008 00010 // 00011 // read-parameters.h -- a simple class for reading some 00012 // parameter values from a stream 00013 // 00014 // 00015 // purpose: say you have a number of numerical parameters 00016 // declared in your program, i.e. an instance of a class for which you want 00017 // sometimes to read in a different value than the predefined one. 00018 // Then you could set up a huge parameter file which is scanned 00019 // at startup time and where you give a value for each variable 00020 // you want to be able to change sometimes. This is very errorprone, 00021 // because you have to remember the ordering of the variables, 00022 // the parameter file is not well readable (you cannot associate 00023 // values with variables) and is larger then it has to be. 00024 // 00025 // A better solution is the following: You give an unique name ( a string) 00026 // to every variable you declare and want to be changeable. The parameterfile 00027 // then contains only the names and values of the variables that are really 00028 // subject to changes, the ordering does not matter, and you may easily 00029 // read your parameter files. The only thing you have to do is to define 00030 // operator >> for each class type you want to read in. 00031 // The class that achieves this is MutableVars: you add the names and 00032 // references to a variable you want to be <<mutable>>, and then you 00033 // may read in parameter files. How does this look like in a piece of code? 00034 // 00035 // MutableVars MV; // define one instance of the bookkeeping class 00036 // ... 00037 // double x; 00038 // myclass A; // a variable of some class readable with >> A 00039 // AddVar(MV, "x",x); // add x to database 00040 // AddVar(MV, "A",A); // add A to database 00041 // ... 00042 // MV.ReadValues(param_file); // read a parameter file 00043 // ... 00044 // 00045 // In the parameter file, you may (but do not have to!!) write the 00046 // following: 00047 // 00048 // x 0.123456 00049 // ... 00050 // A <data of A> 00051 // 00052 // where <data of A> is what you would use when you want to read A 00053 // directly: cin >> A; 00054 // 00056 00057 #include <string> 00058 #include <iostream.h> 00059 #include <map> // STL 00060 00061 #include "IO/mutator.h" 00062 00063 00064 // this is basically a dictionary that maps strings 00065 // to placeholders for a variable reference. 00066 // pointers to the abstract base class are used in order to profit 00067 // from polymorphism (derived classes are automatically 00068 // generated via templates in class TypedMutator). 00069 00070 class string_table_1: public std::map<std::string, Mutator*, std::less<std::string> > { 00071 public: 00072 string_table_1() {} 00073 }; 00074 00075 //class string_table_1; 00076 class string_list; 00077 class Mutator; 00078 00079 class MutableVars { 00080 private: 00081 typedef string_table_1 table_type; 00082 typedef table_type::const_iterator const_iterator; 00083 00084 table_type* table; 00085 string_list* unrecognized; 00086 00087 // FORBIDDEN 00088 MutableVars(MutableVars const&); 00089 MutableVars& operator=(MutableVars const&); 00090 public: 00091 MutableVars(); 00092 ~MutableVars(); 00093 00094 void AddVariable(std::string const& name, Mutator* m); 00095 void AddVariable(char const* name, Mutator* m); 00096 void ReadVariable(std::istream& is); 00097 void ReadValues (std::istream& in); 00098 void PrintValues (std::ostream& out, 00099 std::string const& prefix = "", 00100 std::string const& sep = " ") const; 00101 bool HasUnrecognized() const; 00102 void PrintUnrecognized(std::ostream& out) const; 00103 00104 unsigned size() const; 00105 bool defined (std::string const& nm) const; 00106 Mutator* getMutator(std::string const& nm); 00107 00108 const_iterator begin() const { return table->begin();} 00109 const_iterator end() const { return table->end();} 00110 }; 00111 00112 00113 00114 00115 // this function is necessary, because MutableVars::AddVariable 00116 // (as a member function) is not (yet) allowed to be a template function 00117 00118 template<class T> 00119 inline void AddVar(MutableVars& MV, const std::string& name, T& v) 00120 { MV.AddVariable(name,GetMutator(v));} 00121 00122 00123 template<class T> 00124 inline void AddVar(MutableVars& MV, const char* name, T& v) 00125 { AddVar(MV,string(name),v);} 00126 00127 00128 #endif