44 #include "lsst/pex/exceptions/Runtime.h" 48 namespace pexExcept = lsst::pex::exceptions;
72 for (AnyMap::const_iterator i = _map.begin(); i != _map.end(); ++i) {
73 if (i->second->back().type() ==
typeid(
Ptr)) {
74 for (vector<boost::any>::const_iterator j =
75 i->second->begin(); j != i->second->end(); ++j) {
76 Ptr p = boost::any_cast<
Ptr>(*j);
78 n->add(i->first,
Ptr());
80 n->add(i->first, p->deepCopy());
84 std::shared_ptr< vector<boost::any> > vp(
85 new vector<boost::any>(*(i->second)));
86 n->_map[i->first] = vp;
99 for (AnyMap::const_iterator i = _map.begin(); i != _map.end(); ++i) {
101 if (!topLevelOnly && i->second->back().type() ==
typeid(
Ptr)) {
102 Ptr p = boost::any_cast<
Ptr>(i->second->back());
104 n += p->nameCount(
false);
119 for (AnyMap::const_iterator i = _map.begin(); i != _map.end(); ++i) {
120 v.push_back(i->first);
121 if (!topLevelOnly && i->second->back().type() ==
typeid(
Ptr)) {
122 Ptr p = boost::any_cast<
Ptr>(i->second->back());
124 vector<string> w = p->names(
false);
125 for (vector<string>::const_iterator k = w.begin();
127 v.push_back(i->first +
"." + *k);
144 for (AnyMap::const_iterator i = _map.begin(); i != _map.end(); ++i) {
145 if (i->second->back().type() ==
typeid(
Ptr)) {
146 Ptr p = boost::any_cast<
Ptr>(i->second->back());
147 if (p.get() != 0 && !topLevelOnly) {
148 vector<string> w = p->paramNames(
false);
149 for (vector<string>::const_iterator k = w.begin();
151 v.push_back(i->first +
"." + *k);
155 v.push_back(i->first);
170 for (AnyMap::const_iterator i = _map.begin(); i != _map.end(); ++i) {
171 if (i->second->back().type() ==
typeid(
Ptr)) {
172 v.push_back(i->first);
173 Ptr p = boost::any_cast<
Ptr>(i->second->back());
174 if (p.get() != 0 && !topLevelOnly) {
175 vector<string> w = p->propertySetNames(
false);
176 for (vector<string>::const_iterator k = w.begin();
178 v.push_back(i->first +
"." + *k);
191 return _find(name) != _map.end();
199 AnyMap::const_iterator i = _find(name);
200 return i != _map.end() && i->second->size() > 1U;
208 AnyMap::const_iterator i = _find(name);
209 return i != _map.end() && i->second->back().type() ==
typeid(
Ptr);
217 AnyMap::const_iterator i = _find(name);
218 if (i == _map.end())
return 0;
219 return i->second->size();
228 AnyMap::const_iterator i = _find(name);
229 if (i == _map.end()) {
230 throw LSST_EXCEPT(pexExcept::NotFoundError, name +
" not found");
232 return i->second->back().type();
245 template <
typename T>
247 AnyMap::const_iterator i = _find(name);
248 if (i == _map.end()) {
249 throw LSST_EXCEPT(pexExcept::NotFoundError, name +
" not found");
252 return boost::any_cast<T>(i->second->back());
254 catch (boost::bad_any_cast) {
255 throw LSST_EXCEPT(pexExcept::TypeError, name);
258 return boost::any_cast<T>(i->second->back());
270 template <
typename T>
272 AnyMap::const_iterator i = _find(name);
273 if (i == _map.end()) {
277 return boost::any_cast<T>(i->second->back());
279 catch (boost::bad_any_cast) {
280 throw LSST_EXCEPT(pexExcept::TypeError, name);
283 return boost::any_cast<T>(i->second->back());
294 template <
typename T>
296 AnyMap::const_iterator i = _find(name);
297 if (i == _map.end()) {
298 throw LSST_EXCEPT(pexExcept::NotFoundError, name +
" not found");
301 for (vector<boost::any>::const_iterator j = i->second->begin();
302 j != i->second->end(); ++j) {
304 v.push_back(boost::any_cast<T>(*j));
306 catch (boost::bad_any_cast) {
307 throw LSST_EXCEPT(pexExcept::TypeError, name);
322 return get<bool>(name);
334 AnyMap::const_iterator i = _find(name);
335 if (i == _map.end()) {
336 throw LSST_EXCEPT(pexExcept::NotFoundError, name +
" not found");
338 boost::any v = i->second->back();
339 type_info
const& t = v.type();
340 if (t ==
typeid(
bool)) {
341 return boost::any_cast<
bool>(v);
342 }
else if (t ==
typeid(
char)) {
343 return boost::any_cast<
char>(v);
344 }
else if (t ==
typeid(
signed char)) {
345 return boost::any_cast<
signed char>(v);
346 }
else if (t ==
typeid(
unsigned char)) {
347 return boost::any_cast<
unsigned char>(v);
348 }
else if (t ==
typeid(
short)) {
349 return boost::any_cast<
short>(v);
350 }
else if (t ==
typeid(
unsigned short)) {
351 return boost::any_cast<
unsigned short>(v);
354 return boost::any_cast<
int>(v);
356 catch (boost::bad_any_cast) {
357 throw LSST_EXCEPT(pexExcept::TypeError, name);
360 return boost::any_cast<
int>(v);
373 AnyMap::const_iterator i = _find(name);
374 if (i == _map.end()) {
375 throw LSST_EXCEPT(pexExcept::NotFoundError, name +
" not found");
377 boost::any v = i->second->back();
378 type_info
const& t = v.type();
379 if (t ==
typeid(
bool))
return boost::any_cast<
bool>(v);
380 if (t ==
typeid(
char))
return boost::any_cast<char>(v);
381 if (t ==
typeid(
signed char))
return boost::any_cast<signed char>(v);
382 if (t ==
typeid(
unsigned char))
return boost::any_cast<unsigned char>(v);
383 if (t ==
typeid(
short))
return boost::any_cast<short>(v);
384 if (t ==
typeid(
unsigned short))
return boost::any_cast<unsigned short>(v);
385 if (t ==
typeid(
int))
return boost::any_cast<int>(v);
386 if (t ==
typeid(
unsigned int))
return boost::any_cast<unsigned int>(v);
387 if (t ==
typeid(
long))
return boost::any_cast<long>(v);
388 if (t ==
typeid(
long long))
return boost::any_cast<long long>(v);
390 return boost::any_cast<int64_t>(v);
392 catch (boost::bad_any_cast) {
393 throw LSST_EXCEPT(pexExcept::TypeError, name);
396 return boost::any_cast<int64_t>(v);
407 AnyMap::const_iterator i = _find(name);
408 if (i == _map.end()) {
409 throw LSST_EXCEPT(pexExcept::NotFoundError, name +
" not found");
411 boost::any v = i->second->back();
412 type_info
const& t = v.type();
413 if (t ==
typeid(
bool))
return boost::any_cast<
bool>(v);
414 if (t ==
typeid(
char))
return boost::any_cast<char>(v);
415 if (t ==
typeid(
signed char))
return boost::any_cast<signed char>(v);
416 if (t ==
typeid(
unsigned char))
return boost::any_cast<unsigned char>(v);
417 if (t ==
typeid(
short))
return boost::any_cast<short>(v);
418 if (t ==
typeid(
unsigned short))
return boost::any_cast<unsigned short>(v);
419 if (t ==
typeid(
int))
return boost::any_cast<int>(v);
420 if (t ==
typeid(
unsigned int))
return boost::any_cast<unsigned int>(v);
421 if (t ==
typeid(
long))
return boost::any_cast<long>(v);
422 if (t ==
typeid(
unsigned long))
return boost::any_cast<unsigned long>(v);
423 if (t ==
typeid(
long long))
return boost::any_cast<long long>(v);
424 if (t ==
typeid(
unsigned long long))
return boost::any_cast<unsigned long long>(v);
425 if (t ==
typeid(
float))
return boost::any_cast<float>(v);
427 return boost::any_cast<
double>(v);
429 catch (boost::bad_any_cast) {
430 throw LSST_EXCEPT(pexExcept::TypeError, name);
433 return boost::any_cast<
double>(v);
445 return get<string>(name);
456 return get<Ptr>(name);
467 return get<Persistable::Ptr>(name);
477 std::string
const& indent)
const {
479 vector<string> nv =
names();
480 sort(nv.begin(), nv.end());
481 for (vector<string>::const_iterator i = nv.begin(); i != nv.end(); ++i) {
482 std::shared_ptr< vector<boost::any> > vp = _map.find(*i)->second;
483 type_info
const& t = vp->back().type();
484 if (t ==
typeid(
Ptr)) {
485 s << indent << *i <<
" = ";
489 Ptr p = boost::any_cast<
Ptr>(vp->back());
494 s << p->toString(
false, indent +
"..");
510 AnyMap::const_iterator j = _map.find(name);
511 s << j->first <<
" = ";
512 std::shared_ptr< vector<boost::any> > vp = j->second;
513 if (vp->size() > 1) {
516 type_info
const& t = vp->back().type();
517 for (vector<boost::any>::const_iterator k = vp->begin();
518 k != vp->end(); ++k) {
519 if (k != vp->begin()) {
522 boost::any
const& v(*k);
523 if (t ==
typeid(
bool)) {
524 s << boost::any_cast<bool>(v);
525 }
else if (t ==
typeid(
char)) {
526 s << '\'' << boost::any_cast<char>(v) <<
'\'';
527 }
else if (t ==
typeid(
signed char)) {
528 s << '\'' << boost::any_cast<signed char>(v) <<
'\'';
529 }
else if (t ==
typeid(
unsigned char)) {
530 s << '\'' << boost::any_cast<unsigned char>(v) <<
'\'';
531 }
else if (t ==
typeid(
short)) {
532 s << boost::any_cast<short>(v);
533 }
else if (t ==
typeid(
unsigned short)) {
534 s << boost::any_cast<unsigned short>(v);
535 }
else if (t ==
typeid(
int)) {
536 s << boost::any_cast<int>(v);
537 }
else if (t ==
typeid(
unsigned int)) {
538 s << boost::any_cast<unsigned int>(v);
539 }
else if (t ==
typeid(
long)) {
540 s << boost::any_cast<long>(v);
541 }
else if (t ==
typeid(
unsigned long)) {
542 s << boost::any_cast<unsigned long>(v);
543 }
else if (t ==
typeid(
long long)) {
544 s << boost::any_cast<long long>(v);
545 }
else if (t ==
typeid(
unsigned long long)) {
546 s << boost::any_cast<unsigned long long>(v);
547 }
else if (t ==
typeid(
float)) {
548 s << std::setprecision(7) << boost::any_cast<float>(v);
549 }
else if (t ==
typeid(
double)) {
550 s << std::setprecision(14) << boost::any_cast<double>(v);
551 }
else if (t ==
typeid(
string)) {
552 s <<
'"' << boost::any_cast<
string>(v) <<
'"';
555 }
else if (t ==
typeid(
Ptr)) {
558 s <<
"<Persistable>";
563 if (j->second->size() > 1) {
580 template <
typename T>
582 std::shared_ptr< vector<boost::any> > vp(
new vector<boost::any>);
583 vp->push_back(value);
593 template <
typename T>
595 vector<T>
const& value) {
596 if (value.empty())
return;
597 std::shared_ptr< vector<boost::any> > vp(
new vector<boost::any>);
598 vp->insert(vp->end(), value.begin(), value.end());
608 set(name, string(value));
618 template <
typename T>
620 AnyMap::iterator i = _find(name);
621 if (i == _map.end()) {
625 if (i->second->back().type() !=
typeid(T)) {
626 throw LSST_EXCEPT(pexExcept::TypeError,
627 name +
" has mismatched type");
629 i->second->push_back(value);
634 template <>
void dafBase::PropertySet::add<dafBase::PropertySet::Ptr>(
635 std::string
const& name,
Ptr const& value) {
636 AnyMap::iterator i = _find(name);
637 if (i == _map.end()) {
641 if (i->second->back().type() !=
typeid(
Ptr)) {
642 throw LSST_EXCEPT(pexExcept::TypeError,
643 name +
" has mismatched type");
645 _cycleCheckPtr(value, name);
646 i->second->push_back(value);
659 template <
typename T>
661 vector<T>
const& value) {
662 AnyMap::iterator i = _find(name);
663 if (i == _map.end()) {
667 if (i->second->back().type() !=
typeid(T)) {
668 throw LSST_EXCEPT(pexExcept::TypeError,
669 name +
" has mismatched type");
671 i->second->insert(i->second->end(), value.begin(), value.end());
676 template<>
void dafBase::PropertySet::add<dafBase::PropertySet::Ptr>(
677 std::string
const& name, vector<Ptr>
const& value) {
678 AnyMap::iterator i = _find(name);
679 if (i == _map.end()) {
683 if (i->second->back().type() !=
typeid(
Ptr)) {
684 throw LSST_EXCEPT(pexExcept::TypeError,
685 name +
" has mismatched type");
687 _cycleCheckPtrVec(value, name);
688 i->second->insert(i->second->end(), value.begin(), value.end());
701 add(name,
string(value));
714 ConstPtr source, std::string
const& name) {
715 if (source.get() == 0) {
716 throw LSST_EXCEPT(pexExcept::InvalidParameterError,
719 AnyMap::const_iterator sj = source->_find(name);
720 if (sj == source->_map.end()) {
721 throw LSST_EXCEPT(pexExcept::InvalidParameterError,
722 name +
" not in source");
725 std::shared_ptr< vector<boost::any> > vp(
726 new vector<boost::any>(*(sj->second)));
739 if (source.get() == 0) {
742 vector<string>
names = source->paramNames(
false);
743 for (vector<string>::const_iterator i = names.begin();
744 i != names.end(); ++i) {
745 AnyMap::const_iterator sp = source->_find(*i);
746 _add(*i, sp->second);
755 string::size_type i = name.find(
'.');
756 if (_flat || i == name.npos) {
760 string prefix(name, 0, i);
761 AnyMap::iterator j = _map.find(prefix);
762 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
765 Ptr p = boost::any_cast<
Ptr>(j->second->back());
767 string suffix(name, i + 1);
780 dafBase::PropertySet::AnyMap::iterator
781 dafBase::PropertySet::_find(std::string
const& name) {
782 string::size_type i = name.find(
'.');
783 if (_flat || i == name.npos) {
784 return _map.find(name);
786 string prefix(name, 0, i);
787 AnyMap::iterator j = _map.find(prefix);
788 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
791 Ptr p = boost::any_cast<
Ptr>(j->second->back());
795 string suffix(name, i + 1);
796 AnyMap::iterator x = p->_find(suffix);
797 if (x == p->_map.end()) {
807 dafBase::PropertySet::AnyMap::const_iterator
808 dafBase::PropertySet::_find(std::string
const& name)
const {
809 string::size_type i = name.find(
'.');
810 if (_flat || i == name.npos) {
811 return _map.find(name);
813 string prefix(name, 0, i);
814 AnyMap::const_iterator j = _map.find(prefix);
815 if (j == _map.end() || j->second->back().type() !=
typeid(
Ptr)) {
818 Ptr p = boost::any_cast<
Ptr>(j->second->back());
822 string suffix(name, i + 1);
823 AnyMap::const_iterator x = p->_find(suffix);
824 if (x == p->_map.end()) {
838 std::string
const& name, std::shared_ptr< std::vector<boost::any> > vp) {
839 _findOrInsert(name, vp);
849 std::string
const& name, std::shared_ptr< std::vector<boost::any> > vp) {
851 AnyMap::const_iterator dp = _find(name);
852 if (dp == _map.end()) {
856 if (vp->back().type() != dp->second->back().type()) {
857 throw LSST_EXCEPT(pexExcept::TypeError,
858 name +
" has mismatched type");
861 if (vp->back().type() ==
typeid(
Ptr)) {
862 _cycleCheckAnyVec(*vp, name);
864 dp->second->insert(dp->second->end(), vp->begin(), vp->end());
874 void dafBase::PropertySet::_findOrInsert(
875 std::string
const& name, std::shared_ptr< std::vector<boost::any> > vp) {
876 if (vp->back().type() ==
typeid(
Ptr)) {
878 Ptr source = boost::any_cast<
Ptr>(vp->back());
879 vector<string>
names = source->paramNames(
false);
880 for (vector<string>::const_iterator i = names.begin();
881 i != names.end(); ++i) {
882 AnyMap::const_iterator sp = source->_find(*i);
883 _add(name +
"." + *i, sp->second);
889 _cycleCheckAnyVec(*vp, name);
892 string::size_type i = name.find(
'.');
893 if (_flat || i == name.npos) {
897 string prefix(name, 0, i);
898 string suffix(name, i + 1);
899 AnyMap::iterator j = _map.find(prefix);
900 if (j == _map.end()) {
902 pp->_findOrInsert(suffix, vp);
903 std::shared_ptr< vector<boost::any> > temp(
new vector<boost::any>);
908 else if (j->second->back().type() !=
typeid(
Ptr)) {
909 throw LSST_EXCEPT(pexExcept::InvalidParameterError,
911 " exists but does not contain PropertySet::Ptrs");
913 Ptr p = boost::any_cast<
Ptr>(j->second->back());
915 throw LSST_EXCEPT(pexExcept::InvalidParameterError,
917 " exists but contains null PropertySet::Ptr");
919 p->_findOrInsert(suffix, vp);
922 void dafBase::PropertySet::_cycleCheckPtrVec(std::vector<Ptr>
const& v,
923 std::string
const& name) {
924 for (vector<Ptr>::const_iterator i = v.begin(); i != v.end(); ++i) {
925 _cycleCheckPtr(*i, name);
929 void dafBase::PropertySet::_cycleCheckAnyVec(std::vector<boost::any>
const& v,
930 std::string
const& name) {
931 for (vector<boost::any>::const_iterator i = v.begin(); i != v.end(); ++i) {
932 _cycleCheckPtr(boost::any_cast<Ptr>(*i), name);
936 void dafBase::PropertySet::_cycleCheckPtr(
Ptr const& v,
937 std::string
const& name) {
938 if (v.get() ==
this) {
939 throw LSST_EXCEPT(pexExcept::InvalidParameterError,
940 name +
" would cause a cycle");
942 vector<string> sets = v->propertySetNames(
false);
943 for (vector<string>::const_iterator i = sets.begin();
944 i != sets.end(); ++i) {
945 if (v->getAsPropertySetPtr(*i).get() ==
this) {
946 throw LSST_EXCEPT(pexExcept::InvalidParameterError,
947 name +
" would cause a cycle");
959 #define INSTANTIATE(t) \ 960 template t dafBase::PropertySet::get<t>(string const& name) const; \ 961 template t dafBase::PropertySet::get<t>(string const& name, t const& defaultValue) const; \ 962 template vector<t> dafBase::PropertySet::getArray<t>(string const& name) const; \ 963 template void dafBase::PropertySet::set<t>(string const& name, t const& value); \ 964 template void dafBase::PropertySet::set<t>(string const& name, vector<t> const& value); \ 965 template void dafBase::PropertySet::add<t>(string const& name, t const& value); \ 966 template void dafBase::PropertySet::add<t>(string const& name, vector<t> const& value); 970 INSTANTIATE(
signed char)
971 INSTANTIATE(
unsigned char)
973 INSTANTIATE(
unsigned short)
975 INSTANTIATE(
unsigned int)
977 INSTANTIATE(
unsigned long)
978 INSTANTIATE(
long long)
979 INSTANTIATE(
unsigned long long)
987 double getAsDouble(std::string const &name) const
Get the last value for any arithmetic property name (possibly hierarchical).
virtual Ptr deepCopy(void) const
Copy the PropertySet and all of its contents.
virtual std::string _format(std::string const &name) const
std::shared_ptr< PropertySet > Ptr
Class for handling dates/times, including MJD, UTC, and TAI.
size_t valueCount(std::string const &name) const
Get number of values for a property name (possibly hierarchical).
std::vector< T > getArray(std::string const &name) const
virtual void remove(std::string const &name)
Removes all values for a property name (possibly hierarchical).
virtual void _add(std::string const &name, std::shared_ptr< std::vector< boost::any > > vp)
Finds the property name (possibly hierarchical) and appends or sets its value with the given vector o...
T get(std::string const &name) const
Get the last value for a property name (possibly hierarchical).
virtual void copy(std::string const &dest, ConstPtr source, std::string const &name)
Replaces a single value vector in the destination with one from the source.
bool getAsBool(std::string const &name) const
Get the last value for a bool property name (possibly hierarchical).
std::vector< std::string > paramNames(bool topLevelOnly=true) const
Get the names of parameters (non-subproperties) in the PropertySet, optionally including those in sub...
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
bool isPropertySetPtr(std::string const &name) const
Determine if a name (possibly hierarchical) is a subproperty.
PropertySet(bool flat=false)
Constructor.
virtual std::string toString(bool topLevelOnly=false, std::string const &indent="") const
Generate a string representation of the PropertySet.
void set(std::string const &name, T const &value)
Replace all values for a property name (possibly hierarchical) with a new value.
bool isArray(std::string const &name) const
Determine if a name (possibly hierarchical) has multiple values.
virtual void combine(ConstPtr source)
Appends all value vectors from the source to their corresponding properties.
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::vector< std::string > names(bool topLevelOnly=true) const
Get the names in the PropertySet, optionally including those in subproperties.
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.
Interface for DateTime class.
std::vector< std::string > propertySetNames(bool topLevelOnly=true) const
Get the names of subproperties in the PropertySet, optionally including those in subproperties.
virtual void _set(std::string const &name, std::shared_ptr< std::vector< boost::any > > vp)
Finds the property name (possibly hierarchical) and sets or replaces its value with the given vector ...
Class for storing generic metadata.
std::shared_ptr< Persistable > Ptr
Interface for PropertySet class.
virtual ~PropertySet(void)
Destructor.
std::string getAsString(std::string const &name) const
Get the last value for a string property name (possibly hierarchical).
Citizen is a class that should be among all LSST classes base classes, and handles basic memory manag...
Persistable::Ptr getAsPersistablePtr(std::string const &name) const
Get the last value for a Persistable name (possibly hierarchical).
void add(std::string const &name, T const &value)
Appends 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).