51 for (
const T& val : src) {
60 PropertySet::~PropertySet() noexcept = default;
66 PropertySet::Ptr PropertySet::deepCopy()
const {
67 Ptr n(
new PropertySet(_flat));
68 for (
auto const& elt : _map) {
69 if (elt.second->back().type() ==
typeid(Ptr)) {
70 for (
auto const& j : *elt.second) {
71 Ptr p = std::any_cast<Ptr>(j);
73 n->add(elt.first, Ptr());
75 n->add(elt.first, p->deepCopy());
80 n->_map[elt.first] = vp;
86 size_t PropertySet::nameCount(
bool topLevelOnly)
const {
88 for (
auto const& elt : _map) {
90 if (!topLevelOnly && elt.second->back().type() ==
typeid(Ptr)) {
91 Ptr p = std::any_cast<Ptr>(elt.second->back());
93 n += p->nameCount(
false);
102 for (
auto const& elt : _map) {
104 if (!topLevelOnly && elt.second->back().type() ==
typeid(Ptr)) {
105 Ptr p = std::any_cast<Ptr>(elt.second->back());
108 for (
auto const& k : w) {
119 for (
auto const& elt : _map) {
120 if (elt.second->back().type() ==
typeid(Ptr)) {
121 Ptr p = std::any_cast<Ptr>(elt.second->back());
122 if (p.get() != 0 && !topLevelOnly) {
124 for (
auto const& k : w) {
137 for (
auto const& elt : _map) {
138 if (elt.second->back().type() ==
typeid(Ptr)) {
140 Ptr p = std::any_cast<Ptr>(elt.second->back());
141 if (p.get() != 0 && !topLevelOnly) {
143 for (
auto const& k : w) {
152 bool PropertySet::exists(
std::string const& name)
const {
return _find(name) != _map.
end(); }
154 bool PropertySet::isArray(
std::string const& name)
const {
155 auto const i = _find(name);
156 return i != _map.end() && i->second->size() > 1U;
159 bool PropertySet::isPropertySetPtr(
std::string const& name)
const {
160 auto const i = _find(name);
161 return i != _map.end() && i->second->back().type() ==
typeid(Ptr);
164 bool PropertySet::isUndefined(
std::string const& name)
const {
165 auto const i = _find(name);
166 return i != _map.end() && i->second->back().type() ==
typeid(
nullptr);
169 size_t PropertySet::valueCount()
const {
171 for (
auto const& name : paramNames(
false)) {
172 sum += valueCount(name);
177 size_t PropertySet::valueCount(
std::string const& name)
const {
178 auto const i = _find(name);
179 if (i == _map.end())
return 0;
180 return i->second->size();
184 auto const i = _find(name);
185 if (i == _map.end()) {
186 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
188 return i->second->back().type();
191 template <
typename T>
198 template <
typename T>
201 auto const i = _find(name);
202 if (i == _map.end()) {
203 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
206 return std::any_cast<T>(i->second->back());
207 }
catch (std::bad_any_cast &) {
211 return std::any_cast<T>(i->second->back());
214 template <
typename T>
215 T PropertySet::get(
std::string const& name, T
const& defaultValue)
217 auto const i = _find(name);
218 if (i == _map.end()) {
222 return std::any_cast<T>(i->second->back());
223 }
catch (std::bad_any_cast &) {
227 return std::any_cast<T>(i->second->back());
230 template <
typename T>
232 auto const i = _find(name);
233 if (i == _map.end()) {
234 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
237 for (
auto const& j : *(i->second)) {
240 }
catch (std::bad_any_cast &) {
249 bool PropertySet::getAsBool(
std::string const& name)
251 return get<bool>(name);
254 int PropertySet::getAsInt(
std::string const& name)
const {
255 auto const i = _find(name);
256 if (i == _map.end()) {
257 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
259 std::any v = i->second->
back();
261 if (t ==
typeid(
bool)) {
262 return std::any_cast<bool>(v);
263 }
else if (t ==
typeid(
char)) {
264 return std::any_cast<char>(v);
265 }
else if (t ==
typeid(
signed char)) {
266 return std::any_cast<signed char>(v);
267 }
else if (t ==
typeid(
unsigned char)) {
268 return std::any_cast<unsigned char>(v);
269 }
else if (t ==
typeid(
short)) {
270 return std::any_cast<short>(v);
271 }
else if (t ==
typeid(
unsigned short)) {
272 return std::any_cast<unsigned short>(v);
275 return std::any_cast<int>(v);
276 }
catch (std::bad_any_cast &) {
280 return std::any_cast<int>(v);
283 int64_t PropertySet::getAsInt64(
std::string const& name)
const {
284 auto const i = _find(name);
285 if (i == _map.end()) {
286 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
288 std::any v = i->second->back();
290 if (t ==
typeid(
bool))
return std::any_cast<bool>(v);
291 if (t ==
typeid(
char))
return std::any_cast<char>(v);
292 if (t ==
typeid(
signed char))
return std::any_cast<signed char>(v);
293 if (t ==
typeid(
unsigned char))
return std::any_cast<unsigned char>(v);
294 if (t ==
typeid(
short))
return std::any_cast<short>(v);
295 if (t ==
typeid(
unsigned short))
return std::any_cast<unsigned short>(v);
296 if (t ==
typeid(
int))
return std::any_cast<int>(v);
297 if (t ==
typeid(
unsigned int))
return std::any_cast<unsigned int>(v);
298 if (t ==
typeid(
long))
return std::any_cast<long>(v);
299 if (t ==
typeid(
long long))
return std::any_cast<long long>(v);
301 return std::any_cast<int64_t>(v);
302 }
catch (std::bad_any_cast &) {
306 return std::any_cast<int64_t>(v);
309 uint64_t PropertySet::getAsUInt64(
std::string const& name)
const {
310 auto const i = _find(name);
311 if (i == _map.end()) {
312 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
314 std::any v = i->second->back();
316 if (t ==
typeid(
bool))
return std::any_cast<bool>(v);
317 if (t ==
typeid(
char))
return std::any_cast<char>(v);
318 if (t ==
typeid(
signed char))
return std::any_cast<signed char>(v);
319 if (t ==
typeid(
unsigned char))
return std::any_cast<unsigned char>(v);
320 if (t ==
typeid(
short))
return std::any_cast<short>(v);
321 if (t ==
typeid(
unsigned short))
return std::any_cast<unsigned short>(v);
322 if (t ==
typeid(
int))
return std::any_cast<int>(v);
323 if (t ==
typeid(
unsigned int))
return std::any_cast<unsigned int>(v);
324 if (t ==
typeid(
long))
return std::any_cast<long>(v);
325 if (t ==
typeid(
long long))
return std::any_cast<long long>(v);
326 if (t ==
typeid(
unsigned long long))
return std::any_cast<unsigned long long>(v);
328 return std::any_cast<uint64_t>(v);
329 }
catch (std::bad_any_cast &) {
333 return std::any_cast<uint64_t>(v);
336 double PropertySet::getAsDouble(
std::string const& name)
const {
337 auto const i = _find(name);
338 if (i == _map.end()) {
339 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
341 std::any v = i->second->back();
343 if (t ==
typeid(
bool))
return std::any_cast<bool>(v);
344 if (t ==
typeid(
char))
return std::any_cast<char>(v);
345 if (t ==
typeid(
signed char))
return std::any_cast<signed char>(v);
346 if (t ==
typeid(
unsigned char))
return std::any_cast<unsigned char>(v);
347 if (t ==
typeid(
short))
return std::any_cast<short>(v);
348 if (t ==
typeid(
unsigned short))
return std::any_cast<unsigned short>(v);
349 if (t ==
typeid(
int))
return std::any_cast<int>(v);
350 if (t ==
typeid(
unsigned int))
return std::any_cast<unsigned int>(v);
351 if (t ==
typeid(
long))
return std::any_cast<long>(v);
352 if (t ==
typeid(
unsigned long))
return std::any_cast<unsigned long>(v);
353 if (t ==
typeid(
long long))
return std::any_cast<long long>(v);
354 if (t ==
typeid(
unsigned long long))
return std::any_cast<unsigned long long>(v);
355 if (t ==
typeid(
float))
return std::any_cast<float>(v);
357 return std::any_cast<double>(v);
358 }
catch (std::bad_any_cast &) {
362 return std::any_cast<double>(v);
367 PropertySet::Ptr PropertySet::getAsPropertySetPtr(
std::string const& name)
const {
return get<Ptr>(name); }
369 Persistable::Ptr PropertySet::getAsPersistablePtr(
std::string const& name)
const {
370 return get<Persistable::Ptr>(name);
377 for (
auto const& i : nv) {
380 if (t ==
typeid(Ptr)) {
381 s << indent << i <<
" = ";
385 Ptr p = std::any_cast<Ptr>(vp->back());
390 s << p->toString(
false, indent +
"..");
396 s << indent << _format(i);
405 auto const j = _map.find(name);
406 s << j->first <<
" = ";
408 if (vp->size() > 1) {
413 for (
auto const& k : *vp) {
419 std::any
const& v(k);
420 if (t ==
typeid(
bool)) {
421 s << std::any_cast<bool>(v);
422 }
else if (t ==
typeid(
char)) {
423 s << '\'' << std::any_cast<char>(v) <<
'\'';
424 }
else if (t ==
typeid(
signed char)) {
425 s << '\'' << std::any_cast<signed char>(v) <<
'\'';
426 }
else if (t ==
typeid(
unsigned char)) {
427 s << '\'' << std::any_cast<unsigned char>(v) <<
'\'';
428 }
else if (t ==
typeid(
short)) {
429 s << std::any_cast<short>(v);
430 }
else if (t ==
typeid(
unsigned short)) {
431 s << std::any_cast<unsigned short>(v);
432 }
else if (t ==
typeid(
int)) {
433 s << std::any_cast<int>(v);
434 }
else if (t ==
typeid(
unsigned int)) {
435 s << std::any_cast<unsigned int>(v);
436 }
else if (t ==
typeid(
long)) {
437 s << std::any_cast<long>(v);
438 }
else if (t ==
typeid(
unsigned long)) {
439 s << std::any_cast<unsigned long>(v);
440 }
else if (t ==
typeid(
long long)) {
441 s << std::any_cast<long long>(v);
442 }
else if (t ==
typeid(
unsigned long long)) {
443 s << std::any_cast<unsigned long long>(v);
444 }
else if (t ==
typeid(
float)) {
445 s << std::setprecision(7) << std::any_cast<float>(v);
446 }
else if (t ==
typeid(
double)) {
447 s << std::setprecision(14) << std::any_cast<double>(v);
449 s <<
'"' << std::any_cast<std::string>(v) <<
'"';
450 }
else if (t ==
typeid(DateTime)) {
451 s << std::any_cast<DateTime>(v).toString(DateTime::UTC);
452 }
else if (t ==
typeid(Ptr)) {
454 }
else if (t ==
typeid(Persistable::Ptr)) {
455 s <<
"<Persistable>";
460 if (j->second->size() > 1) {
471 template <
typename T>
472 void PropertySet::set(
std::string const& name, T
const& value) {
474 vp->push_back(value);
478 template <
typename T>
480 if (value.
empty())
return;
488 template <
typename T>
489 void PropertySet::add(
std::string const& name, T
const& value) {
490 AnyMap::iterator i = _find(name);
491 if (i == _map.end()) {
494 if (i->second->back().type() !=
typeid(T)) {
495 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
497 i->second->push_back(value);
503 void PropertySet::add<PropertySet::Ptr>(
std::string const& name, Ptr
const& value) {
504 AnyMap::iterator i = _find(name);
505 if (i == _map.end()) {
508 if (i->second->back().type() !=
typeid(Ptr)) {
509 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
511 _cycleCheckPtr(value, name);
512 i->second->push_back(value);
516 template <
typename T>
518 AnyMap::iterator i = _find(name);
519 if (i == _map.end()) {
522 if (i->second->back().type() !=
typeid(T)) {
523 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
525 _append(*(i->second), value);
532 AnyMap::iterator i = _find(name);
533 if (i == _map.end()) {
536 if (i->second->back().type() !=
typeid(Ptr)) {
537 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
539 _cycleCheckPtrVec(value, name);
540 _append(*(i->second), value);
546 void PropertySet::copy(
std::string const& dest, ConstPtr source,
std::string const& name,
bool asScalar) {
547 if (source.get() == 0) {
548 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
"Missing source");
550 auto const sj = source->_find(name);
551 if (sj == source->_map.end()) {
552 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" not in source");
556 auto vp = std::make_shared<std::vector<std::any>>();
557 vp->push_back(sj->second->back());
560 auto vp = std::make_shared<std::vector<std::any>>(*(sj->second));
565 void PropertySet::combine(ConstPtr source) {
566 if (source.get() == 0) {
570 for (
auto const& name : names) {
571 auto const sp = source->_find(name);
572 _add(name, sp->second);
576 void PropertySet::remove(
std::string const& name) {
577 std::string::size_type i = name.
find(
'.');
578 if (_flat || i == name.npos) {
583 AnyMap::iterator j = _map.find(prefix);
584 if (j == _map.end() || j->second->back().type() !=
typeid(Ptr)) {
587 Ptr p = std::any_cast<Ptr>(j->second->back());
598 PropertySet::AnyMap::iterator PropertySet::_find(
std::string const& name) {
599 std::string::size_type i = name.
find(
'.');
600 if (_flat || i == name.npos) {
601 return _map.find(name);
604 AnyMap::iterator j = _map.find(prefix);
605 if (j == _map.end() || j->second->back().type() !=
typeid(Ptr)) {
608 Ptr p = std::any_cast<Ptr>(j->second->back());
613 AnyMap::iterator x = p->_find(suffix);
614 if (x == p->_map.end()) {
620 PropertySet::AnyMap::const_iterator PropertySet::_find(
std::string const& name)
const {
621 std::string::size_type i = name.
find(
'.');
622 if (_flat || i == name.npos) {
623 return _map.find(name);
626 auto const j = _map.find(prefix);
627 if (j == _map.end() || j->second->back().type() !=
typeid(Ptr)) {
630 Ptr p = std::any_cast<Ptr>(j->second->back());
635 auto const x = p->_find(suffix);
636 if (x == p->_map.end()) {
643 _findOrInsert(name, vp);
647 auto const dp = _find(name);
648 if (dp == _map.end()) {
651 if (vp->back().type() != dp->second->back().type()) {
652 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
655 if (vp->back().type() ==
typeid(Ptr)) {
656 _cycleCheckAnyVec(*vp, name);
658 _append(*(dp->second), *vp);
663 if (vp->back().type() ==
typeid(Ptr)) {
665 Ptr source = std::any_cast<Ptr>(vp->back());
667 for (
auto const& i : names) {
668 auto const sp = source->_find(i);
669 _add(name +
"." + i, sp->second);
675 _cycleCheckAnyVec(*vp, name);
678 std::string::size_type i = name.
find(
'.');
679 if (_flat || i == name.npos) {
685 AnyMap::iterator j = _map.find(prefix);
686 if (j == _map.end()) {
687 PropertySet::Ptr pp(
new PropertySet);
688 pp->_findOrInsert(suffix, vp);
693 }
else if (j->second->back().type() !=
typeid(Ptr)) {
694 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
695 prefix +
" exists but does not contain PropertySet::Ptrs");
697 Ptr p = std::any_cast<Ptr>(j->second->back());
699 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
700 prefix +
" exists but contains null PropertySet::Ptr");
702 p->_findOrInsert(suffix, vp);
706 for (
auto const& i : v) {
707 _cycleCheckPtr(i, name);
712 for (
auto const& i : v) {
713 _cycleCheckPtr(std::any_cast<Ptr>(i), name);
717 void PropertySet::_cycleCheckPtr(Ptr
const& v,
std::string const& name) {
718 if (v.get() ==
this) {
719 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" would cause a cycle");
722 for (
auto const& i : sets) {
723 if (v->getAsPropertySetPtr(i).get() ==
this) {
724 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" would cause a cycle");
736 #define INSTANTIATE(t) \
737 template std::type_info const& PropertySet::typeOfT<t>(); \
738 template t PropertySet::get<t>(std::string const& name) const; \
739 template t PropertySet::get<t>(std::string const& name, t const& defaultValue) const; \
740 template std::vector<t> PropertySet::getArray<t>(std::string const& name) const; \
741 template void PropertySet::set<t>(std::string const& name, t const& value); \
742 template void PropertySet::set<t>(std::string const& name, std::vector<t> const& value); \
743 template void PropertySet::add<t>(std::string const& name, t const& value); \
744 template void PropertySet::add<t>(std::string const& name, std::vector<t> const& value);
746 #define INSTANTIATE_PROPERTY_SET(t) \
747 template std::type_info const& PropertySet::typeOfT<t>(); \
748 template t PropertySet::get<t>(std::string const& name) const; \
749 template t PropertySet::get<t>(std::string const& name, t const& defaultValue) const; \
750 template std::vector<t> PropertySet::getArray<t>(std::string const& name) const; \
751 template void PropertySet::set<t>(std::string const& name, t const& value); \
752 template void PropertySet::set<t>(std::string const& name, std::vector<t> const& value);
756 INSTANTIATE(
signed char)
757 INSTANTIATE(
unsigned char)
759 INSTANTIATE(
unsigned short)
761 INSTANTIATE(
unsigned int)
763 INSTANTIATE(
unsigned long)
764 INSTANTIATE(
long long)
765 INSTANTIATE(
unsigned long long)
770 INSTANTIATE_PROPERTY_SET(PropertySet::Ptr)
771 INSTANTIATE(Persistable::Ptr)
772 INSTANTIATE(DateTime)
Interface for DateTime class.
#define LSST_EXCEPT(type,...)
PropertySet(bool flat=false)
Construct an empty PropertySet.
T throw_with_nested(T... args)