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/src/encoding/block.cpp b/src/encoding/block.cpp
index 639ed68..1aa9756 100644
--- a/src/encoding/block.cpp
+++ b/src/encoding/block.cpp
@@ -34,20 +34,17 @@
 namespace ndn {
 
 BOOST_CONCEPT_ASSERT((boost::EqualityComparable<Block>));
-static_assert(std::is_nothrow_move_constructible<Block>::value,
-              "Block must be MoveConstructible with noexcept");
-static_assert(std::is_nothrow_move_assignable<Block>::value,
-              "Block must be MoveAssignable with noexcept");
 
 const size_t MAX_SIZE_OF_BLOCK_FROM_STREAM = MAX_NDN_PACKET_SIZE;
 
 // ---- constructor, creation, assignment ----
 
-Block::Block()
-  : m_type(std::numeric_limits<uint32_t>::max())
-  , m_size(0)
-{
-}
+Block::Block() = default;
+
+Block::Block(const Block&) = default;
+
+Block&
+Block::operator=(const Block&) = default;
 
 Block::Block(const EncodingBuffer& buffer)
   : Block(buffer.getBuffer(), buffer.begin(), buffer.end(), true)
@@ -116,10 +113,13 @@
   uint64_t length = tlv::readVarNumber(pos, end);
   // pos now points to TLV-VALUE
 
+  BOOST_ASSERT(pos <= end);
   if (length > static_cast<uint64_t>(end - pos)) {
     BOOST_THROW_EXCEPTION(Error("Not enough bytes in the buffer to fully parse TLV"));
   }
-  size_t typeLengthSize = pos - buf;
+
+  BOOST_ASSERT(pos > buf);
+  uint64_t typeLengthSize = static_cast<uint64_t>(pos - buf);
   m_size = typeLengthSize + length;
 
   m_buffer = make_shared<Buffer>(buf, m_size);
@@ -262,7 +262,7 @@
 Block::resetWire()
 {
   m_buffer.reset(); // discard underlying buffer by resetting shared_ptr
-  m_begin = m_end = m_valueBegin = m_valueEnd = Buffer::const_iterator();
+  m_begin = m_end = m_valueBegin = m_valueEnd = {};
 }
 
 Buffer::const_iterator
@@ -313,7 +313,7 @@
 size_t
 Block::value_size() const
 {
-  return hasValue() ? m_valueEnd - m_valueBegin : 0;
+  return hasValue() ? static_cast<size_t>(m_valueEnd - m_valueBegin) : 0;
 }
 
 Block
diff --git a/src/encoding/block.hpp b/src/encoding/block.hpp
index 63f3677..2aec91c 100644
--- a/src/encoding/block.hpp
+++ b/src/encoding/block.hpp
@@ -61,6 +61,24 @@
    */
   Block();
 
+  /** @brief Copy constructor
+   */
+  Block(const Block&);
+
+  /** @brief Copy assignment operator
+   */
+  Block&
+  operator=(const Block&);
+
+  /** @brief Move constructor
+   */
+  Block(Block&&) noexcept;
+
+  /** @brief Move assignment operator
+   */
+  Block&
+  operator=(Block&&) noexcept;
+
   /** @brief Parse Block from an EncodingBuffer
    *  @param buffer an EncodingBuffer containing one TLV element
    *  @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
@@ -412,13 +430,13 @@
   Buffer::const_iterator m_valueBegin; ///< @sa m_buffer
   Buffer::const_iterator m_valueEnd; ///< @sa m_buffer
 
-  uint32_t m_type; ///< TLV-TYPE
+  uint32_t m_type = std::numeric_limits<uint32_t>::max(); ///< TLV-TYPE
 
   /** @brief total size including Type-Length-Value
    *
    *  This field is valid only if empty() is false.
    */
-  uint32_t m_size;
+  size_t m_size = 0;
 
   /** @brief sub elements
    *
@@ -439,6 +457,12 @@
   operator<<(std::ostream& os, const Block& block);
 };
 
+inline
+Block::Block(Block&&) noexcept = default;
+
+inline Block&
+Block::operator=(Block&&) noexcept = default;
+
 /** @brief Compare whether two Blocks have same TLV-TYPE, TLV-LENGTH, and TLV-VALUE
  */
 bool
diff --git a/src/encoding/buffer.cpp b/src/encoding/buffer.cpp
deleted file mode 100644
index 531e9fa..0000000
--- a/src/encoding/buffer.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/*
- * Copyright (c) 2013-2018 Regents of the University of California.
- *
- * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
- *
- * ndn-cxx library is free software: you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
- *
- * You should have received copies of the GNU General Public License and GNU Lesser
- * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
- *
- * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
- */
-
-#include "buffer.hpp"
-
-namespace ndn {
-
-static_assert(std::is_nothrow_move_constructible<Buffer>::value,
-              "Buffer must be MoveConstructible with noexcept");
-static_assert(std::is_nothrow_move_assignable<Buffer>::value,
-              "Buffer must be MoveAssignable with noexcept");
-
-Buffer::Buffer() = default;
-
-Buffer::Buffer(size_t size)
-  : std::vector<uint8_t>(size, 0)
-{
-}
-
-Buffer::Buffer(const void* buf, size_t length)
-  : std::vector<uint8_t>(reinterpret_cast<const uint8_t*>(buf),
-                         reinterpret_cast<const uint8_t*>(buf) + length)
-{
-}
-
-} // namespace ndn
diff --git a/src/encoding/buffer.hpp b/src/encoding/buffer.hpp
index fbfeb00..d695f1c 100644
--- a/src/encoding/buffer.hpp
+++ b/src/encoding/buffer.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2017 Regents of the University of California.
+ * Copyright (c) 2013-2018 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -42,19 +42,44 @@
 public:
   /** @brief Creates an empty Buffer
    */
-  Buffer();
+  Buffer() = default;
+
+  /** @brief Copy constructor
+   */
+  Buffer(const Buffer&);
+
+  /** @brief Copy assignment operator
+   */
+  Buffer&
+  operator=(const Buffer&);
+
+  /** @brief Move constructor
+   */
+  Buffer(Buffer&&) noexcept;
+
+  /** @brief Move assignment operator
+   */
+  Buffer&
+  operator=(Buffer&&) noexcept;
 
   /** @brief Creates a Buffer with pre-allocated size
    *  @param size size of the Buffer to be allocated
    */
   explicit
-  Buffer(size_t size);
+  Buffer(size_t size)
+    : std::vector<uint8_t>(size, 0)
+  {
+  }
 
   /** @brief Creates a Buffer by copying contents from a raw buffer
    *  @param buf const pointer to buffer to copy
    *  @param length length of the buffer to copy
    */
-  Buffer(const void* buf, size_t length);
+  Buffer(const void* buf, size_t length)
+    : std::vector<uint8_t>(reinterpret_cast<const uint8_t*>(buf),
+                           reinterpret_cast<const uint8_t*>(buf) + length)
+  {
+  }
 
   /** @brief Creates a Buffer by copying the elements of the range [first, last)
    *  @param first an input iterator to the first element to copy
@@ -85,6 +110,18 @@
   }
 };
 
+inline
+Buffer::Buffer(const Buffer&) = default;
+
+inline Buffer&
+Buffer::operator=(const Buffer&) = default;
+
+inline
+Buffer::Buffer(Buffer&&) noexcept = default;
+
+inline Buffer&
+Buffer::operator=(Buffer&&) noexcept = default;
+
 using BufferPtr = shared_ptr<Buffer>;
 using ConstBufferPtr = shared_ptr<const Buffer>;
 
diff --git a/src/util/scheduler-scoped-event-id.cpp b/src/util/scheduler-scoped-event-id.cpp
index 0ca7d13..d83fa4c 100644
--- a/src/util/scheduler-scoped-event-id.cpp
+++ b/src/util/scheduler-scoped-event-id.cpp
@@ -25,34 +25,24 @@
 namespace util {
 namespace scheduler {
 
-static_assert(std::is_nothrow_move_constructible<ScopedEventId>::value,
-              "ScopedEventId must be MoveConstructible with noexcept");
-
-ScopedEventId::ScopedEventId(Scheduler& scheduler)
+ScopedEventId::ScopedEventId(Scheduler& scheduler) noexcept
   : m_scheduler(&scheduler)
 {
 }
 
-ScopedEventId::ScopedEventId(ScopedEventId&& other) noexcept
-  : m_scheduler(other.m_scheduler)
-  , m_event(other.m_event)
-{
-  other.release();
-}
-
 ScopedEventId&
-ScopedEventId::operator=(const EventId& event)
+ScopedEventId::operator=(EventId event)
 {
   if (m_event != event) {
-    m_scheduler->cancelEvent(m_event);
-    m_event = event;
+    cancel();
+    m_event = std::move(event);
   }
   return *this;
 }
 
-ScopedEventId::~ScopedEventId() noexcept
+ScopedEventId::~ScopedEventId()
 {
-  m_scheduler->cancelEvent(m_event);
+  cancel();
 }
 
 void
diff --git a/src/util/scheduler-scoped-event-id.hpp b/src/util/scheduler-scoped-event-id.hpp
index ea27016..703a745 100644
--- a/src/util/scheduler-scoped-event-id.hpp
+++ b/src/util/scheduler-scoped-event-id.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+/*
+ * Copyright (c) 2013-2018 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -28,44 +28,53 @@
 namespace util {
 namespace scheduler {
 
-/** \brief Event that is automatically cancelled upon destruction
+/** \brief Event that is automatically cancelled upon destruction.
  */
-class ScopedEventId : noncopyable
+class ScopedEventId
 {
 public:
-  /** \brief Construct ScopedEventId tied to the specified scheduler
+  /** \brief Construct ScopedEventId tied to the specified scheduler.
    *  \param scheduler Scheduler to which the event is tied.  Behavior is undefined if
-   *                   scheduler is destructed before an uncanceled ScopedEventId.
+   *                   \p scheduler is destructed before an uncanceled ScopedEventId.
    */
   explicit
-  ScopedEventId(Scheduler& scheduler);
+  ScopedEventId(Scheduler& scheduler) noexcept;
 
-  /** \brief move constructor
+  ScopedEventId(const ScopedEventId&) = delete;
+
+  ScopedEventId&
+  operator=(const ScopedEventId&) = delete;
+
+  /** \brief Move constructor.
    */
-  ScopedEventId(ScopedEventId&& other) noexcept;
+  ScopedEventId(ScopedEventId&&) noexcept;
 
-  /** \brief assigns an event
+  /** \brief Move assignment operator.
+   */
+  ScopedEventId&
+  operator=(ScopedEventId&&) noexcept;
+
+  /** \brief Assign an event.
    *
    *  If a different event has been assigned to this instance previously,
    *  that event will be cancelled immediately.
    *
-   *  \note The caller should ensure that ScopedEventId is tied to a correct scheduler.
-   *        Behavior is undefined when assigning event scheduled in another scheduler instance.
+   *  \note The caller should ensure that this ScopedEventId is tied to the correct Scheduler.
+   *        Behavior is undefined when assigning an event scheduled in another Scheduler instance.
    */
   ScopedEventId&
-  operator=(const EventId& event);
+  operator=(EventId event);
 
-  /** \brief cancels the event
+  /** \brief Destructor, automatically cancels the event.
    */
-  ~ScopedEventId() noexcept;
+  ~ScopedEventId();
 
-  /** \brief cancels the event manually
+  /** \brief Manually cancel the event.
    */
   void
   cancel();
 
-  /** \brief releases the event so that it won't be canceled
-   *         when this ScopedEventId is destructed
+  /** \brief Release the event so that it won't be canceled when this ScopedEventId is destructed.
    */
   void
   release() noexcept;
@@ -75,6 +84,12 @@
   EventId m_event;
 };
 
+inline
+ScopedEventId::ScopedEventId(ScopedEventId&&) noexcept = default;
+
+inline ScopedEventId&
+ScopedEventId::operator=(ScopedEventId&&) noexcept = default;
+
 } // namespace scheduler
 } // namespace util
 } // namespace ndn
