Dune Core Modules (2.3.1)

parametertree.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_PARAMETERTREE_HH
4#define DUNE_PARAMETERTREE_HH
5
10#include <cstddef>
11#include <iostream>
12#include <istream>
13#include <iterator>
14#include <map>
15#include <ostream>
16#include <sstream>
17#include <string>
18#include <typeinfo>
19#include <vector>
20#include <algorithm>
21#include <cctype>
22
23#include <dune/common/array.hh>
27
28namespace Dune {
29
34 {
35 // class providing a single static parse() function, used by the
36 // generic get() method
37 template<typename T>
38 struct Parser;
39
40 public:
41
44 typedef std::vector<std::string> KeyVector;
45
49
50
58 bool hasKey(const std::string& key) const;
59
60
68 bool hasSub(const std::string& sub) const;
69
70
79 std::string& operator[] (const std::string& key);
80
81
91 const std::string& operator[] (const std::string& key) const;
92
93
101 void report(std::ostream& stream = std::cout,
102 const std::string& prefix = "") const;
103
104
110 ParameterTree& sub(const std::string& sub);
111
112
118 const ParameterTree& sub(const std::string& sub) const;
119
120
129 std::string get(const std::string& key, const std::string& defaultValue) const;
130
141 std::string get(const std::string& key, const char* defaultValue) const;
142
143
152 int get(const std::string& key, int defaultValue) const;
153
154
163 double get(const std::string& key, double defaultValue) const;
164
165
175 template<typename T>
176 T get(const std::string& key, const T& defaultValue) const {
177 if(hasKey(key))
178 return get<T>(key);
179 else
180 return defaultValue;
181 }
182
191 template <class T>
192 T get(const std::string& key) const {
193 if(not hasKey(key))
194 DUNE_THROW(RangeError, "Key '" << key << "' not found in parameter "
195 "file!");
196 try {
197 return Parser<T>::parse((*this)[key]);
198 }
199 catch(const RangeError&) {
200 DUNE_THROW(RangeError, "Cannot parse value \"" <<
201 (*this)[key] << "\" for key \"" << key << "\" as a " <<
202 className<T>());
203 }
204 }
205
213 const KeyVector& getValueKeys() const;
214
215
223 const KeyVector& getSubKeys() const;
224
225 protected:
226 KeyVector valueKeys;
227 KeyVector subKeys;
228
229 std::map<std::string, std::string> values;
230 std::map<std::string, ParameterTree> subs;
231 static std::string ltrim(const std::string& s);
232 static std::string rtrim(const std::string& s);
233 static std::vector<std::string> split(const std::string & s);
234
235 // parse into a fixed-size range of iterators
236 template<class Iterator>
237 static void parseRange(const std::string &str,
238 Iterator it, const Iterator &end)
239 {
240 typedef typename std::iterator_traits<Iterator>::value_type Value;
241 std::istringstream s(str);
242 std::size_t n = 0;
243 for(; it != end; ++it, ++n) {
244 s >> *it;
245 if(!s)
246 DUNE_THROW(RangeError, "Cannot parse value \"" << str << "\" as a "
247 "range of items of type " << className<Value>() << " "
248 "(" << n << " items were extracted successfully)");
249 }
250 Value dummy;
251 s >> dummy;
252 // now extraction should have failed, and eof should be set
253 if(not s.fail() or not s.eof())
254 DUNE_THROW(RangeError, "Cannot parse value \"" << str << "\" as a "
255 "range of " << n << " items of type "
256 << className<Value>() << " (more items than the range "
257 "can hold)");
258 }
259 };
260
261 template<typename T>
262 struct ParameterTree::Parser {
263 static T parse(const std::string& str) {
264 T val;
265 std::istringstream s(str);
266 s >> val;
267 if(!s)
268 DUNE_THROW(RangeError, "Cannot parse value \"" << str << "\" as a " <<
269 className<T>());
270 T dummy;
271 s >> dummy;
272 // now extraction should have failed, and eof should be set
273 if(not s.fail() or not s.eof())
274 DUNE_THROW(RangeError, "Cannot parse value \"" << str << "\" as a " <<
275 className<T>());
276 return val;
277 }
278 };
279
280 // "How do I convert a string into a wstring in C++?" "Why, that very simple
281 // son. You just need a these hundred lines of code."
282 // Instead im gonna restrict myself to string with charT=char here
283 template<typename traits, typename Allocator>
284 struct ParameterTree::Parser<std::basic_string<char, traits, Allocator> > {
285 static std::basic_string<char, traits, Allocator>
286 parse(const std::string& str) {
287 std::string trimmed = ltrim(rtrim(str));
288 return std::basic_string<char, traits, Allocator>(trimmed.begin(),
289 trimmed.end());
290 }
291 };
292
293 template<>
294 struct ParameterTree::Parser< bool > {
295 struct ToLower {
296 int operator()(int c)
297 {
298 return std::tolower(c);
299 }
300 };
301
302 static bool
303 parse(const std::string& str) {
304 std::string ret = str;
305
306 std::transform(ret.begin(), ret.end(), ret.begin(), ToLower());
307
308 if (ret == "yes" || ret == "true")
309 return true;
310
311 if (ret == "no" || ret == "false")
312 return false;
313
314 return (Parser<int>::parse(ret) != 0);
315 }
316 };
317
318 template<typename T, int n>
319 struct ParameterTree::Parser<FieldVector<T, n> > {
320 static FieldVector<T, n>
321 parse(const std::string& str) {
322 FieldVector<T, n> val;
323 parseRange(str, val.begin(), val.end());
324 return val;
325 }
326 };
327
328 template<typename T, std::size_t n>
329 struct ParameterTree::Parser<array<T, n> > {
330 static array<T, n>
331 parse(const std::string& str) {
332 array<T, n> val;
333 parseRange(str, val.begin(), val.end());
334 return val;
335 }
336 };
337
338 template<typename T, typename A>
339 struct ParameterTree::Parser<std::vector<T, A> > {
340 static std::vector<T, A>
341 parse(const std::string& str) {
342 std::vector<std::string> sub = split(str);
343 std::vector<T, A> vec;
344 for (unsigned int i=0; i<sub.size(); ++i) {
345 T val = ParameterTree::Parser<T>::parse(sub[i]);
346 vec.push_back(val);
347 }
348 return vec;
349 }
350 };
351
352} // end namespace Dune
353
354#endif // DUNE_PARAMETERTREE_HH
Fallback implementation of the std::array class (a static array)
Hierarchical structure of string parameters.
Definition: parametertree.hh:34
std::string get(const std::string &key, const std::string &defaultValue) const
get value as string
Definition: parametertree.cc:153
void report(std::ostream &stream=std::cout, const std::string &prefix="") const
print distinct substructure to stream
Definition: parametertree.cc:25
std::vector< std::string > KeyVector
storage for key lists
Definition: parametertree.hh:44
ParameterTree()
Create new empty ParameterTree.
Definition: parametertree.cc:22
std::string & operator[](const std::string &key)
get value reference for key
Definition: parametertree.cc:112
ParameterTree & sub(const std::string &sub)
get substructure by name
Definition: parametertree.cc:78
bool hasKey(const std::string &key) const
test for key
Definition: parametertree.cc:44
const KeyVector & getSubKeys() const
get substructure keys
Definition: parametertree.cc:226
T get(const std::string &key) const
Get value.
Definition: parametertree.hh:192
bool hasSub(const std::string &sub) const
test for substructure
Definition: parametertree.cc:61
T get(const std::string &key, const T &defaultValue) const
get value converted to a certain type
Definition: parametertree.hh:176
const KeyVector & getValueKeys() const
get value keys
Definition: parametertree.cc:221
Default exception class for range errors.
Definition: exceptions.hh:280
A free function to provide the demangled class name of a given object or type as a string.
A few common exception classes.
Implements a vector constructed from a given type representing a field and a compile-time given size.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:244
Dune namespace.
Definition: alignment.hh:14
STL namespace.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 12, 23:30, 2024)