Eradicate all uses of std::bind()

Change-Id: I6e1ccf2d87b76142e6d519c1a288d03022e4d167
diff --git a/core/common.hpp b/core/common.hpp
index dd6d4fb..34da654 100644
--- a/core/common.hpp
+++ b/core/common.hpp
@@ -76,4 +76,7 @@
 
 } // namespace ndn
 
+#define FORWARD_TO_MEM_FN(func) \
+  [this] (auto&&... args) { this->func(std::forward<decltype(args)>(args)...); }
+
 #endif // NDN_TOOLS_CORE_COMMON_HPP
diff --git a/tests/ping/client/ping.t.cpp b/tests/ping/client/ping.t.cpp
index cef62d6..a0eb163 100644
--- a/tests/ping/client/ping.t.cpp
+++ b/tests/ping/client/ping.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2020,  Arizona Board of Regents.
+ * Copyright (c) 2014-2021,  Arizona Board of Regents.
  *
  * This file is part of ndn-tools (Named Data Networking Essential Tools).
  * See AUTHORS.md for complete list of ndn-tools authors and contributors.
@@ -32,9 +32,9 @@
 using namespace ndn::tests;
 
 BOOST_AUTO_TEST_SUITE(Ping)
-BOOST_AUTO_TEST_SUITE(TestPing)
+BOOST_AUTO_TEST_SUITE(TestClient)
 
-using ping::client::Ping;
+using client::Ping;
 
 BOOST_FIXTURE_TEST_CASE(Basic, IoFixture)
 {
@@ -55,10 +55,10 @@
   std::vector<uint64_t> nackSeqs;
   std::vector<uint64_t> timeoutSeqs;
 
-  ping.afterData.connect(bind([&] (uint64_t seq) { dataSeqs.push_back(seq); }, _1));
-  ping.afterNack.connect(bind([&] (uint64_t seq) { nackSeqs.push_back(seq); }, _1));
-  ping.afterTimeout.connect(bind([&] (uint64_t seq) { timeoutSeqs.push_back(seq); }, _1));
-  ping.afterFinish.connect(bind([&] {
+  ping.afterData.connect([&] (uint64_t seq, auto&&...) { dataSeqs.push_back(seq); });
+  ping.afterNack.connect([&] (uint64_t seq, auto&&...) { nackSeqs.push_back(seq); });
+  ping.afterTimeout.connect([&] (uint64_t seq, auto&&...) { timeoutSeqs.push_back(seq); });
+  ping.afterFinish.connect([&] {
     BOOST_REQUIRE_EQUAL(dataSeqs.size(), 2);
     BOOST_REQUIRE_EQUAL(nackSeqs.size(), 1);
     BOOST_REQUIRE_EQUAL(timeoutSeqs.size(), 1);
@@ -69,7 +69,7 @@
     BOOST_CHECK_EQUAL(timeoutSeqs[0], 1003);
 
     nFinishSignals++;
-  }));
+  });
 
   ping.start();
 
@@ -93,7 +93,7 @@
   BOOST_CHECK_EQUAL(nFinishSignals, 1);
 }
 
-BOOST_AUTO_TEST_SUITE_END() // TestPing
+BOOST_AUTO_TEST_SUITE_END() // TestClient
 BOOST_AUTO_TEST_SUITE_END() // Ping
 
 } // namespace tests
diff --git a/tests/ping/server/ping-server.t.cpp b/tests/ping/server/ping-server.t.cpp
index f7ff66f..e01d3d7 100644
--- a/tests/ping/server/ping-server.t.cpp
+++ b/tests/ping/server/ping-server.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2020,  Arizona Board of Regents.
+ * Copyright (c) 2014-2021,  Arizona Board of Regents.
  *
  * This file is part of ndn-tools (Named Data Networking Essential Tools).
  * See AUTHORS.md for complete list of ndn-tools authors and contributors.
@@ -33,12 +33,12 @@
 using namespace ndn::tests;
 
 BOOST_AUTO_TEST_SUITE(Ping)
-BOOST_AUTO_TEST_SUITE(TestPingServer)
+BOOST_AUTO_TEST_SUITE(TestServer)
 
-class CreatePingServerFixture : public IoFixture, public KeyChainFixture
+class PingServerFixture : public IoFixture, public KeyChainFixture
 {
 protected:
-  CreatePingServerFixture()
+  PingServerFixture()
     : face(m_io, m_keyChain, {false, true})
     , pingOptions(makeOptions())
     , pingServer(face, m_keyChain, pingOptions)
@@ -78,9 +78,9 @@
   PingServer pingServer;
 };
 
-BOOST_FIXTURE_TEST_CASE(CreatePingServer, CreatePingServerFixture)
+BOOST_FIXTURE_TEST_CASE(Receive, PingServerFixture)
 {
-  BOOST_REQUIRE_EQUAL(0, pingServer.getNPings());
+  BOOST_TEST(pingServer.getNPings() == 0);
   pingServer.start();
 
   advanceClocks(1_ms, 200);
@@ -90,10 +90,10 @@
 
   m_io.run();
 
-  BOOST_CHECK_EQUAL(2, pingServer.getNPings());
+  BOOST_TEST(pingServer.getNPings() == 2);
 }
 
-BOOST_AUTO_TEST_SUITE_END() // TestPingServer
+BOOST_AUTO_TEST_SUITE_END() // TestServer
 BOOST_AUTO_TEST_SUITE_END() // Ping
 
 } // namespace tests
