Michele Caini 7 лет назад
Родитель
Сommit
58ceb454dd
1 измененных файлов с 26 добавлено и 28 удалено
  1. 26 28
      src/entt/signal/delegate.hpp

+ 26 - 28
src/entt/signal/delegate.hpp

@@ -2,7 +2,6 @@
 #define ENTT_SIGNAL_DELEGATE_HPP
 
 
-#include <utility>
 #include <functional>
 #include <type_traits>
 #include "../config/config.h"
@@ -81,21 +80,6 @@ class delegate;
 template<typename Ret, typename... Args>
 class delegate<Ret(Args...)> final {
     using proto_fn_type = Ret(const void *, Args...);
-    using stub_type = std::pair<const void *, proto_fn_type *>;
-
-    template<auto Function>
-    static Ret proto(const void *, Args... args) {
-        return std::invoke(Function, args...);
-    }
-
-    template<bool Const, typename Class, auto Member>
-    static Ret proto(const void *instance, Args... args) {
-        if constexpr(Const) {
-            return std::invoke(Member, static_cast<const Class *>(instance), args...);
-        } else {
-            return std::invoke(Member, const_cast<Class *>(static_cast<const Class *>(instance)), args...);
-        }
-    }
 
 public:
     /*! @brief Function type of the delegate. */
@@ -103,7 +87,7 @@ public:
 
     /*! @brief Default constructor. */
     delegate() ENTT_NOEXCEPT
-        : stub{}
+        : fn{nullptr}, ref{nullptr}
     {}
 
     /**
@@ -112,7 +96,7 @@ public:
      */
     template<auto Function>
     delegate(connect_arg_t<Function>) ENTT_NOEXCEPT
-        : stub{}
+        : delegate{}
     {
         connect<Function>();
     }
@@ -125,7 +109,7 @@ public:
      */
     template<auto Member, typename Class>
     delegate(connect_arg_t<Member>, Class *instance) ENTT_NOEXCEPT
-        : stub{}
+        : delegate{}
     {
         connect<Member>(instance);
     }
@@ -137,7 +121,11 @@ public:
     template<auto Function>
     void connect() ENTT_NOEXCEPT {
         static_assert(std::is_invocable_r_v<Ret, decltype(Function), Args...>);
-        stub = std::make_pair(nullptr, &proto<Function>);
+        ref = nullptr;
+
+        fn = [](const void *, Args... args) -> Ret {
+            return std::invoke(Function, args...);
+        };
     }
 
     /**
@@ -154,7 +142,15 @@ public:
     template<auto Member, typename Class>
     void connect(Class *instance) ENTT_NOEXCEPT {
         static_assert(std::is_invocable_r_v<Ret, decltype(Member), Class, Args...>);
-        stub = std::make_pair(instance, &proto<std::is_const_v<Class>, std::remove_const_t<Class>, Member>);
+        ref = instance;
+
+        fn = [](const void *instance, Args... args) -> Ret {
+            if constexpr(std::is_const_v<Class>) {
+                return std::invoke(Member, static_cast<Class *>(instance), args...);
+            } else {
+                return std::invoke(Member, static_cast<Class *>(const_cast<void *>(instance)), args...);
+            }
+        };
     }
 
     /**
@@ -163,7 +159,8 @@ public:
      * After a reset, a delegate can be safely invoked with no effect.
      */
     void reset() ENTT_NOEXCEPT {
-        stub = std::make_pair(nullptr, nullptr);
+        ref = nullptr;
+        fn = nullptr;
     }
 
     /**
@@ -171,7 +168,7 @@ public:
      * @return An opaque pointer to the instance bound to the delegate, if any.
      */
     const void * instance() const ENTT_NOEXCEPT {
-        return stub.first;
+        return ref;
     }
 
     /**
@@ -189,7 +186,7 @@ public:
      * @return The value returned by the underlying function.
      */
     Ret operator()(Args... args) const {
-        return stub.second(stub.first, args...);
+        return fn(ref, args...);
     }
 
     /**
@@ -197,8 +194,8 @@ public:
      * @return False if the delegate is empty, true otherwise.
      */
     explicit operator bool() const ENTT_NOEXCEPT {
-        // no need to test also stub.first
-        return stub.second;
+        // no need to test also data
+        return fn;
     }
 
     /**
@@ -210,11 +207,12 @@ public:
      * @return True if the two delegates are identical, false otherwise.
      */
     bool operator==(const delegate<Ret(Args...)> &other) const ENTT_NOEXCEPT {
-        return stub.first == other.stub.first && stub.second == other.stub.second;
+        return ref == other.ref && fn == other.fn;
     }
 
 private:
-    stub_type stub{};
+    proto_fn_type *fn;
+    const void *ref;
 };