diff --git a/src/util/scheduler.cpp b/src/util/scheduler.cpp
index aecf15a..9e52b25 100644
--- a/src/util/scheduler.cpp
+++ b/src/util/scheduler.cpp
@@ -51,15 +51,16 @@
   EventQueue::const_iterator queueIt;
 };
 
-EventId::operator bool() const
+EventId::operator bool() const noexcept
 {
-  return !m_info.expired() && !m_info.lock()->isExpired;
+  auto sp = m_info.lock();
+  return sp != nullptr && !sp->isExpired;
 }
 
 bool
-EventId::operator==(const EventId& other) const
+EventId::operator==(const EventId& other) const noexcept
 {
-  return (!(*this) && !other) ||
+  return (!*this && !other) ||
          !(m_info.owner_before(other.m_info) || other.m_info.owner_before(m_info));
 }
 
@@ -70,7 +71,7 @@
 }
 
 bool
-EventQueueCompare::operator()(const shared_ptr<EventInfo>& a, const shared_ptr<EventInfo>& b) const
+EventQueueCompare::operator()(const shared_ptr<EventInfo>& a, const shared_ptr<EventInfo>& b) const noexcept
 {
   return a->expireTime < b->expireTime;
 }
diff --git a/src/util/scheduler.hpp b/src/util/scheduler.hpp
index 79fbf23..bd4467a 100644
--- a/src/util/scheduler.hpp
+++ b/src/util/scheduler.hpp
@@ -57,7 +57,8 @@
    * \brief Constructs an empty EventId
    * \note EventId is implicitly convertible from nullptr.
    */
