snix/third_party/nix/src/libutil/lazy.hh
Vincent Ambo 1cf11317ca refactor(tvix/libutil): Mark single-argument constructors explicit
This is the clang-tidy lint 'google-explicit-constructor'.

There's a whole bunch of breakage that was introduced by this, and we
had to opt out a few types of this (esp. the string formatting crap).

In some cases minor other changes have been done to keep the code
working, instead of converting between types (e.g. an explicit
comparison operator implementation for nix::Pid).

Change-Id: I12e1ca51a6bc2c882dba81a2526b9729d26988e7
Reviewed-on: https://cl.tvl.fyi/c/depot/+/1832
Tested-by: BuildkiteCI
Reviewed-by: kanepyork <rikingcoding@gmail.com>
Reviewed-by: glittershark <grfn@gws.fyi>
2020-08-23 11:58:44 +00:00

45 lines
905 B
C++

#include <exception>
#include <functional>
#include <mutex>
namespace nix {
/* A helper class for lazily-initialized variables.
Lazy<T> var([]() { return value; });
declares a variable of type T that is initialized to 'value' (in a
thread-safe way) on first use, that is, when var() is first
called. If the initialiser code throws an exception, then all
subsequent calls to var() will rethrow that exception. */
template <typename T>
class Lazy {
typedef std::function<T()> Init;
Init init;
std::once_flag done;
T value;
std::exception_ptr ex;
public:
explicit Lazy(Init init) : init(init) {}
const T& operator()() {
std::call_once(done, [&]() {
try {
value = init();
} catch (...) {
ex = std::current_exception();
}
});
if (ex) {
std::rethrow_exception(ex);
}
return value;
}
};
} // namespace nix