diff --git a/tools/chunks/catchunks/consumer.cpp b/tools/chunks/catchunks/consumer.cpp
index c1be8e8..ac83227 100644
--- a/tools/chunks/catchunks/consumer.cpp
+++ b/tools/chunks/catchunks/consumer.cpp
@@ -46,7 +46,7 @@
 
   m_discover->onDiscoverySuccess.connect([this] (const Name& versionedName) {
     m_pipeline->run(versionedName,
-                    [this] (const Data& data) { handleData(data); },
+                    FORWARD_TO_MEM_FN(handleData),
                     [] (const std::string& msg) { NDN_THROW(std::runtime_error(msg)); });
   });
   m_discover->onDiscoveryFailure.connect([] (const std::string& msg) {
diff --git a/tools/chunks/catchunks/data-fetcher.cpp b/tools/chunks/catchunks/data-fetcher.cpp
index 43d5076..baed34f 100644
--- a/tools/chunks/catchunks/data-fetcher.cpp
+++ b/tools/chunks/catchunks/data-fetcher.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2016-2019, Regents of the University of California,
+ * Copyright (c) 2016-2021, Regents of the University of California,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University.
  *
@@ -85,9 +85,9 @@
 {
   m_nCongestionRetries = 0;
   m_pendingInterest = m_face.expressInterest(interest,
-                                             bind(&DataFetcher::handleData, this, _1, _2, self),
-                                             bind(&DataFetcher::handleNack, this, _1, _2, self),
-                                             bind(&DataFetcher::handleTimeout, this, _1, self));
+    [=] (auto&&... args) { handleData(std::forward<decltype(args)>(args)..., self); },
+    [=] (auto&&... args) { handleNack(std::forward<decltype(args)>(args)..., self); },
+    [=] (auto&&... args) { handleTimeout(std::forward<decltype(args)>(args)..., self); });
 }
 
 void
@@ -113,7 +113,7 @@
 
   if (m_isVerbose)
     std::cerr << "Received Nack with reason " << nack.getReason()
-              << " for Interest " << interest << std::endl;
+              << " for Interest " << interest << "\n";
 
   if (m_nNacks <= m_maxNackRetries || m_maxNackRetries == MAX_RETRIES_INFINITE) {
     Interest newInterest(interest);
@@ -162,7 +162,7 @@
     ++m_nTimeouts;
 
   if (m_isVerbose)
-    std::cerr << "Timeout for Interest " << interest << std::endl;
+    std::cerr << "Timeout for Interest " << interest << "\n";
 
   if (m_nTimeouts <= m_maxTimeoutRetries || m_maxTimeoutRetries == MAX_RETRIES_INFINITE) {
     Interest newInterest(interest);
diff --git a/tools/chunks/catchunks/discover-version.cpp b/tools/chunks/catchunks/discover-version.cpp
index 1efe3b2..e35fc21 100644
--- a/tools/chunks/catchunks/discover-version.cpp
+++ b/tools/chunks/catchunks/discover-version.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2016-2019, Regents of the University of California,
+ * Copyright (c) 2016-2021, Regents of the University of California,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University.
  *
@@ -53,12 +53,13 @@
                       .setInterestLifetime(m_options.interestLifetime);
 
   m_fetcher = DataFetcher::fetch(m_face, interest,
-                                 m_options.maxRetriesOnTimeoutOrNack, m_options.maxRetriesOnTimeoutOrNack,
-                                 bind(&DiscoverVersion::handleData, this, _1, _2),
-                                 [this] (const Interest&, const std::string& reason) {
+                                 m_options.maxRetriesOnTimeoutOrNack,
+                                 m_options.maxRetriesOnTimeoutOrNack,
+                                 FORWARD_TO_MEM_FN(handleData),
+                                 [this] (const auto&, const auto& reason) {
                                    onDiscoveryFailure(reason);
                                  },
-                                 [this] (const Interest&, const std::string& reason) {
+                                 [this] (const auto&, const auto& reason) {
                                    onDiscoveryFailure(reason);
                                  },
                                  m_options.isVerbose);
@@ -68,7 +69,7 @@
 DiscoverVersion::handleData(const Interest& interest, const Data& data)
 {
   if (m_options.isVerbose)
-    std::cerr << "Data: " << data << std::endl;
+    std::cerr << "Data: " << data << "\n";
 
   // make a metadata object from received metadata packet
   MetadataObject mobject;
@@ -86,7 +87,7 @@
   }
 
   if (m_options.isVerbose) {
-    std::cerr << "Discovered Data version: " << mobject.getVersionedName()[-1] << std::endl;
+    std::cerr << "Discovered Data version: " << mobject.getVersionedName()[-1] << "\n";
   }
 
   onDiscoverySuccess(mobject.getVersionedName());
diff --git a/tools/chunks/catchunks/pipeline-interests-adaptive.cpp b/tools/chunks/catchunks/pipeline-interests-adaptive.cpp
index 29e0d27..595dcdc 100644
--- a/tools/chunks/catchunks/pipeline-interests-adaptive.cpp
+++ b/tools/chunks/catchunks/pipeline-interests-adaptive.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2016-2019, Regents of the University of California,
+ * Copyright (c) 2016-2021, Regents of the University of California,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University.
  *
@@ -133,7 +133,7 @@
 
   if (m_options.isVerbose) {
     std::cerr << (isRetransmission ? "Retransmitting" : "Requesting")
-              << " segment #" << segNo << std::endl;
+              << " segment #" << segNo << "\n";
   }
 
   if (isRetransmission) {
@@ -150,7 +150,7 @@
 
       if (m_options.isVerbose) {
         std::cerr << "# of retries for segment #" << segNo
-                  << " is " << m_retxCount[segNo] << std::endl;
+                  << " is " << m_retxCount[segNo] << "\n";
       }
     }
   }
@@ -163,9 +163,9 @@
 
   SegmentInfo& segInfo = m_segmentInfo[segNo];
   segInfo.interestHdl = m_face.expressInterest(interest,
-                                               bind(&PipelineInterestsAdaptive::handleData, this, _1, _2),
-                                               bind(&PipelineInterestsAdaptive::handleNack, this, _1, _2),
-                                               bind(&PipelineInterestsAdaptive::handleLifetimeExpiration, this, _1));
+                                               FORWARD_TO_MEM_FN(handleData),
+                                               FORWARD_TO_MEM_FN(handleNack),
+                                               FORWARD_TO_MEM_FN(handleLifetimeExpiration));
   segInfo.timeSent = time::steady_clock::now();
   segInfo.rto = m_rttEstimator.getEstimatedRto();
 
@@ -239,7 +239,7 @@
   if (m_options.isVerbose) {
     std::cerr << "Received segment #" << recvSegNo
               << ", rtt=" << rtt.count() / 1e6 << "ms"
-              << ", rto=" << segInfo.rto.count() / 1e6 << "ms" << std::endl;
+              << ", rto=" << segInfo.rto.count() / 1e6 << "ms\n";
   }
 
   if (m_highData < recvSegNo) {
@@ -265,7 +265,7 @@
 
         if (m_options.isVerbose) {
           std::cerr << "Received congestion mark, value = " << data.getCongestionMark()
-                    << ", new cwnd = " << m_cwnd << std::endl;
+                    << ", new cwnd = " << m_cwnd << "\n";
         }
       }
     }
@@ -314,7 +314,7 @@
 
   if (m_options.isVerbose)
     std::cerr << "Received Nack with reason " << nack.getReason()
-              << " for Interest " << interest << std::endl;
+              << " for Interest " << interest << "\n";
 
   uint64_t segNo = getSegmentFromPacket(interest);
 
@@ -360,7 +360,7 @@
 
     if (m_options.isVerbose) {
       std::cerr << "Packet loss event, new cwnd = " << m_cwnd
-                << ", ssthresh = " << m_ssthresh << std::endl;
+                << ", ssthresh = " << m_ssthresh << "\n";
     }
   }
 }