-  EventId(std::nullptr_t = nullptr)
+  constexpr
+  EventId(std::nullptr_t = nullptr) noexcept
   {
   }
 
@@ -66,16 +67,16 @@
    * \retval false This EventId is empty, or the event is expired or cancelled.
    */
   explicit
-  operator bool() const;
+  operator bool() const noexcept;
 
   /**
    * \return whether this and other refer to the same event, or are both empty/expired/cancelled
    */
   bool
-  operator==(const EventId& other) const;
+  operator==(const EventId& other) const noexcept;
 
   bool
-  operator!=(const EventId& other) const
+  operator!=(const EventId& other) const noexcept
   {
     return !this->operator==(other);
   }
@@ -86,15 +87,15 @@
    * \post !(*this)
    */
   void
-  reset()
+  reset() noexcept
   {
     m_info.reset();
   }
 
 private:
   explicit
-  EventId(const weak_ptr<EventInfo>& info)
-    : m_info(info)
+  EventId(weak_ptr<EventInfo> info) noexcept
+    : m_info(std::move(info))
   {
   }
 
@@ -112,7 +113,7 @@
 {
 public:
   bool
-  operator()(const shared_ptr<EventInfo>& a, const shared_ptr<EventInfo>& b) const;
+  operator()(const shared_ptr<EventInfo>& a, const shared_ptr<EventInfo>& b) const noexcept;
 };
 
 using EventQueue = std::multiset<shared_ptr<EventInfo>, EventQueueCompare>;
