LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
Namespaces | Classes | Functions | Variables
lsst::cpputils Namespace Reference

Namespaces

 backtrace
 
 python
 
 version
 

Classes

class  Backtrace
 Singleton, enables automatic backtraces on the following signals: More...
 
class  Cache
 Cache of most recently used values. More...
 
class  Symbol
 
struct  n
 
struct  key
 

Functions

std::string demangleType (std::string const _typeName)
 
std::size_t hashCombine (std::size_t seed) noexcept
 Combine hashes. More...
 
template<typename T , typename... Rest>
std::size_t hashCombine (std::size_t seed, const T &value, Rest... rest) noexcept
 Combine hashes. More...
 
template<typename InputIterator >
std::size_t hashIterable (std::size_t seed, InputIterator begin, InputIterator end) noexcept
 Combine hashes in an iterable. More...
 
double nanojanskyToABMagnitude (double flux)
 Convert a flux in nanojansky to AB magnitude. More...
 
double ABMagnitudeToNanojansky (double magnitude)
 Convert an AB magnitude to a flux in nanojansky. More...
 
std::string getPackageDir (std::string const &packageName)
 return the root directory of a setup package More...
 
template<typename T >
constexpr void assertValidHash ()
 Compile-time test of whether a specialization of std::hash conforms to the general spec. More...
 
template<typename T >
void assertHashesEqual (T obj1, T obj2)
 Test that equal objects have equal hashes. More...
 
void wrapBacktrace (python::WrapperCollection &wrappers)
 
void wrapDemangle (python::WrapperCollection &wrappers)
 
 PYBIND11_MODULE (_cpputils, mod)
 

Variables

const double referenceFlux = 1e23 * pow(10, (48.6 / -2.5)) * 1e9
 The Oke & Gunn (1983) AB magnitude reference flux, in nJy (often approximated as 3631.0). More...
 

Function Documentation

◆ ABMagnitudeToNanojansky()

double lsst::cpputils::ABMagnitudeToNanojansky ( double  magnitude)

Convert an AB magnitude to a flux in nanojansky.

Definition at line 32 of file Magnitude.cc.

32 { return pow(10, magnitude / -2.5) * referenceFlux; }
const double referenceFlux
The Oke & Gunn (1983) AB magnitude reference flux, in nJy (often approximated as 3631....
Definition: Magnitude.h:46
T pow(T... args)

◆ assertHashesEqual()

template<typename T >
void lsst::cpputils::assertHashesEqual ( obj1,
obj2 
)

Test that equal objects have equal hashes.

If objects of type T can be equal despite having different internal representations, you should include pairs of such objects.

Template Parameters
TA hashable type.
Parameters
obj1,obj2Two equal objects.

Definition at line 102 of file tests.h.

102  {
103  using Hash = std::hash<std::remove_cv_t<T>>;
104 
105  printIfHashEqual(obj1, obj2, Hash());
106 }

◆ assertValidHash()

template<typename T >
constexpr void lsst::cpputils::assertValidHash ( )
constexpr

Compile-time test of whether a specialization of std::hash conforms to the general spec.

The function itself is a no-op.

Template Parameters
TThe properties of std::hash<T> will be tested.

Definition at line 72 of file tests.h.

72  {
73  using namespace std;
74  using Hash = hash<remove_cv_t<T>>;
75 
77  "std::hash specializations must be default-constructible");
78  static_assert(is_copy_assignable<Hash>::value, "std::hash specializations must be copy-assignable");
79  // Swappability hard to test before C++17
80  static_assert(is_destructible<Hash>::value, "std::hash specializations must be destructible");
81 
82  static_assert(is_same<typename Hash::argument_type, remove_cv_t<T>>::value,
83  "std::hash must have an argument_type member until C++20");
85  "std::hash must have a result_type member until C++20");
86  // Ability to call Hash(T) hard to test before C++17
87  static_assert(is_same<result_of_t<Hash(T)>, size_t>::value,
88  "std::hash specializations must be callable and return a size_t");
89 }
STL namespace.

◆ demangleType()

