Improve and simplify code with modern C++ features

Change-Id: I28d84df3087492ab2ecbeb91169a2cde12c9e31e
diff --git a/src/util/backports-ostream-joiner.hpp b/src/util/backports-ostream-joiner.hpp
index 1ba1380..b52bac6 100644
--- a/src/util/backports-ostream-joiner.hpp
+++ b/src/util/backports-ostream-joiner.hpp
@@ -113,7 +113,7 @@
 };
 
 template<typename CharT, typename Traits, typename DelimT>
-inline ostream_joiner<typename std::decay<DelimT>::type, CharT, Traits>
+inline ostream_joiner<std::decay_t<DelimT>, CharT, Traits>
 make_ostream_joiner(std::basic_ostream<CharT, Traits>& os, DelimT&& delimiter)
 {
   return {os, std::forward<DelimT>(delimiter)};
diff --git a/src/util/logging.cpp b/src/util/logging.cpp
index 0e68092..9513bfb 100644
--- a/src/util/logging.cpp
+++ b/src/util/logging.cpp
@@ -52,7 +52,7 @@
 
 Logging::Logging()
 {
-  this->setDestinationImpl(shared_ptr<std::ostream>(&std::clog, bind([]{})));
+  this->setDestinationImpl(shared_ptr<std::ostream>(&std::clog, [] (auto) {}));
 
   const char* environ = std::getenv("NDN_LOG");
   if (environ != nullptr) {
@@ -202,7 +202,7 @@
 void
 Logging::setDestination(std::ostream& os)
 {
-  setDestination(shared_ptr<std::ostream>(&os, bind([]{})));
+  setDestination(shared_ptr<std::ostream>(&os, [] (auto) {}));
 }
 
 void
@@ -214,7 +214,7 @@
 
   auto backend = boost::make_shared<boost::log::sinks::text_ostream_backend>();
   backend->auto_flush(true);
-  backend->add_stream(boost::shared_ptr<std::ostream>(m_destination.get(), bind([]{})));
+  backend->add_stream(boost::shared_ptr<std::ostream>(m_destination.get(), [] (auto) {}));
 
   if (m_sink != nullptr) {
     boost::log::core::get()->remove_sink(m_sink);
diff --git a/src/util/notification-subscriber.cpp b/src/util/notification-subscriber.cpp
index 66ffd8c..e69800a 100644
--- a/src/util/notification-subscriber.cpp
+++ b/src/util/notification-subscriber.cpp
@@ -43,6 +43,7 @@
   , m_attempts(1)
   , m_scheduler(face.getIoService())
   , m_nackEvent(m_scheduler)
+  , m_lastInterestId(nullptr)
   , m_interestLifetime(interestLifetime)
 {
 }
@@ -56,7 +57,7 @@
     return;
   m_isRunning = true;
 
-  this->sendInitialInterest();
+  sendInitialInterest();
 }
 
 void
@@ -66,15 +67,15 @@
     return;
   m_isRunning = false;
 
-  if (m_lastInterestId != 0)
+  if (m_lastInterestId != nullptr)
     m_face.removePendingInterest(m_lastInterestId);
-  m_lastInterestId = 0;
+  m_lastInterestId = nullptr;
 }
 
 void
 NotificationSubscriberBase::sendInitialInterest()
 {
-  if (this->shouldStop())
+  if (shouldStop())
     return;
 
   auto interest = make_shared<Interest>(m_prefix);
@@ -83,15 +84,15 @@
   interest->setInterestLifetime(getInterestLifetime());
 
   m_lastInterestId = m_face.expressInterest(*interest,
-                       bind(&NotificationSubscriberBase::afterReceiveData, this, _2),
-                       bind(&NotificationSubscriberBase::afterReceiveNack, this, _2),
-                       bind(&NotificationSubscriberBase::afterTimeout, this));
+                                            [this] (const auto&, const auto& d) { this->afterReceiveData(d); },
+                                            [this] (const auto&, const auto& n) { this->afterReceiveNack(n); },
+                                            [this] (const auto&) { this->afterTimeout(); });
 }
 
 void
 NotificationSubscriberBase::sendNextInterest()
 {
-  if (this->shouldStop())
+  if (shouldStop())
     return;
 
   BOOST_ASSERT(m_lastSequenceNo != std::numeric_limits<uint64_t>::max()); // overflow or missing initial reply
@@ -103,9 +104,9 @@
   interest->setInterestLifetime(getInterestLifetime());
 
   m_lastInterestId = m_face.expressInterest(*interest,
-                       bind(&NotificationSubscriberBase::afterReceiveData, this, _2),
-                       bind(&NotificationSubscriberBase::afterReceiveNack, this, _2),
-                       bind(&NotificationSubscriberBase::afterTimeout, this));
+                                            [this] (const auto&, const auto& d) { this->afterReceiveData(d); },
+                                            [this] (const auto&, const auto& n) { this->afterReceiveNack(n); },
+                                            [this] (const auto&) { this->afterTimeout(); });
 }
 
 bool