diff --git a/src/util/signal/connection.cpp b/src/util/signal/connection.cpp
index 7d46eb1..1d93326 100644
--- a/src/util/signal/connection.cpp
+++ b/src/util/signal/connection.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2017 Regents of the University of California.
+ * Copyright (c) 2013-2018 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -27,26 +27,22 @@
 
 BOOST_CONCEPT_ASSERT((boost::EqualityComparable<Connection>));
 
-Connection::Connection()
-{
-}
-
-Connection::Connection(weak_ptr<function<void()>> disconnect)
-  : m_disconnect(disconnect)
+Connection::Connection(weak_ptr<function<void()>> disconnect) noexcept
+  : m_disconnect(std::move(disconnect))
 {
 }
 
 void
 Connection::disconnect()
 {
-  shared_ptr<function<void()>> f = m_disconnect.lock();
+  auto f = m_disconnect.lock();
   if (f != nullptr) {
     (*f)();
   }
 }
 
 bool
-Connection::isConnected() const
+Connection::isConnected() const noexcept
 {
   return !m_disconnect.expired();
 }
@@ -54,8 +50,8 @@
 bool
 Connection::operator==(const Connection& other) const
 {
-  shared_ptr<function<void()>> f1 = m_disconnect.lock();
-  shared_ptr<function<void()>> f2 = other.m_disconnect.lock();
+  auto f1 = m_disconnect.lock();
+  auto f2 = other.m_disconnect.lock();
   return f1 == f2;
 }
 
