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 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");
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");
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");
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) {
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);
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); 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 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).
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).
std::shared_ptr< PropertySet const > ConstPtr
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 any(CoordinateExpr< N > const &expr) noexcept
Return true if any elements are true.
bool isArray(std::string const &name) const
Determine if a name (possibly hierarchical) has multiple values.
A base class for image defects.
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.
const char * source()
Source function that allows astChannel to source from a Stream.
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).
std::shared_ptr< RecordT > src
#define LSST_EXCEPT(type,...)
Create an exception with a given 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).
#define INSTANTIATE(FROMSYS, TOSYS)
std::type_info const & typeOf(std::string const &name) const
Get the type of values for a property name (possibly hierarchical).