dune-common  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>
25 #include <dune/common/fvector.hh>
26 #include <dune/common/classname.hh>
27 
28 namespace 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 
48  ParameterTree();
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:
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
static std::string ltrim(const std::string &s)
Definition: parametertree.cc:187
int operator()(int c)
Definition: parametertree.hh:296
void report(std::ostream &stream=std::cout, const std::string &prefix="") const
print distinct substructure to stream
Definition: parametertree.cc:25
char c
Definition: alignment.hh:37
Iterator end()
end iterator
Definition: densevector.hh:302
static std::string rtrim(const std::string &s)
Definition: parametertree.cc:196
A few common exception classes.
ParameterTree()
Create new empty ParameterTree.
Definition: parametertree.cc:22
static std::vector< std::string > split(const std::string &s)
Definition: parametertree.cc:205
const KeyVector & getValueKeys() const
get value keys
Definition: parametertree.cc:221
std::vector< std::string > KeyVector
storage for key lists
Definition: parametertree.hh:38
std::map< std::string, std::string > values
Definition: parametertree.hh:229
const KeyVector & getSubKeys() const
get substructure keys
Definition: parametertree.cc:226
std::map< std::string, ParameterTree > subs
Definition: parametertree.hh:230
iterator begin()
Definition: array.hh:104
bool hasSub(const std::string &sub) const
test for substructure
Definition: parametertree.cc:61
Iterator begin()
begin iterator
Definition: densevector.hh:296
std::string & operator[](const std::string &key)
get value reference for key
Definition: parametertree.cc:112
static FieldVector< T, n > parse(const std::string &str)
Definition: parametertree.hh:321
ParameterTree & sub(const std::string &sub)
get substructure by name
Definition: parametertree.cc:78
Hierarchical structure of string parameters.
Definition: parametertree.hh:33
#define DUNE_THROW(E, m)
Definition: exceptions.hh:244
Simple fixed size array class. This replaces std::array, if that is not available.
Definition: array.hh:40
static std::vector< T, A > parse(const std::string &str)
Definition: parametertree.hh:341
iterator end()
Definition: array.hh:114
vector space out of a tensor product of fields.
Definition: densematrix.hh:38
KeyVector valueKeys
Definition: parametertree.hh:226
Implements a vector constructed from a given type representing a field and a compile-time given size...
A free function to provide the demangled class name of a given object or type as a string...
static void parseRange(const std::string &str, Iterator it, const Iterator &end)
Definition: parametertree.hh:237
KeyVector subKeys
Definition: parametertree.hh:227
static std::basic_string< char, traits, Allocator > parse(const std::string &str)
Definition: parametertree.hh:286
static bool parse(const std::string &str)
Definition: parametertree.hh:303
bool hasKey(const std::string &key) const
test for key
Definition: parametertree.cc:44
static array< T, n > parse(const std::string &str)
Definition: parametertree.hh:331
Fallback implementation of the std::array class (a static array)
Default exception class for range errors.
Definition: exceptions.hh:280