diff --git a/src/util/signal/connection.hpp b/src/util/signal/connection.hpp
index 6ee8e1c..528dcba 100644
--- a/src/util/signal/connection.hpp
+++ b/src/util/signal/connection.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2017 Regents of the University of California.
+ * Copyright (c) 2013-2018 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -34,7 +34,8 @@
 class Connection
 {
 public:
-  Connection();
+  constexpr
+  Connection() noexcept = default;
 
   /** \brief disconnects from the signal
    *  \note If the connection is already disconnected, or if the Signal has been destructed,
@@ -49,7 +50,7 @@
    *  \return false if disconnected from the signal
    */
   bool
-  isConnected() const;
+  isConnected() const noexcept;
 
   /** \brief compare for equality
    *
@@ -66,7 +67,7 @@
   /** \param disconnect weak_ptr to a function that disconnects the handler
    */
   explicit
-  Connection(weak_ptr<function<void()>> disconnect);
+  Connection(weak_ptr<function<void()>> disconnect) noexcept;
 
   template<typename Owner, typename ...TArgs>
   friend class Signal;
diff --git a/src/util/signal/scoped-connection.cpp b/src/util/signal/scoped-connection.cpp
index 3fed4a3..7a231b0 100644
--- a/src/util/signal/scoped-connection.cpp
+++ b/src/util/signal/scoped-connection.cpp
@@ -25,35 +25,24 @@
 namespace util {
 namespace signal {
 
-static_assert(std::is_nothrow_move_constructible<ScopedConnection>::value,
-              "ScopedConnection must be MoveConstructible with noexcept");
-
-ScopedConnection::ScopedConnection() = default;
-
-ScopedConnection::ScopedConnection(const Connection& connection)
-  : m_connection(connection)
+ScopedConnection::ScopedConnection(Connection connection) noexcept
+  : m_connection(std::move(connection))
 {
 }
 
-ScopedConnection::ScopedConnection(ScopedConnection&& other) noexcept
-  : m_connection(other.m_connection)
-{
-  other.release();
-}
-
 ScopedConnection&
-ScopedConnection::operator=(const Connection& connection)
+ScopedConnection::operator=(Connection connection)
 {
   if (m_connection != connection) {
-    m_connection.disconnect();
-    m_connection = connection;
+    disconnect();
+    m_connection = std::move(connection);
   }
   return *this;
 }
 
-ScopedConnection::~ScopedConnection() noexcept
+ScopedConnection::~ScopedConnection()
 {
-  m_connection.disconnect();
+  disconnect();
 }
 
 void
@@ -63,13 +52,13 @@
 }
 
 bool
-ScopedConnection::isConnected() const
+ScopedConnection::isConnected() const noexcept
 {
   return m_connection.isConnected();
 }
 
 void
-ScopedConnection::release()
+ScopedConnection::release() noexcept
 {
   m_connection = {};
 }
diff --git a/src/util/signal/scoped-connection.hpp b/src/util/signal/scoped-connection.hpp
index 5c77c2f..f352be0 100644
--- a/src/util/signal/scoped-connection.hpp
+++ b/src/util/signal/scoped-connection.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2017 Regents of the University of California.
+ * Copyright (c) 2013-2018 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -28,56 +28,73 @@
 namespace util {
 namespace signal {
 
-/** \brief disconnects a Connection automatically upon destruction
+/** \brief Disconnects a Connection automatically upon destruction.
  */
-class ScopedConnection : noncopyable
+class ScopedConnection
 {
 public:
-  ScopedConnection();
+  constexpr
+  ScopedConnection() noexcept = default;
 
-  /** \brief implicit constructor from Connection
+  ScopedConnection(const ScopedConnection&) = delete;
+
+  ScopedConnection&
+  operator=(const ScopedConnection&) = delete;
+
+  /** \brief Move constructor.
+   */
+  ScopedConnection(ScopedConnection&&) noexcept;
+
+  /** \brief Move assignment operator.
+   */
+  ScopedConnection&
+  operator=(ScopedConnection&&) noexcept;
+
+  /** \brief Implicit constructor from Connection.
    *  \param connection the Connection to be disconnected upon destruction
    */
-  ScopedConnection(const Connection& connection);
+  ScopedConnection(Connection connection) noexcept;
 
-  /** \brief move constructor
-   */
-  ScopedConnection(ScopedConnection&& other) noexcept;
-
-  /** \brief assigns a connection
+  /** \brief Assign a connection.
    *
    *  If a different connection has been assigned to this instance previously,
    *  that connection will be disconnected immediately.
    */
   ScopedConnection&
-  operator=(const Connection& connection);
+  operator=(Connection connection);
 
-  /** \brief disconnects the connection
+  /** \brief Destructor, automatically disconnects the connection.
    */
-  ~ScopedConnection() noexcept;
+  ~ScopedConnection();
 
-  /** \brief disconnects the connection manually
+  /** \brief Manually disconnect the connection.
    */
   void
   disconnect();
 
-  /** \brief check if the connection is connected to the signal
+  /** \brief Check if the connection is connected to the signal.
    *  \return false when a default-constructed connection is used, the connection is released,
    *          or the connection is disconnected
    */
   bool
-  isConnected() const;
+  isConnected() const noexcept;
 
-  /** \brief releases the connection so that it won't be disconnected
-   *         when this ScopedConnection is destructed
+  /** \brief Release the connection so that it won't be disconnected
+   *         when this ScopedConnection is destructed.
    */
   void
-  release();
+  release() noexcept;
 
 private:
   Connection m_connection;
 };
 
+inline
+ScopedConnection::ScopedConnection(ScopedConnection&&) noexcept = default;
+
+inline ScopedConnection&
+ScopedConnection::operator=(ScopedConnection&&) noexcept = default;
+
 } // namespace signal
 } // namespace util
 } // namespace ndn
diff --git a/tests/unit-tests/util/scheduler.t.cpp b/tests/unit-tests/util/scheduler.t.cpp
index de54800..05380f3 100644
--- a/tests/unit-tests/util/scheduler.t.cpp
+++ b/tests/unit-tests/util/scheduler.t.cpp
@@ -24,6 +24,7 @@
 
 #include "boost-test.hpp"
 #include "../unit-test-time-fixture.hpp"
+
 #include <boost/lexical_cast.hpp>
 
 namespace ndn {
@@ -253,9 +254,9 @@
 {
   EventId eid;
   eid = nullptr;
+  EventId eid2(nullptr);
 
-  // avoid "test case [...] did not check any assertions" message from Boost.Test
-  BOOST_CHECK(true);
+  BOOST_CHECK(!eid && !eid2);
 }
 
 BOOST_AUTO_TEST_CASE(Compare)
@@ -273,12 +274,12 @@
   BOOST_CHECK_EQUAL(eid != nullptr, true);
 
   eid2 = eid;
-  BOOST_CHECK_EQUAL(eid == eid2, true);
+  BOOST_CHECK_EQUAL(eid, eid2);
   BOOST_CHECK_EQUAL(eid != eid2, false);
 
   eid2 = scheduler.scheduleEvent(10_ms, []{});
   BOOST_CHECK_EQUAL(eid == eid2, false);
-  BOOST_CHECK_EQUAL(eid != eid2, true);
+  BOOST_CHECK_NE(eid, eid2);
 }
 
 BOOST_AUTO_TEST_CASE(Valid)
@@ -293,10 +294,8 @@
 
   EventId eid2 = eid;
   scheduler.cancelEvent(eid2);
-  BOOST_CHECK_EQUAL(static_cast<bool>(eid), false);
-  BOOST_CHECK_EQUAL(!eid, true);
-  BOOST_CHECK_EQUAL(static_cast<bool>(eid2), false);
-  BOOST_CHECK_EQUAL(!eid2, true);
+  BOOST_CHECK(!eid);
+  BOOST_CHECK(!eid2);
 }
 
 BOOST_AUTO_TEST_CASE(DuringCallback)
