1
// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2
// vi: set et ts=8 sw=2 sts=2:
3
#ifndef DUNE_PARAMETERTREE_HH
4
#define DUNE_PARAMETERTREE_HH
18
#include <dune/common/array.hh>
19
#include <dune/common/exceptions.hh>
20
#include <dune/common/fvector.hh>
21
#include <dune/common/classname.hh>
25
/** \brief Hierarchical structure of string parameters
30
// class providing a single static parse() function, used by the
31
// generic get() method
37
typedef std::vector<std::string> KeyVector;
39
/** \brief Create new empty ParameterTree
44
/** \brief test for key
46
* Tests whether given key exists.
49
* \return true if key exists in structure, otherwise false
51
bool hasKey(const std::string& key) const;
54
/** \brief test for substructure
56
* Tests whether given substructure exists.
58
* \param sub substructure name
59
* \return true if substructure exists in structure, otherwise false
61
bool hasSub(const std::string& sub) const;
64
/** \brief get value reference for key
66
* Returns reference to value for given key name.
67
* This creates the key, if not existent.
70
* \return reference to corresponding value
72
std::string& operator[] (const std::string& key);
75
/** \brief get value reference for key
77
* Returns reference to value for given key name.
78
* This creates the key, if not existent.
81
* \return reference to corresponding value
82
* \throw Dune::RangeError if key is not found
84
const std::string& operator[] (const std::string& key) const;
87
/** \brief print distinct substructure to stream
89
* Prints all entries with given prefix.
91
* \param stream Stream to print to
92
* \param prefix for key and substructure names
94
void report(std::ostream& stream = std::cout,
95
const std::string& prefix = "") const;
98
/** \brief get substructure by name
100
* \param sub substructure name
101
* \return reference to substructure
103
ParameterTree& sub(const std::string& sub);
106
/** \brief get const substructure by name
108
* \param sub substructure name
109
* \return reference to substructure
111
const ParameterTree& sub(const std::string& sub) const;
114
/** \brief get value as string
116
* Returns pure string value for given key.
118
* \param key key name
119
* \param defaultValue default if key does not exist
120
* \return value as string
122
std::string get(const std::string& key, const std::string& defaultValue) const;
124
/** \brief get value as string
126
* Returns pure string value for given key.
128
* \todo This is a hack so get("my_key", "xyz") compiles
129
* (without this method "xyz" resolves to bool instead of std::string)
130
* \param key key name
131
* \param defaultValue default if key does not exist
132
* \return value as string
134
std::string get(const std::string& key, const char* defaultValue) const;
137
/** \brief get value as int
139
* Returns value for given key interpreted as int.
141
* \param key key name
142
* \param defaultValue default if key does not exist
143
* \return value as int
145
int get(const std::string& key, int defaultValue) const;
148
/** \brief get value as double
150
* Returns value for given key interpreted as double.
152
* \param key key name
153
* \param defaultValue default if key does not exist
154
* \return value as double
156
double get(const std::string& key, double defaultValue) const;
159
/** \brief get value converted to a certain type
161
* Returns value as type T for given key.
163
* \tparam T type of returned value.
164
* \param key key name
165
* \param defaultValue default if key does not exist
166
* \return value converted to T
169
T get(const std::string& key, const T& defaultValue) const {
178
* \tparam T Type of the value
179
* \param key Key name
180
* \throws RangeError if key does not exist
181
* \throws NotImplemented Type is not supported
185
T get(const std::string& key) const {
187
DUNE_THROW(RangeError, "Key '" << key << "' not found in parameter "
190
return Parser<T>::parse((*this)[key]);
192
catch(const RangeError&) {
193
DUNE_THROW(RangeError, "Cannot parse value \"" <<
194
(*this)[key] << "\" for key \"" << key << "\" as a " <<
199
/** \brief get value keys
201
* Returns a vector of all keys associated to (key,values) entries in
202
* order of appearance
204
* \return reference to entry vector
206
const KeyVector& getValueKeys() const;
209
/** \brief get substructure keys
211
* Returns a vector of all keys associated to (key,substructure) entries
212
* in order of appearance
214
* \return reference to entry vector
216
const KeyVector& getSubKeys() const;
222
std::map<std::string, std::string> values;
223
std::map<std::string, ParameterTree> subs;
224
static std::string ltrim(const std::string& s);
225
static std::string rtrim(const std::string& s);
226
static std::vector<std::string> split(const std::string & s);
228
// parse into a fixed-size range of iterators
229
template<class Iterator>
230
static void parseRange(const std::string &str,
231
Iterator it, const Iterator &end)
233
typedef typename std::iterator_traits<Iterator>::value_type Value;
234
std::istringstream s(str);
236
for(; it != end; ++it, ++n) {
239
DUNE_THROW(RangeError, "Cannot parse value \"" << str << "\" as a "
240
"range of items of type " << className<Value>() << " "
241
"(" << n << " items were extracted successfully)");
245
// now extraction should have failed, and eof should be set
246
if(not s.fail() or not s.eof())
247
DUNE_THROW(RangeError, "Cannot parse value \"" << str << "\" as a "
248
"range of " << n << " items of type "
249
<< className<Value>() << " (more items than the range "
255
struct ParameterTree::Parser {
256
static T parse(const std::string& str) {
258
std::istringstream s(str);
261
DUNE_THROW(RangeError, "Cannot parse value \"" << str << "\" as a " <<
265
// now extraction should have failed, and eof should be set
266
if(not s.fail() or not s.eof())
267
DUNE_THROW(RangeError, "Cannot parse value \"" << str << "\" as a " <<
273
// "How do I convert a string into a wstring in C++?" "Why, that very simple
274
// son. You just need a these hundred lines of code."
275
// Instead im gonna restrict myself to string with charT=char here
276
template<typename traits, typename Allocator>
277
struct ParameterTree::Parser<std::basic_string<char, traits, Allocator> > {
278
static std::basic_string<char, traits, Allocator>
279
parse(const std::string& str) {
280
std::string trimmed = ltrim(rtrim(str));
281
return std::basic_string<char, traits, Allocator>(trimmed.begin(),
287
struct ParameterTree::Parser< bool > {
289
int operator()(int c)
291
return std::tolower(c);
296
parse(const std::string& str) {
297
std::string ret = str;
299
std::transform(ret.begin(), ret.end(), ret.begin(), ToLower());
301
if (ret == "yes" || ret == "true")
304
if (ret == "no" || ret == "false")
307
return (Parser<int>::parse(ret) != 0);
311
template<typename T, int n>
312
struct ParameterTree::Parser<FieldVector<T, n> > {
313
static FieldVector<T, n>
314
parse(const std::string& str) {
315
FieldVector<T, n> val;
316
parseRange(str, val.begin(), val.end());
321
template<typename T, std::size_t n>
322
struct ParameterTree::Parser<array<T, n> > {
324
parse(const std::string& str) {
326
parseRange(str, val.begin(), val.end());
331
template<typename T, typename A>
332
struct ParameterTree::Parser<std::vector<T, A> > {
333
static std::vector<T, A>
334
parse(const std::string& str) {
335
std::vector<std::string> sub = split(str);
336
std::vector<T, A> vec;
337
for (unsigned int i=0; i<sub.size(); ++i) {
338
T val = ParameterTree::Parser<T>::parse(sub[i]);
345
} // end namespace Dune
347
#endif // DUNE_PARAMETERTREE_HH