50 for (
const T& val : src) {
59 PropertySet::~PropertySet() noexcept = default;
65 PropertySet::Ptr PropertySet::deepCopy()
const {
66 Ptr n(
new PropertySet(_flat));
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;
85 size_t PropertySet::nameCount(
bool topLevelOnly)
const {
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) {
151 bool PropertySet::exists(
std::string const& name)
const {
return _find(name) != _map.
end(); }
153 bool PropertySet::isArray(
std::string const& name)
const {
154 auto const i = _find(name);
155 return i != _map.end() && i->second->size() > 1U;
158 bool PropertySet::isPropertySetPtr(
std::string const& name)
const {
159 auto const i = _find(name);
160 return i != _map.end() && i->second->back().type() ==
typeid(Ptr);
163 bool PropertySet::isUndefined(
std::string const& name)
const {
164 auto const i = _find(name);
165 return i != _map.end() && i->second->back().type() ==
typeid(
nullptr);
168 size_t PropertySet::valueCount()
const {
170 for (
auto const& name : paramNames(
false)) {
171 sum += valueCount(name);
176 size_t PropertySet::valueCount(
std::string const& name)
const {
177 auto const i = _find(name);
178 if (i == _map.end())
return 0;
179 return i->second->size();
183 auto const i = _find(name);
184 if (i == _map.end()) {
185 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
187 return i->second->back().type();
190 template <
typename T>
197 template <
typename T>
200 auto const i = _find(name);
201 if (i == _map.end()) {
202 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
205 return boost::any_cast<T>(i->second->back());
206 }
catch (boost::bad_any_cast) {
207 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
210 return boost::any_cast<T>(i->second->back());
213 template <
typename T>
214 T PropertySet::get(
std::string const& name, T
const& defaultValue)
216 auto const i = _find(name);
217 if (i == _map.end()) {
221 return boost::any_cast<T>(i->second->back());
222 }
catch (boost::bad_any_cast) {
223 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
226 return boost::any_cast<T>(i->second->back());
229 template <
typename T>
231 auto const i = _find(name);
232 if (i == _map.end()) {
233 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
236 for (
auto const& j : *(i->second)) {
239 }
catch (boost::bad_any_cast) {
240 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
248 bool PropertySet::getAsBool(
std::string const& name)
250 return get<bool>(name);
253 int PropertySet::getAsInt(
std::string const& name)
const {
254 auto const i = _find(name);
255 if (i == _map.end()) {
256 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
258 boost::any v = i->second->
back();
260 if (t ==
typeid(
bool)) {
261 return boost::any_cast<bool>(v);
262 }
else if (t ==
typeid(
char)) {
263 return boost::any_cast<char>(v);
264 }
else if (t ==
typeid(
signed char)) {
265 return boost::any_cast<signed char>(v);
266 }
else if (t ==
typeid(
unsigned char)) {
267 return boost::any_cast<unsigned char>(v);
268 }
else if (t ==
typeid(
short)) {
269 return boost::any_cast<short>(v);
270 }
else if (t ==
typeid(
unsigned short)) {
271 return boost::any_cast<unsigned short>(v);
274 return boost::any_cast<int>(v);
275 }
catch (boost::bad_any_cast) {
276 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
279 return boost::any_cast<int>(v);
282 int64_t PropertySet::getAsInt64(
std::string const& name)
const {
283 auto const i = _find(name);
284 if (i == _map.end()) {
285 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
287 boost::any v = i->second->back();
289 if (t ==
typeid(
bool))
return boost::any_cast<bool>(v);
290 if (t ==
typeid(
char))
return boost::any_cast<char>(v);
291 if (t ==
typeid(
signed char))
return boost::any_cast<signed char>(v);
292 if (t ==
typeid(
unsigned char))
return boost::any_cast<unsigned char>(v);
293 if (t ==
typeid(
short))
return boost::any_cast<short>(v);
294 if (t ==
typeid(
unsigned short))
return boost::any_cast<unsigned short>(v);
295 if (t ==
typeid(
int))
return boost::any_cast<int>(v);
296 if (t ==
typeid(
unsigned int))
return boost::any_cast<unsigned int>(v);
297 if (t ==
typeid(
long))
return boost::any_cast<long>(v);
298 if (t ==
typeid(
long long))
return boost::any_cast<long long>(v);
300 return boost::any_cast<int64_t>(v);
301 }
catch (boost::bad_any_cast) {
302 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
305 return boost::any_cast<int64_t>(v);
308 uint64_t PropertySet::getAsUInt64(
std::string const& name)
const {
309 auto const i = _find(name);
310 if (i == _map.end()) {
311 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
313 boost::any v = i->second->back();
315 if (t ==
typeid(
bool))
return boost::any_cast<bool>(v);
316 if (t ==
typeid(
char))
return boost::any_cast<char>(v);
317 if (t ==
typeid(
signed char))
return boost::any_cast<signed char>(v);
318 if (t ==
typeid(
unsigned char))
return boost::any_cast<unsigned char>(v);
319 if (t ==
typeid(
short))
return boost::any_cast<short>(v);
320 if (t ==
typeid(
unsigned short))
return boost::any_cast<unsigned short>(v);
321 if (t ==
typeid(
int))
return boost::any_cast<int>(v);
322 if (t ==
typeid(
unsigned int))
return boost::any_cast<unsigned int>(v);
323 if (t ==
typeid(
long))
return boost::any_cast<long>(v);
324 if (t ==
typeid(
long long))
return boost::any_cast<long long>(v);
325 if (t ==
typeid(
unsigned long long))
return boost::any_cast<unsigned long long>(v);
327 return boost::any_cast<uint64_t>(v);
328 }
catch (boost::bad_any_cast) {
329 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
332 return boost::any_cast<uint64_t>(v);
335 double PropertySet::getAsDouble(
std::string const& name)
const {
336 auto const i = _find(name);
337 if (i == _map.end()) {
338 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
340 boost::any v = i->second->back();
342 if (t ==
typeid(
bool))
return boost::any_cast<bool>(v);
343 if (t ==
typeid(
char))
return boost::any_cast<char>(v);
344 if (t ==
typeid(
signed char))
return boost::any_cast<signed char>(v);
345 if (t ==
typeid(
unsigned char))
return boost::any_cast<unsigned char>(v);
346 if (t ==
typeid(
short))
return boost::any_cast<short>(v);
347 if (t ==
typeid(
unsigned short))
return boost::any_cast<unsigned short>(v);
348 if (t ==
typeid(
int))
return boost::any_cast<int>(v);
349 if (t ==
typeid(
unsigned int))
return boost::any_cast<unsigned int>(v);
350 if (t ==
typeid(
long))
return boost::any_cast<long>(v);
351 if (t ==
typeid(
unsigned long))
return boost::any_cast<unsigned long>(v);
352 if (t ==
typeid(
long long))
return boost::any_cast<long long>(v);
353 if (t ==
typeid(
unsigned long long))
return boost::any_cast<unsigned long long>(v);
354 if (t ==
typeid(
float))
return boost::any_cast<float>(v);
356 return boost::any_cast<double>(v);
357 }
catch (boost::bad_any_cast) {
358 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
361 return boost::any_cast<double>(v);
366 PropertySet::Ptr PropertySet::getAsPropertySetPtr(
std::string const& name)
const {
return get<Ptr>(name); }
368 Persistable::Ptr PropertySet::getAsPersistablePtr(
std::string const& name)
const {
369 return get<Persistable::Ptr>(name);
376 for (
auto const& i : nv) {
379 if (t ==
typeid(Ptr)) {
380 s << indent << i <<
" = ";
384 Ptr p = boost::any_cast<Ptr>(vp->back());
389 s << p->toString(
false, indent +
"..");
395 s << indent << _format(i);
404 auto const j = _map.find(name);
405 s << j->first <<
" = ";
407 if (vp->size() > 1) {
412 for (
auto const& k : *vp) {
418 boost::any
const& v(k);
419 if (t ==
typeid(
bool)) {
420 s << boost::any_cast<bool>(v);
421 }
else if (t ==
typeid(
char)) {
422 s << '\'' << boost::any_cast<char>(v) <<
'\'';
423 }
else if (t ==
typeid(
signed char)) {
424 s << '\'' << boost::any_cast<signed char>(v) <<
'\'';
425 }
else if (t ==
typeid(
unsigned char)) {
426 s << '\'' << boost::any_cast<unsigned char>(v) <<
'\'';
427 }
else if (t ==
typeid(
short)) {
428 s << boost::any_cast<short>(v);
429 }
else if (t ==
typeid(
unsigned short)) {
430 s << boost::any_cast<unsigned short>(v);
431 }
else if (t ==
typeid(
int)) {
432 s << boost::any_cast<int>(v);
433 }
else if (t ==
typeid(
unsigned int)) {
434 s << boost::any_cast<unsigned int>(v);
435 }
else if (t ==
typeid(
long)) {
436 s << boost::any_cast<long>(v);
437 }
else if (t ==
typeid(
unsigned long)) {
438 s << boost::any_cast<unsigned long>(v);
439 }
else if (t ==
typeid(
long long)) {
440 s << boost::any_cast<long long>(v);
441 }
else if (t ==
typeid(
unsigned long long)) {
442 s << boost::any_cast<unsigned long long>(v);
443 }
else if (t ==
typeid(
float)) {
444 s << std::setprecision(7) << boost::any_cast<float>(v);
445 }
else if (t ==
typeid(
double)) {
446 s << std::setprecision(14) << boost::any_cast<double>(v);
448 s <<
'"' << boost::any_cast<std::string>(v) <<
'"';
449 }
else if (t ==
typeid(DateTime)) {
450 s << boost::any_cast<DateTime>(v).toString(DateTime::UTC);
451 }
else if (t ==
typeid(Ptr)) {
453 }
else if (t ==
typeid(Persistable::Ptr)) {
454 s <<
"<Persistable>";
459 if (j->second->size() > 1) {
470 template <
typename T>
471 void PropertySet::set(
std::string const& name, T
const& value) {
473 vp->push_back(value);
477 template <
typename T>
479 if (value.
empty())
return;
487 template <
typename T>
488 void PropertySet::add(
std::string const& name, T
const& value) {
489 AnyMap::iterator i = _find(name);
490 if (i == _map.end()) {
493 if (i->second->back().type() !=
typeid(T)) {
494 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
496 i->second->push_back(value);
502 void PropertySet::add<PropertySet::Ptr>(
std::string const& name, Ptr
const& value) {
503 AnyMap::iterator i = _find(name);
504 if (i == _map.end()) {
507 if (i->second->back().type() !=
typeid(Ptr)) {
508 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
510 _cycleCheckPtr(value, name);
511 i->second->push_back(value);
515 template <
typename T>
517 AnyMap::iterator i = _find(name);
518 if (i == _map.end()) {
521 if (i->second->back().type() !=
typeid(T)) {
522 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
524 _append(*(i->second), value);
531 AnyMap::iterator i = _find(name);
532 if (i == _map.end()) {
535 if (i->second->back().type() !=
typeid(Ptr)) {
536 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
538 _cycleCheckPtrVec(value, name);
539 _append(*(i->second), value);
545 void PropertySet::copy(
std::string const& dest, ConstPtr source,
std::string const& name,
bool asScalar) {
546 if (source.get() == 0) {
547 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
"Missing source");
549 auto const sj = source->_find(name);
550 if (sj == source->_map.end()) {
551 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" not in source");
555 auto vp = std::make_shared<std::vector<boost::any>>();
556 vp->push_back(sj->second->back());
559 auto vp = std::make_shared<std::vector<boost::any>>(*(sj->second));
564 void PropertySet::combine(ConstPtr source) {
565 if (source.get() == 0) {
569 for (
auto const& name : names) {
570 auto const sp = source->_find(name);
571 _add(name, sp->second);
575 void PropertySet::remove(
std::string const& name) {
576 std::string::size_type i = name.
find(
'.');
577 if (_flat || i == name.npos) {
582 AnyMap::iterator j = _map.find(prefix);
583 if (j == _map.end() || j->second->back().type() !=
typeid(Ptr)) {
586 Ptr p = boost::any_cast<Ptr>(j->second->back());
597 PropertySet::AnyMap::iterator PropertySet::_find(
std::string const& name) {
598 std::string::size_type i = name.
find(
'.');
599 if (_flat || i == name.npos) {
600 return _map.find(name);
603 AnyMap::iterator j = _map.find(prefix);
604 if (j == _map.end() || j->second->back().type() !=
typeid(Ptr)) {
607 Ptr p = boost::any_cast<Ptr>(j->second->back());
612 AnyMap::iterator x = p->_find(suffix);
613 if (x == p->_map.end()) {
619 PropertySet::AnyMap::const_iterator PropertySet::_find(
std::string const& name)
const {
620 std::string::size_type i = name.
find(
'.');
621 if (_flat || i == name.npos) {
622 return _map.find(name);
625 auto const j = _map.find(prefix);
626 if (j == _map.end() || j->second->back().type() !=
typeid(Ptr)) {
629 Ptr p = boost::any_cast<Ptr>(j->second->back());
634 auto const x = p->_find(suffix);
635 if (x == p->_map.end()) {
642 _findOrInsert(name, vp);
646 auto const dp = _find(name);
647 if (dp == _map.end()) {
650 if (vp->back().type() != dp->second->back().type()) {
651 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
654 if (vp->back().type() ==
typeid(Ptr)) {
655 _cycleCheckAnyVec(*vp, name);
657 _append(*(dp->second), *vp);
662 if (vp->back().type() ==
typeid(Ptr)) {
664 Ptr source = boost::any_cast<Ptr>(vp->back());
666 for (
auto const& i : names) {
667 auto const sp = source->_find(i);
668 _add(name +
"." + i, sp->second);
674 _cycleCheckAnyVec(*vp, name);
677 std::string::size_type i = name.
find(
'.');
678 if (_flat || i == name.npos) {
684 AnyMap::iterator j = _map.find(prefix);
685 if (j == _map.end()) {
686 PropertySet::Ptr pp(
new PropertySet);
687 pp->_findOrInsert(suffix, vp);
692 }
else if (j->second->back().type() !=
typeid(Ptr)) {
693 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
694 prefix +
" exists but does not contain PropertySet::Ptrs");
696 Ptr p = boost::any_cast<Ptr>(j->second->back());
698 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
699 prefix +
" exists but contains null PropertySet::Ptr");
701 p->_findOrInsert(suffix, vp);
705 for (
auto const& i : v) {
706 _cycleCheckPtr(i, name);
711 for (
auto const& i : v) {
712 _cycleCheckPtr(boost::any_cast<Ptr>(i), name);
716 void PropertySet::_cycleCheckPtr(Ptr
const& v,
std::string const& name) {
717 if (v.get() ==
this) {
718 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" would cause a cycle");
721 for (
auto const& i : sets) {
722 if (v->getAsPropertySetPtr(i).get() ==
this) {
723 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" would cause a cycle");
735 #define INSTANTIATE(t) \
736 template std::type_info const& PropertySet::typeOfT<t>(); \
737 template t PropertySet::get<t>(std::string const& name) const; \
738 template t PropertySet::get<t>(std::string const& name, t const& defaultValue) const; \
739 template std::vector<t> PropertySet::getArray<t>(std::string const& name) const; \
740 template void PropertySet::set<t>(std::string const& name, t const& value); \
741 template void PropertySet::set<t>(std::string const& name, std::vector<t> const& value); \
742 template void PropertySet::add<t>(std::string const& name, t const& value); \
743 template void PropertySet::add<t>(std::string const& name, std::vector<t> const& value);
745 #define INSTANTIATE_PROPERTY_SET(t) \
746 template std::type_info const& PropertySet::typeOfT<t>(); \
747 template t PropertySet::get<t>(std::string const& name) const; \
748 template t PropertySet::get<t>(std::string const& name, t const& defaultValue) const; \
749 template std::vector<t> PropertySet::getArray<t>(std::string const& name) const; \
750 template void PropertySet::set<t>(std::string const& name, t const& value); \
751 template void PropertySet::set<t>(std::string const& name, std::vector<t> const& value);
755 INSTANTIATE(
signed char)
756 INSTANTIATE(
unsigned char)
758 INSTANTIATE(
unsigned short)
760 INSTANTIATE(
unsigned int)
762 INSTANTIATE(
unsigned long)
763 INSTANTIATE(
long long)
764 INSTANTIATE(
unsigned long long)
769 INSTANTIATE_PROPERTY_SET(PropertySet::Ptr)
770 INSTANTIATE(Persistable::Ptr)
771 INSTANTIATE(DateTime)
Interface for DateTime class.
#define LSST_EXCEPT(type,...)
PropertySet(bool flat=false)
Construct an empty PropertySet.