ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/auterman/SusyScan/Limits/ConfigFile.h
Revision: 1.1.1.1 (vendor branch)
Committed: Wed Jan 26 14:37:51 2011 UTC (14 years, 3 months ago) by auterman
Content type: text/plain
Branch: Limits
CVS Tags: start
Changes since 1.1: +0 -0 lines
Log Message:
Limt calculation code

File Contents

# User Rev Content
1 auterman 1.1 // ConfigFile.h
2     // Class for reading named values from configuration files
3     // Richard J. Wagner v2.1 24 May 2004 wagnerr@umich.edu
4    
5     // Copyright (c) 2004 Richard J. Wagner
6     //
7     // Permission is hereby granted, free of charge, to any person obtaining a copy
8     // of this software and associated documentation files (the "Software"), to
9     // deal in the Software without restriction, including without limitation the
10     // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11     // sell copies of the Software, and to permit persons to whom the Software is
12     // furnished to do so, subject to the following conditions:
13     //
14     // The above copyright notice and this permission notice shall be included in
15     // all copies or substantial portions of the Software.
16     //
17     // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18     // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19     // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20     // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21     // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22     // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23     // IN THE SOFTWARE.
24    
25     // Typical usage
26     // -------------
27     //
28     // Given a configuration file "settings.inp":
29     // atoms = 25
30     // length = 8.0 # nanometers
31     // name = Reece Surcher
32     //
33     // Named values are read in various ways, with or without default values:
34     // ConfigFile config( "settings.inp" );
35     // int atoms = config.read<int>( "atoms" );
36     // double length = config.read( "length", 10.0 );
37     // string author, title;
38     // config.readInto( author, "name" );
39     // config.readInto( title, "title", string("Untitled") );
40     //
41     // See file example.cpp for more examples.
42    
43     #ifndef CONFIGFILE_H
44     #define CONFIGFILE_H
45    
46     #include <string>
47     #include <map>
48     #include <iostream>
49     #include <fstream>
50     #include <sstream>
51     #include <vector>
52     #include <cassert>
53    
54     using std::string;
55    
56    
57     template<class datatype> class bag_of : public std::vector<datatype> {
58     public:
59     bag_of(std::string s = "");
60     };
61    
62     template<class datatype> bag_of<datatype>::bag_of(std::string s)
63     : std::vector<datatype>::vector() {
64     // constructor
65     if(s.length()) {
66     std::stringstream ss(s);
67     datatype buffer;
68     while (!ss.eof()) {
69     ss >> buffer;
70     this->push_back(buffer);
71     //do not read more numbers than characters in strint
72     //this can happen with bag_of<double> and string "0.0."
73     assert(this->size() <= s.length());
74     }
75     }
76     }
77    
78     class bag_of_string : public std::vector<std::string> {
79     public:
80     bag_of_string(std::string s = "null;");
81     };
82    
83    
84     class ConfigFile {
85     // Data
86     protected:
87     string myDelimiter; // separator between key and value
88     string myComment; // separator between value and comments
89     string mySentry; // optional string to signal end of file
90     std::map<string,string> myContents; // extracted keys and values
91    
92     typedef std::map<string,string>::iterator mapi;
93     typedef std::map<string,string>::const_iterator mapci;
94    
95     // Methods
96     public:
97     ConfigFile( string filename,
98     string delimiter = "=",
99     string comment = "#",
100     string sentry = "EndConfigFile" );
101     ConfigFile();
102    
103     // Search for key and read value or optional default value
104     template<class T> T read( const string& key ) const; // call as read<T>
105     template<class T> T read( const string& key, const T& value ) const;
106     template<class T> bool readInto( T& var, const string& key ) const;
107     template<class T> bool readInto( T& var, const string& key, const T& value ) const;
108    
109     // template<class T> std::vector<T> readvec( const string& key ) const;
110    
111     // Modify keys and values
112     template<class T> void add( string key, const T& value );
113     void remove( const string& key );
114    
115     // Check whether key exists in configuration
116     bool keyExists( const string& key ) const;
117    
118     // Check or change configuration syntax
119     string getDelimiter() const { return myDelimiter; }
120     string getComment() const { return myComment; }
121     string getSentry() const { return mySentry; }
122     string setDelimiter( const string& s )
123     { string old = myDelimiter; myDelimiter = s; return old; }
124     string setComment( const string& s )
125     { string old = myComment; myComment = s; return old; }
126    
127     // Write or read configuration
128     friend std::ostream& operator<<( std::ostream& os, const ConfigFile& cf );
129     friend std::istream& operator>>( std::istream& is, ConfigFile& cf );
130    
131     protected:
132     template<class T> static string T_as_string( const T& t );
133     template<class T> static T string_as_T( const string& s );
134     static void trim( string& s );
135    
136    
137     // Exception types
138     public:
139     struct file_not_found {
140     string filename;
141     file_not_found( const string& filename_ = string() )
142     : filename(filename_) {} };
143     struct key_not_found { // thrown only by T read(key) variant of read()
144     string key;
145     key_not_found( const string& key_ = string() )
146     : key(key_) {} };
147     };
148    
149    
150     /* static */
151     template<class T>
152     string ConfigFile::T_as_string( const T& t )
153     {
154     // Convert from a T to a string
155     // Type T must support << operator
156     std::ostringstream ost;
157     ost << t;
158     return ost.str();
159     }
160    
161    
162     /* static */
163     template<class T>
164     T ConfigFile::string_as_T( const string& s )
165     {
166     // Convert from a string to a T
167     // Type T must support >> operator
168     T t;
169     std::istringstream ist(s);
170     ist >> t;
171     return t;
172     }
173    
174    
175     /* static */
176     template<>
177     inline string ConfigFile::string_as_T<string>( const string& s )
178     {
179     // Convert from a string to a string
180     // In other words, do nothing
181     return s;
182     }
183    
184    
185     /* static */
186     template<>
187     inline bool ConfigFile::string_as_T<bool>( const string& s )
188     {
189     // Convert from a string to a bool
190     // Interpret "false", "F", "no", "n", "0" as false
191     // Interpret "true", "T", "yes", "y", "1", "-1", or anything else as true
192     bool b = true;
193     string sup = s;
194     for( string::iterator p = sup.begin(); p != sup.end(); ++p )
195     *p = toupper(*p); // make string all caps
196     if( sup==string("FALSE") || sup==string("F") ||
197     sup==string("NO") || sup==string("N") ||
198     sup==string("0") || sup==string("NONE") )
199     b = false;
200     return b;
201     }
202    
203    
204     template<class T>
205     T ConfigFile::read( const string& key ) const
206     {
207     // Read the value corresponding to key
208     mapci p = myContents.find(key);
209     if( p == myContents.end() ) throw key_not_found(key);
210     return string_as_T<T>( p->second );
211     }
212    
213    
214     template<class T>
215     T ConfigFile::read( const string& key, const T& value ) const
216     {
217     // Return the value corresponding to key or given default value
218     // if key is not found
219     mapci p = myContents.find(key);
220     if( p == myContents.end() ) return value;
221     return string_as_T<T>( p->second );
222     }
223    
224     // CTA -------------------------------------------------------------------
225     //template<class T>
226     //std::vector<T> ConfigFile::readvec( const string& key ) const
227     //{
228     // std::vector<int> t;
229     // t.push_back(0);
230     // t.push_back(3);
231     // return t;
232     //}
233     // CTA -------------------------------------------------------------------
234    
235     template<class T>
236     bool ConfigFile::readInto( T& var, const string& key ) const
237     {
238     // Get the value corresponding to key and store in var
239     // Return true if key is found
240     // Otherwise leave var untouched
241     mapci p = myContents.find(key);
242     bool found = ( p != myContents.end() );
243     if( found ) var = string_as_T<T>( p->second );
244     return found;
245     }
246    
247    
248     template<class T>
249     bool ConfigFile::readInto( T& var, const string& key, const T& value ) const
250     {
251     // Get the value corresponding to key and store in var
252     // Return true if key is found
253     // Otherwise set var to given default
254     mapci p = myContents.find(key);
255     bool found = ( p != myContents.end() );
256     if( found )
257     var = string_as_T<T>( p->second );
258     else
259     var = value;
260     return found;
261     }
262    
263    
264     template<class T>
265     void ConfigFile::add( string key, const T& value )
266     {
267     // Add a key with given value
268     string v = T_as_string( value );
269     trim(key);
270     trim(v);
271     myContents[key] = v;
272     return;
273     }
274    
275     #endif // CONFIGFILE_H
276    
277     // Release notes:
278     // v1.0 21 May 1999
279     // + First release
280     // + Template read() access only through non-member readConfigFile()
281     // + ConfigurationFileBool is only built-in helper class
282     //
283     // v2.0 3 May 2002
284     // + Shortened name from ConfigurationFile to ConfigFile
285     // + Implemented template member functions
286     // + Changed default comment separator from % to #
287     // + Enabled reading of multiple-line values
288     //
289     // v2.1 24 May 2004
290     // + Made template specializations inline to avoid compiler-dependent linkage
291     // + Allowed comments within multiple-line values
292     // + Enabled blank line termination for multiple-line values
293     // + Added optional sentry to detect end of configuration file
294     // + Rewrote messy trimWhitespace() function as elegant trim()