LSSTApplications  17.0+11,17.0+34,17.0+56,17.0+57,17.0+59,17.0+7,17.0-1-g377950a+33,17.0.1-1-g114240f+2,17.0.1-1-g4d4fbc4+28,17.0.1-1-g55520dc+49,17.0.1-1-g5f4ed7e+52,17.0.1-1-g6dd7d69+17,17.0.1-1-g8de6c91+11,17.0.1-1-gb9095d2+7,17.0.1-1-ge9fec5e+5,17.0.1-1-gf4e0155+55,17.0.1-1-gfc65f5f+50,17.0.1-1-gfc6fb1f+20,17.0.1-10-g87f9f3f+1,17.0.1-11-ge9de802+16,17.0.1-16-ga14f7d5c+4,17.0.1-17-gc79d625+1,17.0.1-17-gdae4c4a+8,17.0.1-2-g26618f5+29,17.0.1-2-g54f2ebc+9,17.0.1-2-gf403422+1,17.0.1-20-g2ca2f74+6,17.0.1-23-gf3eadeb7+1,17.0.1-3-g7e86b59+39,17.0.1-3-gb5ca14a,17.0.1-3-gd08d533+40,17.0.1-30-g596af8797,17.0.1-4-g59d126d+4,17.0.1-4-gc69c472+5,17.0.1-6-g5afd9b9+4,17.0.1-7-g35889ee+1,17.0.1-7-gc7c8782+18,17.0.1-9-gc4bbfb2+3,w.2019.22
LSSTDataManagementBasePackage
PropertySet.cc
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008, 2009, 2010 LSST Corporation.
6  *
7  * This product includes software developed by the
8  * LSST Project (http://www.lsst.org/).
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more errors.
19  *
20  * You should have received a copy of the LSST License Statement and
21  * the GNU General Public License along with this program. If not,
22  * see <http://www.lsstcorp.org/LegalNotices/>.
23  */
24 
26 
27 #include <algorithm>
28 #include <iomanip>
29 #include <sstream>
30 #include <stdexcept>
31 
33 #include "lsst/daf/base/DateTime.h"
34 
35 namespace lsst {
36 namespace daf {
37 namespace base {
38 
39 namespace {
40 
47 template <typename T>
48 void _append(std::vector<boost::any>& dest, std::vector<T> const& src) {
49  dest.reserve(dest.size() + src.size());
50  for (const T& val : src) {
51  dest.push_back(static_cast<T>(val));
52  }
53 }
54 
55 } // namespace
56 
57 PropertySet::PropertySet(bool flat) : Citizen(typeid(*this)), _flat(flat) {}
58 
60 
62 // Accessors
64 
65 PropertySet::Ptr PropertySet::deepCopy() const {
66  Ptr n(new PropertySet(_flat));
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);
71  if (p.get() == 0) {
72  n->add(elt.first, Ptr());
73  } else {
74  n->add(elt.first, p->deepCopy());
75  }
76  }
77  } else {
79  n->_map[elt.first] = vp;
80  }
81  }
82  return n;
83 }
84 
85 size_t PropertySet::nameCount(bool topLevelOnly) const {
86  int n = 0;
87  for (auto const& elt : _map) {
88  ++n;
89  if (!topLevelOnly && elt.second->back().type() == typeid(Ptr)) {
90  Ptr p = boost::any_cast<Ptr>(elt.second->back());
91  if (p.get() != 0) {
92  n += p->nameCount(false);
93  }
94  }
95  }
96  return n;
97 }
98 
99 std::vector<std::string> PropertySet::names(bool topLevelOnly) const {
101  for (auto const& elt : _map) {
102  v.push_back(elt.first);
103  if (!topLevelOnly && elt.second->back().type() == typeid(Ptr)) {
104  Ptr p = boost::any_cast<Ptr>(elt.second->back());
105  if (p.get() != 0) {
106  std::vector<std::string> w = p->names(false);
107  for (auto const& k : w) {
108  v.push_back(elt.first + "." + k);
109  }
110  }
111  }
112  }
113  return v;
114 }
115 
116 std::vector<std::string> PropertySet::paramNames(bool topLevelOnly) const {
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) {
122  std::vector<std::string> w = p->paramNames(false);
123  for (auto const& k : w) {
124  v.push_back(elt.first + "." + k);
125  }
126  }
127  } else {
128  v.push_back(elt.first);
129  }
130  }
131  return v;
132 }
133 
136  for (auto const& elt : _map) {
137  if (elt.second->back().type() == typeid(Ptr)) {
138  v.push_back(elt.first);
139  Ptr p = boost::any_cast<Ptr>(elt.second->back());
140  if (p.get() != 0 && !topLevelOnly) {
141  std::vector<std::string> w = p->propertySetNames(false);
142  for (auto const& k : w) {
143  v.push_back(elt.first + "." + k);
144  }
145  }
146  }
147  }
148  return v;
149 }
150 
151 bool PropertySet::exists(std::string const& name) const { return _find(name) != _map.end(); }
152 
153 bool PropertySet::isArray(std::string const& name) const {
154  auto const i = _find(name);
155  return i != _map.end() && i->second->size() > 1U;
156 }
157 
158 bool PropertySet::isPropertySetPtr(std::string const& name) const {
159  auto const i = _find(name);
160  return i != _map.end() && i->second->back().type() == typeid(Ptr);
161 }
162 
163 bool PropertySet::isUndefined(std::string const& name) const {
164  auto const i = _find(name);
165  return i != _map.end() && i->second->back().type() == typeid(nullptr);
166 }
167 
168 size_t PropertySet::valueCount(std::string const& name) const {
169  auto const i = _find(name);
170  if (i == _map.end()) return 0;
171  return i->second->size();
172 }
173 
174 std::type_info const& PropertySet::typeOf(std::string const& name) const {
175  auto const i = _find(name);
176  if (i == _map.end()) {
177  throw LSST_EXCEPT(pex::exceptions::NotFoundError, name + " not found");
178  }
179  return i->second->back().type();
180 }
181 
182 template <typename T>
184  return typeid(T);
185 }
186 
187 // The following throw an exception if the type does not match exactly.
188 
189 template <typename T>
190 T PropertySet::get(std::string const& name)
191  const { /* parasoft-suppress LsstDm-3-4a LsstDm-4-6 "allow template over bool" */
192  auto const i = _find(name);
193  if (i == _map.end()) {
194  throw LSST_EXCEPT(pex::exceptions::NotFoundError, name + " not found");
195  }
196  try {
197  return boost::any_cast<T>(i->second->back());
198  } catch (boost::bad_any_cast) {
199  throw LSST_EXCEPT(pex::exceptions::TypeError, name);
200  }
201  // not reached
202  return boost::any_cast<T>(i->second->back());
203 }
204 
205 template <typename T>
206 T PropertySet::get(std::string const& name, T const& defaultValue)
207  const { /* parasoft-suppress LsstDm-3-4a LsstDm-4-6 "allow template over bool" */
208  auto const i = _find(name);
209  if (i == _map.end()) {
210  return defaultValue;
211  }
212  try {
213  return boost::any_cast<T>(i->second->back());
214  } catch (boost::bad_any_cast) {
215  throw LSST_EXCEPT(pex::exceptions::TypeError, name);
216  }
217  // not reached
218  return boost::any_cast<T>(i->second->back());
219 }
220 
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");
226  }
227  std::vector<T> v;
228  for (auto const& j : *(i->second)) {
229  try {
230  v.push_back(boost::any_cast<T>(j));
231  } catch (boost::bad_any_cast) {
232  throw LSST_EXCEPT(pex::exceptions::TypeError, name);
233  }
234  }
235  return v;
236 }
237 
238 // The following throw an exception if the conversion is inappropriate.
239 
240 bool PropertySet::getAsBool(std::string const& name)
241  const { /* parasoft-suppress LsstDm-3-4a LsstDm-4-6 "for symmetry with other types" */
242  return get<bool>(name);
243 }
244 
245 int PropertySet::getAsInt(std::string const& name) const {
246  auto const i = _find(name);
247  if (i == _map.end()) {
248  throw LSST_EXCEPT(pex::exceptions::NotFoundError, name + " not found");
249  }
250  boost::any v = i->second->back();
251  std::type_info const& t = v.type();
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);
264  }
265  try {
266  return boost::any_cast<int>(v);
267  } catch (boost::bad_any_cast) {
268  throw LSST_EXCEPT(pex::exceptions::TypeError, name);
269  }
270  // not reached
271  return boost::any_cast<int>(v);
272 }
273 
274 int64_t PropertySet::getAsInt64(std::string const& name) const {
275  auto const i = _find(name);
276  if (i == _map.end()) {
277  throw LSST_EXCEPT(pex::exceptions::NotFoundError, name + " not found");
278  }
279  boost::any v = i->second->back();
280  std::type_info const& t = v.type();
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);
291  try {
292  return boost::any_cast<int64_t>(v);
293  } catch (boost::bad_any_cast) {
294  throw LSST_EXCEPT(pex::exceptions::TypeError, name);
295  }
296  // not reached
297  return boost::any_cast<int64_t>(v);
298 }
299 
300 double PropertySet::getAsDouble(std::string const& name) const {
301  auto const i = _find(name);
302  if (i == _map.end()) {
303  throw LSST_EXCEPT(pex::exceptions::NotFoundError, name + " not found");
304  }
305  boost::any v = i->second->back();
306  std::type_info const& t = v.type();
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);
320  try {
321  return boost::any_cast<double>(v);
322  } catch (boost::bad_any_cast) {
323  throw LSST_EXCEPT(pex::exceptions::TypeError, name);
324  }
325  // not reached
326  return boost::any_cast<double>(v);
327 }
328 
329 std::string PropertySet::getAsString(std::string const& name) const { return get<std::string>(name); }
330 
331 PropertySet::Ptr PropertySet::getAsPropertySetPtr(std::string const& name) const { return get<Ptr>(name); }
332 
334  return get<Persistable::Ptr>(name);
335 }
336 
337 std::string PropertySet::toString(bool topLevelOnly, std::string const& indent) const {
340  sort(nv.begin(), nv.end());
341  for (auto const& i : nv) {
342  std::shared_ptr<std::vector<boost::any>> vp = _map.find(i)->second;
343  std::type_info const& t = vp->back().type();
344  if (t == typeid(Ptr)) {
345  s << indent << i << " = ";
346  if (topLevelOnly) {
347  s << "{ ... }";
348  } else {
349  Ptr p = boost::any_cast<Ptr>(vp->back());
350  if (p.get() == 0) {
351  s << "{ NULL }";
352  } else {
353  s << '{' << std::endl;
354  s << p->toString(false, indent + "..");
355  s << indent << '}';
356  }
357  }
358  s << std::endl;
359  } else {
360  s << indent << _format(i);
361  }
362  }
363  return s.str();
364 }
365 
366 std::string PropertySet::_format(std::string const& name) const {
368  s << std::showpoint; // Always show a decimal point for floats
369  auto const j = _map.find(name);
370  s << j->first << " = ";
372  if (vp->size() > 1) {
373  s << "[ ";
374  }
375  std::type_info const& t = vp->back().type();
376  bool isFirst = true;
377  for (auto const& k : *vp) {
378  if (isFirst) {
379  isFirst = false;
380  } else {
381  s << ", ";
382  }
383  boost::any const& v(k);
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);
412  } else if (t == typeid(std::string)) {
413  s << '"' << boost::any_cast<std::string>(v) << '"';
414  } else if (t == typeid(DateTime)) {
415  s << boost::any_cast<DateTime>(v).toString(DateTime::UTC);
416  } else if (t == typeid(Ptr)) {
417  s << "{ ... }";
418  } else if (t == typeid(Persistable::Ptr)) {
419  s << "<Persistable>";
420  } else {
421  s << "<Unknown>";
422  }
423  }
424  if (j->second->size() > 1) {
425  s << " ]";
426  }
427  s << std::endl;
428  return s.str();
429 }
430 
432 // Modifiers
434 
435 template <typename T>
436 void PropertySet::set(std::string const& name, T const& value) {
438  vp->push_back(value);
439  _set(name, vp);
440 }
441 
442 template <typename T>
443 void PropertySet::set(std::string const& name, std::vector<T> const& value) {
444  if (value.empty()) return;
446  _append(*vp, value);
447  _set(name, vp);
448 }
449 
450 void PropertySet::set(std::string const& name, char const* value) { set(name, std::string(value)); }
451 
452 template <typename T>
453 void PropertySet::add(std::string const& name, T const& value) {
454  AnyMap::iterator i = _find(name);
455  if (i == _map.end()) {
456  set(name, value);
457  } else {
458  if (i->second->back().type() != typeid(T)) {
459  throw LSST_EXCEPT(pex::exceptions::TypeError, name + " has mismatched type");
460  }
461  i->second->push_back(value);
462  }
463 }
464 
465 // Specialize for Ptrs to check for cycles.
466 template <>
467 void PropertySet::add<PropertySet::Ptr>(std::string const& name, Ptr const& value) {
468  AnyMap::iterator i = _find(name);
469  if (i == _map.end()) {
470  set(name, value);
471  } else {
472  if (i->second->back().type() != typeid(Ptr)) {
473  throw LSST_EXCEPT(pex::exceptions::TypeError, name + " has mismatched type");
474  }
475  _cycleCheckPtr(value, name);
476  i->second->push_back(value);
477  }
478 }
479 
480 template <typename T>
481 void PropertySet::add(std::string const& name, std::vector<T> const& value) {
482  AnyMap::iterator i = _find(name);
483  if (i == _map.end()) {
484  set(name, value);
485  } else {
486  if (i->second->back().type() != typeid(T)) {
487  throw LSST_EXCEPT(pex::exceptions::TypeError, name + " has mismatched type");
488  }
489  _append(*(i->second), value);
490  }
491 }
492 
493 // Specialize for Ptrs to check for cycles.
494 template <>
495 void PropertySet::add<PropertySet::Ptr>(std::string const& name, std::vector<Ptr> const& value) {
496  AnyMap::iterator i = _find(name);
497  if (i == _map.end()) {
498  set(name, value);
499  } else {
500  if (i->second->back().type() != typeid(Ptr)) {
501  throw LSST_EXCEPT(pex::exceptions::TypeError, name + " has mismatched type");
502  }
503  _cycleCheckPtrVec(value, name);
504  _append(*(i->second), value);
505  }
506 }
507 
508 void PropertySet::add(std::string const& name, char const* value) { add(name, std::string(value)); }
509 
510 void PropertySet::copy(std::string const& dest, ConstPtr source, std::string const& name, bool asScalar) {
511  if (source.get() == 0) {
512  throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, "Missing source");
513  }
514  auto const sj = source->_find(name);
515  if (sj == source->_map.end()) {
516  throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name + " not in source");
517  }
518  remove(dest);
519  if (asScalar) {
520  auto vp = std::make_shared<std::vector<boost::any>>();
521  vp->push_back(sj->second->back());
522  _set(dest, vp);
523  } else {
524  auto vp = std::make_shared<std::vector<boost::any>>(*(sj->second));
525  _set(dest, vp);
526  }
527 }
528 
529 void PropertySet::combine(ConstPtr source) {
530  if (source.get() == 0) {
531  return;
532  }
533  std::vector<std::string> names = source->paramNames(false);
534  for (auto const& name : names) {
535  auto const sp = source->_find(name);
536  _add(name, sp->second);
537  }
538 }
539 
540 void PropertySet::remove(std::string const& name) {
541  std::string::size_type i = name.find('.');
542  if (_flat || i == name.npos) {
543  _map.erase(name);
544  return;
545  }
546  std::string prefix(name, 0, i);
547  AnyMap::iterator j = _map.find(prefix);
548  if (j == _map.end() || j->second->back().type() != typeid(Ptr)) {
549  return;
550  }
551  Ptr p = boost::any_cast<Ptr>(j->second->back());
552  if (p.get() != 0) {
553  std::string suffix(name, i + 1);
554  p->remove(suffix);
555  }
556 }
557 
559 // Private member functions
561 
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);
566  }
567  std::string prefix(name, 0, i);
568  AnyMap::iterator j = _map.find(prefix);
569  if (j == _map.end() || j->second->back().type() != typeid(Ptr)) {
570  return _map.end();
571  }
572  Ptr p = boost::any_cast<Ptr>(j->second->back());
573  if (p.get() == 0) {
574  return _map.end();
575  }
576  std::string suffix(name, i + 1);
577  AnyMap::iterator x = p->_find(suffix);
578  if (x == p->_map.end()) {
579  return _map.end();
580  }
581  return x;
582 }
583 
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);
588  }
589  std::string prefix(name, 0, i);
590  auto const j = _map.find(prefix);
591  if (j == _map.end() || j->second->back().type() != typeid(Ptr)) {
592  return _map.end();
593  }
594  Ptr p = boost::any_cast<Ptr>(j->second->back());
595  if (p.get() == 0) {
596  return _map.end();
597  }
598  std::string suffix(name, i + 1);
599  auto const x = p->_find(suffix);
600  if (x == p->_map.end()) {
601  return _map.end();
602  }
603  return x;
604 }
605 
607  _findOrInsert(name, vp);
608 }
609 
611  auto const dp = _find(name);
612  if (dp == _map.end()) {
613  _set(name, vp);
614  } else {
615  if (vp->back().type() != dp->second->back().type()) {
616  throw LSST_EXCEPT(pex::exceptions::TypeError, name + " has mismatched type");
617  }
618  // Check for cycles
619  if (vp->back().type() == typeid(Ptr)) {
620  _cycleCheckAnyVec(*vp, name);
621  }
622  _append(*(dp->second), *vp);
623  }
624 }
625 
626 void PropertySet::_findOrInsert(std::string const& name, std::shared_ptr<std::vector<boost::any>> vp) {
627  if (vp->back().type() == typeid(Ptr)) {
628  if (_flat) {
629  Ptr source = boost::any_cast<Ptr>(vp->back());
630  std::vector<std::string> names = source->paramNames(false);
631  for (auto const& i : names) {
632  auto const sp = source->_find(i);
633  _add(name + "." + i, sp->second);
634  }
635  return;
636  }
637 
638  // Check for cycles
639  _cycleCheckAnyVec(*vp, name);
640  }
641 
642  std::string::size_type i = name.find('.');
643  if (_flat || i == name.npos) {
644  _map[name] = vp;
645  return;
646  }
647  std::string prefix(name, 0, i);
648  std::string suffix(name, i + 1);
649  AnyMap::iterator j = _map.find(prefix);
650  if (j == _map.end()) {
652  pp->_findOrInsert(suffix, vp);
654  temp->push_back(pp);
655  _map[prefix] = temp;
656  return;
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");
660  }
661  Ptr p = boost::any_cast<Ptr>(j->second->back());
662  if (p.get() == 0) {
663  throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
664  prefix + " exists but contains null PropertySet::Ptr");
665  }
666  p->_findOrInsert(suffix, vp);
667 }
668 
669 void PropertySet::_cycleCheckPtrVec(std::vector<Ptr> const& v, std::string const& name) {
670  for (auto const& i : v) {
671  _cycleCheckPtr(i, name);
672  }
673 }
674 
675 void PropertySet::_cycleCheckAnyVec(std::vector<boost::any> const& v, std::string const& name) {
676  for (auto const& i : v) {
677  _cycleCheckPtr(boost::any_cast<Ptr>(i), name);
678  }
679 }
680 
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");
684  }
685  std::vector<std::string> sets = v->propertySetNames(false);
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");
689  }
690  }
691 }
692 
694 // Explicit template instantiations
696 
698 // Explicit template instantiations are not well understood by doxygen.
699 
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);
709 
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);
717 
718 INSTANTIATE(bool)
719 INSTANTIATE(char)
720 INSTANTIATE(signed char)
721 INSTANTIATE(unsigned char)
722 INSTANTIATE(short)
723 INSTANTIATE(unsigned short)
724 INSTANTIATE(int)
725 INSTANTIATE(unsigned int)
726 INSTANTIATE(long)
727 INSTANTIATE(unsigned long)
728 INSTANTIATE(long long)
729 INSTANTIATE(unsigned long long)
730 INSTANTIATE(float)
731 INSTANTIATE(double)
734 INSTANTIATE_PROPERTY_SET(PropertySet::Ptr)
736 INSTANTIATE(DateTime)
737 
738 } // namespace base
739 } // namespace daf
740 } // namespace lsst
741 
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.
T empty(T... args)
std::shared_ptr< PropertySet > Ptr
Definition: PropertySet.h:71
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).
T endl(T... args)
ImageT val
Definition: CR.cc:146
PropertySet::Ptr getAsPropertySetPtr(std::string const &name) const
Get the last value for a subproperty name (possibly hierarchical).
std::shared_ptr< PropertySet const > ConstPtr
Definition: PropertySet.h:72
virtual std::string _format(std::string const &name) const
T end(T... args)
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.
std::string prefix
Definition: SchemaMapper.cc:79
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.
STL class.
bool isArray(std::string const &name) const
Determine if a name (possibly hierarchical) has multiple values.
T push_back(T... args)
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.
T str(T... args)
bool exists(std::string const &name) const
Determine if a name (possibly hierarchical) exists.
T showpoint(T... args)
const char * source()
Source function that allows astChannel to source from a Stream.
Definition: Stream.h:224
virtual void _set(std::string const &name, std::shared_ptr< std::vector< boost::any > > vp)
solver_t * s
double x
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
Definition: Match.cc:48
double w
Definition: CoaddPsf.cc:69
T find(T... args)
T size(T... args)
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
STL class.
virtual void _add(std::string const &name, std::shared_ptr< std::vector< boost::any > > vp)
T begin(T... args)
T back(T... args)
virtual ~PropertySet() noexcept
Destructor.
std::shared_ptr< Persistable > Ptr
Definition: Persistable.h:77
T sort(T... args)
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)
Definition: Detector.cc:349
T reserve(T... args)
std::type_info const & typeOf(std::string const &name) const
Get the type of values for a property name (possibly hierarchical).