LSSTApplications  16.0-10-g0ee56ad+5,16.0-11-ga33d1f2+5,16.0-12-g3ef5c14+3,16.0-12-g71e5ef5+18,16.0-12-gbdf3636+3,16.0-13-g118c103+3,16.0-13-g8f68b0a+3,16.0-15-gbf5c1cb+4,16.0-16-gfd17674+3,16.0-17-g7c01f5c+3,16.0-18-g0a50484+1,16.0-20-ga20f992+8,16.0-21-g0e05fd4+6,16.0-21-g15e2d33+4,16.0-22-g62d8060+4,16.0-22-g847a80f+4,16.0-25-gf00d9b8+1,16.0-28-g3990c221+4,16.0-3-gf928089+3,16.0-32-g88a4f23+5,16.0-34-gd7987ad+3,16.0-37-gc7333cb+2,16.0-4-g10fc685+2,16.0-4-g18f3627+26,16.0-4-g5f3a788+26,16.0-5-gaf5c3d7+4,16.0-5-gcc1f4bb+1,16.0-6-g3b92700+4,16.0-6-g4412fcd+3,16.0-6-g7235603+4,16.0-69-g2562ce1b+2,16.0-8-g14ebd58+4,16.0-8-g2df868b+1,16.0-8-g4cec79c+6,16.0-8-gadf6c7a+1,16.0-8-gfc7ad86,16.0-82-g59ec2a54a+1,16.0-9-g5400cdc+2,16.0-9-ge6233d7+5,master-g2880f2d8cf+3,v17.0.rc1
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 size_t PropertySet::valueCount(std::string const& name) const {
164  auto const i = _find(name);
165  if (i == _map.end()) return 0;
166  return i->second->size();
167 }
168 
169 std::type_info const& PropertySet::typeOf(std::string const& name) const {
170  auto const i = _find(name);
171  if (i == _map.end()) {
172  throw LSST_EXCEPT(pex::exceptions::NotFoundError, name + " not found");
173  }
174  return i->second->back().type();
175 }
176 
177 template <typename T>
179  return typeid(T);
180 }
181 
182 // The following throw an exception if the type does not match exactly.
183 
184 template <typename T>
185 T PropertySet::get(std::string const& name)
186  const { /* parasoft-suppress LsstDm-3-4a LsstDm-4-6 "allow template over bool" */
187  auto const i = _find(name);
188  if (i == _map.end()) {
189  throw LSST_EXCEPT(pex::exceptions::NotFoundError, name + " not found");
190  }
191  try {
192  return boost::any_cast<T>(i->second->back());
193  } catch (boost::bad_any_cast) {
194  throw LSST_EXCEPT(pex::exceptions::TypeError, name);
195  }
196  // not reached
197  return boost::any_cast<T>(i->second->back());
198 }
199 
200 template <typename T>
201 T PropertySet::get(std::string const& name, T const& defaultValue)
202  const { /* parasoft-suppress LsstDm-3-4a LsstDm-4-6 "allow template over bool" */
203  auto const i = _find(name);
204  if (i == _map.end()) {
205  return defaultValue;
206  }
207  try {
208  return boost::any_cast<T>(i->second->back());
209  } catch (boost::bad_any_cast) {
210  throw LSST_EXCEPT(pex::exceptions::TypeError, name);
211  }
212  // not reached
213  return boost::any_cast<T>(i->second->back());
214 }
215 
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");
221  }
222  std::vector<T> v;
223  for (auto const& j : *(i->second)) {
224  try {
225  v.push_back(boost::any_cast<T>(j));
226  } catch (boost::bad_any_cast) {
227  throw LSST_EXCEPT(pex::exceptions::TypeError, name);
228  }
229  }
230  return v;
231 }
232 
233 // The following throw an exception if the conversion is inappropriate.
234 
235 bool PropertySet::getAsBool(std::string const& name)
236  const { /* parasoft-suppress LsstDm-3-4a LsstDm-4-6 "for symmetry with other types" */
237  return get<bool>(name);
238 }
239 
240 int PropertySet::getAsInt(std::string const& name) const {
241  auto const i = _find(name);
242  if (i == _map.end()) {
243  throw LSST_EXCEPT(pex::exceptions::NotFoundError, name + " not found");
244  }
245  boost::any v = i->second->back();
246  std::type_info const& t = v.type();
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);
259  }
260  try {
261  return boost::any_cast<int>(v);
262  } catch (boost::bad_any_cast) {
263  throw LSST_EXCEPT(pex::exceptions::TypeError, name);
264  }
265  // not reached
266  return boost::any_cast<int>(v);
267 }
268 
269 int64_t PropertySet::getAsInt64(std::string const& name) const {
270  auto const i = _find(name);
271  if (i == _map.end()) {
272  throw LSST_EXCEPT(pex::exceptions::NotFoundError, name + " not found");
273  }
274  boost::any v = i->second->back();
275  std::type_info const& t = v.type();
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);
286  try {
287  return boost::any_cast<int64_t>(v);
288  } catch (boost::bad_any_cast) {
289  throw LSST_EXCEPT(pex::exceptions::TypeError, name);
290  }
291  // not reached
292  return boost::any_cast<int64_t>(v);
293 }
294 
295 double PropertySet::getAsDouble(std::string const& name) const {
296  auto const i = _find(name);
297  if (i == _map.end()) {
298  throw LSST_EXCEPT(pex::exceptions::NotFoundError, name + " not found");
299  }
300  boost::any v = i->second->back();
301  std::type_info const& t = v.type();
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);
315  try {
316  return boost::any_cast<double>(v);
317  } catch (boost::bad_any_cast) {
318  throw LSST_EXCEPT(pex::exceptions::TypeError, name);
319  }
320  // not reached
321  return boost::any_cast<double>(v);
322 }
323 
324 std::string PropertySet::getAsString(std::string const& name) const { return get<std::string>(name); }
325 
326 PropertySet::Ptr PropertySet::getAsPropertySetPtr(std::string const& name) const { return get<Ptr>(name); }
327 
329  return get<Persistable::Ptr>(name);
330 }
331 
332 std::string PropertySet::toString(bool topLevelOnly, std::string const& indent) const {
335  sort(nv.begin(), nv.end());
336  for (auto const& i : nv) {
337  std::shared_ptr<std::vector<boost::any>> vp = _map.find(i)->second;
338  std::type_info const& t = vp->back().type();
339  if (t == typeid(Ptr)) {
340  s << indent << i << " = ";
341  if (topLevelOnly) {
342  s << "{ ... }";
343  } else {
344  Ptr p = boost::any_cast<Ptr>(vp->back());
345  if (p.get() == 0) {
346  s << "{ NULL }";
347  } else {
348  s << '{' << std::endl;
349  s << p->toString(false, indent + "..");
350  s << indent << '}';
351  }
352  }
353  s << std::endl;
354  } else {
355  s << indent << _format(i);
356  }
357  }
358  return s.str();
359 }
360 
361 std::string PropertySet::_format(std::string const& name) const {
363  s << std::showpoint; // Always show a decimal point for floats
364  auto const j = _map.find(name);
365  s << j->first << " = ";
367  if (vp->size() > 1) {
368  s << "[ ";
369  }
370  std::type_info const& t = vp->back().type();
371  bool isFirst = true;
372  for (auto const& k : *vp) {
373  if (isFirst) {
374  isFirst = false;
375  } else {
376  s << ", ";
377  }
378  boost::any const& v(k);
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);
407  } else if (t == typeid(std::string)) {
408  s << '"' << boost::any_cast<std::string>(v) << '"';
409  } else if (t == typeid(DateTime)) {
410  s << boost::any_cast<DateTime>(v).toString(DateTime::UTC);
411  } else if (t == typeid(Ptr)) {
412  s << "{ ... }";
413  } else if (t == typeid(Persistable::Ptr)) {
414  s << "<Persistable>";
415  } else {
416  s << "<Unknown>";
417  }
418  }
419  if (j->second->size() > 1) {
420  s << " ]";
421  }
422  s << std::endl;
423  return s.str();
424 }
425 
427 // Modifiers
429 
430 template <typename T>
431 void PropertySet::set(std::string const& name, T const& value) {
433  vp->push_back(value);
434  _set(name, vp);
435 }
436 
437 template <typename T>
438 void PropertySet::set(std::string const& name, std::vector<T> const& value) {
439  if (value.empty()) return;
441  _append(*vp, value);
442  _set(name, vp);
443 }
444 
445 void PropertySet::set(std::string const& name, char const* value) { set(name, std::string(value)); }
446 
447 template <typename T>
448 void PropertySet::add(std::string const& name, T const& value) {
449  AnyMap::iterator i = _find(name);
450  if (i == _map.end()) {
451  set(name, value);
452  } else {
453  if (i->second->back().type() != typeid(T)) {
454  throw LSST_EXCEPT(pex::exceptions::TypeError, name + " has mismatched type");
455  }
456  i->second->push_back(value);
457  }
458 }
459 
460 // Specialize for Ptrs to check for cycles.
461 template <>
462 void PropertySet::add<PropertySet::Ptr>(std::string const& name, Ptr const& value) {
463  AnyMap::iterator i = _find(name);
464  if (i == _map.end()) {
465  set(name, value);
466  } else {
467  if (i->second->back().type() != typeid(Ptr)) {
468  throw LSST_EXCEPT(pex::exceptions::TypeError, name + " has mismatched type");
469  }
470  _cycleCheckPtr(value, name);
471  i->second->push_back(value);
472  }
473 }
474 
475 template <typename T>
476 void PropertySet::add(std::string const& name, std::vector<T> const& value) {
477  AnyMap::iterator i = _find(name);
478  if (i == _map.end()) {
479  set(name, value);
480  } else {
481  if (i->second->back().type() != typeid(T)) {
482  throw LSST_EXCEPT(pex::exceptions::TypeError, name + " has mismatched type");
483  }
484  _append(*(i->second), value);
485  }
486 }
487 
488 // Specialize for Ptrs to check for cycles.
489 template <>
490 void PropertySet::add<PropertySet::Ptr>(std::string const& name, std::vector<Ptr> const& value) {
491  AnyMap::iterator i = _find(name);
492  if (i == _map.end()) {
493  set(name, value);
494  } else {
495  if (i->second->back().type() != typeid(Ptr)) {
496  throw LSST_EXCEPT(pex::exceptions::TypeError, name + " has mismatched type");
497  }
498  _cycleCheckPtrVec(value, name);
499  _append(*(i->second), value);
500  }
501 }
502 
503 void PropertySet::add(std::string const& name, char const* value) { add(name, std::string(value)); }
504 
505 void PropertySet::copy(std::string const& dest, ConstPtr source, std::string const& name, bool asScalar) {
506  if (source.get() == 0) {
507  throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, "Missing source");
508  }
509  auto const sj = source->_find(name);
510  if (sj == source->_map.end()) {
511  throw LSST_EXCEPT(pex::exceptions::InvalidParameterError, name + " not in source");
512  }
513  remove(dest);
514  if (asScalar) {
515  auto vp = std::make_shared<std::vector<boost::any>>();
516  vp->push_back(sj->second->back());
517  _set(dest, vp);
518  } else {
519  auto vp = std::make_shared<std::vector<boost::any>>(*(sj->second));
520  _set(dest, vp);
521  }
522 }
523 
524 void PropertySet::combine(ConstPtr source) {
525  if (source.get() == 0) {
526  return;
527  }
528  std::vector<std::string> names = source->paramNames(false);
529  for (auto const& name : names) {
530  auto const sp = source->_find(name);
531  _add(name, sp->second);
532  }
533 }
534 
535 void PropertySet::remove(std::string const& name) {
536  std::string::size_type i = name.find('.');
537  if (_flat || i == name.npos) {
538  _map.erase(name);
539  return;
540  }
541  std::string prefix(name, 0, i);
542  AnyMap::iterator j = _map.find(prefix);
543  if (j == _map.end() || j->second->back().type() != typeid(Ptr)) {
544  return;
545  }
546  Ptr p = boost::any_cast<Ptr>(j->second->back());
547  if (p.get() != 0) {
548  std::string suffix(name, i + 1);
549  p->remove(suffix);
550  }
551 }
552 
554 // Private member functions
556 
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);
561  }
562  std::string prefix(name, 0, i);
563  AnyMap::iterator j = _map.find(prefix);
564  if (j == _map.end() || j->second->back().type() != typeid(Ptr)) {
565  return _map.end();
566  }
567  Ptr p = boost::any_cast<Ptr>(j->second->back());
568  if (p.get() == 0) {
569  return _map.end();
570  }
571  std::string suffix(name, i + 1);
572  AnyMap::iterator x = p->_find(suffix);
573  if (x == p->_map.end()) {
574  return _map.end();
575  }
576  return x;
577 }
578 
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);
583  }
584  std::string prefix(name, 0, i);
585  auto const j = _map.find(prefix);
586  if (j == _map.end() || j->second->back().type() != typeid(Ptr)) {
587  return _map.end();
588  }
589  Ptr p = boost::any_cast<Ptr>(j->second->back());
590  if (p.get() == 0) {
591  return _map.end();
592  }
593  std::string suffix(name, i + 1);
594  auto const x = p->_find(suffix);
595  if (x == p->_map.end()) {
596  return _map.end();
597  }
598  return x;
599 }
600 
602  _findOrInsert(name, vp);
603 }
604 
606  auto const dp = _find(name);
607  if (dp == _map.end()) {
608  _set(name, vp);
609  } else {
610  if (vp->back().type() != dp->second->back().type()) {
611  throw LSST_EXCEPT(pex::exceptions::TypeError, name + " has mismatched type");
612  }
613  // Check for cycles
614  if (vp->back().type() == typeid(Ptr)) {
615  _cycleCheckAnyVec(*vp, name);
616  }
617  _append(*(dp->second), *vp);
618  }
619 }
620 
621 void PropertySet::_findOrInsert(std::string const& name, std::shared_ptr<std::vector<boost::any>> vp) {
622  if (vp->back().type() == typeid(Ptr)) {
623  if (_flat) {
624  Ptr source = boost::any_cast<Ptr>(vp->back());
625  std::vector<std::string> names = source->paramNames(false);
626  for (auto const& i : names) {
627  auto const sp = source->_find(i);
628  _add(name + "." + i, sp->second);
629  }
630  return;
631  }
632 
633  // Check for cycles
634  _cycleCheckAnyVec(*vp, name);
635  }
636 
637  std::string::size_type i = name.find('.');
638  if (_flat || i == name.npos) {
639  _map[name] = vp;
640  return;
641  }
642  std::string prefix(name, 0, i);
643  std::string suffix(name, i + 1);
644  AnyMap::iterator j = _map.find(prefix);
645  if (j == _map.end()) {
647  pp->_findOrInsert(suffix, vp);
649  temp->push_back(pp);
650  _map[prefix] = temp;
651  return;
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");
655  }
656  Ptr p = boost::any_cast<Ptr>(j->second->back());
657  if (p.get() == 0) {
658  throw LSST_EXCEPT(pex::exceptions::InvalidParameterError,
659  prefix + " exists but contains null PropertySet::Ptr");
660  }
661  p->_findOrInsert(suffix, vp);
662 }
663 
664 void PropertySet::_cycleCheckPtrVec(std::vector<Ptr> const& v, std::string const& name) {
665  for (auto const& i : v) {
666  _cycleCheckPtr(i, name);
667  }
668 }
669 
670 void PropertySet::_cycleCheckAnyVec(std::vector<boost::any> const& v, std::string const& name) {
671  for (auto const& i : v) {
672  _cycleCheckPtr(boost::any_cast<Ptr>(i), name);
673  }
674 }
675 
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");
679  }
680  std::vector<std::string> sets = v->propertySetNames(false);
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");
684  }
685  }
686 }
687 
689 // Explicit template instantiations
691 
693 // Explicit template instantiations are not well understood by doxygen.
694 
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);
704 
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);
712 
713 INSTANTIATE(bool)
714 INSTANTIATE(char)
715 INSTANTIATE(signed char)
716 INSTANTIATE(unsigned char)
717 INSTANTIATE(short)
718 INSTANTIATE(unsigned short)
719 INSTANTIATE(int)
720 INSTANTIATE(unsigned int)
721 INSTANTIATE(long)
722 INSTANTIATE(unsigned long)
723 INSTANTIATE(long long)
724 INSTANTIATE(unsigned long long)
725 INSTANTIATE(float)
726 INSTANTIATE(double)
728 INSTANTIATE_PROPERTY_SET(PropertySet::Ptr)
730 INSTANTIATE(DateTime)
731 
732 } // namespace base
733 } // namespace daf
734 } // namespace lsst
735 
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).
#define INSTANTIATE(FROMSYS, TOSYS)
Definition: Detector.cc:312
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).