50 for (
const T& val : src) {
65 PropertySet::Ptr PropertySet::deepCopy()
const {
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(
long long))
return boost::any_cast<long long>(v);
317 if (t ==
typeid(
unsigned long long))
return boost::any_cast<unsigned long long>(v);
319 return boost::any_cast<uint64_t>(v);
320 }
catch (boost::bad_any_cast) {
321 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
324 return boost::any_cast<uint64_t>(v);
328 auto const i = _find(name);
329 if (i == _map.end()) {
330 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
332 boost::any v = i->second->back();
334 if (t ==
typeid(
bool))
return boost::any_cast<bool>(v);
335 if (t ==
typeid(
char))
return boost::any_cast<char>(v);
336 if (t ==
typeid(
signed char))
return boost::any_cast<signed char>(v);
337 if (t ==
typeid(
unsigned char))
return boost::any_cast<unsigned char>(v);
338 if (t ==
typeid(
short))
return boost::any_cast<short>(v);
339 if (t ==
typeid(
unsigned short))
return boost::any_cast<unsigned short>(v);
340 if (t ==
typeid(
int))
return boost::any_cast<int>(v);
341 if (t ==
typeid(
unsigned int))
return boost::any_cast<unsigned int>(v);
342 if (t ==
typeid(
long))
return boost::any_cast<long>(v);
343 if (t ==
typeid(
unsigned long))
return boost::any_cast<unsigned long>(v);
344 if (t ==
typeid(
long long))
return boost::any_cast<long long>(v);
345 if (t ==
typeid(
unsigned long long))
return boost::any_cast<unsigned long long>(v);
346 if (t ==
typeid(
float))
return boost::any_cast<float>(v);
348 return boost::any_cast<double>(v);
349 }
catch (boost::bad_any_cast) {
350 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
353 return boost::any_cast<double>(v);
361 return get<Persistable::Ptr>(name);
368 for (
auto const& i : nv) {
371 if (t ==
typeid(
Ptr)) {
372 s << indent << i <<
" = ";
376 Ptr p = boost::any_cast<Ptr>(vp->back());
381 s << p->toString(
false, indent +
"..");
396 auto const j = _map.find(name);
397 s << j->first <<
" = ";
399 if (vp->size() > 1) {
404 for (
auto const& k : *vp) {
410 boost::any
const& v(k);
411 if (t ==
typeid(
bool)) {
412 s << boost::any_cast<bool>(v);
413 }
else if (t ==
typeid(
char)) {
414 s << '\'' << boost::any_cast<char>(v) <<
'\'';
415 }
else if (t ==
typeid(
signed char)) {
416 s << '\'' << boost::any_cast<signed char>(v) <<
'\'';
417 }
else if (t ==
typeid(
unsigned char)) {
418 s << '\'' << boost::any_cast<unsigned char>(v) <<
'\'';
419 }
else if (t ==
typeid(
short)) {
420 s << boost::any_cast<short>(v);
421 }
else if (t ==
typeid(
unsigned short)) {
422 s << boost::any_cast<unsigned short>(v);
423 }
else if (t ==
typeid(
int)) {
424 s << boost::any_cast<int>(v);
425 }
else if (t ==
typeid(
unsigned int)) {
426 s << boost::any_cast<unsigned int>(v);
427 }
else if (t ==
typeid(
long)) {
428 s << boost::any_cast<long>(v);
429 }
else if (t ==
typeid(
unsigned long)) {
430 s << boost::any_cast<unsigned long>(v);
431 }
else if (t ==
typeid(
long long)) {
432 s << boost::any_cast<long long>(v);
433 }
else if (t ==
typeid(
unsigned long long)) {
434 s << boost::any_cast<unsigned long long>(v);
435 }
else if (t ==
typeid(
float)) {
436 s << std::setprecision(7) << boost::any_cast<float>(v);
437 }
else if (t ==
typeid(
double)) {
438 s << std::setprecision(14) << boost::any_cast<double>(v);
440 s <<
'"' << boost::any_cast<std::string>(v) <<
'"';
441 }
else if (t ==
typeid(DateTime)) {
443 }
else if (t ==
typeid(
Ptr)) {
446 s <<
"<Persistable>";
451 if (j->second->size() > 1) {
462 template <
typename T>
465 vp->push_back(value);
469 template <
typename T>
471 if (value.
empty())
return;
479 template <
typename T>
481 AnyMap::iterator i = _find(name);
482 if (i == _map.end()) {
485 if (i->second->back().type() !=
typeid(T)) {
486 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
488 i->second->push_back(value);
494 void PropertySet::add<PropertySet::Ptr>(
std::string const& name, Ptr
const& value) {
495 AnyMap::iterator i = _find(name);
496 if (i == _map.end()) {
499 if (i->second->back().type() !=
typeid(Ptr)) {
500 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
502 _cycleCheckPtr(value, name);
503 i->second->push_back(value);
507 template <
typename T>
509 AnyMap::iterator i = _find(name);
510 if (i == _map.end()) {
513 if (i->second->back().type() !=
typeid(T)) {
514 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
516 _append(*(i->second), value);
523 AnyMap::iterator i = _find(name);
524 if (i == _map.end()) {
527 if (i->second->back().type() !=
typeid(Ptr)) {
528 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
530 _cycleCheckPtrVec(value, name);
531 _append(*(i->second), value);
538 if (source.get() == 0) {
539 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
"Missing source");
541 auto const sj = source->_find(name);
542 if (sj == source->_map.end()) {
543 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" not in source");
547 auto vp = std::make_shared<std::vector<boost::any>>();
548 vp->push_back(sj->second->back());
551 auto vp = std::make_shared<std::vector<boost::any>>(*(sj->second));
557 if (source.get() == 0) {
561 for (
auto const& name :
names) {
562 auto const sp = source->_find(name);
563 _add(name, sp->second);
568 std::string::size_type i = name.
find(
'.');
569 if (_flat || i == name.npos) {
574 AnyMap::iterator j = _map.find(prefix);
575 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
578 Ptr p = boost::any_cast<Ptr>(j->second->back());
589 PropertySet::AnyMap::iterator PropertySet::_find(
std::string const& name) {
590 std::string::size_type i = name.
find(
'.');
591 if (_flat || i == name.npos) {
592 return _map.find(name);
595 AnyMap::iterator j = _map.find(prefix);
596 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
599 Ptr p = boost::any_cast<Ptr>(j->second->back());
604 AnyMap::iterator x = p->_find(suffix);
605 if (x == p->_map.end()) {
611 PropertySet::AnyMap::const_iterator PropertySet::_find(
std::string const& name)
const {
612 std::string::size_type i = name.
find(
'.');
613 if (_flat || i == name.npos) {
614 return _map.find(name);
617 auto const j = _map.find(prefix);
618 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
621 Ptr p = boost::any_cast<Ptr>(j->second->back());
626 auto const x = p->_find(suffix);
627 if (x == p->_map.end()) {
634 _findOrInsert(name, vp);
638 auto const dp = _find(name);
639 if (dp == _map.end()) {
642 if (vp->back().type() != dp->second->back().type()) {
643 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
646 if (vp->back().type() ==
typeid(
Ptr)) {
647 _cycleCheckAnyVec(*vp, name);
649 _append(*(dp->second), *vp);
654 if (vp->back().type() ==
typeid(
Ptr)) {
656 Ptr source = boost::any_cast<Ptr>(vp->back());
658 for (
auto const& i :
names) {
659 auto const sp = source->_find(i);
660 _add(name +
"." + i, sp->second);
666 _cycleCheckAnyVec(*vp, name);
669 std::string::size_type i = name.
find(
'.');
670 if (_flat || i == name.npos) {
676 AnyMap::iterator j = _map.find(prefix);
677 if (j == _map.end()) {
679 pp->_findOrInsert(suffix, vp);
684 }
else if (j->second->back().type() !=
typeid(
Ptr)) {
685 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
686 prefix +
" exists but does not contain PropertySet::Ptrs");
688 Ptr p = boost::any_cast<Ptr>(j->second->back());
690 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
691 prefix +
" exists but contains null PropertySet::Ptr");
693 p->_findOrInsert(suffix, vp);
697 for (
auto const& i : v) {
698 _cycleCheckPtr(i, name);
703 for (
auto const& i : v) {
704 _cycleCheckPtr(boost::any_cast<Ptr>(i), name);
708 void PropertySet::_cycleCheckPtr(Ptr
const& v,
std::string const& name) {
709 if (v.get() ==
this) {
710 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" would cause a cycle");
713 for (
auto const& i : sets) {
714 if (v->getAsPropertySetPtr(i).get() ==
this) {
715 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" would cause a cycle");
727 #define INSTANTIATE(t) \
728 template std::type_info const& PropertySet::typeOfT<t>(); \
729 template t PropertySet::get<t>(std::string const& name) const; \
730 template t PropertySet::get<t>(std::string const& name, t const& defaultValue) const; \
731 template std::vector<t> PropertySet::getArray<t>(std::string const& name) const; \
732 template void PropertySet::set<t>(std::string const& name, t const& value); \
733 template void PropertySet::set<t>(std::string const& name, std::vector<t> const& value); \
734 template void PropertySet::add<t>(std::string const& name, t const& value); \
735 template void PropertySet::add<t>(std::string const& name, std::vector<t> const& value);
737 #define INSTANTIATE_PROPERTY_SET(t) \
738 template std::type_info const& PropertySet::typeOfT<t>(); \
739 template t PropertySet::get<t>(std::string const& name) const; \
740 template t PropertySet::get<t>(std::string const& name, t const& defaultValue) const; \
741 template std::vector<t> PropertySet::getArray<t>(std::string const& name) const; \
742 template void PropertySet::set<t>(std::string const& name, t const& value); \
743 template void PropertySet::set<t>(std::string const& name, std::vector<t> const& value);
747 INSTANTIATE(
signed char)
748 INSTANTIATE(
unsigned char)
750 INSTANTIATE(
unsigned short)
752 INSTANTIATE(
unsigned int)
754 INSTANTIATE(
unsigned long)
755 INSTANTIATE(
long long)
756 INSTANTIATE(
unsigned long long)
763 INSTANTIATE(DateTime)