ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/auterman/SusyScan/Limits/ConfigFile.h
Revision: 1.2
Committed: Sat Mar 12 07:22:08 2011 UTC (14 years, 2 months ago) by auterman
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +3 -1 lines
Log Message:
moriond limits 2011

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 auterman 1.2 : key(key_) {
147     std::cout<<"key:"<<key<<std::endl;
148     } };
149 auterman 1.1 };
150    
151    
152     /* static */
153     template<class T>
154     string ConfigFile::T_as_string( const T& t )
155     {
156     // Convert from a T to a string
157     // Type T must support << operator
158     std::ostringstream ost;
159     ost << t;
160     return ost.str();
161     }
162    
163    
164     /* static */
165     template<class T>
166     T ConfigFile::string_as_T( const string& s )
167     {
168     // Convert from a string to a T
169     // Type T must support >> operator
170     T t;
171     std::istringstream ist(s);
172     ist >> t;
173     return t;
174     }
175    
176    
177     /* static */
178     template<>
179     inline string ConfigFile::string_as_T<string>( const string& s )
180     {
181     // Convert from a string to a string
182     // In other words, do nothing
183     return s;
184     }
185    
186    
187     /* static */
188     template<>
189     inline bool ConfigFile::string_as_T<bool>( const string& s )
190     {
191     // Convert from a string to a bool
192     // Interpret "false", "F", "no", "n", "0" as false
193     // Interpret "true", "T", "yes", "y", "1", "-1", or anything else as true
194     bool b = true;
195     string sup = s;
196     for( string::iterator p = sup.begin(); p != sup.end(); ++p )
197     *p = toupper(*p); // make string all caps
198     if( sup==string("FALSE") || sup==string("F") ||
199     sup==string("NO") || sup==string("N") ||
200     sup==string("0") || sup==string("NONE") )
201     b = false;
202     return b;
203     }
204    
205    
206     template<class T>
207     T ConfigFile::read( const string& key ) const
208     {
209     // Read the value corresponding to key
210     mapci p = myContents.find(key);
211     if( p == myContents.end() ) throw key_not_found(key);
212     return string_as_T<T>( p->second );
213     }
214    
215    
216     template<class T>
217     T ConfigFile::read( const string& key, const T& value ) const
218     {
219     // Return the value corresponding to key or given default value
220     // if key is not found
221     mapci p = myContents.find(key);
222     if( p == myContents.end() ) return value;
223     return string_as_T<T>( p->second );
224     }
225    
226     // CTA -------------------------------------------------------------------
227     //template<class T>
228     //std::vector<T> ConfigFile::readvec( const string& key ) const
229     //{
230     // std::vector<int> t;
231     // t.push_back(0);
232     // t.push_back(3);
233     // return t;
234     //}
235     // CTA -------------------------------------------------------------------
236    
237     template<class T>
238     bool ConfigFile::readInto( T& var, const string& key ) const
239     {
240     // Get the value corresponding to key and store in var
241     // Return true if key is found
242     // Otherwise leave var untouched
243     mapci p = myContents.find(key);
244     bool found = ( p != myContents.end() );
245     if( found ) var = string_as_T<T>( p->second );
246     return found;
247     }
248    
249    
250     template<class T>
251     bool ConfigFile::readInto( T& var, const string& key, const T& value ) const
252     {
253     // Get the value corresponding to key and store in var
254     // Return true if key is found
255     // Otherwise set var to given default
256     mapci p = myContents.find(key);
257     bool found = ( p != myContents.end() );
258     if( found )
259     var = string_as_T<T>( p->second );
260     else
261     var = value;
262     return found;
263     }
264    
265    
266     template<class T>
267     void ConfigFile::add( string key, const T& value )
268     {
269     // Add a key with given value
270     string v = T_as_string( value );
271     trim(key);
272     trim(v);
273     myContents[key] = v;
274     return;
275     }
276    
277     #endif // CONFIGFILE_H
278    
279     // Release notes:
280     // v1.0 21 May 1999
281     // + First release
282     // + Template read() access only through non-member readConfigFile()
283     // + ConfigurationFileBool is only built-in helper class
284     //
285     // v2.0 3 May 2002
286     // + Shortened name from ConfigurationFile to ConfigFile
287     // + Implemented template member functions
288     // + Changed default comment separator from % to #
289     // + Enabled reading of multiple-line values
290     //
291     // v2.1 24 May 2004
292     // + Made template specializations inline to avoid compiler-dependent linkage
293     // + Allowed comments within multiple-line values
294     // + Enabled blank line termination for multiple-line values
295     // + Added optional sentry to detect end of configuration file
296     // + Rewrote messy trimWhitespace() function as elegant trim()