std::string lsst::cpputils::demangleType ( std::string const  _typeName)

Definition at line 113 of file Demangle.cc.

113  {
114 #if 1
115  typedef multi_index_container<
116  Symbol,
117  indexed_by<
118  ordered_unique<tag<n>,
119  member<Symbol, int, &Symbol::n> >,
120  ordered_unique<tag<key>,
121  member<Symbol, std::string, &Symbol::key> >
122  >
123  > SymbolTable;
124  typedef SymbolTable::index<n>::type::iterator nIterator;
125  typedef SymbolTable::index<key>::type::iterator keyIterator;
126  Symbol::reset();
127 
128  // Here's my symbol table and its indices
129  SymbolTable st;
130 
131  SymbolTable::index<n>::type &nIndex = st.get<n>();
132  SymbolTable::index<key>::type &keyIndex = st.get<key>();
133  //
134  // Start mangling
135  //
136  std::string typeName("");
137  const char *ptr = _typeName.c_str();
138 
139  if (*ptr == 'r' || *ptr == 'V' || *ptr == 'K') {
140  ptr++; // (restrict/volatile/const)
141  }
142 
143  if (*ptr == 'P') ptr++; // We passed "this" which is (type *)
144 
145  std::string currentSymbol = ""; // Current symbol
146  std::stack<char> typeStack; // Did we last see an N or an I?
147 
148  int lastTokenWasType = 0; // When > 0, the last token was a type such as int or float
149  while (*ptr != '\0') {
150  lastTokenWasType--;
151  switch (*ptr) {
152  case 'E':
153  ptr++;
154  currentSymbol = "";
155 
156  if (typeStack.empty()) {
157  typeStack.push('\a'); // at least don't crash
158  }
159 
160  if (typeStack.top() == 'I') {
161  typeName += '>';
162  } else if (typeStack.top() == 'L') {
163  ;
164  } else if (typeStack.top() == 'N') {
165  ;
166  }
167  typeStack.pop();
168 
169  if (!typeStack.empty() && typeStack.top() == 'I') {
170  if (*ptr != 'E' && typeName[typeName.size() - 1] != '<') {
171  typeName += ',';
172  }
173  }
174 
175  break;
176  case 'I':
177  typeStack.push(*ptr++);
178  currentSymbol = "";
179 
180  typeName += '<';
181  break;
182  case 'L':
183  typeStack.push(*ptr++);
184  currentSymbol = "";
185  {
187  if (interpret_typeletter(*ptr, type)) {
188  typeName += "(" + type + ')';
189  } else {
190  typeName += 'c';
191  }
192  ptr++;
193  }
194  if (*ptr == 'n') {
195  typeName += '-'; ptr++;
196  }
197  while (*ptr != '\0' && *ptr != 'E') {
198  typeName += *ptr++;
199  }
200  break;
201  case 'N':
202  typeStack.push(*ptr++);
203  currentSymbol = "";
204  break;
205  case 'S':
206  ++ptr;
207  switch (*ptr) {
208  case 't': typeName += "::std::"; break;
209  case 'a': typeName += "::std::allocator"; break;
210  case 'b': typeName += "::std::basic_string"; break;
211  case 's': typeName += "::std::basic_string<char,::std::char_traits<char>,::std::allocator<char>>"; break;
212  case 'i': typeName += "::std::basic_istream<char, std::char_traits<char> >"; break;
213  case 'o': typeName += "::std::basic_ostream<char,std::char_traits<char>>"; break;
214  case 'd': typeName += "::std::basic_iostream<char,std::char_traits<char>>"; break;
215  default:
216  {
217  int subst = 0; // number of substitution
218 
219  if (*ptr == '_') {
220  ; // S_ => 0
221  } else if (isdigit(*ptr) || isupper(*ptr)) {
222  while (isdigit(*ptr) || isupper(*ptr)) {
223  if (isdigit(*ptr)) {
224  subst = 36*subst + (*ptr - '0');
225  } else {
226  subst = 36*subst + 10 + (*ptr - 'A');
227  }
228  ptr++;
229  }
230  subst++; // S_ == 0; S1_ == 1
231  assert (*ptr == '_');
232  ptr++;
233  }
234 
235  nIterator sym = nIndex.find(subst);
236  if (sym == nIndex.end()) { // not found
237  typeName += (boost::format("[S%d]") % subst).str();
238  } else {
239  typeName += sym->key;
240  }
241 
242  }
243  break;
244  }
245  currentSymbol = "";
246  break;
247  case '0': case '1': case '2': case '3': case '4':
248  case '5': case '6': case '7': case '8': case '9':
249  {
250  const int len = atoi(ptr++);
251  while (isdigit(*ptr)) ptr++;
252 
253  std::string name = "";
254  for (int i = 0; *ptr != '\0' && i < len; i++) {
255  name += *ptr++;
256  }
257 
258  if (currentSymbol != "") {
259  currentSymbol += "::";
260  typeName += "::";
261  }
262 
263  currentSymbol += name;
264  typeName += name;
265 
266  if (keyIndex.find(currentSymbol) == keyIndex.end()) {
267  st.insert(currentSymbol);
268  }
269  }
270  break;
271  default:
272  {
274  if (interpret_typeletter(*ptr, type)) {
275  if (lastTokenWasType > 0) {
276  typeName += ",";
277  }
278  typeName += type;
279  lastTokenWasType = 2; // it'll be decremented on every char in the name
280  } else {
281  typeName += *ptr;
282  }
283  ptr++;
284  }
285  }
286  }
287 
288  static volatile bool dumpSymbolTable = false; // can be set from gdb
289  if (dumpSymbolTable) {
290  // The test on the iterator is paranoid, but they _could_
291  // have deleted elements. In this case, they didn't.
292  for (unsigned int i = 0; i < st.size(); i++) {
293  nIterator el = nIndex.find(2);
294  if (el != nIndex.end()) { // did we find it?
295  el->print();
296  }
297  }
298  }
299 
300  return typeName;
301 #else
302  return _typeName;
303 #endif
304 }
table::Key< std::string > name
Definition: Amplifier.cc:116
table::Key< int > type
Definition: Detector.cc:163
uint64_t * ptr
Definition: RangeSet.cc:88
T atoi(T... args)
T empty(T... args)
T isdigit(T... args)
T isupper(T... args)
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:174
T pop(T... args)
T push(T... args)
T top(T... args)

