Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2019-10-26 19:29:46 +0300
committerMyles Borins <mylesborins@google.com>2019-11-17 10:59:10 +0300
commit058a8d53631df7aba5fbbff8859ebc8e88fade49 (patch)
tree62e675c12684a8c4f09b68ea26fa8a45baab2330 /src/util.h
parent31a3b724f0ec4d246f6bf2538e2c401af8dc1552 (diff)
src: do not use `std::function` for `OnScopeLeave`
Using `std::function` adds an extra layer of indirection, and in particular, heap allocations that are not necessary in our use case here. PR-URL: https://github.com/nodejs/node/pull/30134 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'src/util.h')
-rw-r--r--src/util.h45
1 files changed, 34 insertions, 11 deletions
diff --git a/src/util.h b/src/util.h
index c8bb44721f6..f2d3f355f9f 100644
--- a/src/util.h
+++ b/src/util.h
@@ -42,6 +42,12 @@
#include <unordered_map>
#include <utility>
+#ifdef __GNUC__
+#define MUST_USE_RESULT __attribute__((warn_unused_result))
+#else
+#define MUST_USE_RESULT
+#endif
+
namespace node {
// Maybe remove kPathSeparator when cpp17 is ready
@@ -494,14 +500,37 @@ class BufferValue : public MaybeStackBuffer<char> {
// silence a compiler warning about that.
template <typename T> inline void USE(T&&) {}
-// Run a function when exiting the current scope.
-struct OnScopeLeave {
- std::function<void()> fn_;
+template <typename Fn>
+struct OnScopeLeaveImpl {
+ Fn fn_;
+ bool active_;
+
+ explicit OnScopeLeaveImpl(Fn&& fn) : fn_(std::move(fn)), active_(true) {}
+ ~OnScopeLeaveImpl() { if (active_) fn_(); }
- explicit OnScopeLeave(std::function<void()> fn) : fn_(std::move(fn)) {}
- ~OnScopeLeave() { fn_(); }
+ OnScopeLeaveImpl(const OnScopeLeaveImpl& other) = delete;
+ OnScopeLeaveImpl& operator=(const OnScopeLeaveImpl& other) = delete;
+ OnScopeLeaveImpl(OnScopeLeaveImpl&& other)
+ : fn_(std::move(other.fn_)), active_(other.active_) {
+ other.active_ = false;
+ }
+ OnScopeLeaveImpl& operator=(OnScopeLeaveImpl&& other) {
+ if (this == &other) return *this;
+ this->~OnScopeLeave();
+ new (this)OnScopeLeaveImpl(std::move(other));
+ return *this;
+ }
};
+// Run a function when exiting the current scope. Used like this:
+// auto on_scope_leave = OnScopeLeave([&] {
+// // ... run some code ...
+// });
+template <typename Fn>
+inline MUST_USE_RESULT OnScopeLeaveImpl<Fn> OnScopeLeave(Fn&& fn) {
+ return OnScopeLeaveImpl<Fn>{std::move(fn)};
+}
+
// Simple RAII wrapper for contiguous data that uses malloc()/free().
template <typename T>
struct MallocedBuffer {
@@ -679,12 +708,6 @@ constexpr T RoundUp(T a, T b) {
return a % b != 0 ? a + b - (a % b) : a;
}
-#ifdef __GNUC__
-#define MUST_USE_RESULT __attribute__((warn_unused_result))
-#else
-#define MUST_USE_RESULT
-#endif
-
class SlicedArguments : public MaybeStackBuffer<v8::Local<v8::Value>> {
public:
inline explicit SlicedArguments(