31 #ifndef _PARAMETER_TREE_HH_
32 #define _PARAMETER_TREE_HH_
41 template<
typename T >
45 typedef std :: vector< std :: string >
KeyVector;
55 bool hasKey(
const std :: string &key)
const;
57 bool hasSub(
const std :: string &sub)
const;
59 std :: string &
operator[] (
const std :: string & key );
61 const std :: string &
operator[] (
const std :: string & key )
const;
63 void report(std :: ostream &stream = std :: cout,
const std :: string &prefix =
"")
const;
69 std :: string
get(
const std :: string &key,
const std :: string &defaultValue)
const;
71 std :: string
get(
const std :: string &key,
const char *defaultValue)
const;
73 int get(
const std :: string &key,
int defaultValue)
const;
75 double get(
const std :: string &key,
double defaultValue)
const;
86 template<
typename T >
87 T
get(
const std :: string &key,
const T &defaultValue)
const
105 T
get(
const std :: string &key)
const
108 std :: cerr <<
"MSBGRID_THROW : Key '" << key <<
"' not found in parameter file!\nCalling exit(1)\n";
121 std :: cerr <<
"MSBGRID_THROW : Cannot parse value \"" << ( * this ) [ key ] <<
"\" for key \"" << key <<
"\" as a " << className< T >() <<
"\nCalling exit(1)\n";
135 std :: map< std :: string, std :: string >
values;
136 std :: map< std :: string, ParameterTree >
subs;
137 static std :: string
ltrim(
const std :: string &s);
138 static std :: string
rtrim(
const std :: string &s);
139 static std :: vector< std :: string >
split(
const std :: string &s);
142 template<
class Iterator >
143 static void parseRange(
const std :: string &str, Iterator it,
const Iterator &end)
145 typedef typename std :: iterator_traits< Iterator > :: value_type Value;
146 std :: istringstream s(str);
148 for ( ; it != end; ++it, ++n ) {
151 std :: cerr <<
"Cannot parse value \"" << str <<
"\" as a range of items of type "
152 << className< Value >() <<
" (" << n <<
" items were extracted successfully)\nCalling exit(1)\n";
160 if ( not s.fail() or not s.eof() ) {
161 std :: cerr <<
"Cannot parse value \"" << str <<
"\" as a range of " << n <<
" items of type "
162 << className< Value >() <<
" (more items than the range can hold)\nCalling exit(1)\n";
173 typedef std :: map< std :: string, std :: string > :: const_iterator ValueIt;
174 ValueIt vit = values.begin();
175 ValueIt vend = values.end();
177 for ( ; vit != vend; ++vit ) {
178 stream << vit->first <<
" = \"" << vit->second <<
"\"" << std :: endl;
181 typedef std :: map< std :: string, ParameterTree > :: const_iterator SubIt;
182 SubIt sit = subs.begin();
183 SubIt send = subs.end();
184 for ( ; sit != send; ++sit ) {
185 stream <<
"[ " << prefix + sit->first <<
" ]" << std :: endl;
186 ( sit->second ).
report(stream, prefix + sit->first +
".");
192 std :: string :: size_type dot = key.find(
".");
194 if ( dot != std :: string :: npos ) {
195 std :: string prefix = key.substr(0, dot);
196 if ( subs.count(prefix) == 0 ) {
201 return s.
hasKey( key.substr(dot + 1) );
203 return ( values.count(key) != 0 );
209 std :: string :: size_type dot = key.find(
".");
211 if ( dot != std :: string :: npos ) {
212 std :: string prefix = key.substr(0, dot);
213 if ( subs.count(prefix) == 0 ) {
218 return s.
hasSub( key.substr(dot + 1) );
220 return ( subs.count(key) != 0 );
226 std :: string :: size_type dot = key.find(
".");
228 if ( dot != std :: string :: npos ) {
230 return s.
sub( key.substr(dot + 1) );
232 if ( subs.count(key) == 0 ) {
233 subKeys.push_back( key.substr(0, dot) );
242 std :: string :: size_type dot = key.find(
".");
244 if ( dot != std :: string :: npos ) {
246 return s.
sub( key.substr(dot + 1) );
248 if ( subs.count(key) == 0 ) {
249 std :: cerr <<
"Key '" << key <<
"' not found in ParameterTree\nCalling exit(1)\n";
253 return subs.find(key)->second;
259 std :: string :: size_type dot = key.find(
".");
261 if ( dot != std :: string :: npos ) {
262 if ( not (
hasSub( key.substr(0, dot) ) ) ) {
263 subs [ key.substr(0, dot) ];
264 subKeys.push_back( key.substr(0, dot) );
268 return s [ key.substr(dot + 1) ];
270 if ( not (
hasKey(key) ) ) {
271 valueKeys.push_back(key);
274 return values [ key ];
280 std :: string :: size_type dot = key.find(
".");
282 if ( dot != std :: string :: npos ) {
283 if ( not (
hasSub( key.substr(0, dot) ) ) ) {
284 std :: cerr <<
"Key '" << key <<
"' not found in ParameterTree\nCalling exit(1)\n";
289 return s [ key.substr(dot + 1) ];
291 if ( not (
hasKey(key) ) ) {
292 std :: cerr <<
"Key '" << key <<
"' not found in ParameterTree\nCalling exit(1)\n";
296 return values.find(key)->second;
303 return ( *
this ) [ key ];
312 return ( *
this ) [ key ];
320 std :: stringstream stream;
321 stream << defaultValue;
322 std :: string ret =
get( key, stream.str() );
324 return atoi( ret.c_str() );
330 return atof( ( *
this ) [ key ].c_str() );
338 std :: size_t firstNonWS = s.find_first_not_of(
" \t\n\r");
340 if ( firstNonWS != std :: string :: npos ) {
341 return s.substr(firstNonWS);
344 return std :: string();
349 std :: size_t lastNonWS = s.find_last_not_of(
" \t\n\r");
351 if ( lastNonWS != std :: string :: npos ) {
352 return s.substr(0, lastNonWS + 1);
355 return std :: string();
360 std :: vector< std :: string > substrings;
361 std :: size_t front = 0, back = 0, size = 0;
363 while ( front != std :: string :: npos ) {
365 front = s.find_first_not_of(
" \t\n\r", back);
366 back = s.find_first_of(
" \t\n\r", front);
369 substrings.push_back( s.substr(front, size) );
386 template<
typename T >
389 static T parse(
const std :: string &str)
392 std :: istringstream s(str);
395 std :: cerr <<
"Cannot parse value \"" << str <<
"\" as a " << className< T >() <<
"\nCalling exit(1)\n";
403 if ( not s.fail() or not s.eof() ) {
404 std :: cerr <<
"Cannot parse value \"" << str <<
"\" as a " << className< T >() <<
"\nCalling exit(1)\n";
414 template<
typename traits,
typename Allocator >
417 static std :: basic_string< char, traits, Allocator >
418 parse(
const std :: string &str)
420 std :: string trimmed = ltrim( rtrim(str) );
421 return std :: basic_string< char, traits, Allocator >( trimmed.begin(), trimmed.end() );
430 int operator() (
int c)
432 return std :: tolower(c);
437 parse(
const std :: string &str)
439 std :: string ret = str;
441 std :: transform( ret.begin(), ret.end(), ret.begin(), ToLower() );
443 if ( ret ==
"yes" || ret ==
"true" ) {
447 if ( ret ==
"no" || ret ==
"false" ) {
455 template<
typename T,
typename A >
458 static std :: vector< T, A >
459 parse(
const std :: string &str)
461 std :: vector< std :: string > sub = split(str);
462 std :: vector< T, A > vec;
463 for (
unsigned int i = 0; i < sub.size(); ++i ) {