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