◆ getPackageDir()

std::string lsst::cpputils::getPackageDir ( std::string const &  packageName)

return the root directory of a setup package

Parameters
[in]packageNamename of package (e.g. "utils")
Exceptions
lsst::pex::exceptions::NotFoundErrorif desired version can't be found

Definition at line 33 of file packaging.cc.

33  {
34  std::string envVar = packageName; // package's environment variable
35 
36  transform(envVar.begin(), envVar.end(), envVar.begin(), (int (*)(int)) toupper);
37  envVar += "_DIR";
38 
39  char const *dir = getenv(envVar.c_str());
40  if (!dir) {
41  throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError, "Package " + packageName + " not found");
42  }
43 
44  return dir;
45 }
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition: Exception.h:48
table::Key< int > transform
T begin(T... args)
T c_str(T... args)
Reports attempts to access elements using an invalid key.
Definition: Runtime.h:151
T end(T... args)
T getenv(T... args)

◆ hashCombine() [1/2]

std::size_t lsst::cpputils::hashCombine ( std::size_t  seed)
inlinenoexcept

Combine hashes.

A specialization of hashCombine for a trivial argument list.

Definition at line 35 of file hashCombine.h.

35 { return seed; }

◆ hashCombine() [2/2]

template<typename T , typename... Rest>
std::size_t lsst::cpputils::hashCombine ( std::size_t  seed,
const T &  value,
Rest...  rest 
)
noexcept

Combine hashes.

This is provided as a convenience for those who need to hash a composite. C++11 includes std::hash, but neglects to include a facility for combining hashes.