@@ -113,8 +114,9 @@
 {
   if (!m_isRunning)
     return true;
-  if (!this->hasSubscriber() && onNack.isEmpty()) {
-    this->stop();
+
+  if (!hasSubscriber() && onNack.isEmpty()) {
+    stop();
     return true;
   }
   return false;
@@ -123,55 +125,54 @@
 void
 NotificationSubscriberBase::afterReceiveData(const Data& data)
 {
-  if (this->shouldStop())
+  if (shouldStop())
     return;
 
   try {
     m_lastSequenceNo = data.getName().get(-1).toSequenceNumber();
   }
   catch (const tlv::Error&) {
-    this->onDecodeError(data);
-    this->sendInitialInterest();
+    onDecodeError(data);
+    sendInitialInterest();
     return;
   }
 
-  if (!this->decodeAndDeliver(data)) {
-    this->onDecodeError(data);
-    this->sendInitialInterest();
+  if (!decodeAndDeliver(data)) {
+    onDecodeError(data);
+    sendInitialInterest();
     return;
   }
 
-  this->sendNextInterest();
+  sendNextInterest();
 }
 
 void
 NotificationSubscriberBase::afterReceiveNack(const lp::Nack& nack)
 {
-  if (this->shouldStop())
+  if (shouldStop())
     return;
 
-  this->onNack(nack);
+  onNack(nack);
 
   time::milliseconds delay = exponentialBackoff(nack);
-  m_nackEvent = m_scheduler.scheduleEvent(delay, [this] {this->sendInitialInterest();});
+  m_nackEvent = m_scheduler.scheduleEvent(delay, [this] { sendInitialInterest(); });
 }
 
 void
 NotificationSubscriberBase::afterTimeout()
 {
-  if (this->shouldStop())
+  if (shouldStop())
     return;
 
-  this->onTimeout();
+  onTimeout();
 
-  this->sendInitialInterest();
+  sendInitialInterest();
 }
 
 time::milliseconds
 NotificationSubscriberBase::exponentialBackoff(lp::Nack nack)
 {
   uint64_t nackSequenceNo;
-
   try {
     nackSequenceNo = nack.getInterest().getName().get(-1).toSequenceNumber();
   }
diff --git a/src/util/regex/regex-top-matcher.cpp b/src/util/regex/regex-top-matcher.cpp
index 0c2ac9a..3514951 100644
--- a/src/util/regex/regex-top-matcher.cpp
+++ b/src/util/regex/regex-top-matcher.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).
  *
@@ -172,9 +172,9 @@
 {
   std::string regexStr("^");
 
-  for (auto it = name.begin(); it != name.end(); it++) {
+  for (const auto& i : name) {
     regexStr.append("<");
-    regexStr.append(convertSpecialChar(it->toUri()));
+    regexStr.append(convertSpecialChar(i.toUri()));
     regexStr.append(">");
   }
 
diff --git a/src/util/scheduler.cpp b/src/util/scheduler.cpp
index 167b6e0..aecf15a 100644
--- a/src/util/scheduler.cpp
+++ b/src/util/scheduler.cpp
@@ -41,7 +41,7 @@
   time::nanoseconds
   expiresFromNow() const
   {
-    return std::max(expireTime - time::steady_clock::now(), time::nanoseconds::zero());
+    return std::max(expireTime - time::steady_clock::now(), 0_ns);
   }
 
 public:
@@ -129,7 +129,7 @@
 {
   if (!m_queue.empty()) {
     m_timer->expires_from_now((*m_queue.begin())->expiresFromNow());
-    m_timer->async_wait(bind(&Scheduler::executeEvent, this, _1));
+    m_timer->async_wait([this] (const auto& error) { this->executeEvent(error); });
   }
 }
 
diff --git a/src/util/signal/signal.hpp b/src/util/signal/signal.hpp
index 8c76e13..6eab994 100644
--- a/src/util/signal/signal.hpp
+++ b/src/util/signal/signal.hpp
@@ -64,14 +64,14 @@
    *  \warning The handler is permitted to disconnect itself, but it must ensure its validity.
    */
   Connection
-  connect(const Handler& handler);
+  connect(Handler handler);
 
   /** \brief connects a single-shot handler to the signal
    *
    *  After the handler is executed once, it is automatically disconnected.
    */
   Connection
-  connectSingleShot(const Handler& handler);
+  connectSingleShot(Handler handler);
 
 private: // API for owner
   /** \retval true if there is no connection
@@ -162,23 +162,23 @@
 
 template<typename Owner, typename ...TArgs>
 Connection
-Signal<Owner, TArgs...>::connect(const Handler& handler)
+Signal<Owner, TArgs...>::connect(Handler handler)
 {
-  auto it = m_slots.insert(m_slots.end(), {handler, nullptr});
-  it->disconnect = make_shared<function<void()>>(bind(&Self::disconnect, this, it));
+  auto it = m_slots.insert(m_slots.end(), {std::move(handler), nullptr});
+  it->disconnect = make_shared<function<void()>>([=] { disconnect(it); });
 
   return signal::Connection(weak_ptr<function<void()>>(it->disconnect));
 }
 
 template<typename Owner, typename ...TArgs>
 Connection
-Signal<Owner, TArgs...>::connectSingleShot(const Handler& handler)
+Signal<Owner, TArgs...>::connectSingleShot(Handler handler)
 {
   auto it = m_slots.insert(m_slots.end(), {nullptr, nullptr});
-  it->disconnect = make_shared<function<void()>>(bind(&Self::disconnect, this, it));
+  it->disconnect = make_shared<function<void()>>([=] { disconnect(it); });
   signal::Connection conn(weak_ptr<function<void()>>(it->disconnect));
 
-  it->handler = [conn, handler] (const TArgs&... args) mutable {
+  it->handler = [conn, handler = std::move(handler)] (const TArgs&... args) mutable {
     handler(args...);
     conn.disconnect();
   };
diff --git a/src/util/string-helper.cpp b/src/util/string-helper.cpp
index 642b238..abfacbe 100644
--- a/src/util/string-helper.cpp
+++ b/src/util/string-helper.cpp
@@ -87,7 +87,7 @@
     tr::bufferSource(hexString) >> tr::hexDecode() >> tr::streamSink(os);
   }
   catch (const tr::Error& e) {
-    BOOST_THROW_EXCEPTION(StringHelperError(std::string("Conversion from hex failed: ") + e.what()));
+    BOOST_THROW_EXCEPTION(StringHelperError("Conversion from hex failed: "s + e.what()));
   }
 
   return os.buf();
diff --git a/src/util/time.hpp b/src/util/time.hpp
index 0d1250d..9d5f8bb 100644
--- a/src/util/time.hpp
+++ b/src/util/time.hpp
@@ -45,8 +45,7 @@
  *  \note The function does not participate in the overload resolution
  *        unless std::numeric_limits<Rep>::is_signed is true.
  */
-template<typename Rep, typename Period,
-         typename = typename std::enable_if<std::numeric_limits<Rep>::is_signed>::type>
+template<typename Rep, typename Period, typename = std::enable_if_t<std::numeric_limits<Rep>::is_signed>>
 constexpr duration<Rep, Period>
 abs(duration<Rep, Period> d)
 {