@@ -309,17 +308,14 @@
     isCallbackInvoked = true;
 
     // eid is "expired" during callback execution
-    BOOST_CHECK_EQUAL(static_cast<bool>(eid), false);
-    BOOST_CHECK_EQUAL(!eid, true);
-    BOOST_CHECK_EQUAL(eid == eid2, false);
-    BOOST_CHECK_EQUAL(eid != eid2, true);
-    BOOST_CHECK_EQUAL(eid == nullptr, true);
-    BOOST_CHECK_EQUAL(eid != nullptr, false);
+    BOOST_CHECK(!eid);
+    BOOST_CHECK(eid == nullptr);
+    BOOST_CHECK_NE(eid, eid2);
 
     scheduler.cancelEvent(eid2);
-    BOOST_CHECK_EQUAL(eid == eid2, true);
-    BOOST_CHECK_EQUAL(eid != eid2, false);
+    BOOST_CHECK_EQUAL(eid, eid2);
   });
+
   this->advanceClocks(6_ms, 2);
   BOOST_CHECK(isCallbackInvoked);
 }
@@ -327,11 +323,10 @@
 BOOST_AUTO_TEST_CASE(Reset)
 {
   bool isCallbackInvoked = false;
-  EventId eid = scheduler.scheduleEvent(10_ms,
-                                        [&isCallbackInvoked]{ isCallbackInvoked = true; });
+  EventId eid = scheduler.scheduleEvent(10_ms, [&isCallbackInvoked] { isCallbackInvoked = true; });
   eid.reset();
-  BOOST_CHECK_EQUAL(!eid, true);
-  BOOST_CHECK_EQUAL(eid == nullptr, true);
+  BOOST_CHECK(!eid);
+  BOOST_CHECK(eid == nullptr);
 
   this->advanceClocks(6_ms, 2);
   BOOST_CHECK(isCallbackInvoked);
@@ -392,14 +387,23 @@
 BOOST_AUTO_TEST_CASE(Move)
 {
   int hit = 0;
-  unique_ptr<scheduler::ScopedEventId> se2;
+  unique_ptr<ScopedEventId> se2;
   {
     ScopedEventId se(scheduler);
     se = scheduler.scheduleEvent(10_ms, [&] { ++hit; });
-    se2.reset(new ScopedEventId(std::move(se)));
+    se2 = make_unique<ScopedEventId>(std::move(se)); // move constructor
   } // se goes out of scope
   this->advanceClocks(1_ms, 15);
   BOOST_CHECK_EQUAL(hit, 1);
+
+  ScopedEventId se3(scheduler);
+  {
+    ScopedEventId se(scheduler);
+    se = scheduler.scheduleEvent(10_ms, [&] { ++hit; });
+    se3 = std::move(se); // move assignment
+  } // se goes out of scope
+  this->advanceClocks(1_ms, 15);
+  BOOST_CHECK_EQUAL(hit, 2);
 }
 
 BOOST_AUTO_TEST_SUITE_END() // ScopedEventId
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)