diff --git a/tools/chunks/catchunks/pipeline-interests-adaptive.hpp b/tools/chunks/catchunks/pipeline-interests-adaptive.hpp
index 158656e..596c70e 100644
--- a/tools/chunks/catchunks/pipeline-interests-adaptive.hpp
+++ b/tools/chunks/catchunks/pipeline-interests-adaptive.hpp
@@ -60,7 +60,7 @@
 struct SegmentInfo
 {
   ScopedPendingInterestHandle interestHdl;
-  time::steady_clock::TimePoint timeSent;
+  time::steady_clock::time_point timeSent;
   time::nanoseconds rto;
   SegmentState state;
 };
diff --git a/tools/chunks/catchunks/pipeline-interests-cubic.hpp b/tools/chunks/catchunks/pipeline-interests-cubic.hpp
index 078560c..daa59eb 100644
--- a/tools/chunks/catchunks/pipeline-interests-cubic.hpp
+++ b/tools/chunks/catchunks/pipeline-interests-cubic.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2016-2019, Regents of the University of California,
+ * Copyright (c) 2016-2021, Regents of the University of California,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University.
  *
@@ -52,7 +52,7 @@
 private:
   double m_wmax = 0.0; ///< window size before last window decrease
   double m_lastWmax = 0.0; ///< last wmax
-  time::steady_clock::TimePoint m_lastDecrease; ///< time of last window decrease
+  time::steady_clock::time_point m_lastDecrease; ///< time of last window decrease
 };
 
 } // namespace chunks
diff --git a/tools/chunks/catchunks/pipeline-interests-fixed.cpp b/tools/chunks/catchunks/pipeline-interests-fixed.cpp
index ce11295..7fab8e3 100644
--- a/tools/chunks/catchunks/pipeline-interests-fixed.cpp
+++ b/tools/chunks/catchunks/pipeline-interests-fixed.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2016-2019, Regents of the University of California,
+ * Copyright (c) 2016-2021, Regents of the University of California,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University.
  *
@@ -79,7 +79,7 @@
 
   // send interest for next segment
   if (m_options.isVerbose)
-    std::cerr << "Requesting segment #" << nextSegmentNo << std::endl;
+    std::cerr << "Requesting segment #" << nextSegmentNo << "\n";
 
   auto interest = Interest()
                   .setName(Name(m_prefix).appendSegment(nextSegmentNo))
@@ -90,9 +90,15 @@
   auto fetcher = DataFetcher::fetch(m_face, interest,
                                     m_options.maxRetriesOnTimeoutOrNack,
                                     m_options.maxRetriesOnTimeoutOrNack,
-                                    bind(&PipelineInterestsFixed::handleData, this, _1, _2, pipeNo),
-                                    bind(&PipelineInterestsFixed::handleFail, this, _2, pipeNo),
-                                    bind(&PipelineInterestsFixed::handleFail, this, _2, pipeNo),
+                                    [=] (const auto& interest, const auto& data) {
+                                      handleData(interest, data, pipeNo);
+                                    },
+                                    [=] (const auto&, const auto& reason) {
+                                      handleFail(reason, pipeNo);
+                                    },
+                                    [=] (const auto&, const auto& reason) {
+                                      handleFail(reason, pipeNo);
+                                    },
                                     m_options.isVerbose);
 
   BOOST_ASSERT(!m_segmentFetchers[pipeNo].first || !m_segmentFetchers[pipeNo].first->isRunning());
