Explorar o código

sigh: make scoped_connection move constructible/assignable (close #760)

Michele Caini %!s(int64=4) %!d(string=hai) anos
pai
achega
8ec899a8e7
Modificáronse 2 ficheiros con 68 adicións e 1 borrados
  1. 18 0
      src/entt/signal/sigh.hpp
  2. 50 1
      test/entt/signal/sigh.cpp

+ 18 - 0
src/entt/signal/sigh.hpp

@@ -208,6 +208,14 @@ struct scoped_connection {
     /*! @brief Default copy constructor, deleted on purpose. */
     scoped_connection(const scoped_connection &) = delete;
 
+    /**
+     * @brief Move constructor.
+     * @param other The scoped connection to move from.
+     */
+    scoped_connection(scoped_connection &&other) ENTT_NOEXCEPT
+        : conn{std::exchange(other.conn, {})}
+    {}
+
     /*! @brief Automatically breaks the link on destruction. */
     ~scoped_connection() {
         conn.release();
@@ -219,6 +227,16 @@ struct scoped_connection {
      */
     scoped_connection & operator=(const scoped_connection &) = delete;
 
+    /**
+     * @brief Move assignment operator.
+     * @param other The scoped connection to move from.
+     * @return This scoped connection.
+     */
+    scoped_connection & operator=(scoped_connection &&other) ENTT_NOEXCEPT {
+        conn = std::exchange(other.conn, {});
+        return *this;
+    }
+
     /**
      * @brief Acquires a connection.
      * @param other The connection object to acquire.

+ 50 - 1
test/entt/signal/sigh.cpp

@@ -11,7 +11,7 @@ struct sigh_listener {
 
     void i() {}
     // useless definition just because msvc does weird things if both are empty
-    void l() { k = k && k; }
+    void l() { k = true && k; }
 
     bool k{false};
 };
@@ -277,6 +277,55 @@ TEST_F(SigH, ScopedConnection) {
     ASSERT_TRUE(listener.k);
 }
 
+TEST_F(SigH, ScopedConnectionMove) {
+    sigh_listener listener;
+    entt::sigh<void(int)> sigh;
+    entt::sink sink{sigh};
+
+    entt::scoped_connection outer{sink.connect<&sigh_listener::g>(listener)};
+
+    ASSERT_FALSE(sigh.empty());
+    ASSERT_TRUE(outer);
+
+    {
+        entt::scoped_connection inner{std::move(outer)};
+
+        ASSERT_FALSE(listener.k);
+        ASSERT_FALSE(outer);
+        ASSERT_TRUE(inner);
+
+        sigh.publish(42);
+
+        ASSERT_TRUE(listener.k);
+    }
+
+    ASSERT_TRUE(sigh.empty());
+
+    outer = sink.connect<&sigh_listener::g>(listener);
+
+    ASSERT_FALSE(sigh.empty());
+    ASSERT_TRUE(outer);
+
+    {
+        entt::scoped_connection inner{};
+
+        ASSERT_TRUE(listener.k);
+        ASSERT_TRUE(outer);
+        ASSERT_FALSE(inner);
+
+        inner = std::move(outer);
+
+        ASSERT_FALSE(outer);
+        ASSERT_TRUE(inner);
+
+        sigh.publish(42);
+
+        ASSERT_FALSE(listener.k);
+    }
+
+    ASSERT_TRUE(sigh.empty());
+}
+
 TEST_F(SigH, ScopedConnectionConstructorsAndOperators) {
     sigh_listener listener;
     entt::sigh<void(int)> sigh;