Dune Core Modules (2.6.0)

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 <array>
11 #include <cstddef>
12 #include <iostream>
13 #include <istream>
14 #include <iterator>
15 #include <locale>
16 #include <map>
17 #include <ostream>
18 #include <sstream>
19 #include <string>
20 #include <typeinfo>
21 #include <vector>
22 #include <algorithm>
23 #include <bitset>
24 
26 #include <dune/common/fvector.hh>
27 #include <dune/common/classname.hh>
28 
29 namespace Dune {
30 
35  {
36  // class providing a single static parse() function, used by the
37  // generic get() method
38  template<typename T>
39  struct Parser;
40 
41  public:
42 
45  typedef std::vector<std::string> KeyVector;
46 
49  ParameterTree();
50 
51 
59  bool hasKey(const std::string& key) const;
60 
61 
69  bool hasSub(const std::string& sub) const;
70 
71 
80  std::string& operator[] (const std::string& key);
81 
82 
92  const std::string& operator[] (const std::string& key) const;
93 
94 
102  void report(std::ostream& stream = std::cout,
103  const std::string& prefix = "") const;
104 
105 
111  ParameterTree& sub(const std::string& sub);
112 
113 
120  const ParameterTree& sub(const std::string& sub, bool fail_if_missing = false) const;
121 
122 
131  std::string get(const std::string& key, const std::string& defaultValue) const;
132 
143  std::string get(const std::string& key, const char* defaultValue) const;
144 
145 
155  template<typename T>
156  T get(const std::string& key, const T& defaultValue) const {
157  if(hasKey(key))
158  return get<T>(key);
159  else
160  return defaultValue;
161  }
162 
171  template <class T>
172  T get(const std::string& key) const {
173  if(not hasKey(key))
174  DUNE_THROW(Dune::RangeError, "Key '" << key
175  << "' not found in ParameterTree (prefix " + prefix_ + ")");
176  try {
177  return Parser<T>::parse((*this)[key]);
178  }
179  catch(const RangeError& e) {
180  // rethrow the error and add more information
181  DUNE_THROW(RangeError, "Cannot parse value \"" << (*this)[key]
182  << "\" for key \"" << prefix_ << "." << key << "\""
183  << e.what());
184  }
185  }
186 
194  const KeyVector& getValueKeys() const;
195 
196 
204  const KeyVector& getSubKeys() const;
205 
206  protected:
207 
208  static const ParameterTree empty_;
209 
210  std::string prefix_;
211 
212  KeyVector valueKeys_;
213  KeyVector subKeys_;
214 
215  std::map<std::string, std::string> values_;
216  std::map<std::string, ParameterTree> subs_;
217 
218  static std::string ltrim(const std::string& s);
219  static std::string rtrim(const std::string& s);
220  static std::vector<std::string> split(const std::string & s);
221 
222  // parse into a fixed-size range of iterators
223  template<class Iterator>
224  static void parseRange(const std::string &str,
225  Iterator it, const Iterator &end)
226  {
227  typedef typename std::iterator_traits<Iterator>::value_type Value;
228  std::istringstream s(str);
229  // make sure we are in locale "C"
230  s.imbue(std::locale::classic());
231  std::size_t n = 0;
232  for(; it != end; ++it, ++n) {
233  s >> *it;
234  if(!s)
235  DUNE_THROW(RangeError, "as a range of items of type "
236  << className<Value>()
237  << " (" << n << " items were extracted successfully)");
238  }
239  Value dummy;
240  s >> dummy;
241  // now extraction should have failed, and eof should be set
242  if(not s.fail() or not s.eof())
243  DUNE_THROW(RangeError, "as a range of "
244  << n << " items of type "
245  << className<Value>() << " (more items than the range can hold)");
246  }
247  };
248 
249  template<typename T>
250  struct ParameterTree::Parser {
251  static T parse(const std::string& str) {
252  T val;
253  std::istringstream s(str);
254  // make sure we are in locale "C"
255  s.imbue(std::locale::classic());
256  s >> val;
257  if(!s)
258  DUNE_THROW(RangeError, " as a " << className<T>());
259  T dummy;
260  s >> dummy;
261  // now extraction should have failed, and eof should be set
262  if ((! s.fail()) || (! s.eof()))
263  DUNE_THROW(RangeError, " as a " << className<T>());
264  return val;
265  }
266  };
267 
268  // "How do I convert a string into a wstring in C++?" "Why, that very simple
269  // son. You just need a these hundred lines of code."
270  // Instead im gonna restrict myself to string with charT=char here
271  template<typename traits, typename Allocator>
272  struct ParameterTree::Parser<std::basic_string<char, traits, Allocator> > {
273  static std::basic_string<char, traits, Allocator>
274  parse(const std::string& str) {
275  std::string trimmed = ltrim(rtrim(str));
276  return std::basic_string<char, traits, Allocator>(trimmed.begin(),
277  trimmed.end());
278  }
279  };
280 
281  template<>
282  struct ParameterTree::Parser< bool > {
283  struct ToLower {
284  char operator()(char c)
285  {
286  return std::tolower(c, std::locale::classic());
287  }
288  };
289 
290  static bool
291  parse(const std::string& str) {
292  std::string ret = str;
293 
294  std::transform(ret.begin(), ret.end(), ret.begin(), ToLower());
295 
296  if (ret == "yes" || ret == "true")
297  return true;
298 
299  if (ret == "no" || ret == "false")
300  return false;
301 
302  return (Parser<int>::parse(ret) != 0);
303  }
304  };
305 
306  template<typename T, int n>
307  struct ParameterTree::Parser<FieldVector<T, n> > {
308  static FieldVector<T, n>
309  parse(const std::string& str) {
310  FieldVector<T, n> val;
311  parseRange(str, val.begin(), val.end());
312  return val;
313  }
314  };
315 
316  template<typename T, std::size_t n>
317  struct ParameterTree::Parser<std::array<T, n> > {
318  static std::array<T, n>
319  parse(const std::string& str) {
320  std::array<T, n> val;
321  parseRange(str, val.begin(), val.end());
322  return val;
323  }
324  };
325 
326  template<std::size_t n>
327  struct ParameterTree::Parser<std::bitset<n> > {
328  static std::bitset<n>
329  parse(const std::string& str) {
330  std::bitset<n> val;
331  std::vector<std::string> sub = split(str);
332  if (sub.size() != n)
333  DUNE_THROW(RangeError, "as a bitset<" << n << "> "
334  << "because of unmatching size " << sub.size());
335  for (std::size_t i=0; i<n; ++i) {
336  val[i] = ParameterTree::Parser<bool>::parse(sub[i]);
337  }
338  return val;
339  }
340  };
341 
342  template<typename T, typename A>
343  struct ParameterTree::Parser<std::vector<T, A> > {
344  static std::vector<T, A>
345  parse(const std::string& str) {
346  std::vector<std::string> sub = split(str);
347  std::vector<T, A> vec;
348  for (unsigned int i=0; i<sub.size(); ++i) {
349  T val = ParameterTree::Parser<T>::parse(sub[i]);
350  vec.push_back(val);
351  }
352  return vec;
353  }
354  };
355 
356 } // end namespace Dune
357 
358 #endif // DUNE_PARAMETERTREE_HH
Hierarchical structure of string parameters.
Definition: parametertree.hh:35
std::string get(const std::string &key, const std::string &defaultValue) const
get value as string
Definition: parametertree.cc:183
void report(std::ostream &stream=std::cout, const std::string &prefix="") const
print distinct substructure to stream
Definition: parametertree.cc:27
std::vector< std::string > KeyVector
storage for key lists
Definition: parametertree.hh:39
ParameterTree()
Create new empty ParameterTree.
Definition: parametertree.cc:22
std::string & operator[](const std::string &key)
get value reference for key
Definition: parametertree.cc:148
ParameterTree & sub(const std::string &sub)
get substructure by name
Definition: parametertree.cc:101
bool hasKey(const std::string &key) const
test for key
Definition: parametertree.cc:46
const KeyVector & getSubKeys() const
get substructure keys
Definition: parametertree.cc:238
T get(const std::string &key) const
Get value.
Definition: parametertree.hh:172
bool hasSub(const std::string &sub) const
test for substructure
Definition: parametertree.cc:74
T get(const std::string &key, const T &defaultValue) const
get value converted to a certain type
Definition: parametertree.hh:156
const KeyVector & getValueKeys() const
get value keys
Definition: parametertree.cc:233
Default exception class for range errors.
Definition: exceptions.hh:252
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.
const char * what() const noexcept override
output internal message buffer
Definition: exceptions.cc:35
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
Dune namespace.
Definition: alignedallocator.hh:10
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 25, 22:37, 2024)