@@ -122,7 +128,7 @@
   BOOST_ASSERT(data.getName().equals(interest.getName()));
 
   if (m_options.isVerbose)
-    std::cerr << "Received segment #" << getSegmentFromPacket(data) << std::endl;
+    std::cerr << "Received segment #" << getSegmentFromPacket(data) << "\n";
 
   onData(data);
 
diff --git a/tools/chunks/catchunks/pipeline-interests.hpp b/tools/chunks/catchunks/pipeline-interests.hpp
index dd8b5de..9fc3389 100644
--- a/tools/chunks/catchunks/pipeline-interests.hpp
+++ b/tools/chunks/catchunks/pipeline-interests.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2016-2019, Regents of the University of California,
+ * Copyright (c) 2016-2021, Regents of the University of California,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University.
  *
@@ -80,7 +80,7 @@
   cancel();
 
 protected:
-  time::steady_clock::TimePoint
+  time::steady_clock::time_point
   getStartTime() const
   {
     return m_startTime;
@@ -166,7 +166,7 @@
   DataCallback m_onData;
   FailureCallback m_onFailure;
   uint64_t m_nextSegmentNo;
-  time::steady_clock::TimePoint m_startTime;
+  time::steady_clock::time_point m_startTime;
   bool m_isStopping;
 };
 
diff --git a/tools/chunks/putchunks/producer.cpp b/tools/chunks/putchunks/producer.cpp
index ff4bafb..0a39c3b 100644
--- a/tools/chunks/putchunks/producer.cpp
+++ b/tools/chunks/putchunks/producer.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2016-2019, Regents of the University of California,
+ * Copyright (c) 2016-2021, Regents of the University of California,
  *                          Colorado State University,
  *                          University Pierre & Marie Curie, Sorbonne University.
  *
@@ -53,24 +53,32 @@
   populateStore(is);
 
   if (m_options.wantShowVersion)
-    std::cout << m_versionedPrefix[-1] << std::endl;
+    std::cout << m_versionedPrefix[-1] << "\n";
 
   // register m_prefix without interest handler
-  m_face.registerPrefix(m_prefix, nullptr, bind(&Producer::onRegisterFailed, this, _1, _2));
+  m_face.registerPrefix(m_prefix, nullptr, [this] (const Name& prefix, const auto& reason) {
+    std::cerr << "ERROR: Failed to register prefix '" << prefix << "' (" << reason << ")\n";
+    m_face.shutdown();
+  });
 
   // match Interests whose name starts with m_versionedPrefix
-  face.setInterestFilter(m_versionedPrefix, bind(&Producer::processSegmentInterest, this, _2));
+  face.setInterestFilter(m_versionedPrefix, [this] (const auto&, const auto& interest) {
+    processSegmentInterest(interest);
+  });
 
   // match Interests whose name is exactly m_prefix
-  face.setInterestFilter(InterestFilter(m_prefix, ""),
-                         bind(&Producer::processSegmentInterest, this, _2));
+  face.setInterestFilter(InterestFilter(m_prefix, ""), [this] (const auto&, const auto& interest) {
+    processSegmentInterest(interest);
+  });
 
   // match discovery Interests
-  face.setInterestFilter(MetadataObject::makeDiscoveryInterest(m_prefix).getName(),
-                         bind(&Producer::processDiscoveryInterest, this, _2));
+  auto discoveryName = MetadataObject::makeDiscoveryInterest(m_prefix).getName();
+  face.setInterestFilter(discoveryName, [this] (const auto&, const auto& interest) {
+    processDiscoveryInterest(interest);
+  });
 
   if (!m_options.isQuiet)
-    std::cerr << "Data published with name: " << m_versionedPrefix << std::endl;
+    std::cerr << "Data published with name: " << m_versionedPrefix << "\n";
 }
 
 void
@@ -83,11 +91,11 @@
 Producer::processDiscoveryInterest(const Interest& interest)
 {
   if (m_options.isVerbose)
-    std::cerr << "Discovery Interest: " << interest << std::endl;
+    std::cerr << "Discovery Interest: " << interest << "\n";
 
   if (!interest.getCanBePrefix()) {
     if (m_options.isVerbose)
-      std::cerr << "Discovery Interest lacks CanBePrefix, sending Nack" << std::endl;
+      std::cerr << "Discovery Interest lacks CanBePrefix, sending Nack\n";
     m_face.put(lp::Nack(interest));
     return;
   }
@@ -99,7 +107,7 @@
   Data mdata(mobject.makeData(interest.getName(), m_keyChain, m_options.signingInfo));
 
   if (m_options.isVerbose)
-    std::cerr << "Sending metadata: " << mdata << std::endl;
+    std::cerr << "Sending metadata: " << mdata << "\n";
 
   m_face.put(mdata);
 }
@@ -110,7 +118,7 @@
   BOOST_ASSERT(m_store.size() > 0);
 
   if (m_options.isVerbose)
-    std::cerr << "Interest: " << interest << std::endl;
+    std::cerr << "Interest: " << interest << "\n";
 
   const Name& name = interest.getName();
   shared_ptr<Data> data;
@@ -129,13 +137,13 @@
 
   if (data != nullptr) {
     if (m_options.isVerbose)
-      std::cerr << "Data: " << *data << std::endl;
+      std::cerr << "Data: " << *data << "\n";
 
     m_face.put(*data);
   }
   else {
     if (m_options.isVerbose)
-      std::cerr << "Interest cannot be satisfied, sending Nack" << std::endl;
+      std::cerr << "Interest cannot be satisfied, sending Nack\n";
     m_face.put(lp::Nack(interest));
   }
 }
