DUNE PDELab (2.8)

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
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
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 char 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: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: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.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
Dune namespace.
Definition: alignedallocator.hh:11
STL namespace.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Dec 21, 23:30, 2024)