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");
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");
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");
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");
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) {
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);
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); 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.
uint64_t getAsUInt64(std::string const &name) const
Get the last value for an bool/char/short/int/int64_t property name (possibly hierarchical).
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).
std::shared_ptr< RecordT > src
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).
#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).
bool isUndefined(std::string const &name) const
Determine if a name (possibly hierarchical) has a defined value.
#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).