@@ -146,7 +154,7 @@
   BOOST_ASSERT(m_store.empty());
 
   if (!m_options.isQuiet)
-    std::cerr << "Loading input ..." << std::endl;
+    std::cerr << "Loading input ...\n";
 
   std::vector<uint8_t> buffer(m_options.maxSegmentSize);
   while (is.good()) {
@@ -174,15 +182,7 @@
   }
 
   if (!m_options.isQuiet)
-    std::cerr << "Created " << m_store.size() << " chunks for prefix " << m_prefix << std::endl;
-}
-
-void
-Producer::onRegisterFailed(const Name& prefix, const std::string& reason)
-{
-  std::cerr << "ERROR: Failed to register prefix '"
-            << prefix << "' (" << reason << ")" << std::endl;
-  m_face.shutdown();
+    std::cerr << "Created " << m_store.size() << " chunks for prefix " << m_prefix << "\n";
 }
 
 } // namespace chunks
diff --git a/tools/chunks/putchunks/producer.hpp b/tools/chunks/putchunks/producer.hpp
index 77365ed..aad6245 100644
--- a/tools/chunks/putchunks/producer.hpp
+++ b/tools/chunks/putchunks/producer.hpp
@@ -96,9 +96,6 @@
   void
   processSegmentInterest(const Interest& interest);
 
-  void
-  onRegisterFailed(const Name& prefix, const std::string& reason);
-
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   std::vector<shared_ptr<Data>> m_store;
 
diff --git a/tools/peek/ndnpeek/ndnpeek.hpp b/tools/peek/ndnpeek/ndnpeek.hpp
index 998d049..afb0ea7 100644
--- a/tools/peek/ndnpeek/ndnpeek.hpp
+++ b/tools/peek/ndnpeek/ndnpeek.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2019,  Regents of the University of California,
+ * Copyright (c) 2014-2021,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -113,7 +113,7 @@
   const PeekOptions m_options;
   Face& m_face;
   Scheduler m_scheduler;
-  time::steady_clock::TimePoint m_sendTime;
+  time::steady_clock::time_point m_sendTime;
   ScopedPendingInterestHandle m_pendingInterest;
   scheduler::ScopedEventId m_timeoutEvent;
   Result m_result = Result::UNKNOWN;
diff --git a/tools/ping/client/main.cpp b/tools/ping/client/main.cpp
index 590c2db..f49c972 100644
--- a/tools/ping/client/main.cpp
+++ b/tools/ping/client/main.cpp
@@ -47,12 +47,9 @@
     , m_signalSetInt(m_face.getIoService(), SIGINT)
     , m_signalSetQuit(m_face.getIoService(), SIGQUIT)
   {
-    m_signalSetInt.async_wait(bind(&Runner::afterIntSignal, this, _1));
-    m_signalSetQuit.async_wait(bind(&Runner::afterQuitSignal, this, _1));
-
-    m_ping.afterFinish.connect([this] {
-        this->cancel();
-      });
+    m_signalSetInt.async_wait([this] (const auto& err, int) { onInterruptSignal(err); });
+    m_signalSetQuit.async_wait([this] (const auto& err, int) { onQuitSignal(err); });
+    m_ping.afterFinish.connect([this] { cancel(); });
   }
 
   int
@@ -68,8 +65,7 @@
     }
 
     Statistics statistics = m_statisticsCollector.computeStatistics();
-
-    std::cout << statistics << std::endl;
+    std::cout << statistics << "\n";
 
     if (statistics.nReceived == statistics.nSent) {
       return 0;
@@ -89,7 +85,7 @@
   }
 
   void
-  afterIntSignal(const boost::system::error_code& errorCode)
+  onInterruptSignal(const boost::system::error_code& errorCode)
   {
     if (errorCode == boost::asio::error::operation_aborted) {
       return;
@@ -99,14 +95,14 @@
   }
 
   void
-  afterQuitSignal(const boost::system::error_code& errorCode)
+  onQuitSignal(const boost::system::error_code& errorCode)
   {
     if (errorCode == boost::asio::error::operation_aborted) {
       return;
     }
 
     m_statisticsCollector.computeStatistics().printSummary(std::cout);
-    m_signalSetQuit.async_wait(bind(&Runner::afterQuitSignal, this, _1));
+    m_signalSetQuit.async_wait([this] (const auto& err, int) { onQuitSignal(err); });
   }
 
 private:
@@ -203,7 +199,7 @@
     }
 
     if (optVm.count("version") > 0) {
-      std::cout << "ndnping " << tools::VERSION << std::endl;
+      std::cout << "ndnping " << tools::VERSION << "\n";
       exit(0);
     }
 
@@ -211,14 +207,14 @@
       options.prefix = Name(optVm["prefix"].as<std::string>());
     }
     else {
-      std::cerr << "ERROR: No prefix specified" << std::endl;
+      std::cerr << "ERROR: No prefix specified\n";
       usage(visibleOptDesc);
     }
 
     options.interval = time::milliseconds(optVm["interval"].as<time::milliseconds::rep>());
     if (options.interval < getMinimumPingInterval()) {
-      std::cerr << "ERROR: Specified ping interval is less than the minimum " <<
-                   getMinimumPingInterval() << std::endl;
+      std::cerr << "ERROR: Specified ping interval is less than the minimum "
+                << getMinimumPingInterval() << "\n";
       usage(visibleOptDesc);
     }
 