Template Parameters
T,Restthe types to hash. All types must have a valid (in particular, non-throwing) specialization of std::hash.
Parameters
seedAn arbitrary starting value.
value,restThe objects to hash.
Returns
A combined hash for all the arguments after seed.
Exception Safety
Shall not throw exceptions.

To use it:

// Arbitrary seed; can change to get different hashes of same argument list
std::size_t seed = 0;
result = hashCombine(seed, obj1, obj2, obj3);

Definition at line 63 of file hashCombine.h.

63  {
64  std::hash<T> hasher;
65  seed ^= hasher(value) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
66  return hashCombine(seed, rest...);
67 }
std::size_t hashCombine(std::size_t seed, const T &value, Rest... rest) noexcept
Combine hashes.
Definition: hashCombine.h:63

◆ hashIterable()

template<typename InputIterator >
std::size_t lsst::cpputils::hashIterable ( std::size_t  seed,
InputIterator  begin,
InputIterator  end 
)
noexcept

Combine hashes in an iterable.

This is provided as a convenience for those who need to hash a container.

Template Parameters
InputIteratoran iterator to the objects to be hashed. The pointed-to type must have a valid (in particular, non-throwing) specialization of std::hash.
Parameters
seedAn arbitrary starting value.
begin,endThe range to hash.
Returns
A combined hash for all the elements in [begin, end).
Exception Safety
Shall not throw exceptions.

To use it:

// Arbitrary seed; can change to get different hashes of same argument list
std::size_t seed = 0;
result = hashIterable(seed, container.begin(), container.end());

Definition at line 93 of file hashCombine.h.

93  {
94  std::size_t result = 0;
95  for (; begin != end; ++begin) {
96  result = hashCombine(result, *begin);
97  }
98  return result;
99 }
py::object result
Definition: _schema.cc:429
int end

◆ nanojanskyToABMagnitude()

double lsst::cpputils::nanojanskyToABMagnitude ( double  flux)

Convert a flux in nanojansky to AB magnitude.

Definition at line 30 of file Magnitude.cc.

30 { return -2.5 * log10(flux / referenceFlux); }
T log10(T... args)

◆ PYBIND11_MODULE()

lsst::cpputils::PYBIND11_MODULE ( _cpputils  ,
mod   
)

Definition at line 32 of file _cpputils.cc.

32  {
33  python::WrapperCollection wrappers(mod, "_cpputils");
34  {
35  auto backtraceWrappers = wrappers.makeSubmodule("backtrace");
36  wrapBacktrace(backtraceWrappers);
37  wrappers.collectSubmodule(std::move(backtraceWrappers));
38  }
39  wrapDemangle(wrappers);
40  wrappers.finish();
41 }
T move(T... args)
void wrapBacktrace(python::WrapperCollection &wrappers)
Definition: _Backtrace.cc:32
void wrapDemangle(python::WrapperCollection &wrappers)
Definition: _Demangle.cc:32

◆ wrapBacktrace()

void lsst::cpputils::wrapBacktrace ( python::WrapperCollection wrappers)

Definition at line 32 of file _Backtrace.cc.

32  {
33  wrappers.wrap(
34  [](auto & mod) {
35  Backtrace &backtrace = Backtrace::get();
36  // Trick to tell the compiler backtrace is used and should not be
37  // optimized away, as well as convenient way to check if backtrace
38  // is enabled.
39  mod.def("isEnabled", [&backtrace]() -> bool { return backtrace.isEnabled(); });
40  }
41  );
42 }

◆ wrapDemangle()

void lsst::cpputils::wrapDemangle ( python::WrapperCollection wrappers)

Definition at line 32 of file _Demangle.cc.

32  {
33  wrappers.wrap(
34  [](auto & mod) {
35  mod.def("demangleType", demangleType);
36  }
37  );
38 }
std::string demangleType(std::string const _typeName)
Definition: Demangle.cc:113

Variable Documentation

◆ referenceFlux

const double lsst::cpputils::referenceFlux = 1e23 * pow(10, (48.6 / -2.5)) * 1e9

The Oke & Gunn (1983) AB magnitude reference flux, in nJy (often approximated as 3631.0).

Definition at line 46 of file Magnitude.h.