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 {
45 : boost::property_tree::ptree {
47 using Base = boost::property_tree::ptree;
59 , section_(other.section_)
60 , fallbackConfig_(other.fallbackConfig_
61 ?new
Config(*other.fallbackConfig_)
70 section_ = other.section_;
71 fallbackConfig_.reset(other.fallbackConfig_
72 ?
new Config(*other.fallbackConfig_)
86 Config(std::istream&& is,
char const* section =
nullptr)
87 : section_(section?section:
"") {
88 read_json(is, (Base&)*
this);
101 Config(std::istream& is,
char const* section =
nullptr)
102 : section_(section?section:
"") {
103 read_json(is, (Base&)*
this);
116 Config(
char const* json,
char const* section =
nullptr)
117 :
Config(
std::istringstream(json), section)
128 Config(boost::property_tree::ptree
const& t,
char const* section =
nullptr)
130 , section_(section?section:
"") {
142 Config(boost::property_tree::ptree
const& dft, boost::property_tree::ptree
const& section)
144 , fallbackConfig_(new
Config(dft)) {
154 if (!fallbackConfig_) {
155 fallbackConfig_.reset(
new Config(c));
157 fallbackConfig_->setAdditionalFallbackConfig(c);
177 if (sectionExists) get_child(section);
178 auto sec = section?section:
"";
179 if (get_child_optional(sec)) section_ = sec;
180 if (fallbackConfig_) {
181 fallbackConfig_->resetSection(section,
false);
193 template <
typename ...Args>
195 Base::put(std::forward<Args>(args)...);
209 boost::property_tree::ptree
const&
getChildExt(
const path_type& param) {
211 auto res = get_child_optional(sec/=param);
213 res = get_child_optional(param);
215 if (fallbackConfig_) {
216 return fallbackConfig_->getChildExt(param);
218 throw boost::property_tree::ptree_bad_path(
219 "invalid param and no default user Config set", param);
237 template <
typename T>
238 T
getExt(
const path_type& param,
bool throwIfMissing =
true)
const {
240 auto res = get_optional<T>(sec/=param);
242 res = get_optional<T>(param);
244 if (fallbackConfig_) {
245 return fallbackConfig_->getExt<T>(param, throwIfMissing);
246 }
else if (throwIfMissing) {
247 throw boost::property_tree::ptree_bad_path(
248 "invalid param and no default user Config set", param);
268 template <
typename T>
269 std::vector<T>
getArray(
const path_type& param)
const {
272 auto children = get_child_optional(sec/=param);
273 if (!children) children = get_child_optional(param);
275 for (
auto& v : *children) {
276 if (v.first.empty()) {
277 res.push_back(v.second.get_value<T>());
279 throw boost::property_tree::ptree_bad_data(
280 "param not pointing to array ", param);
284 }
else if (fallbackConfig_) {
285 return fallbackConfig_->getArray<T>(param);
287 throw boost::property_tree::ptree_bad_path(
288 "invalid array param and no default user Config set", param);
301 template <
typename T>
302 T
getHex(boost::property_tree::ptree::path_type
const& param)
const {
303 std::istringstream iss(getExt<std::string>(param));
305 iss >> std::hex >> res;
319 template <
typename T>
321 ,
bool throwIfMissing =
true)
const {
322 to = getExt<T>(param, throwIfMissing);
336 template <
typename T>
338 ,
const boost::property_tree::ptree::path_type& param,
bool throwIfMissing =
true)
const {
340 auto s = getExt<std::string>(param, throwIfMissing);
341 std::istringstream iss(s);
343 for (
auto iit = std::istream_iterator<T>(iss)
344 ; iit != std::istream_iterator<T>()
349 throw (boost::property_tree::ptree_bad_data(
350 "not space separated items in Config ", param));
366 template <
typename T>
367 Config const&
operator()(std::vector<T>& to,
const boost::property_tree::ptree::path_type& param
368 ,
bool throwIfMissing =
true)
const {
370 auto s = getExt<std::string>(param, throwIfMissing);
371 std::istringstream iss(s);
373 for (
auto iit = std::istream_iterator<T>(iss)
374 ; iit != std::istream_iterator<T>()
376 to.emplace_back(*iit);
379 throw (boost::property_tree::ptree_bad_data(
380 "not space separated items in Config ", param));
393 std::list<std::pair<std::string, std::string>>
content(
394 std::unordered_set<std::string>
const& skipThese = std::unordered_set<std::string>())
const {
395 std::list<std::pair<std::string, std::string>> res;
396 std::unordered_set<std::string> history(skipThese);
397 auto secTree = get_child_optional(section_);
399 for (
auto& p : *secTree) {
400 if (history.find(p.first) == history.end()) {
401 history.insert(p.first);
402 if (p.second.empty()) {
403 res.push_back(make_pair(p.first, p.second.get_value<std::string>()));
414 for (
auto& p : *
this) {
415 if (history.find(p.first) == history.end()) {
416 history.insert(p.first);
417 if (p.second.empty()) {
418 res.push_back(make_pair(p.first, p.second.get_value<std::string>()));
428 if (fallbackConfig_) {
429 auto more = fallbackConfig_->content(history);
430 res.insert(res.end(), more.begin(), more.end());
444 for (
auto& r : cfg.
content()) {
445 os << r.first <<
'=' << r.second << std::endl;
447 if (cfg.fallbackConfig_) {
448 os <<
"next in line fallback" << std::endl;
449 os << *cfg.fallbackConfig_ << std::endl;
473 boost::property_tree::ptree::path_type section_;
474 std::unique_ptr<Config> fallbackConfig_;
478 using Config = config_detail::Config;
std::vector< T > getArray(const path_type ¶m) const
get a vector of value from the json array
Definition: Config.hpp:269
T getExt(const path_type ¶m, bool throwIfMissing=true) const
get a value from the config
Definition: Config.hpp:238
Config(Config const &other)
copt ctor
Definition: Config.hpp:57
Config const & operator()(T &to, const boost::property_tree::ptree::path_type ¶m, bool throwIfMissing=true) const
fill in a variable with a configured value retrieved using getExt
Definition: Config.hpp:320
void setDefaultUserConfig(Config const &c)
depracated
Definition: Config.hpp:163
class to hold an hmbdc configuration
Definition: Config.hpp:44
void setAdditionalFallbackConfig(Config const &c)
set additional defaults
Definition: Config.hpp:153
Config(boost::property_tree::ptree const &t, char const *section=nullptr)
construct using another ptree as fallbacks, optionally specifying the section name ...
Definition: Config.hpp:128
Definition: TypedString.hpp:84
Config & resetSection(char const *section, bool sectionExists=true)
change section name
Definition: Config.hpp:176
Config const & operator()(std::vector< T > &to, const boost::property_tree::ptree::path_type ¶m, bool throwIfMissing=true) const
fill an list with a configured value retrieved using getExt
Definition: Config.hpp:367
Config const & operator()(std::unordered_set< T > &to, const boost::property_tree::ptree::path_type ¶m, bool throwIfMissing=true) const
fill an unordered_set with a configured value retrieved using getExt
Definition: Config.hpp:337
friend std::ostream & operator<<(std::ostream &os, Config const &cfg)
stream out the effective settings
Definition: Config.hpp:443
std::list< std::pair< std::string, std::string > > content(std::unordered_set< std::string > const &skipThese=std::unordered_set< std::string >()) const
get contents of all the effective configure in the form of list of string pairs
Definition: Config.hpp:393
Config(char const *json, char const *section=nullptr)
construct using a string, optionally specifying the section name
Definition: Config.hpp:116
Config(std::istream &&is, char const *section=nullptr)
construct using stream, optionally specifying the section name
Definition: Config.hpp:86
Config(std::istream &is, char const *section=nullptr)
construct using stream, optionally specifying the section name
Definition: Config.hpp:101
Config(boost::property_tree::ptree const &dft, boost::property_tree::ptree const §ion)
construct using a fallback ptree, and specify the section ptree
Definition: Config.hpp:142
Config & operator=(Config const &other)
assignment
Definition: Config.hpp:68
Config & put(Args &&... args)
forward the call to ptree's put but return Configure
Definition: Config.hpp:194
Config()
empty config
Definition: Config.hpp:52
boost::property_tree::ptree const & getChildExt(const path_type ¶m)
Gets the child from the config.
Definition: Config.hpp:209
T getHex(boost::property_tree::ptree::path_type const ¶m) const
get a number value in hex format
Definition: Config.hpp:302