@@ -226,7 +222,7 @@
 
     if (optVm.count("count") > 0) {
       if (options.nPings <= 0) {
-        std::cerr << "ERROR: Number of ping must be positive" << std::endl;
+        std::cerr << "ERROR: Number of ping must be positive\n";
         usage(visibleOptDesc);
       }
     }
@@ -238,7 +234,7 @@
     if (optVm.count("identifier") > 0) {
       bool isIdentifierAcceptable = std::all_of(identifier.begin(), identifier.end(), &isalnum);
       if (identifier.empty() || !isIdentifierAcceptable) {
-        std::cerr << "ERROR: Unacceptable client identifier" << std::endl;
+        std::cerr << "ERROR: Unacceptable client identifier\n";
         usage(visibleOptDesc);
       }
 
@@ -254,11 +250,11 @@
     }
   }
   catch (const po::error& e) {
-    std::cerr << "ERROR: " << e.what() << std::endl;
+    std::cerr << "ERROR: " << e.what() << "\n";
     usage(visibleOptDesc);
   }
 
-  std::cout << "PING " << options.prefix << std::endl;
+  std::cout << "PING " << options.prefix << "\n";
   return Runner(options).run();
 }
 
diff --git a/tools/ping/client/ping.cpp b/tools/ping/client/ping.cpp
index e3cb20f..c52ed10 100644
--- a/tools/ping/client/ping.cpp
+++ b/tools/ping/client/ping.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2019,  Arizona Board of Regents.
+ * Copyright (c) 2014-2021,  Arizona Board of Regents.
  *
  * This file is part of ndn-tools (Named Data Networking Essential Tools).
  * See AUTHORS.md for complete list of ndn-tools authors and contributors.
@@ -22,6 +22,7 @@
  */
 
 #include "ping.hpp"
+
 #include <ndn-cxx/util/random.hpp>
 
 namespace ndn {
@@ -65,9 +66,9 @@
 
   auto now = time::steady_clock::now();
   m_face.expressInterest(interest,
-                         bind(&Ping::onData, this, m_nextSeq, now),
-                         bind(&Ping::onNack, this, _2, m_nextSeq, now),
-                         bind(&Ping::onTimeout, this, m_nextSeq));
+    [=, seq = m_nextSeq] (auto&&...) { onData(seq, now); },
+    [=, seq = m_nextSeq] (auto&&, const auto& nack) { onNack(seq, now, nack); },
+    [=, seq = m_nextSeq] (auto&&...) { onTimeout(seq); });
 
   ++m_nSent;
   ++m_nextSeq;
@@ -82,7 +83,7 @@
 }
 
 void
-Ping::onData(uint64_t seq, const time::steady_clock::TimePoint& sendTime)
+Ping::onData(uint64_t seq, const time::steady_clock::time_point& sendTime)
 {
   time::nanoseconds rtt = time::steady_clock::now() - sendTime;
   afterData(seq, rtt);
@@ -90,7 +91,7 @@
 }
 
 void
-Ping::onNack(const lp::Nack& nack, uint64_t seq, const time::steady_clock::TimePoint& sendTime)
+Ping::onNack(uint64_t seq, const time::steady_clock::time_point& sendTime, const lp::Nack& nack)
 {
   time::nanoseconds rtt = time::steady_clock::now() - sendTime;
   afterNack(seq, rtt, nack.getHeader());
diff --git a/tools/ping/client/ping.hpp b/tools/ping/client/ping.hpp
index 48f2485..a44ca0c 100644
--- a/tools/ping/client/ping.hpp
+++ b/tools/ping/client/ping.hpp
@@ -108,8 +108,6 @@
 private:
   /**
    * @brief Creates a ping Name from the sequence number
-   *
-   * @param seq ping sequence number
    */
   Name
   makePingName(uint64_t seq) const;
@@ -122,30 +120,18 @@
 
   /**
    * @brief Called when a Data packet is received in response to a ping
-   *
-   * @param seq ping sequence number
-   * @param sendTime time ping sent
    */
   void
-  onData(uint64_t seq, const time::steady_clock::TimePoint& sendTime);
+  onData(uint64_t seq, const time::steady_clock::time_point& sendTime);
 
   /**
    * @brief Called when a Nack is received in response to a ping
-   *
-   * @param interest NDN interest
-   * @param nack returned nack
-   * @param seq ping sequence number
-   * @param sendTime time ping sent
    */
   void
-  onNack(const lp::Nack& nack, uint64_t seq,
-         const time::steady_clock::TimePoint& sendTime);
+  onNack(uint64_t seq, const time::steady_clock::time_point& sendTime, const lp::Nack& nack);
 
   /**
    * @brief Called when ping timed out
-   *
-   * @param interest NDN interest
-   * @param seq ping sequence number
    */
   void
   onTimeout(uint64_t seq);
diff --git a/tools/ping/client/statistics-collector.cpp b/tools/ping/client/statistics-collector.cpp
index 7954e64..6c29405 100644
--- a/tools/ping/client/statistics-collector.cpp
+++ b/tools/ping/client/statistics-collector.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2015-2016,  Arizona Board of Regents.
+/*
+ * Copyright (c) 2015-2021,  Arizona Board of Regents.
  *
  * This file is part of ndn-tools (Named Data Networking Essential Tools).
  * See AUTHORS.md for complete list of ndn-tools authors and contributors.
@@ -16,9 +16,9 @@
  * You should have received a copy of the GNU General Public License along with
  * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  *
- * @author: Eric Newberry <enewberry@email.arizona.edu>
- * @author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
- * @author: Teng Liang <philoliang@email.arizona.edu>
+ * @author Eric Newberry <enewberry@email.arizona.edu>
+ * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
+ * @author Teng Liang <philoliang@email.arizona.edu>
  */
 
 #include "statistics-collector.hpp"
@@ -39,9 +39,9 @@
   , m_sumRtt(0.0)
   , m_sumRttSquared(0.0)
 {
-  m_ping.afterData.connect(bind(&StatisticsCollector::recordData, this, _2));
-  m_ping.afterNack.connect(bind(&StatisticsCollector::recordNack, this));
-  m_ping.afterTimeout.connect(bind(&StatisticsCollector::recordTimeout, this));
+  m_ping.afterData.connect([this] (auto&&, Rtt rtt) { recordData(rtt); });
+  m_ping.afterNack.connect([this] (auto&&...) { recordNack(); });
+  m_ping.afterTimeout.connect([this] (auto&&...) { recordTimeout(); });
 }
 
 void
@@ -53,7 +53,6 @@
   double rttMs = rtt.count();
 
   m_minRtt = std::min(m_minRtt, rttMs);
-
   m_maxRtt = std::max(m_maxRtt, rttMs);
 
   m_sumRtt += rttMs;
@@ -74,7 +73,7 @@
 }
 
 Statistics
