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();
179 template <
typename T>
182 auto const i = _find(name);
183 if (i == _map.end()) {
184 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
187 return boost::any_cast<T>(i->second->back());
188 }
catch (boost::bad_any_cast) {
189 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
192 return boost::any_cast<T>(i->second->back());
195 template <
typename T>
198 auto const i = _find(name);
199 if (i == _map.end()) {
203 return boost::any_cast<T>(i->second->back());
204 }
catch (boost::bad_any_cast) {
205 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
208 return boost::any_cast<T>(i->second->back());
211 template <
typename T>
213 auto const i = _find(name);
214 if (i == _map.end()) {
215 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
218 for (
auto const& j : *(i->second)) {
221 }
catch (boost::bad_any_cast) {
222 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
232 return get<bool>(name);
236 auto const i = _find(name);
237 if (i == _map.end()) {
238 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
240 boost::any v = i->second->
back();
242 if (t ==
typeid(
bool)) {
243 return boost::any_cast<
bool>(v);
244 }
else if (t ==
typeid(
char)) {
245 return boost::any_cast<
char>(v);
246 }
else if (t ==
typeid(
signed char)) {
247 return boost::any_cast<
signed char>(v);
248 }
else if (t ==
typeid(
unsigned char)) {
249 return boost::any_cast<
unsigned char>(v);
250 }
else if (t ==
typeid(
short)) {
251 return boost::any_cast<
short>(v);
252 }
else if (t ==
typeid(
unsigned short)) {
253 return boost::any_cast<
unsigned short>(v);
256 return boost::any_cast<
int>(v);
257 }
catch (boost::bad_any_cast) {
258 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
261 return boost::any_cast<
int>(v);
265 auto const i = _find(name);
266 if (i == _map.end()) {
267 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
269 boost::any v = i->second->back();
271 if (t ==
typeid(
bool))
return boost::any_cast<
bool>(v);
272 if (t ==
typeid(
char))
return boost::any_cast<char>(v);
273 if (t ==
typeid(
signed char))
return boost::any_cast<signed char>(v);
274 if (t ==
typeid(
unsigned char))
return boost::any_cast<unsigned char>(v);
275 if (t ==
typeid(
short))
return boost::any_cast<short>(v);
276 if (t ==
typeid(
unsigned short))
return boost::any_cast<unsigned short>(v);
277 if (t ==
typeid(
int))
return boost::any_cast<int>(v);
278 if (t ==
typeid(
unsigned int))
return boost::any_cast<unsigned int>(v);
279 if (t ==
typeid(
long))
return boost::any_cast<long>(v);
280 if (t ==
typeid(
long long))
return boost::any_cast<long long>(v);
282 return boost::any_cast<int64_t>(v);
283 }
catch (boost::bad_any_cast) {
284 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
287 return boost::any_cast<int64_t>(v);
291 auto const i = _find(name);
292 if (i == _map.end()) {
293 throw LSST_EXCEPT(pex::exceptions::NotFoundError, name +
" not found");
295 boost::any v = i->second->back();
297 if (t ==
typeid(
bool))
return boost::any_cast<
bool>(v);
298 if (t ==
typeid(
char))
return boost::any_cast<char>(v);
299 if (t ==
typeid(
signed char))
return boost::any_cast<signed char>(v);
300 if (t ==
typeid(
unsigned char))
return boost::any_cast<unsigned char>(v);
301 if (t ==
typeid(
short))
return boost::any_cast<short>(v);
302 if (t ==
typeid(
unsigned short))
return boost::any_cast<unsigned short>(v);
303 if (t ==
typeid(
int))
return boost::any_cast<int>(v);
304 if (t ==
typeid(
unsigned int))
return boost::any_cast<unsigned int>(v);
305 if (t ==
typeid(
long))
return boost::any_cast<long>(v);
306 if (t ==
typeid(
unsigned long))
return boost::any_cast<unsigned long>(v);
307 if (t ==
typeid(
long long))
return boost::any_cast<long long>(v);
308 if (t ==
typeid(
unsigned long long))
return boost::any_cast<unsigned long long>(v);
309 if (t ==
typeid(
float))
return boost::any_cast<float>(v);
311 return boost::any_cast<
double>(v);
312 }
catch (boost::bad_any_cast) {
313 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
316 return boost::any_cast<
double>(v);
324 return get<Persistable::Ptr>(name);
331 for (
auto const& i : nv) {
334 if (t ==
typeid(
Ptr)) {
335 s << indent << i <<
" = ";
339 Ptr p = boost::any_cast<
Ptr>(vp->back());
344 s << p->toString(
false, indent +
"..");
359 auto const j = _map.find(name);
360 s << j->first <<
" = ";
362 if (vp->size() > 1) {
367 for (
auto const& k : *vp) {
373 boost::any
const& v(k);
374 if (t ==
typeid(
bool)) {
375 s << boost::any_cast<bool>(v);
376 }
else if (t ==
typeid(
char)) {
377 s << '\'' << boost::any_cast<char>(v) <<
'\'';
378 }
else if (t ==
typeid(
signed char)) {
379 s << '\'' << boost::any_cast<signed char>(v) <<
'\'';
380 }
else if (t ==
typeid(
unsigned char)) {
381 s << '\'' << boost::any_cast<unsigned char>(v) <<
'\'';
382 }
else if (t ==
typeid(
short)) {
383 s << boost::any_cast<short>(v);
384 }
else if (t ==
typeid(
unsigned short)) {
385 s << boost::any_cast<unsigned short>(v);
386 }
else if (t ==
typeid(
int)) {
387 s << boost::any_cast<int>(v);
388 }
else if (t ==
typeid(
unsigned int)) {
389 s << boost::any_cast<unsigned int>(v);
390 }
else if (t ==
typeid(
long)) {
391 s << boost::any_cast<long>(v);
392 }
else if (t ==
typeid(
unsigned long)) {
393 s << boost::any_cast<unsigned long>(v);
394 }
else if (t ==
typeid(
long long)) {
395 s << boost::any_cast<long long>(v);
396 }
else if (t ==
typeid(
unsigned long long)) {
397 s << boost::any_cast<unsigned long long>(v);
398 }
else if (t ==
typeid(
float)) {
399 s << std::setprecision(7) << boost::any_cast<float>(v);
400 }
else if (t ==
typeid(
double)) {
401 s << std::setprecision(14) << boost::any_cast<double>(v);
403 s <<
'"' << boost::any_cast<
std::string>(v) <<
'"';
404 }
else if (t ==
typeid(DateTime)) {
406 }
else if (t ==
typeid(
Ptr)) {
409 s <<
"<Persistable>";
414 if (j->second->size() > 1) {
425 template <
typename T>
428 vp->push_back(value);
432 template <
typename T>
434 if (value.
empty())
return;
442 template <
typename T>
444 AnyMap::iterator i = _find(name);
445 if (i == _map.end()) {
448 if (i->second->back().type() !=
typeid(T)) {
449 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
451 i->second->push_back(value);
457 void PropertySet::add<PropertySet::Ptr>(
std::string const& name,
Ptr const& value) {
458 AnyMap::iterator i = _find(name);
459 if (i == _map.end()) {
462 if (i->second->back().type() !=
typeid(
Ptr)) {
463 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
465 _cycleCheckPtr(value, name);
466 i->second->push_back(value);
470 template <
typename T>
472 AnyMap::iterator i = _find(name);
473 if (i == _map.end()) {
476 if (i->second->back().type() !=
typeid(T)) {
477 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
479 _append(*(i->second), value);
486 AnyMap::iterator i = _find(name);
487 if (i == _map.end()) {
490 if (i->second->back().type() !=
typeid(
Ptr)) {
491 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
493 _cycleCheckPtrVec(value, name);
494 _append(*(i->second), value);
501 if (source.get() == 0) {
502 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
"Missing source");
504 auto const sj = source->_find(name);
505 if (sj == source->_map.end()) {
506 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" not in source");
510 auto vp = std::make_shared<std::vector<boost::any>>();
511 vp->push_back(sj->second->back());
514 auto vp = std::make_shared<std::vector<boost::any>>(*(sj->second));
520 if (source.get() == 0) {
524 for (
auto const& name : names) {
525 auto const sp = source->_find(name);
526 _add(name, sp->second);
531 std::string::size_type i = name.
find(
'.');
532 if (_flat || i == name.npos) {
537 AnyMap::iterator j = _map.find(prefix);
538 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
541 Ptr p = boost::any_cast<
Ptr>(j->second->back());
552 PropertySet::AnyMap::iterator PropertySet::_find(
std::string const& name) {
553 std::string::size_type i = name.
find(
'.');
554 if (_flat || i == name.npos) {
555 return _map.find(name);
558 AnyMap::iterator j = _map.find(prefix);
559 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
562 Ptr p = boost::any_cast<
Ptr>(j->second->back());
567 AnyMap::iterator x = p->_find(suffix);
568 if (x == p->_map.end()) {
574 PropertySet::AnyMap::const_iterator PropertySet::_find(
std::string const& name)
const {
575 std::string::size_type i = name.
find(
'.');
576 if (_flat || i == name.npos) {
577 return _map.find(name);
580 auto const j = _map.find(prefix);
581 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
584 Ptr p = boost::any_cast<
Ptr>(j->second->back());
589 auto const x = p->_find(suffix);
590 if (x == p->_map.end()) {
597 _findOrInsert(name, vp);
601 auto const dp = _find(name);
602 if (dp == _map.end()) {
605 if (vp->back().type() != dp->second->back().type()) {
606 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
609 if (vp->back().type() ==
typeid(
Ptr)) {
610 _cycleCheckAnyVec(*vp, name);
612 _append(*(dp->second), *vp);
617 if (vp->back().type() ==
typeid(
Ptr)) {
619 Ptr source = boost::any_cast<
Ptr>(vp->back());
621 for (
auto const& i : names) {
622 auto const sp = source->_find(i);
623 _add(name +
"." + i, sp->second);
629 _cycleCheckAnyVec(*vp, name);
632 std::string::size_type i = name.
find(
'.');
633 if (_flat || i == name.npos) {
639 AnyMap::iterator j = _map.find(prefix);
640 if (j == _map.end()) {
642 pp->_findOrInsert(suffix, vp);
647 }
else if (j->second->back().type() !=
typeid(
Ptr)) {
648 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
649 prefix +
" exists but does not contain PropertySet::Ptrs");
651 Ptr p = boost::any_cast<
Ptr>(j->second->back());
653 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
654 prefix +
" exists but contains null PropertySet::Ptr");
656 p->_findOrInsert(suffix, vp);
660 for (
auto const& i : v) {
661 _cycleCheckPtr(i, name);
666 for (
auto const& i : v) {
667 _cycleCheckPtr(boost::any_cast<Ptr>(i), name);
671 void PropertySet::_cycleCheckPtr(
Ptr const& v,
std::string const& name) {
672 if (v.get() ==
this) {
673 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" would cause a cycle");
676 for (
auto const& i : sets) {
677 if (v->getAsPropertySetPtr(i).get() ==
this) {
678 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" would cause a cycle");
690 #define INSTANTIATE(t) \ 691 template t PropertySet::get<t>(std::string const& name) const; \ 692 template t PropertySet::get<t>(std::string const& name, t const& defaultValue) const; \ 693 template std::vector<t> PropertySet::getArray<t>(std::string const& name) const; \ 694 template void PropertySet::set<t>(std::string const& name, t const& value); \ 695 template void PropertySet::set<t>(std::string const& name, std::vector<t> const& value); \ 696 template void PropertySet::add<t>(std::string const& name, t const& value); \ 697 template void PropertySet::add<t>(std::string const& name, std::vector<t> const& value); 699 #define INSTANTIATE_PROPERTY_SET(t) \ 700 template t PropertySet::get<t>(std::string const& name) const; \ 701 template t PropertySet::get<t>(std::string const& name, t const& defaultValue) const; \ 702 template std::vector<t> PropertySet::getArray<t>(std::string const& name) const; \ 703 template void PropertySet::set<t>(std::string const& name, t const& value); \ 704 template void PropertySet::set<t>(std::string const& name, std::vector<t> const& value); 708 INSTANTIATE(
signed char)
709 INSTANTIATE(
unsigned char)
711 INSTANTIATE(
unsigned short)
713 INSTANTIATE(
unsigned int)
715 INSTANTIATE(
unsigned long)
716 INSTANTIATE(
long long)
717 INSTANTIATE(
unsigned long long)
723 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.
std::shared_ptr< PropertySet > Ptr
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.
virtual Ptr deepCopy(void) const
Make a deep copy of the PropertySet and all of its contents.
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).
virtual ~PropertySet(void)
Destructor.
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)
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).