encoding+util: ensure move constructors are properly declared

This also fixes a race condition in scheduler::EventId::operator bool()

Change-Id: I468f0c46039a3d1a38c69c419ae45b4445d8205a
Refs: #3414
diff --git a/tests/unit-tests/util/signal.t.cpp b/tests/unit-tests/util/signal.t.cpp
index 70ab22f..c319f64 100644
--- a/tests/unit-tests/util/signal.t.cpp
+++ b/tests/unit-tests/util/signal.t.cpp
@@ -289,9 +289,9 @@
 BOOST_AUTO_TEST_CASE(AutoDisconnectMove)
 {
   SignalOwner0 so;
-  unique_ptr<ScopedConnection> sc2;
-
   int hit = 0;
+
+  unique_ptr<ScopedConnection> sc2;
   {
     ScopedConnection sc = so.sig.connect([&hit] { ++hit; });
 
@@ -299,15 +299,35 @@
     BOOST_CHECK_EQUAL(hit, 1); // handler called
     BOOST_CHECK_EQUAL(sc.isConnected(), true);
 
-    sc2.reset(new ScopedConnection(std::move(sc)));
+    sc2 = make_unique<ScopedConnection>(std::move(sc)); // move constructor
     BOOST_CHECK_EQUAL(sc.isConnected(), false);
     BOOST_CHECK_EQUAL(sc2->isConnected(), true);
 
-    // sc goes out of scope, but not disconnecting
+    // sc goes out of scope, but without disconnecting
   }
 
   so.emitSignal(sig);
   BOOST_CHECK_EQUAL(hit, 2); // handler called
+  sc2.reset();
+
+  ScopedConnection sc3;
+  {
+    ScopedConnection sc = so.sig.connect([&hit] { ++hit; });
+
+    so.emitSignal(sig);
+    BOOST_CHECK_EQUAL(hit, 3); // handler called
+    BOOST_CHECK_EQUAL(sc.isConnected(), true);
+    BOOST_CHECK_EQUAL(sc3.isConnected(), false);
+
+    sc3 = std::move(sc); // move assignment
+    BOOST_CHECK_EQUAL(sc.isConnected(), false);
+    BOOST_CHECK_EQUAL(sc3.isConnected(), true);
+
+    // sc goes out of scope, but without disconnecting
+  }
+
+  so.emitSignal(sig);
+  BOOST_CHECK_EQUAL(hit, 4); // handler called
 }
 
 BOOST_AUTO_TEST_CASE(ConnectSingleShot)