-StatisticsCollector::computeStatistics()
+StatisticsCollector::computeStatistics() const
 {
   Statistics statistics;
 
@@ -123,7 +122,7 @@
        << " ms";
   }
 
-  return os << std::endl;
+  return os << "\n";
 }
 
 std::ostream&
diff --git a/tools/ping/client/statistics-collector.hpp b/tools/ping/client/statistics-collector.hpp
index ee67f80..9622717 100644
--- a/tools/ping/client/statistics-collector.hpp
+++ b/tools/ping/client/statistics-collector.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2015-2016,  Arizona Board of Regents.
+/*
+ * Copyright (c) 2015-2021,  Arizona Board of Regents.
  *
  * This file is part of ndn-tools (Named Data Networking Essential Tools).
  * See AUTHORS.md for complete list of ndn-tools authors and contributors.
@@ -16,9 +16,9 @@
  * You should have received a copy of the GNU General Public License along with
  * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  *
- * @author: Eric Newberry <enewberry@email.arizona.edu>
- * @author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
- * @author: Teng Liang <philoliang@email.arizona.edu>
+ * @author Eric Newberry <enewberry@email.arizona.edu>
+ * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
+ * @author Teng Liang <philoliang@email.arizona.edu>
  */
 
 #ifndef NDN_TOOLS_PING_CLIENT_STATISTICS_COLLECTOR_HPP
@@ -41,7 +41,7 @@
   int nSent;                                    //!< number of pings sent
   int nReceived;                                //!< number of pings received
   int nNacked;                                  //!< number of nacks received
-  time::steady_clock::TimePoint pingStartTime;  //!< time pings started
+  time::steady_clock::time_point pingStartTime; //!< time pings started
   double minRtt;                                //!< minimum round trip time
   double maxRtt;                                //!< maximum round trip time
   double packetLossRate;                        //!< packet loss rate
@@ -67,16 +67,14 @@
   StatisticsCollector(Ping& ping, const Options& options);
 
   /**
-   * @brief Compute ping statistics as structure
+   * @brief Compute and return ping statistics as structure
    */
   Statistics
-  computeStatistics();
+  computeStatistics() const;
 
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   /**
    * @brief Called when a Data packet is received
-   *
-   * @param rtt round trip time
    */
   void
   recordData(Rtt rtt);
@@ -99,7 +97,7 @@
   int m_nSent;
   int m_nReceived;
   int m_nNacked;
-  time::steady_clock::TimePoint m_pingStartTime;
+  time::steady_clock::time_point m_pingStartTime;
   double m_minRtt;
   double m_maxRtt;
   double m_sumRtt;
diff --git a/tools/ping/client/tracer.cpp b/tools/ping/client/tracer.cpp
index 9510af8..7db5085 100644
--- a/tools/ping/client/tracer.cpp
+++ b/tools/ping/client/tracer.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2015-2016,  Arizona Board of Regents.
+/*
+ * Copyright (c) 2015-2021,  Arizona Board of Regents.
  *
  * This file is part of ndn-tools (Named Data Networking Essential Tools).
  * See AUTHORS.md for complete list of ndn-tools authors and contributors.
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU General Public License along with
  * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  *
- * @author: Eric Newberry <enewberry@email.arizona.edu>
- * @author: Teng Liang <philoliang@email.arizona.edu>
+ * @author Eric Newberry <enewberry@email.arizona.edu>
+ * @author Teng Liang <philoliang@email.arizona.edu>
  */
 
 #include "tracer.hpp"
@@ -29,9 +29,9 @@
 Tracer::Tracer(Ping& ping, const Options& options)
   : m_options(options)
 {
-  ping.afterData.connect(bind(&Tracer::onData, this, _1, _2));
-  ping.afterNack.connect(bind(&Tracer::onNack, this, _1, _2, _3));
-  ping.afterTimeout.connect(bind(&Tracer::onTimeout, this, _1));
+  ping.afterData.connect(FORWARD_TO_MEM_FN(onData));
+  ping.afterNack.connect(FORWARD_TO_MEM_FN(onNack));
+  ping.afterTimeout.connect(FORWARD_TO_MEM_FN(onTimeout));
 }
 
 void
@@ -42,7 +42,7 @@
   }
 
   std::cout << "content from " << m_options.prefix << ": seq=" << seq << " time="
-            << rtt.count() << " ms" << std::endl;
+            << rtt.count() << " ms\n";
 }
 
 void
@@ -53,7 +53,7 @@
   }
 
   std::cout << "nack from " << m_options.prefix << ": seq=" << seq << " time="
