50 for (
const T& val : src) {
67 for (
auto const& elt : _map) {
68 if (elt.second->back().type() ==
typeid(
Ptr)) {
69 for (
auto const& j : *elt.second) {
70 Ptr p = boost::any_cast<
Ptr>(j);
72 n->add(elt.first,
Ptr());
74 n->add(elt.first, p->deepCopy());
79 n->_map[elt.first] = vp;
87 for (
auto const& elt : _map) {
89 if (!topLevelOnly && elt.second->back().type() ==
typeid(
Ptr)) {
90 Ptr p = boost::any_cast<
Ptr>(elt.second->back());
92 n += p->nameCount(
false);
101 for (
auto const& elt : _map) {
103 if (!topLevelOnly && elt.second->back().type() ==
typeid(
Ptr)) {
104 Ptr p = boost::any_cast<
Ptr>(elt.second->back());
107 for (
auto const& k : w) {
118 for (
auto const& elt : _map) {
119 if (elt.second->back().type() ==
typeid(
Ptr)) {
120 Ptr p = boost::any_cast<
Ptr>(elt.second->back());
121 if (p.get() != 0 && !topLevelOnly) {
123 for (
auto const& k : w) {
136 for (
auto const& elt : _map) {
137 if (elt.second->back().type() ==
typeid(
Ptr)) {
139 Ptr p = boost::any_cast<
Ptr>(elt.second->back());
140 if (p.get() != 0 && !topLevelOnly) {
142 for (
auto const& k : w) {
154 auto const i = _find(name);
155 return i != _map.end() && i->second->size() > 1U;
159 auto const i = _find(name);
160 return i != _map.end() && i->second->back().type() ==
typeid(
Ptr);
164 auto const i = _find(name);
165 return i != _map.end() && i->second->back().type() ==
typeid(
nullptr);
169 auto const i = _find(name);
170 if (i == _map.end())
return 0;
171 return i->second->size();
175 auto const i = _find(name);
176 if (i == _map.end()) {
177 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
179 return i->second->back().type();
182 template <
typename T>
189 template <
typename T>
192 auto const i = _find(name);
193 if (i == _map.end()) {
194 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
197 return boost::any_cast<T>(i->second->back());
198 }
catch (boost::bad_any_cast) {
199 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
202 return boost::any_cast<T>(i->second->back());
205 template <
typename T>
208 auto const i = _find(name);
209 if (i == _map.end()) {
213 return boost::any_cast<T>(i->second->back());
214 }
catch (boost::bad_any_cast) {
215 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
218 return boost::any_cast<T>(i->second->back());
221 template <
typename T>
223 auto const i = _find(name);
224 if (i == _map.end()) {
225 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
228 for (
auto const& j : *(i->second)) {
231 }
catch (boost::bad_any_cast) {
232 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
242 return get<bool>(name);
246 auto const i = _find(name);
247 if (i == _map.end()) {
248 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
250 boost::any v = i->second->
back();
252 if (t ==
typeid(
bool)) {
253 return boost::any_cast<
bool>(v);
254 }
else if (t ==
typeid(
char)) {
255 return boost::any_cast<
char>(v);
256 }
else if (t ==
typeid(
signed char)) {
257 return boost::any_cast<
signed char>(v);
258 }
else if (t ==
typeid(
unsigned char)) {
259 return boost::any_cast<
unsigned char>(v);
260 }
else if (t ==
typeid(
short)) {
261 return boost::any_cast<
short>(v);
262 }
else if (t ==
typeid(
unsigned short)) {
263 return boost::any_cast<
unsigned short>(v);
266 return boost::any_cast<
int>(v);
267 }
catch (boost::bad_any_cast) {
268 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
271 return boost::any_cast<
int>(v);
275 auto const i = _find(name);
276 if (i == _map.end()) {
277 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
279 boost::any v = i->second->back();
281 if (t ==
typeid(
bool))
return boost::any_cast<
bool>(v);
282 if (t ==
typeid(
char))
return boost::any_cast<char>(v);
283 if (t ==
typeid(
signed char))
return boost::any_cast<signed char>(v);
284 if (t ==
typeid(
unsigned char))
return boost::any_cast<unsigned char>(v);
285 if (t ==
typeid(
short))
return boost::any_cast<short>(v);
286 if (t ==
typeid(
unsigned short))
return boost::any_cast<unsigned short>(v);
287 if (t ==
typeid(
int))
return boost::any_cast<int>(v);
288 if (t ==
typeid(
unsigned int))
return boost::any_cast<unsigned int>(v);
289 if (t ==
typeid(
long))
return boost::any_cast<long>(v);
290 if (t ==
typeid(
long long))
return boost::any_cast<long long>(v);
292 return boost::any_cast<int64_t>(v);
293 }
catch (boost::bad_any_cast) {
294 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
297 return boost::any_cast<int64_t>(v);
301 auto const i = _find(name);
302 if (i == _map.end()) {
303 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
305 boost::any v = i->second->back();
307 if (t ==
typeid(
bool))
return boost::any_cast<
bool>(v);
308 if (t ==
typeid(
char))
return boost::any_cast<char>(v);
309 if (t ==
typeid(
signed char))
return boost::any_cast<signed char>(v);
310 if (t ==
typeid(
unsigned char))
return boost::any_cast<unsigned char>(v);
311 if (t ==
typeid(
short))
return boost::any_cast<short>(v);
312 if (t ==
typeid(
unsigned short))
return boost::any_cast<unsigned short>(v);
313 if (t ==
typeid(
int))
return boost::any_cast<int>(v);
314 if (t ==
typeid(
unsigned int))
return boost::any_cast<unsigned int>(v);
315 if (t ==
typeid(
long))
return boost::any_cast<long>(v);
316 if (t ==
typeid(
unsigned long))
return boost::any_cast<unsigned long>(v);
317 if (t ==
typeid(
long long))
return boost::any_cast<long long>(v);
318 if (t ==
typeid(
unsigned long long))
return boost::any_cast<unsigned long long>(v);
319 if (t ==
typeid(
float))
return boost::any_cast<float>(v);
321 return boost::any_cast<
double>(v);
322 }
catch (boost::bad_any_cast) {
323 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
326 return boost::any_cast<
double>(v);
334 return get<Persistable::Ptr>(name);
341 for (
auto const& i : nv) {
344 if (t ==
typeid(
Ptr)) {
345 s << indent << i <<
" = ";
349 Ptr p = boost::any_cast<
Ptr>(vp->back());
354 s << p->toString(
false, indent +
"..");
369 auto const j = _map.find(name);
370 s << j->first <<
" = ";
372 if (vp->size() > 1) {
377 for (
auto const& k : *vp) {
383 boost::any
const& v(k);
384 if (t ==
typeid(
bool)) {
385 s << boost::any_cast<bool>(v);
386 }
else if (t ==
typeid(
char)) {
387 s << '\'' << boost::any_cast<char>(v) <<
'\'';
388 }
else if (t ==
typeid(
signed char)) {
389 s << '\'' << boost::any_cast<signed char>(v) <<
'\'';
390 }
else if (t ==
typeid(
unsigned char)) {
391 s << '\'' << boost::any_cast<unsigned char>(v) <<
'\'';
392 }
else if (t ==
typeid(
short)) {
393 s << boost::any_cast<short>(v);
394 }
else if (t ==
typeid(
unsigned short)) {
395 s << boost::any_cast<unsigned short>(v);
396 }
else if (t ==
typeid(
int)) {
397 s << boost::any_cast<int>(v);
398 }
else if (t ==
typeid(
unsigned int)) {
399 s << boost::any_cast<unsigned int>(v);
400 }
else if (t ==
typeid(
long)) {
401 s << boost::any_cast<long>(v);
402 }
else if (t ==
typeid(
unsigned long)) {
403 s << boost::any_cast<unsigned long>(v);
404 }
else if (t ==
typeid(
long long)) {
405 s << boost::any_cast<long long>(v);
406 }
else if (t ==
typeid(
unsigned long long)) {
407 s << boost::any_cast<unsigned long long>(v);
408 }
else if (t ==
typeid(
float)) {
409 s << std::setprecision(7) << boost::any_cast<float>(v);
410 }
else if (t ==
typeid(
double)) {
411 s << std::setprecision(14) << boost::any_cast<double>(v);
413 s <<
'"' << boost::any_cast<
std::string>(v) <<
'"';
414 }
else if (t ==
typeid(DateTime)) {
416 }
else if (t ==
typeid(
Ptr)) {
419 s <<
"<Persistable>";
424 if (j->second->size() > 1) {
435 template <
typename T>
438 vp->push_back(value);
442 template <
typename T>
444 if (value.
empty())
return;
452 template <
typename T>
454 AnyMap::iterator i = _find(name);
455 if (i == _map.end()) {
458 if (i->second->back().type() !=
typeid(T)) {
459 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
461 i->second->push_back(value);
467 void PropertySet::add<PropertySet::Ptr>(
std::string const& name,
Ptr const& value) {
468 AnyMap::iterator i = _find(name);
469 if (i == _map.end()) {
472 if (i->second->back().type() !=
typeid(
Ptr)) {
473 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
475 _cycleCheckPtr(value, name);
476 i->second->push_back(value);
480 template <
typename T>
482 AnyMap::iterator i = _find(name);
483 if (i == _map.end()) {
486 if (i->second->back().type() !=
typeid(T)) {
487 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
489 _append(*(i->second), value);
496 AnyMap::iterator i = _find(name);
497 if (i == _map.end()) {
500 if (i->second->back().type() !=
typeid(
Ptr)) {
501 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
503 _cycleCheckPtrVec(value, name);
504 _append(*(i->second), value);
511 if (source.get() == 0) {
512 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
"Missing source");
514 auto const sj = source->_find(name);
515 if (sj == source->_map.end()) {
516 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" not in source");
520 auto vp = std::make_shared<std::vector<boost::any>>();
521 vp->push_back(sj->second->back());
524 auto vp = std::make_shared<std::vector<boost::any>>(*(sj->second));
530 if (source.get() == 0) {
534 for (
auto const& name : names) {
535 auto const sp = source->_find(name);
536 _add(name, sp->second);
541 std::string::size_type i = name.
find(
'.');
542 if (_flat || i == name.npos) {
547 AnyMap::iterator j = _map.find(prefix);
548 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
551 Ptr p = boost::any_cast<
Ptr>(j->second->back());
562 PropertySet::AnyMap::iterator PropertySet::_find(
std::string const& name) {
563 std::string::size_type i = name.
find(
'.');
564 if (_flat || i == name.npos) {
565 return _map.find(name);
568 AnyMap::iterator j = _map.find(prefix);
569 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
572 Ptr p = boost::any_cast<
Ptr>(j->second->back());
577 AnyMap::iterator x = p->_find(suffix);
578 if (x == p->_map.end()) {
584 PropertySet::AnyMap::const_iterator PropertySet::_find(
std::string const& name)
const {
585 std::string::size_type i = name.
find(
'.');
586 if (_flat || i == name.npos) {
587 return _map.find(name);
590 auto const j = _map.find(prefix);
591 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
594 Ptr p = boost::any_cast<
Ptr>(j->second->back());
599 auto const x = p->_find(suffix);
600 if (x == p->_map.end()) {
607 _findOrInsert(name, vp);
611 auto const dp = _find(name);
612 if (dp == _map.end()) {
615 if (vp->back().type() != dp->second->back().type()) {
616 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
619 if (vp->back().type() ==
typeid(
Ptr)) {
620 _cycleCheckAnyVec(*vp, name);
622 _append(*(dp->second), *vp);
627 if (vp->back().type() ==
typeid(
Ptr)) {
629 Ptr source = boost::any_cast<
Ptr>(vp->back());
631 for (
auto const& i : names) {
632 auto const sp = source->_find(i);
633 _add(name +
"." + i, sp->second);
639 _cycleCheckAnyVec(*vp, name);
642 std::string::size_type i = name.
find(
'.');
643 if (_flat || i == name.npos) {
649 AnyMap::iterator j = _map.find(prefix);
650 if (j == _map.end()) {
652 pp->_findOrInsert(suffix, vp);
657 }
else if (j->second->back().type() !=
typeid(
Ptr)) {
658 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
659 prefix +
" exists but does not contain PropertySet::Ptrs");
661 Ptr p = boost::any_cast<
Ptr>(j->second->back());
663 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
664 prefix +
" exists but contains null PropertySet::Ptr");
666 p->_findOrInsert(suffix, vp);
670 for (
auto const& i : v) {
671 _cycleCheckPtr(i, name);
676 for (
auto const& i : v) {
677 _cycleCheckPtr(boost::any_cast<Ptr>(i), name);
681 void PropertySet::_cycleCheckPtr(
Ptr const& v,
std::string const& name) {
682 if (v.get() ==
this) {
683 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" would cause a cycle");
686 for (
auto const& i : sets) {
687 if (v->getAsPropertySetPtr(i).get() ==
this) {
688 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" would cause a cycle");
700 #define INSTANTIATE(t) \ 701 template std::type_info const& PropertySet::typeOfT<t>(); \ 702 template t PropertySet::get<t>(std::string const& name) const; \ 703 template t PropertySet::get<t>(std::string const& name, t const& defaultValue) const; \ 704 template std::vector<t> PropertySet::getArray<t>(std::string const& name) const; \ 705 template void PropertySet::set<t>(std::string const& name, t const& value); \ 706 template void PropertySet::set<t>(std::string const& name, std::vector<t> const& value); \ 707 template void PropertySet::add<t>(std::string const& name, t const& value); \ 708 template void PropertySet::add<t>(std::string const& name, std::vector<t> const& value); 710 #define INSTANTIATE_PROPERTY_SET(t) \ 711 template std::type_info const& PropertySet::typeOfT<t>(); \ 712 template t PropertySet::get<t>(std::string const& name) const; \ 713 template t PropertySet::get<t>(std::string const& name, t const& defaultValue) const; \ 714 template std::vector<t> PropertySet::getArray<t>(std::string const& name) const; \ 715 template void PropertySet::set<t>(std::string const& name, t const& value); \ 716 template void PropertySet::set<t>(std::string const& name, std::vector<t> const& value); 720 INSTANTIATE(
signed char)
721 INSTANTIATE(
unsigned char)
723 INSTANTIATE(
unsigned short)
725 INSTANTIATE(
unsigned int)
727 INSTANTIATE(
unsigned long)
728 INSTANTIATE(
long long)
729 INSTANTIATE(
unsigned long long)
736 INSTANTIATE(DateTime)
double getAsDouble(std::string const &name) const
Get the last value for any arithmetic property name (possibly hierarchical).
virtual std::string toString(bool topLevelOnly=false, std::string const &indent="") const
Generate a string representation of the PropertySet.
static std::type_info const & typeOfT()
Get type info for the specified class.
std::shared_ptr< PropertySet > Ptr
virtual PropertySet::Ptr deepCopy() const
Make a deep copy of the PropertyList and all of its contents.
virtual void copy(std::string const &dest, ConstPtr source, std::string const &name, bool asScalar=false)
Replace a single value vector in the destination with one from the source.
size_t valueCount(std::string const &name) const
Get the number of values for a property name (possibly hierarchical).
virtual std::string toString(bool topLevelOnly=false, std::string const &indent="") const
Generate a string representation of the PropertySet.
std::vector< T > getArray(std::string const &name) const
Get the vector of values for a property name (possibly hierarchical).
virtual void combine(ConstPtr source)
Append all value vectors from the source to their corresponding properties.
T get(std::string const &name) const
Get the last value for a property name (possibly hierarchical).
bool getAsBool(std::string const &name) const
Get the last value for a bool property name (possibly hierarchical).
std::vector< std::string > propertySetNames(bool topLevelOnly=true) const
A variant of names that only returns the names of subproperties.
int getAsInt(std::string const &name) const
Get the last value for a bool/char/short/int property name (possibly hierarchical).
PropertySet::Ptr getAsPropertySetPtr(std::string const &name) const
Get the last value for a subproperty name (possibly hierarchical).
virtual std::string _format(std::string const &name) const
bool isPropertySetPtr(std::string const &name) const
Determine if a name (possibly hierarchical) is a subproperty.
virtual void remove(std::string const &name)
Remove all values for a property name (possibly hierarchical).
std::vector< std::string > paramNames(bool topLevelOnly=true) const
A variant of names that excludes the names of subproperties.
PropertySet(bool flat=false)
Construct an empty PropertySet.
void set(std::string const &name, T const &value)
Replace all values for a property name (possibly hierarchical) with a new scalar value.
bool isArray(std::string const &name) const
Determine if a name (possibly hierarchical) has multiple values.
std::shared_ptr< PropertyList const > ConstPtr
std::shared_ptr< PropertyList > Ptr
void add(std::string const &name, T const &value)
Append a single value to the vector of values for a property name (possibly hierarchical).
int64_t getAsInt64(std::string const &name) const
Get the last value for a bool/char/short/int/int64_t property name (possibly hierarchical).
size_t nameCount(bool topLevelOnly=true) const
Get the number of names in the PropertySet, optionally including those in subproperties.
bool exists(std::string const &name) const
Determine if a name (possibly hierarchical) exists.
virtual void _set(std::string const &name, std::shared_ptr< std::vector< boost::any > > vp)
Interface for DateTime class.
Persistable::Ptr getAsPersistablePtr(std::string const &name) const
Get the last value for a Persistable name (possibly hierarchical).
#define LSST_EXCEPT(type,...)
virtual void _add(std::string const &name, std::shared_ptr< std::vector< boost::any > > vp)
virtual ~PropertySet() noexcept
Destructor.
std::shared_ptr< Persistable > Ptr
std::string getAsString(std::string const &name) const
Get the last value for a string property name (possibly hierarchical).
std::vector< std::string > names(bool topLevelOnly=true) const
Get the names in the PropertySet, optionally including those in subproperties.
void add(std::string const &name, T const &value)
Append a single value to the vector of values for a property name (possibly hierarchical).
bool isUndefined(std::string const &name) const
Determine if a name (possibly hierarchical) has a defined value.
std::type_info const & typeOf(std::string const &name) const
Get the type of values for a property name (possibly hierarchical).