Dune Core Modules (2.9.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 // SPDX-FileCopyrightInfo: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
4 // SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5 #ifndef DUNE_PARAMETERTREE_HH
6 #define DUNE_PARAMETERTREE_HH
7 
12 #include <array>
13 #include <cstddef>
14 #include <iostream>
15 #include <istream>
16 #include <iterator>
17 #include <locale>
18 #include <map>
19 #include <ostream>
20 #include <sstream>
21 #include <string>
22 #include <typeinfo>
23 #include <vector>
24 #include <algorithm>
25 #include <bitset>
26 
28 #include <dune/common/fvector.hh>
29 #include <dune/common/classname.hh>
30 
31 namespace Dune {
32 
37  {
38  // class providing a single static parse() function, used by the
39  // generic get() method
40  template<typename T>
41  struct Parser;
42 
43  public:
44 
47  typedef std::vector<std::string> KeyVector;
48 
51  ParameterTree();
52 
53 
61  bool hasKey(const std::string& key) const;
62 
63 
71  bool hasSub(const std::string& sub) const;
72 
73 
82  std::string& operator[] (const std::string& key);
83 
84 
94  const std::string& operator[] (const std::string& key) const;
95 
96 
104  void report(std::ostream& stream = std::cout,
105  const std::string& prefix = "") const;
106 
107 
113  ParameterTree& sub(const std::string& sub);
114 
115 
122  const ParameterTree& sub(const std::string& sub, bool fail_if_missing = false) const;
123 
124 
133  std::string get(const std::string& key, const std::string& defaultValue) const;
134 
145  std::string get(const std::string& key, const char* defaultValue) const;
146 
147 
157  template<typename T>
158  T get(const std::string& key, const T& defaultValue) const {
159  if(hasKey(key))
160  return get<T>(key);
161  else
162  return defaultValue;
163  }
164 
173  template <class T>
174  T get(const std::string& key) const {
175  if(not hasKey(key))
176  DUNE_THROW(Dune::RangeError, "Key '" << key
177  << "' not found in ParameterTree (prefix " + prefix_ + ")");
178  try {
179  return Parser<T>::parse((*this)[key]);
180  }
181  catch(const RangeError& e) {
182  // rethrow the error and add more information
183  DUNE_THROW(RangeError, "Cannot parse value \"" << (*this)[key]
184  << "\" for key \"" << prefix_ << "." << key << "\""
185  << e.what());
186  }
187  }
188 
196  const KeyVector& getValueKeys() const;
197 
198 
206  const KeyVector& getSubKeys() const;
207 
208  protected:
209 
210  static const ParameterTree empty_;
211 
212  std::string prefix_;
213 
214  KeyVector valueKeys_;
215  KeyVector subKeys_;
216 
217  std::map<std::string, std::string> values_;
218  std::map<std::string, ParameterTree> subs_;
219 
220  static std::string ltrim(const std::string& s);
221  static std::string rtrim(const std::string& s);
222  static std::vector<std::string> split(const std::string & s);
223 
224  // parse into a fixed-size range of iterators
225  template<class Iterator>
226  static void parseRange(const std::string &str,
227  Iterator it, const Iterator &end)
228  {
229  typedef typename std::iterator_traits<Iterator>::value_type Value;
230  std::istringstream s(str);
231  // make sure we are in locale "C"
232  s.imbue(std::locale::classic());
233  std::size_t n = 0;
234  for(; it != end; ++it, ++n) {
235  s >> *it;
236  if(!s)
237  DUNE_THROW(RangeError, "as a range of items of type "
238  << className<Value>()
239  << " (" << n << " items were extracted successfully)");
240  }
241  Value dummy;
242  s >> dummy;
243  // now extraction should have failed, and eof should be set
244  if(not s.fail() or not s.eof())
245  DUNE_THROW(RangeError, "as a range of "
246  << n << " items of type "
247  << className<Value>() << " (more items than the range can hold)");
248  }
249  };
250 
251  template<typename T>
252  struct ParameterTree::Parser {
253  static T parse(const std::string& str) {
254  T val;
255  std::istringstream s(str);
256  // make sure we are in locale "C"
257  s.imbue(std::locale::classic());
258  s >> val;
259  if(!s)
260  DUNE_THROW(RangeError, " as a " << className<T>());
261  char dummy;
262  s >> dummy;
263  // now extraction should have failed, and eof should be set
264  if ((! s.fail()) || (! s.eof()))
265  DUNE_THROW(RangeError, " as a " << className<T>());
266  return val;
267  }
268  };
269 
270  // "How do I convert a string into a wstring in C++?" "Why, that very simple
271  // son. You just need a these hundred lines of code."
272  // Instead im going to restrict myself to string with charT=char here.
273  template<typename traits, typename Allocator>
274  struct ParameterTree::Parser<std::basic_string<char, traits, Allocator> > {
275  static std::basic_string<char, traits, Allocator>
276  parse(const std::string& str) {
277  std::string trimmed = ltrim(rtrim(str));
278  return std::basic_string<char, traits, Allocator>(trimmed.begin(),
279  trimmed.end());
280  }
281  };
282 
283  template<>
284  struct ParameterTree::Parser< bool > {
285  struct ToLower {
286  char operator()(char c)
287  {
288  return std::tolower(c, std::locale::classic());
289  }
290  };
291 
292  static bool
293  parse(const std::string& str) {
294  std::string ret = str;
295 
296  std::transform(ret.begin(), ret.end(), ret.begin(), ToLower());
297 
298  if (ret == "yes" || ret == "true")
299  return true;
300 
301  if (ret == "no" || ret == "false")
302  return false;
303 
304  return (Parser<int>::parse(ret) != 0);
305  }
306  };
307 
308  template<typename T, int n>
309  struct ParameterTree::Parser<FieldVector<T, n> > {
310  static FieldVector<T, n>
311  parse(const std::string& str) {
312  FieldVector<T, n> val;
313  parseRange(str, val.begin(), val.end());
314  return val;
315  }
316  };
317 
318  template<typename T, std::size_t n>
319  struct ParameterTree::Parser<std::array<T, n> > {
320  static std::array<T, n>
321  parse(const std::string& str) {
322  std::array<T, n> val;
323  parseRange(str, val.begin(), val.end());
324  return val;
325  }
326  };
327 
328  template<std::size_t n>
329  struct ParameterTree::Parser<std::bitset<n> > {
330  static std::bitset<n>
331  parse(const std::string& str) {
332  std::bitset<n> val;
333  std::vector<std::string> sub = split(str);
334  if (sub.size() != n)
335  DUNE_THROW(RangeError, "as a bitset<" << n << "> "
336  << "because of unmatching size " << sub.size());
337  for (std::size_t i=0; i<n; ++i) {
338  val[i] = ParameterTree::Parser<bool>::parse(sub[i]);
339  }
340  return val;
341  }
342  };
343 
344  template<typename T, typename A>
345  struct ParameterTree::Parser<std::vector<T, A> > {
346  static std::vector<T, A>
347  parse(const std::string& str) {
348  std::vector<std::string> sub = split(str);
349  std::vector<T, A> vec;
350  for (unsigned int i=0; i<sub.size(); ++i) {
351  T val = ParameterTree::Parser<T>::parse(sub[i]);
352  vec.push_back(val);
353  }
354  return vec;
355  }
356  };
357 
358 } // end namespace Dune
359 
360 #endif // DUNE_PARAMETERTREE_HH
Hierarchical structure of string parameters.
Definition: parametertree.hh:37
std::string get(const std::string &key, const std::string &defaultValue) const
get value as string
Definition: parametertree.cc:185
void report(std::ostream &stream=std::cout, const std::string &prefix="") const
print distinct substructure to stream
Definition: parametertree.cc:29
std::vector< std::string > KeyVector
storage for key lists
Definition: parametertree.hh:41
ParameterTree()
Create new empty ParameterTree.
Definition: parametertree.cc:24
std::string & operator[](const std::string &key)
get value reference for key
Definition: parametertree.cc:150
ParameterTree & sub(const std::string &sub)
get substructure by name
Definition: parametertree.cc:103
bool hasKey(const std::string &key) const
test for key
Definition: parametertree.cc:48
const KeyVector & getSubKeys() const
get substructure keys
Definition: parametertree.cc:240
T get(const std::string &key) const
Get value.
Definition: parametertree.hh:174
bool hasSub(const std::string &sub) const
test for substructure
Definition: parametertree.cc:76
T get(const std::string &key, const T &defaultValue) const
get value converted to a certain type
Definition: parametertree.hh:158
const KeyVector & getValueKeys() const
get value keys
Definition: parametertree.cc:235
Default exception class for range errors.
Definition: exceptions.hh:254
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:37
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
Dune namespace.
Definition: alignedallocator.hh:13
std::vector< decltype(std::declval< Op >)(std::declval< T >))) > transform(const std::vector< T > &in, Op op)
copy a vector, performing an operation on each element
Definition: misc.hh:24
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Feb 21, 23:30, 2024)