1 #include "hmbdc/Copyright.hpp" 5 #include <boost/property_tree/ptree.hpp> 6 #include <boost/property_tree/json_parser.hpp> 12 #include <unordered_set> 20 namespace hmbdc {
namespace app {
22 namespace config_detail {
49 using Base = boost::property_tree::ptree;
61 , section_(other.section_)
62 , fallbackConfig_(other.fallbackConfig_
63 ?new
Config(*other.fallbackConfig_)
72 section_ = other.section_;
73 fallbackConfig_.reset(other.fallbackConfig_
74 ?
new Config(*other.fallbackConfig_)
88 Config(istream&& is,
char const* section =
nullptr)
89 : section_(section?section:
"") {
90 read_json(is, (Base&)*
this);
103 Config(istream& is,
char const* section =
nullptr)
104 : section_(section?section:
"") {
105 read_json(is, (Base&)*
this);
118 Config(
char const* json,
char const* section =
nullptr)
119 :
Config(istringstream(json), section)
130 Config(ptree
const& t,
char const* section =
nullptr)
132 , section_(section?section:
"") {
144 Config(ptree
const& dft, ptree
const& section)
146 , fallbackConfig_(new
Config(dft)) {
156 if (!fallbackConfig_) {
157 fallbackConfig_.reset(
new Config(c));
159 fallbackConfig_->setAdditionalFallbackConfig(c);
166 setAdditionalFallbackConfig(c);
179 if (sectionExists) get_child(section);
180 auto sec = section?section:
"";
181 if (get_child_optional(sec)) section_ = sec;
182 if (fallbackConfig_) {
183 fallbackConfig_->resetSection(section,
false);
200 auto res = get_child_optional(sec/=param);
202 res = get_child_optional(param);
204 if (fallbackConfig_) {
205 return fallbackConfig_->getChildExt(param);
207 throw ptree_bad_path(
"invalid param and no default user Config set", param);
225 template <
typename T>
226 T
getExt(
const path_type& param,
bool throwIfMissing =
true)
const {
228 auto res = get_optional<T>(sec/=param);
230 res = get_optional<T>(param);
232 if (fallbackConfig_) {
233 return fallbackConfig_->getExt<T>(param, throwIfMissing);
234 }
else if (throwIfMissing) {
235 throw ptree_bad_path(
"invalid param and no default user Config set", param);
255 template <
typename T>
256 std::vector<T>
getArray(
const path_type& param)
const {
259 auto children = get_child_optional(sec/=param);
260 if (!children) children = get_child_optional(param);
262 for (
auto& v : *children) {
263 if (v.first.empty()) {
264 res.push_back(v.second.get_value<T>());
266 throw ptree_bad_data(
"param not pointing to array ", param);
270 }
else if (fallbackConfig_) {
271 return fallbackConfig_->getArray<T>(param);
273 throw ptree_bad_path(
"invalid array param and no default user Config set", param);
286 template <
typename T>
287 T
getHex(ptree::path_type
const& param)
const {
288 istringstream iss(getExt<string>(param));
304 template <
typename T>
305 Config const&
operator()(T& to,
const path_type& param,
bool throwIfMissing =
true)
const {
306 to = getExt<T>(param, throwIfMissing);
320 template <
typename T>
321 Config const&
operator()(std::unordered_set<T>& to,
const path_type& param,
bool throwIfMissing =
true)
const {
323 auto s = getExt<string>(param, throwIfMissing);
324 istringstream iss(s);
326 for (
auto iit = istream_iterator<T>(iss)
327 ; iit != istream_iterator<T>()
332 throw (ptree_bad_data(
"not space separated items in Config ", param));
348 template <
typename T>
349 Config const&
operator()(std::vector<T>& to,
const path_type& param,
bool throwIfMissing =
true)
const {
351 auto s = getExt<string>(param, throwIfMissing);
352 istringstream iss(s);
354 for (
auto iit = istream_iterator<T>(iss)
355 ; iit != istream_iterator<T>()
357 to.emplace_back(*iit);
360 throw (ptree_bad_data(
"not space separated items in Config ", param));
374 unordered_set<string>
const& skipThese = unordered_set<string>())
const {
375 list<pair<string, string>> res;
376 unordered_set<string> history(skipThese);
377 auto secTree = get_child_optional(section_);
379 for (
auto& p : *secTree) {
380 if (history.find(p.first) == history.end()) {
381 history.insert(p.first);
382 if (p.second.empty()) {
383 res.push_back(make_pair(p.first, p.second.get_value<
string>()));
394 for (
auto& p : *
this) {
395 if (history.find(p.first) == history.end()) {
396 history.insert(p.first);
397 if (p.second.empty()) {
398 res.push_back(make_pair(p.first, p.second.get_value<
string>()));
408 if (fallbackConfig_) {
409 auto more = fallbackConfig_->content(history);
410 res.insert(res.end(), more.begin(), more.end());
423 friend ostream& operator << (ostream& os,
Config const& cfg) {
424 for (
auto& r : cfg.
content()) {
425 os << r.first <<
'=' << r.second << endl;
427 if (cfg.fallbackConfig_) {
428 os <<
"next in line fallback" << endl;
429 os << *cfg.fallbackConfig_ << endl;
454 std::unique_ptr<Config> fallbackConfig_;
std::vector< T > getArray(const path_type ¶m) const
get a vector of value from the json array
Definition: Config.hpp:256
T getExt(const path_type ¶m, bool throwIfMissing=true) const
get a value from the config
Definition: Config.hpp:226
Config const & operator()(std::vector< T > &to, const path_type ¶m, bool throwIfMissing=true) const
fill an list with a configured value retrieved using getExt
Definition: Config.hpp:349
Config(Config const &other)
copt ctor
Definition: Config.hpp:59
void setDefaultUserConfig(Config const &c)
depracated
Definition: Config.hpp:165
class to hold an hmbdc configuration
Definition: Config.hpp:46
void setAdditionalFallbackConfig(Config const &c)
set additional defaults
Definition: Config.hpp:155
Config & resetSection(char const *section, bool sectionExists=true)
change section name
Definition: Config.hpp:178
Config const & operator()(T &to, const path_type ¶m, bool throwIfMissing=true) const
fill in a variable with a configured value retrieved using getExt
Definition: Config.hpp:305
Config(istream &&is, char const *section=nullptr)
construct using stream, optionally specifying the section name
Definition: Config.hpp:88
T getHex(ptree::path_type const ¶m) const
get a number value in hex format
Definition: Config.hpp:287
Config(char const *json, char const *section=nullptr)
construct using a string, optionally specifying the section name
Definition: Config.hpp:118
Config(ptree const &dft, ptree const §ion)
construct using a fallback ptree, and specify the section ptree
Definition: Config.hpp:144
ptree const & getChildExt(const path_type ¶m)
Gets the child from the config.
Definition: Config.hpp:198
Config const & operator()(std::unordered_set< T > &to, const path_type ¶m, bool throwIfMissing=true) const
fill an unordered_set with a configured value retrieved using getExt
Definition: Config.hpp:321
Config(istream &is, char const *section=nullptr)
construct using stream, optionally specifying the section name
Definition: Config.hpp:103
Config()
empty config
Definition: Config.hpp:54
Config(ptree const &t, char const *section=nullptr)
construct using another ptree as fallbacks, optionally specifying the section name ...
Definition: Config.hpp:130
list< pair< string, string > > content(unordered_set< string > const &skipThese=unordered_set< string >()) const
get contents of all the effective configure in the form of list of string pairs
Definition: Config.hpp:373