-            << rtt.count() << " ms" << " reason=" << header.getReason() << std::endl;
+            << rtt.count() << " ms" << " reason=" << header.getReason() << "\n";
 }
 
 void
@@ -63,13 +63,13 @@
     std::cout << time::toIsoString(time::system_clock::now()) << " - ";
   }
 
-  std::cout << "timeout from " << m_options.prefix << ": seq=" << seq << std::endl;
+  std::cout << "timeout from " << m_options.prefix << ": seq=" << seq << "\n";
 }
 
 void
-Tracer::onError(std::string msg)
+Tracer::onError(const std::string& msg)
 {
-  std::cerr << "ERROR: " << msg << std::endl;
+  std::cerr << "ERROR: " << msg << "\n";
 }
 
 } // namespace client
diff --git a/tools/ping/client/tracer.hpp b/tools/ping/client/tracer.hpp
index ca75fb5..b6b4812 100644
--- a/tools/ping/client/tracer.hpp
+++ b/tools/ping/client/tracer.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2015-2016,  Arizona Board of Regents.
+/*
+ * Copyright (c) 2015-2021,  Arizona Board of Regents.
  *
  * This file is part of ndn-tools (Named Data Networking Essential Tools).
  * See AUTHORS.md for complete list of ndn-tools authors and contributors.
@@ -16,8 +16,8 @@
  * You should have received a copy of the GNU General Public License along with
  * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  *
- * @author: Eric Newberry <enewberry@email.arizona.edu>
- * @author: Teng Liang <philoliang@email.arizona.edu>
+ * @author Eric Newberry <enewberry@email.arizona.edu>
+ * @author Teng Liang <philoliang@email.arizona.edu>
  */
 
 #ifndef NDN_TOOLS_PING_CLIENT_TRACER_HPP
@@ -74,7 +74,7 @@
    * @brief Outputs ping errors to cerr
    */
   void
-  onError(std::string msg);
+  onError(const std::string& msg);
 
 private:
   const Options& m_options;
diff --git a/tools/ping/server/ping-server.cpp b/tools/ping/server/ping-server.cpp
index ad8177c..5ceeb76 100644
--- a/tools/ping/server/ping-server.cpp
+++ b/tools/ping/server/ping-server.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2015-2019,  Arizona Board of Regents.
+ * Copyright (c) 2015-2021,  Arizona Board of Regents.
  *
  * This file is part of ndn-tools (Named Data Networking Essential Tools).
  * See AUTHORS.md for complete list of ndn-tools authors and contributors.
@@ -42,12 +42,11 @@
 void
 PingServer::start()
 {
-  m_registeredPrefix = m_face.setInterestFilter(
-                       Name(m_options.prefix).append("ping"),
-                       bind(&PingServer::onInterest, this, _2),
-                       [] (const auto&, const auto& reason) {
-                         NDN_THROW(std::runtime_error("Failed to register prefix: " + reason));
-                       });
+  m_registeredPrefix = m_face.setInterestFilter(Name(m_options.prefix).append("ping"),
+                         [this] (const auto&, const auto& interest) { onInterest(interest); },
+                         [] (const auto&, const auto& reason) {
+                           NDN_THROW(std::runtime_error("Failed to register prefix: " + reason));
+                         });
 }
 
 void
diff --git a/tools/ping/server/tracer.cpp b/tools/ping/server/tracer.cpp
index 51b191c..c6b30b9 100644
--- a/tools/ping/server/tracer.cpp
+++ b/tools/ping/server/tracer.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2015-2018,  Arizona Board of Regents.
+ * Copyright (c) 2015-2021,  Arizona Board of Regents.
  *
  * This file is part of ndn-tools (Named Data Networking Essential Tools).
  * See AUTHORS.md for complete list of ndn-tools authors and contributors.
@@ -29,20 +29,15 @@
   : m_options(options)
 {
   if (!m_options.wantQuiet) {
-    pingServer.afterReceive.connect([this] (const Name& name) { onReceive(name); });
+    pingServer.afterReceive.connect([this] (const Name& name) {
+      if (m_options.wantTimestamp) {
+        std::cout << time::toIsoString(time::system_clock::now()) << " - ";
+      }
+      std::cout << "interest received: seq=" << name.at(-1) << "\n";
+    });
   }
 }
 
-void
-Tracer::onReceive(const Name& name)
-{
-  if (m_options.wantTimestamp) {
-    std::cout << time::toIsoString(time::system_clock::now()) << " - ";
-  }
-
-  std::cout << "interest received: seq=" << name.at(-1) << std::endl;
-}
-
 } // namespace server
 } // namespace ping
 } // namespace ndn
diff --git a/tools/ping/server/tracer.hpp b/tools/ping/server/tracer.hpp
index b8b6952..a84b72e 100644
--- a/tools/ping/server/tracer.hpp
+++ b/tools/ping/server/tracer.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2015,  Arizona Board of Regents.
+/*
+ * Copyright (c) 2015-2021,  Arizona Board of Regents.
  *
  * This file is part of ndn-tools (Named Data Networking Essential Tools).
  * See AUTHORS.md for complete list of ndn-tools authors and contributors.
@@ -31,20 +31,13 @@
 namespace server {
 
 /**
- * @brief logs ping responses
+ * @brief Logs ping responses
  */
 class Tracer : noncopyable
 {
 public:
   Tracer(PingServer& pingServer, const Options& options);
 
-  /**
-   * @brief Prints ping information when interest received
-   * @param name interest name received
-   */
-  void
-  onReceive(const Name& name);
-
 private:
   const Options& m_options;
 };