00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef SST_CORE_PARAM_H
00013 #define SST_CORE_PARAM_H
00014
00015 #include <sst/core/serialization.h>
00016
00017 #include <sst/core/output.h>
00018
00019 #include <inttypes.h>
00020 #include <iostream>
00021 #include <map>
00022 #include <stack>
00023 #include <stdlib.h>
00024 #include <utility>
00025
00026 namespace SST {
00027
00028 class ConfigGraph;
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 class Params {
00040 private:
00041 struct KeyCompare : std::binary_function<std::string, std::string, bool>
00042 {
00043 bool operator()(const std::string& X, const std::string& Y) const
00044 {
00045 const char *x = X.c_str();
00046 const char *y = Y.c_str();
00047
00048 #define EAT_VAR(A, B) \
00049 do { \
00050 if ( *x == '%' && (*(x+1) == '(' || *(x+1) == 'd')) { \
00051 \
00052 ++x; \
00053 if ( *x == '(' ) { \
00054 do { x++; } while ( *x && *x != ')' ); \
00055 x++; \
00056 } \
00057 if ( *x != 'd' ) goto NO_VARIABLE; \
00058 x++; \
00059 \
00060 while ( *y && isdigit(*y) ) y++; \
00061 } \
00062 } while(0)
00063
00064 do {
00065 EAT_VAR(x, y);
00066 EAT_VAR(y, x);
00067 NO_VARIABLE:
00068 if ( *x == *y ) {
00069 if ( '\0' == *x ) return false;
00070 x++;
00071 y++;
00072 } else {
00073 if ( *x < *y ) return true;
00074 return false;
00075 }
00076 } while ( *x && *y );
00077 if ( !(*x) && (*y) ) return true;
00078 return false;
00079
00080 #undef EAT_VAR
00081 }
00082 };
00083
00084 public:
00085 typedef std::map<std::string, std::string>::key_type key_type;
00086 typedef std::map<uint32_t, std::string>::mapped_type mapped_type;
00087 typedef std::map<std::string, std::string>::value_type value_type;
00088 typedef std::map<uint32_t, std::string>::key_compare key_compare;
00089 typedef std::map<uint32_t, std::string>::value_compare value_compare;
00090 typedef std::map<uint32_t, std::string>::pointer pointer;
00091 typedef std::map<uint32_t, std::string>::reference reference;
00092 typedef std::map<uint32_t, std::string>::const_reference const_reference;
00093 typedef std::map<uint32_t, std::string>::size_type size_type;
00094 typedef std::map<uint32_t, std::string>::difference_type difference_type;
00095 typedef std::map<uint32_t, std::string>::iterator iterator;
00096 typedef std::map<uint32_t, std::string>::const_iterator const_iterator;
00097 typedef std::map<uint32_t, std::string>::reverse_iterator reverse_iterator;
00098 typedef std::map<uint32_t, std::string>::const_reverse_iterator const_reverse_iterator;
00099 typedef std::set<key_type, KeyCompare> KeySet_t;
00100
00101
00102
00103
00104
00105
00106 bool enableVerify(bool enable) { bool old = verify_enabled; verify_enabled = enable; return old; }
00107
00108
00109
00110
00111
00112
00113 static void enableVerify() { g_verify_enabled = true; };
00114
00115
00116
00117
00118
00119
00120 iterator begin() { return data.begin(); }
00121
00122
00123
00124
00125 iterator end() { return data.end(); }
00126
00127
00128
00129
00130 const_iterator begin() const { return data.begin(); }
00131
00132
00133
00134
00135 const_iterator end() const { return data.end(); }
00136
00137
00138
00139
00140 reverse_iterator rbegin() { return data.rbegin(); }
00141
00142
00143
00144
00145 reverse_iterator rend() { return data.rend(); }
00146
00147
00148
00149
00150 const_reverse_iterator rbegin() const { return data.rbegin(); }
00151
00152
00153
00154
00155 const_reverse_iterator rend() const { return data.rend(); }
00156
00157 size_type size() const { return data.size(); }
00158
00159 size_type max_size() const { return data.max_size(); }
00160
00161 bool empty() const { return data.empty(); }
00162
00163
00164
00165 Params() : data(), verify_enabled(true) { }
00166
00167
00168 Params(const key_compare& comp) : data(comp), verify_enabled(true) { }
00169
00170
00171
00172 Params(const Params& old) : data(old.data), allowedKeys(old.allowedKeys), verify_enabled(old.verify_enabled) { }
00173
00174 virtual ~Params() { }
00175
00176
00177
00178
00179
00180
00181
00182
00183 Params& operator=(const Params& old) {
00184 data = old.data;
00185 verify_enabled = old.verify_enabled;
00186 allowedKeys = old.allowedKeys;
00187 return *this;
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 std::pair<iterator, bool> insert(const value_type& x) {
00207 uint32_t id = getKey(x.first);
00208 return data.insert(std::make_pair(id, x.second));
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 iterator insert(iterator pos, const value_type& x) {
00231 uint32_t id = getKey(x.first);
00232 return data.insert(pos, std::make_pair(id, x.second));
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242 template <class InputIterator>
00243 void insert(InputIterator f, InputIterator l) {
00244 data.insert(f, l);
00245 }
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 void erase(iterator pos) { data.erase(pos); }
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 size_type erase(const key_type& k) { return data.erase(getKey(k)); }
00270
00271
00272
00273
00274
00275
00276 void clear() { data.clear(); }
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 iterator find(const key_type& k) { verifyParam(k); return data.find(getKey(k)); }
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 const_iterator find(const key_type& k) const { verifyParam(k); return data.find(getKey(k)); }
00303
00304
00305
00306
00307
00308
00309
00310
00311 size_type count(const key_type& k) { return data.count(getKey(k)); }
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 mapped_type& operator[](const key_type& k) { verifyParam(k); return data[getKey(k)]; }
00325
00326
00327
00328
00329
00330
00331 int64_t find_integer(const key_type &k, long default_value, bool &found) const {
00332 verifyParam(k);
00333 const_iterator i = data.find(getKey(k));
00334 if (i == data.end()) {
00335 found = false;
00336 return default_value;
00337 } else {
00338 found = true;
00339 return strtol(i->second.c_str(), NULL, 0);
00340 }
00341 }
00342
00343
00344
00345
00346
00347 int64_t find_integer(const key_type &k, long default_value = -1) const {
00348 bool tmp;
00349 return find_integer(k, default_value, tmp);
00350 }
00351
00352
00353
00354
00355
00356
00357 double find_floating(const key_type& k, double default_value, bool &found) const {
00358 verifyParam(k);
00359 const_iterator i = data.find(getKey(k));
00360 if (i == data.end()) {
00361 found = false;
00362 return default_value;
00363 } else {
00364 found = true;
00365 return strtod(i->second.c_str(), NULL);
00366 }
00367 }
00368
00369
00370
00371
00372
00373 double find_floating(const key_type& k, double default_value = -1.0) const {
00374 bool tmp;
00375 return find_floating(k, default_value, tmp);
00376 }
00377
00378
00379
00380
00381
00382
00383 std::string find_string(const key_type &k, std::string default_value, bool &found) const {
00384 verifyParam(k);
00385 const_iterator i = data.find(getKey(k));
00386 if (i == data.end()) {
00387 found = false;
00388 return default_value;
00389 } else {
00390 found = true;
00391 return i->second;
00392 }
00393 }
00394
00395
00396
00397
00398
00399 std::string find_string(const key_type &k, std::string default_value = "") const {
00400 bool tmp;
00401 return find_string(k, default_value, tmp);
00402 }
00403
00404
00405 void print_all_params(std::ostream &os, std::string prefix = "") const {
00406 for (const_iterator i = data.begin() ; i != data.end() ; ++i) {
00407 os << prefix << "key=" << keyMapReverse[i->first] << ", value=" << i->second << std::endl;
00408 }
00409 }
00410
00411
00412
00413
00414 Params find_prefix_params(std::string prefix) const {
00415 Params ret;
00416 ret.enableVerify(false);
00417 for (const_iterator i = data.begin() ; i != data.end() ; ++i) {
00418 std::string key = keyMapReverse[i->first].substr(0, prefix.length());
00419 if (key == prefix) {
00420 ret[keyMapReverse[i->first].substr(prefix.length())] = i->second;
00421 }
00422 }
00423 ret.allowedKeys = allowedKeys;
00424 ret.enableVerify(verify_enabled);
00425
00426 return ret;
00427 }
00428
00429
00430
00431
00432
00433
00434 bool contains(const key_type &k) {
00435 return data.find(getKey(k)) != data.end();
00436 }
00437
00438
00439
00440
00441
00442 void pushAllowedKeys(const KeySet_t &keys) {
00443 allowedKeys.push_back(keys);
00444 }
00445
00446
00447
00448
00449 void popAllowedKeys() {
00450 allowedKeys.pop_back();
00451 }
00452
00453
00454
00455
00456
00457 void verifyParam(const key_type &k) const {
00458 if ( !g_verify_enabled || !verify_enabled ) return;
00459
00460 for ( std::vector<KeySet_t>::const_reverse_iterator ri = allowedKeys.rbegin() ; ri != allowedKeys.rend() ; ++ri ) {
00461 if ( ri->find(k) != ri->end() ) return;
00462 }
00463
00464 #ifdef USE_PARAM_WARNINGS
00465 SST::Output outXX("ParamWarning: ", 0, 0, Output::STDERR);
00466 outXX.output(CALL_INFO, "Warning: Parameter \"%s\" is undocumented.\n", k.c_str());
00467 #endif
00468 }
00469
00470
00471
00472
00473
00474
00475
00476 static const std::string& getParamName(uint32_t id)
00477 {
00478 return keyMapReverse[id];
00479 }
00480
00481
00482
00483 private:
00484 std::map<uint32_t, std::string> data;
00485 std::vector<KeySet_t> allowedKeys;
00486 bool verify_enabled;
00487 static bool g_verify_enabled;
00488
00489 uint32_t getKey(const std::string &str) const
00490 {
00491 std::map<std::string, uint32_t>::iterator i = keyMap.find(str);
00492 if ( i == keyMap.end() ) {
00493 return (uint32_t)-1;
00494 }
00495 return i->second;
00496 }
00497
00498 uint32_t getKey(const std::string &str)
00499 {
00500 std::map<std::string, uint32_t>::iterator i = keyMap.find(str);
00501 if ( i == keyMap.end() ) {
00502 uint32_t id = nextKeyID++;
00503 keyMap.insert(std::make_pair(str, id));
00504 keyMapReverse.push_back(str);
00505 assert(keyMapReverse.size() == nextKeyID);
00506 return id;
00507 }
00508 return i->second;
00509 }
00510
00511 friend class boost::serialization::access;
00512 template<class Archive>
00513 void serialize(Archive& ar, const unsigned int version)
00514 {
00515 ar & BOOST_SERIALIZATION_NVP(data);
00516 }
00517
00518
00519 public:
00520
00521 static std::map<std::string, uint32_t> keyMap;
00522
00523 static std::vector<std::string> keyMapReverse;
00524
00525 static uint32_t nextKeyID;
00526
00527
00528 };
00529
00530 }
00531
00532 #endif //SST_CORE_PARAMS_H