LSST Applications g0b6bd0c080+a72a5dd7e6,g1182afd7b4+2a019aa3bb,g17e5ecfddb+2b8207f7de,g1d67935e3f+06cf436103,g38293774b4+ac198e9f13,g396055baef+6a2097e274,g3b44f30a73+6611e0205b,g480783c3b1+98f8679e14,g48ccf36440+89c08d0516,g4b93dc025c+98f8679e14,g5c4744a4d9+a302e8c7f0,g613e996a0d+e1c447f2e0,g6c8d09e9e7+25247a063c,g7271f0639c+98f8679e14,g7a9cd813b8+124095ede6,g9d27549199+a302e8c7f0,ga1cf026fa3+ac198e9f13,ga32aa97882+7403ac30ac,ga786bb30fb+7a139211af,gaa63f70f4e+9994eb9896,gabf319e997+ade567573c,gba47b54d5d+94dc90c3ea,gbec6a3398f+06cf436103,gc6308e37c7+07dd123edb,gc655b1545f+ade567573c,gcc9029db3c+ab229f5caf,gd01420fc67+06cf436103,gd877ba84e5+06cf436103,gdb4cecd868+6f279b5b48,ge2d134c3d5+cc4dbb2e3f,ge448b5faa6+86d1ceac1d,gecc7e12556+98f8679e14,gf3ee170dca+25247a063c,gf4ac96e456+ade567573c,gf9f5ea5b4d+ac198e9f13,gff490e6085+8c2580be5c,w.2022.27
LSST Data Management Base Package
Namespaces | Classes | Functions | Variables
lsst::cpputils Namespace Reference

Namespaces

namespace  backtrace
 
namespace  python
 
namespace  version
 

Classes

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

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

◆ 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
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)

◆ 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 {
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); }

◆ 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}
A helper class for subdividing pybind11 module across multiple translation units (i....
Definition: python.h:242
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}
Singleton, enables automatic backtraces on the following signals:
Definition: Backtrace.h:42
bool const isEnabled() const noexcept
Definition: Backtrace.h:56
void wrap(WrapperCallback function)
Add a set of wrappers without defining a class.
Definition: python.h:369

◆ 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.