- Home
- About DUNE
- Download
- Documentation
- Community
- Development
00001 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 00002 // vi: set et ts=8 sw=2 sts=2: 00003 #ifndef DUNE_PARAMETERTREE_HH 00004 #define DUNE_PARAMETERTREE_HH 00005 00006 #include <cstddef> 00007 #include <iostream> 00008 #include <istream> 00009 #include <iterator> 00010 #include <map> 00011 #include <ostream> 00012 #include <sstream> 00013 #include <string> 00014 #include <typeinfo> 00015 #include <vector> 00016 00017 #include <dune/common/array.hh> 00018 #include <dune/common/exceptions.hh> 00019 #include <dune/common/fvector.hh> 00020 #include <dune/common/classname.hh> 00021 00022 namespace Dune { 00023 00027 class ParameterTree 00028 { 00029 // class providing a single static parse() function, used by the 00030 // generic get() method 00031 template<typename T> 00032 struct Parser; 00033 00034 public: 00035 00036 typedef std::vector<std::string> KeyVector; 00037 00040 ParameterTree(); 00041 00042 00050 bool hasKey(const std::string& key) const; 00051 00052 00060 bool hasSub(const std::string& sub) const; 00061 00062 00071 std::string& operator[] (const std::string& key); 00072 00073 00083 const std::string& operator[] (const std::string& key) const; 00084 00085 00093 void report(std::ostream& stream = std::cout, 00094 const std::string& prefix = "") const; 00095 00096 00102 ParameterTree& sub(const std::string& sub); 00103 00104 00110 const ParameterTree& sub(const std::string& sub) const; 00111 00112 00121 std::string get(const std::string& key, const std::string& defaultValue) const; 00122 00133 std::string get(const std::string& key, const char* defaultValue) const; 00134 00135 00144 int get(const std::string& key, int defaultValue) const; 00145 00146 00155 double get(const std::string& key, double defaultValue) const; 00156 00157 00167 template<typename T> 00168 T get(const std::string& key, const T& defaultValue) const { 00169 if(hasKey(key)) 00170 return get<T>(key); 00171 else 00172 return defaultValue; 00173 } 00174 00183 template <class T> 00184 T get(const std::string& key) const { 00185 if(not hasKey(key)) 00186 DUNE_THROW(RangeError, "Key '" << key << "' not found in parameter " 00187 "file!"); 00188 try { 00189 return Parser<T>::parse((*this)[key]); 00190 } 00191 catch(const RangeError&) { 00192 DUNE_THROW(RangeError, "Cannot parse value \"" << 00193 (*this)[key] << "\" for key \"" << key << "\" as a " << 00194 className<T>()); 00195 } 00196 } 00197 00205 const KeyVector& getValueKeys() const; 00206 00207 00215 const KeyVector& getSubKeys() const; 00216 00217 protected: 00218 KeyVector valueKeys; 00219 KeyVector subKeys; 00220 00221 std::map<std::string, std::string> values; 00222 std::map<std::string, ParameterTree> subs; 00223 static std::string ltrim(const std::string& s); 00224 static std::string rtrim(const std::string& s); 00225 static std::vector<std::string> split(const std::string & s); 00226 00227 // parse into a fixed-size range of iterators 00228 template<class Iterator> 00229 static void parseRange(const std::string &str, 00230 Iterator it, const Iterator &end) 00231 { 00232 typedef typename std::iterator_traits<Iterator>::value_type Value; 00233 std::istringstream s(str); 00234 std::size_t n = 0; 00235 for(; it != end; ++it, ++n) { 00236 s >> *it; 00237 if(!s) 00238 DUNE_THROW(RangeError, "Cannot parse value \"" << str << "\" as a " 00239 "range of items of type " << className<Value>() << " " 00240 "(" << n << " items were extracted successfully)"); 00241 } 00242 Value dummy; 00243 s >> dummy; 00244 // now extraction should have failed, and eof should be set 00245 if(not s.fail() or not s.eof()) 00246 DUNE_THROW(RangeError, "Cannot parse value \"" << str << "\" as a " 00247 "range of " << n << " items of type " 00248 << className<Value>() << " (more items than the range " 00249 "can hold)"); 00250 } 00251 }; 00252 00253 template<typename T> 00254 struct ParameterTree::Parser { 00255 static T parse(const std::string& str) { 00256 T val; 00257 std::istringstream s(str); 00258 s >> val; 00259 if(!s) 00260 DUNE_THROW(RangeError, "Cannot parse value \"" << str << "\" as a " << 00261 className<T>()); 00262 T dummy; 00263 s >> dummy; 00264 // now extraction should have failed, and eof should be set 00265 if(not s.fail() or not s.eof()) 00266 DUNE_THROW(RangeError, "Cannot parse value \"" << str << "\" as a " << 00267 className<T>()); 00268 return val; 00269 } 00270 }; 00271 00272 // "How do I convert a string into a wstring in C++?" "Why, that very simple 00273 // son. You just need a these hundred lines of code." 00274 // Instead im gonna restrict myself to string with charT=char here 00275 template<typename traits, typename Allocator> 00276 struct ParameterTree::Parser<std::basic_string<char, traits, Allocator> > { 00277 static std::basic_string<char, traits, Allocator> 00278 parse(const std::string& str) { 00279 std::string trimmed = ltrim(rtrim(str)); 00280 return std::basic_string<char, traits, Allocator>(trimmed.begin(), 00281 trimmed.end()); 00282 } 00283 }; 00284 00285 template<> 00286 struct ParameterTree::Parser< bool > { 00287 struct ToLower { 00288 int operator()(int c) 00289 { 00290 return std::tolower(c); 00291 } 00292 }; 00293 00294 static bool 00295 parse(const std::string& str) { 00296 std::string ret = str; 00297 00298 std::transform(ret.begin(), ret.end(), ret.begin(), ToLower()); 00299 00300 if (ret == "yes" || ret == "true") 00301 return true; 00302 00303 if (ret == "no" || ret == "false") 00304 return false; 00305 00306 return (Parser<int>::parse(ret) != 0); 00307 } 00308 }; 00309 00310 template<typename T, int n> 00311 struct ParameterTree::Parser<FieldVector<T, n> > { 00312 static FieldVector<T, n> 00313 parse(const std::string& str) { 00314 FieldVector<T, n> val; 00315 parseRange(str, val.begin(), val.end()); 00316 return val; 00317 } 00318 }; 00319 00320 template<typename T, std::size_t n> 00321 struct ParameterTree::Parser<array<T, n> > { 00322 static array<T, n> 00323 parse(const std::string& str) { 00324 array<T, n> val; 00325 parseRange(str, val.begin(), val.end()); 00326 return val; 00327 } 00328 }; 00329 00330 template<typename T, typename A> 00331 struct ParameterTree::Parser<std::vector<T, A> > { 00332 static std::vector<T, A> 00333 parse(const std::string& str) { 00334 std::vector<std::string> sub = split(str); 00335 std::vector<T, A> vec; 00336 for (unsigned int i=0; i<sub.size(); ++i) { 00337 T val = ParameterTree::Parser<T>::parse(sub[i]); 00338 vec.push_back(val); 00339 } 00340 return vec; 00341 } 00342 }; 00343 00344 } // end namespace Dune 00345 00346 #endif // DUNE_PARAMETERTREE_HH
Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].