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 if (i == _map.end())
return 0;
166 return i->second->size();
170 auto const i = _find(name);
171 if (i == _map.end()) {
172 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
174 return i->second->back().type();
177 template <
typename T>
184 template <
typename T>
187 auto const i = _find(name);
188 if (i == _map.end()) {
189 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
192 return boost::any_cast<T>(i->second->back());
193 }
catch (boost::bad_any_cast) {
194 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
197 return boost::any_cast<T>(i->second->back());
200 template <
typename T>
203 auto const i = _find(name);
204 if (i == _map.end()) {
208 return boost::any_cast<T>(i->second->back());
209 }
catch (boost::bad_any_cast) {
210 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
213 return boost::any_cast<T>(i->second->back());
216 template <
typename T>
218 auto const i = _find(name);
219 if (i == _map.end()) {
220 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
223 for (
auto const& j : *(i->second)) {
226 }
catch (boost::bad_any_cast) {
227 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
237 return get<bool>(name);
241 auto const i = _find(name);
242 if (i == _map.end()) {
243 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
245 boost::any v = i->second->
back();
247 if (t ==
typeid(
bool)) {
248 return boost::any_cast<
bool>(v);
249 }
else if (t ==
typeid(
char)) {
250 return boost::any_cast<
char>(v);
251 }
else if (t ==
typeid(
signed char)) {
252 return boost::any_cast<
signed char>(v);
253 }
else if (t ==
typeid(
unsigned char)) {
254 return boost::any_cast<
unsigned char>(v);
255 }
else if (t ==
typeid(
short)) {
256 return boost::any_cast<
short>(v);
257 }
else if (t ==
typeid(
unsigned short)) {
258 return boost::any_cast<
unsigned short>(v);
261 return boost::any_cast<
int>(v);
262 }
catch (boost::bad_any_cast) {
263 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
266 return boost::any_cast<
int>(v);
270 auto const i = _find(name);
271 if (i == _map.end()) {
272 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
274 boost::any v = i->second->back();
276 if (t ==
typeid(
bool))
return boost::any_cast<
bool>(v);
277 if (t ==
typeid(
char))
return boost::any_cast<char>(v);
278 if (t ==
typeid(
signed char))
return boost::any_cast<signed char>(v);
279 if (t ==
typeid(
unsigned char))
return boost::any_cast<unsigned char>(v);
280 if (t ==
typeid(
short))
return boost::any_cast<short>(v);
281 if (t ==
typeid(
unsigned short))
return boost::any_cast<unsigned short>(v);
282 if (t ==
typeid(
int))
return boost::any_cast<int>(v);
283 if (t ==
typeid(
unsigned int))
return boost::any_cast<unsigned int>(v);
284 if (t ==
typeid(
long))
return boost::any_cast<long>(v);
285 if (t ==
typeid(
long long))
return boost::any_cast<long long>(v);
287 return boost::any_cast<int64_t>(v);
288 }
catch (boost::bad_any_cast) {
289 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
292 return boost::any_cast<int64_t>(v);
296 auto const i = _find(name);
297 if (i == _map.end()) {
298 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
300 boost::any v = i->second->back();
302 if (t ==
typeid(
bool))
return boost::any_cast<
bool>(v);
303 if (t ==
typeid(
char))
return boost::any_cast<char>(v);
304 if (t ==
typeid(
signed char))
return boost::any_cast<signed char>(v);
305 if (t ==
typeid(
unsigned char))
return boost::any_cast<unsigned char>(v);
306 if (t ==
typeid(
short))
return boost::any_cast<short>(v);
307 if (t ==
typeid(
unsigned short))
return boost::any_cast<unsigned short>(v);
308 if (t ==
typeid(
int))
return boost::any_cast<int>(v);
309 if (t ==
typeid(
unsigned int))
return boost::any_cast<unsigned int>(v);
310 if (t ==
typeid(
long))
return boost::any_cast<long>(v);
311 if (t ==
typeid(
unsigned long))
return boost::any_cast<unsigned long>(v);
312 if (t ==
typeid(
long long))
return boost::any_cast<long long>(v);
313 if (t ==
typeid(
unsigned long long))
return boost::any_cast<unsigned long long>(v);
314 if (t ==
typeid(
float))
return boost::any_cast<float>(v);
316 return boost::any_cast<
double>(v);
317 }
catch (boost::bad_any_cast) {
318 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
321 return boost::any_cast<
double>(v);
329 return get<Persistable::Ptr>(name);
336 for (
auto const& i : nv) {
339 if (t ==
typeid(
Ptr)) {
340 s << indent << i <<
" = ";
344 Ptr p = boost::any_cast<
Ptr>(vp->back());
349 s << p->toString(
false, indent +
"..");
364 auto const j = _map.find(name);
365 s << j->first <<
" = ";
367 if (vp->size() > 1) {
372 for (
auto const& k : *vp) {
378 boost::any
const& v(k);
379 if (t ==
typeid(
bool)) {
380 s << boost::any_cast<bool>(v);
381 }
else if (t ==
typeid(
char)) {
382 s << '\'' << boost::any_cast<char>(v) <<
'\'';
383 }
else if (t ==
typeid(
signed char)) {
384 s << '\'' << boost::any_cast<signed char>(v) <<
'\'';
385 }
else if (t ==
typeid(
unsigned char)) {
386 s << '\'' << boost::any_cast<unsigned char>(v) <<
'\'';
387 }
else if (t ==
typeid(
short)) {
388 s << boost::any_cast<short>(v);
389 }
else if (t ==
typeid(
unsigned short)) {
390 s << boost::any_cast<unsigned short>(v);
391 }
else if (t ==
typeid(
int)) {
392 s << boost::any_cast<int>(v);
393 }
else if (t ==
typeid(
unsigned int)) {
394 s << boost::any_cast<unsigned int>(v);
395 }
else if (t ==
typeid(
long)) {
396 s << boost::any_cast<long>(v);
397 }
else if (t ==
typeid(
unsigned long)) {
398 s << boost::any_cast<unsigned long>(v);
399 }
else if (t ==
typeid(
long long)) {
400 s << boost::any_cast<long long>(v);
401 }
else if (t ==
typeid(
unsigned long long)) {
402 s << boost::any_cast<unsigned long long>(v);
403 }
else if (t ==
typeid(
float)) {
404 s << std::setprecision(7) << boost::any_cast<float>(v);
405 }
else if (t ==
typeid(
double)) {
406 s << std::setprecision(14) << boost::any_cast<double>(v);
408 s <<
'"' << boost::any_cast<
std::string>(v) <<
'"';
409 }
else if (t ==
typeid(DateTime)) {
411 }
else if (t ==
typeid(
Ptr)) {
414 s <<
"<Persistable>";
419 if (j->second->size() > 1) {
430 template <
typename T>
433 vp->push_back(value);
437 template <
typename T>
439 if (value.
empty())
return;
447 template <
typename T>
449 AnyMap::iterator i = _find(name);
450 if (i == _map.end()) {
453 if (i->second->back().type() !=
typeid(T)) {
454 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
456 i->second->push_back(value);
462 void PropertySet::add<PropertySet::Ptr>(
std::string const& name,
Ptr const& value) {
463 AnyMap::iterator i = _find(name);
464 if (i == _map.end()) {
467 if (i->second->back().type() !=
typeid(
Ptr)) {
468 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
470 _cycleCheckPtr(value, name);
471 i->second->push_back(value);
475 template <
typename T>
477 AnyMap::iterator i = _find(name);
478 if (i == _map.end()) {
481 if (i->second->back().type() !=
typeid(T)) {
482 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
484 _append(*(i->second), value);
491 AnyMap::iterator i = _find(name);
492 if (i == _map.end()) {
495 if (i->second->back().type() !=
typeid(
Ptr)) {
496 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
498 _cycleCheckPtrVec(value, name);
499 _append(*(i->second), value);
506 if (source.get() == 0) {
507 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
"Missing source");
509 auto const sj = source->_find(name);
510 if (sj == source->_map.end()) {
511 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" not in source");
515 auto vp = std::make_shared<std::vector<boost::any>>();
516 vp->push_back(sj->second->back());
519 auto vp = std::make_shared<std::vector<boost::any>>(*(sj->second));
525 if (source.get() == 0) {
529 for (
auto const& name : names) {
530 auto const sp = source->_find(name);
531 _add(name, sp->second);
536 std::string::size_type i = name.
find(
'.');
537 if (_flat || i == name.npos) {
542 AnyMap::iterator j = _map.find(prefix);
543 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
546 Ptr p = boost::any_cast<
Ptr>(j->second->back());
557 PropertySet::AnyMap::iterator PropertySet::_find(
std::string const& name) {
558 std::string::size_type i = name.
find(
'.');
559 if (_flat || i == name.npos) {
560 return _map.find(name);
563 AnyMap::iterator j = _map.find(prefix);
564 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
567 Ptr p = boost::any_cast<
Ptr>(j->second->back());
572 AnyMap::iterator x = p->_find(suffix);
573 if (x == p->_map.end()) {
579 PropertySet::AnyMap::const_iterator PropertySet::_find(
std::string const& name)
const {
580 std::string::size_type i = name.
find(
'.');
581 if (_flat || i == name.npos) {
582 return _map.find(name);
585 auto const j = _map.find(prefix);
586 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
589 Ptr p = boost::any_cast<
Ptr>(j->second->back());
594 auto const x = p->_find(suffix);
595 if (x == p->_map.end()) {
602 _findOrInsert(name, vp);
606 auto const dp = _find(name);
607 if (dp == _map.end()) {
610 if (vp->back().type() != dp->second->back().type()) {
611 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
614 if (vp->back().type() ==
typeid(
Ptr)) {
615 _cycleCheckAnyVec(*vp, name);
617 _append(*(dp->second), *vp);
622 if (vp->back().type() ==
typeid(
Ptr)) {
624 Ptr source = boost::any_cast<
Ptr>(vp->back());
626 for (
auto const& i : names) {
627 auto const sp = source->_find(i);
628 _add(name +
"." + i, sp->second);
634 _cycleCheckAnyVec(*vp, name);
637 std::string::size_type i = name.
find(
'.');
638 if (_flat || i == name.npos) {
644 AnyMap::iterator j = _map.find(prefix);
645 if (j == _map.end()) {
647 pp->_findOrInsert(suffix, vp);
652 }
else if (j->second->back().type() !=
typeid(
Ptr)) {
653 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
654 prefix +
" exists but does not contain PropertySet::Ptrs");
656 Ptr p = boost::any_cast<
Ptr>(j->second->back());
658 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
659 prefix +
" exists but contains null PropertySet::Ptr");
661 p->_findOrInsert(suffix, vp);
665 for (
auto const& i : v) {
666 _cycleCheckPtr(i, name);
671 for (
auto const& i : v) {
672 _cycleCheckPtr(boost::any_cast<Ptr>(i), name);
676 void PropertySet::_cycleCheckPtr(
Ptr const& v,
std::string const& name) {
677 if (v.get() ==
this) {
678 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" would cause a cycle");
681 for (
auto const& i : sets) {
682 if (v->getAsPropertySetPtr(i).get() ==
this) {
683 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" would cause a cycle");
695 #define INSTANTIATE(t) \ 696 template std::type_info const& PropertySet::typeOfT<t>(); \ 697 template t PropertySet::get<t>(std::string const& name) const; \ 698 template t PropertySet::get<t>(std::string const& name, t const& defaultValue) const; \ 699 template std::vector<t> PropertySet::getArray<t>(std::string const& name) const; \ 700 template void PropertySet::set<t>(std::string const& name, t const& value); \ 701 template void PropertySet::set<t>(std::string const& name, std::vector<t> const& value); \ 702 template void PropertySet::add<t>(std::string const& name, t const& value); \ 703 template void PropertySet::add<t>(std::string const& name, std::vector<t> const& value); 705 #define INSTANTIATE_PROPERTY_SET(t) \ 706 template std::type_info const& PropertySet::typeOfT<t>(); \ 707 template t PropertySet::get<t>(std::string const& name) const; \ 708 template t PropertySet::get<t>(std::string const& name, t const& defaultValue) const; \ 709 template std::vector<t> PropertySet::getArray<t>(std::string const& name) const; \ 710 template void PropertySet::set<t>(std::string const& name, t const& value); \ 711 template void PropertySet::set<t>(std::string const& name, std::vector<t> const& value); 715 INSTANTIATE(
signed char)
716 INSTANTIATE(
unsigned char)
718 INSTANTIATE(
unsigned short)
720 INSTANTIATE(
unsigned int)
722 INSTANTIATE(
unsigned long)
723 INSTANTIATE(
long long)
724 INSTANTIATE(
unsigned long long)
730 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).
std::type_info const & typeOf(std::string const &name) const
Get the type of values for a property name (possibly hierarchical).