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(
unsigned long))
return boost::any_cast<unsigned long>(v);
317 if (t ==
typeid(
long long))
return boost::any_cast<long long>(v);
318 if (t ==
typeid(
unsigned long long))
return boost::any_cast<unsigned long long>(v);
319 if (t ==
typeid(
float))
return boost::any_cast<float>(v);
321 return boost::any_cast<
double>(v);
322 }
catch (boost::bad_any_cast) {
323 throw LSST_EXCEPT(pex::exceptions::TypeError, name);
326 return boost::any_cast<
double>(v);
334 return get<Persistable::Ptr>(
name);
341 for (
auto const& i : nv) {
344 if (t ==
typeid(
Ptr)) {
345 s << indent << i <<
" = ";
349 Ptr p = boost::any_cast<
Ptr>(vp->back());
354 s << p->toString(
false, indent +
"..");
369 auto const j = _map.find(name);
370 s << j->first <<
" = ";
372 if (vp->size() > 1) {
377 for (
auto const& k : *vp) {
384 if (t ==
typeid(
bool)) {
385 s << boost::any_cast<bool>(v);
386 }
else if (t ==
typeid(
char)) {
387 s << '\'' << boost::any_cast<char>(v) <<
'\'';
388 }
else if (t ==
typeid(
signed char)) {
389 s << '\'' << boost::any_cast<signed char>(v) <<
'\'';
390 }
else if (t ==
typeid(
unsigned char)) {
391 s << '\'' << boost::any_cast<unsigned char>(v) <<
'\'';
392 }
else if (t ==
typeid(
short)) {
393 s << boost::any_cast<short>(v);
394 }
else if (t ==
typeid(
unsigned short)) {
395 s << boost::any_cast<unsigned short>(v);
396 }
else if (t ==
typeid(
int)) {
397 s << boost::any_cast<int>(v);
398 }
else if (t ==
typeid(
unsigned int)) {
399 s << boost::any_cast<unsigned int>(v);
400 }
else if (t ==
typeid(
long)) {
401 s << boost::any_cast<long>(v);
402 }
else if (t ==
typeid(
unsigned long)) {
403 s << boost::any_cast<unsigned long>(v);
404 }
else if (t ==
typeid(
long long)) {
405 s << boost::any_cast<long long>(v);
406 }
else if (t ==
typeid(
unsigned long long)) {
407 s << boost::any_cast<unsigned long long>(v);
408 }
else if (t ==
typeid(
float)) {
409 s << std::setprecision(7) << boost::any_cast<float>(v);
410 }
else if (t ==
typeid(
double)) {
411 s << std::setprecision(14) << boost::any_cast<double>(v);
413 s <<
'"' << boost::any_cast<
std::string>(v) <<
'"';
414 }
else if (t ==
typeid(DateTime)) {
416 }
else if (t ==
typeid(
Ptr)) {
419 s <<
"<Persistable>";
424 if (j->second->size() > 1) {
435 template <
typename T>
438 vp->push_back(value);
442 template <
typename T>
444 if (value.
empty())
return;
452 template <
typename T>
454 AnyMap::iterator i = _find(name);
455 if (i == _map.end()) {
458 if (i->second->back().type() !=
typeid(T)) {
459 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
461 i->second->push_back(value);
468 AnyMap::iterator i = _find(name);
469 if (i == _map.end()) {
472 if (i->second->back().type() !=
typeid(
Ptr)) {
473 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
475 _cycleCheckPtr(value, name);
476 i->second->push_back(value);
480 template <
typename T>
482 AnyMap::iterator i = _find(name);
483 if (i == _map.end()) {
486 if (i->second->back().type() !=
typeid(T)) {
487 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
489 _append(*(i->second), value);
496 AnyMap::iterator i = _find(name);
497 if (i == _map.end()) {
500 if (i->second->back().type() !=
typeid(
Ptr)) {
501 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
503 _cycleCheckPtrVec(value, name);
504 _append(*(i->second), value);
511 if (source.get() == 0) {
512 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
"Missing source");
514 auto const sj = source->_find(name);
515 if (sj == source->_map.end()) {
516 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" not in source");
520 auto vp = std::make_shared<std::vector<boost::any>>();
521 vp->push_back(sj->second->back());
524 auto vp = std::make_shared<std::vector<boost::any>>(*(sj->second));
530 if (source.get() == 0) {
534 for (
auto const& name : names) {
535 auto const sp = source->_find(name);
536 _add(name, sp->second);
541 std::string::size_type i = name.
find(
'.');
542 if (_flat || i == name.npos) {
547 AnyMap::iterator j = _map.find(
prefix);
548 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
551 Ptr p = boost::any_cast<
Ptr>(j->second->back());
562 PropertySet::AnyMap::iterator PropertySet::_find(
std::string const& name) {
563 std::string::size_type i = name.
find(
'.');
564 if (_flat || i == name.npos) {
565 return _map.find(name);
568 AnyMap::iterator j = _map.find(
prefix);
569 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
572 Ptr p = boost::any_cast<
Ptr>(j->second->back());
577 AnyMap::iterator
x = p->_find(suffix);
578 if (x == p->_map.end()) {
584 PropertySet::AnyMap::const_iterator PropertySet::_find(
std::string const& name)
const {
585 std::string::size_type i = name.
find(
'.');
586 if (_flat || i == name.npos) {
587 return _map.find(name);
590 auto const j = _map.find(
prefix);
591 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
594 Ptr p = boost::any_cast<
Ptr>(j->second->back());
599 auto const x = p->_find(suffix);
600 if (x == p->_map.end()) {
607 _findOrInsert(name, vp);
611 auto const dp = _find(name);
612 if (dp == _map.end()) {
615 if (vp->back().type() != dp->second->back().type()) {
616 throw LSST_EXCEPT(pex::exceptions::TypeError, name +
" has mismatched type");
619 if (vp->back().type() ==
typeid(
Ptr)) {
620 _cycleCheckAnyVec(*vp, name);
622 _append(*(dp->second), *vp);
627 if (vp->back().type() ==
typeid(
Ptr)) {
629 Ptr source = boost::any_cast<
Ptr>(vp->back());
631 for (
auto const& i : names) {
632 auto const sp = source->_find(i);
633 _add(name +
"." + i, sp->second);
639 _cycleCheckAnyVec(*vp, name);
642 std::string::size_type i = name.
find(
'.');
643 if (_flat || i == name.npos) {
649 AnyMap::iterator j = _map.find(
prefix);
650 if (j == _map.end()) {
652 pp->_findOrInsert(suffix, vp);
657 }
else if (j->second->back().type() !=
typeid(
Ptr)) {
658 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
659 prefix +
" exists but does not contain PropertySet::Ptrs");
661 Ptr p = boost::any_cast<
Ptr>(j->second->back());
663 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
664 prefix +
" exists but contains null PropertySet::Ptr");
666 p->_findOrInsert(suffix, vp);
670 for (
auto const& i : v) {
671 _cycleCheckPtr(i, name);
676 for (
auto const& i : v) {
677 _cycleCheckPtr(boost::any_cast<Ptr>(i), name);
681 void PropertySet::_cycleCheckPtr(
Ptr const& v,
std::string const& name) {
682 if (v.get() ==
this) {
683 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" would cause a cycle");
686 for (
auto const& i : sets) {
687 if (v->getAsPropertySetPtr(i).get() ==
this) {
688 throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name +
" would cause a cycle");
700 #define INSTANTIATE(t) \ 701 template std::type_info const& PropertySet::typeOfT<t>(); \ 702 template t PropertySet::get<t>(std::string const& name) const; \ 703 template t PropertySet::get<t>(std::string const& name, t const& defaultValue) const; \ 704 template std::vector<t> PropertySet::getArray<t>(std::string const& name) const; \ 705 template void PropertySet::set<t>(std::string const& name, t const& value); \ 706 template void PropertySet::set<t>(std::string const& name, std::vector<t> const& value); \ 707 template void PropertySet::add<t>(std::string const& name, t const& value); \ 708 template void PropertySet::add<t>(std::string const& name, std::vector<t> const& value); 710 #define INSTANTIATE_PROPERTY_SET(t) \ 711 template std::type_info const& PropertySet::typeOfT<t>(); \ 712 template t PropertySet::get<t>(std::string const& name) const; \ 713 template t PropertySet::get<t>(std::string const& name, t const& defaultValue) const; \ 714 template std::vector<t> PropertySet::getArray<t>(std::string const& name) const; \ 715 template void PropertySet::set<t>(std::string const& name, t const& value); \ 716 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).
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).