table: simplify PIT with C++11 features

refs #2100

Change-Id: I1159761d9439f0a2ff9f6463f89f39372a696e48
diff --git a/daemon/table/pit-entry.cpp b/daemon/table/pit-entry.cpp
index 35cc2e0..da7c6ed 100644
--- a/daemon/table/pit-entry.cpp
+++ b/daemon/table/pit-entry.cpp
@@ -43,61 +43,30 @@
   return m_interest->getName();
 }
 
-const InRecordCollection&
-Entry::getInRecords() const
-{
-  return m_inRecords;
-}
-
-const OutRecordCollection&
-Entry::getOutRecords() const
-{
-  return m_outRecords;
-}
-
-static inline bool
-predicate_InRecord_isLocal(const InRecord& inRecord)
-{
-  return inRecord.getFace()->isLocal();
-}
-
 bool
 Entry::hasLocalInRecord() const
 {
-  InRecordCollection::const_iterator it = std::find_if(
-    m_inRecords.begin(), m_inRecords.end(), &predicate_InRecord_isLocal);
-  return it != m_inRecords.end();
-}
-
-static inline bool
-predicate_FaceRecord_Face(const FaceRecord& faceRecord, const Face* face)
-{
-  return faceRecord.getFace().get() == face;
-}
-
-static inline bool
-predicate_FaceRecord_ne_Face_and_unexpired(const FaceRecord& faceRecord,
-  const Face* face, const time::steady_clock::TimePoint& now)
-{
-  return faceRecord.getFace().get() != face && faceRecord.getExpiry() >= now;
+  return std::any_of(m_inRecords.begin(), m_inRecords.end(),
+                     [] (const InRecord& inRecord) { return inRecord.getFace()->isLocal(); });
 }
 
 bool
 Entry::canForwardTo(const Face& face) const
 {
-  OutRecordCollection::const_iterator outIt = std::find_if(
-    m_outRecords.begin(), m_outRecords.end(),
-    bind(&predicate_FaceRecord_Face, _1, &face));
-  bool hasUnexpiredOutRecord = outIt != m_outRecords.end() &&
-                               outIt->getExpiry() >= time::steady_clock::now();
+  time::steady_clock::TimePoint now = time::steady_clock::now();
+
+  bool hasUnexpiredOutRecord = std::any_of(m_outRecords.begin(), m_outRecords.end(),
+    [&face, &now] (const OutRecord& outRecord) {
+      return outRecord.getFace().get() == &face && outRecord.getExpiry() >= now;
+    });
   if (hasUnexpiredOutRecord) {
     return false;
   }
 
-  InRecordCollection::const_iterator inIt = std::find_if(
-    m_inRecords.begin(), m_inRecords.end(),
-    bind(&predicate_FaceRecord_ne_Face_and_unexpired, _1, &face, time::steady_clock::now()));
-  bool hasUnexpiredOtherInRecord = inIt != m_inRecords.end();
+  bool hasUnexpiredOtherInRecord = std::any_of(m_inRecords.begin(), m_inRecords.end(),
+    [&face, &now] (const InRecord& inRecord) {
+      return inRecord.getFace().get() != &face && inRecord.getExpiry() >= now;
+    });
   if (!hasUnexpiredOtherInRecord) {
     return false;
   }
@@ -133,10 +102,9 @@
 
   int dnw = DUPLICATE_NONCE_NONE;
 
-  for (InRecordCollection::const_iterator it = m_inRecords.begin();
-       it != m_inRecords.end(); ++it) {
-    if (it->getLastNonce() == nonce) {
-      if (it->getFace().get() == &face) {
+  for (const InRecord& inRecord : m_inRecords) {
+    if (inRecord.getLastNonce() == nonce) {
+      if (inRecord.getFace().get() == &face) {
         dnw |= DUPLICATE_NONCE_IN_SAME;
       }
       else {
@@ -145,10 +113,9 @@
     }
   }
 
-  for (OutRecordCollection::const_iterator it = m_outRecords.begin();
-       it != m_outRecords.end(); ++it) {
-    if (it->getLastNonce() == nonce) {
-      if (it->getFace().get() == &face) {
+  for (const OutRecord& outRecord : m_outRecords) {
+    if (outRecord.getLastNonce() == nonce) {
+      if (outRecord.getFace().get() == &face) {
         dnw |= DUPLICATE_NONCE_OUT_SAME;
       }
       else {
@@ -163,10 +130,10 @@
 InRecordCollection::iterator
 Entry::insertOrUpdateInRecord(shared_ptr<Face> face, const Interest& interest)
 {
-  InRecordCollection::iterator it = std::find_if(m_inRecords.begin(),
-    m_inRecords.end(), bind(&predicate_FaceRecord_Face, _1, face.get()));
+  auto it = std::find_if(m_inRecords.begin(), m_inRecords.end(),
+    [&face] (const InRecord& inRecord) { return inRecord.getFace() == face; });
   if (it == m_inRecords.end()) {
-    m_inRecords.push_front(InRecord(face));
+    m_inRecords.emplace_front(face);
     it = m_inRecords.begin();
   }
 
@@ -175,10 +142,10 @@
 }
 
 InRecordCollection::const_iterator
-Entry::getInRecord(shared_ptr<Face> face) const
+Entry::getInRecord(const Face& face) const
 {
   return std::find_if(m_inRecords.begin(), m_inRecords.end(),
-                      bind(&predicate_FaceRecord_Face, _1, face.get()));
+    [&face] (const InRecord& inRecord) { return inRecord.getFace().get() == &face; });
 }
 
 void
@@ -190,10 +157,10 @@
 OutRecordCollection::iterator
 Entry::insertOrUpdateOutRecord(shared_ptr<Face> face, const Interest& interest)
 {
-  OutRecordCollection::iterator it = std::find_if(m_outRecords.begin(),
-    m_outRecords.end(), bind(&predicate_FaceRecord_Face, _1, face.get()));
+  auto it = std::find_if(m_outRecords.begin(), m_outRecords.end(),
+    [&face] (const OutRecord& outRecord) { return outRecord.getFace() == face; });
   if (it == m_outRecords.end()) {
-    m_outRecords.push_front(OutRecord(face));
+    m_outRecords.emplace_front(face);
     it = m_outRecords.begin();
   }
 
@@ -202,34 +169,29 @@
 }
 
 OutRecordCollection::const_iterator
-Entry::getOutRecord(shared_ptr<Face> face) const
+Entry::getOutRecord(const Face& face) const
 {
   return std::find_if(m_outRecords.begin(), m_outRecords.end(),
-                      bind(&predicate_FaceRecord_Face, _1, face.get()));
+    [&face] (const OutRecord& outRecord) { return outRecord.getFace().get() == &face; });
 }
 
 void
-Entry::deleteOutRecord(shared_ptr<Face> face)
+Entry::deleteOutRecord(const Face& face)
 {
-  OutRecordCollection::iterator it = std::find_if(m_outRecords.begin(),
-    m_outRecords.end(), bind(&predicate_FaceRecord_Face, _1, face.get()));
+  auto it = std::find_if(m_outRecords.begin(), m_outRecords.end(),
+    [&face] (const OutRecord& outRecord) { return outRecord.getFace().get() == &face; });
   if (it != m_outRecords.end()) {
     m_outRecords.erase(it);
   }
 }
 
-static inline bool
-predicate_FaceRecord_unexpired(const FaceRecord& faceRecord, const time::steady_clock::TimePoint& now)
-{
-  return faceRecord.getExpiry() >= now;
-}
-
 bool
 Entry::hasUnexpiredOutRecords() const
 {
-  OutRecordCollection::const_iterator it = std::find_if(m_outRecords.begin(),
-    m_outRecords.end(), bind(&predicate_FaceRecord_unexpired, _1, time::steady_clock::now()));
-  return it != m_outRecords.end();
+  time::steady_clock::TimePoint now = time::steady_clock::now();
+
+  return std::any_of(m_outRecords.begin(), m_outRecords.end(),
+    [&now] (const OutRecord& outRecord) { return outRecord.getExpiry() >= now; });
 }
 
 } // namespace pit
diff --git a/daemon/table/pit-entry.hpp b/daemon/table/pit-entry.hpp
index 5a691de..8fcf4a7 100644
--- a/daemon/table/pit-entry.hpp
+++ b/daemon/table/pit-entry.hpp
@@ -130,7 +130,7 @@
    *  \return an iterator to the InRecord, or .end if it does not exist
    */
   InRecordCollection::const_iterator
-  getInRecord(shared_ptr<Face> face) const;
+  getInRecord(const Face& face) const;
 
   /// deletes all InRecords
   void
@@ -152,11 +152,11 @@
    *  \return an iterator to the OutRecord, or .end if it does not exist
    */
   OutRecordCollection::const_iterator
-  getOutRecord(shared_ptr<Face> face) const;
+  getOutRecord(const Face& face) const;
 
   /// deletes one OutRecord for face if exists
   void
-  deleteOutRecord(shared_ptr<Face> face);
+  deleteOutRecord(const Face& face);
 
   /** \return true if there is one or more unexpired OutRecords
    */
@@ -187,6 +187,18 @@
   return *m_interest;
 }
 
+inline const InRecordCollection&
+Entry::getInRecords() const
+{
+  return m_inRecords;
+}
+
+inline const OutRecordCollection&
+Entry::getOutRecords() const
+{
+  return m_outRecords;
+}
+
 } // namespace pit
 } // namespace nfd
 
diff --git a/daemon/table/pit.cpp b/daemon/table/pit.cpp
index 21b4321..13a11d4 100644
--- a/daemon/table/pit.cpp
+++ b/daemon/table/pit.cpp
@@ -24,8 +24,17 @@
  */
 
 #include "pit.hpp"
+#include <type_traits>
 
 namespace nfd {
+namespace pit {
+
+#if HAVE_IS_MOVE_CONSTRUCTIBLE
+static_assert(std::is_move_constructible<DataMatchResult>::value,
+              "DataMatchResult must be MoveConstructible");
+#endif // HAVE_IS_MOVE_CONSTRUCTIBLE
+
+} // namespace pit
 
 Pit::Pit(NameTree& nameTree)
   : m_nameTree(nameTree)
@@ -37,79 +46,48 @@
 {
 }
 
-static inline bool
-predicate_NameTreeEntry_hasPitEntry(const name_tree::Entry& entry)
-{
-  return entry.hasPitEntries();
-}
-
-static inline bool
-predicate_PitEntry_similar_Interest(const shared_ptr<pit::Entry>& entry,
-                                    const Interest& interest)
-{
-  const Interest& pi = entry->getInterest();
-  return pi.getName().equals(interest.getName()) &&
-         pi.getMinSuffixComponents() == interest.getMinSuffixComponents() &&
-         pi.getMaxSuffixComponents() == interest.getMaxSuffixComponents() &&
-         pi.getPublisherPublicKeyLocator() == interest.getPublisherPublicKeyLocator() &&
-         pi.getExclude() == interest.getExclude() &&
-         pi.getChildSelector() == interest.getChildSelector() &&
-         pi.getMustBeFresh() == interest.getMustBeFresh();
-}
-
 std::pair<shared_ptr<pit::Entry>, bool>
 Pit::insert(const Interest& interest)
 {
-  // - first lookup() the Interest Name in the NameTree, which will creates all
+  // first lookup() the Interest Name in the NameTree, which will creates all
   // the intermedia nodes, starting from the shortest prefix.
-  // - if it is guaranteed that this Interest already has a NameTree Entry, we
-  // could use findExactMatch() instead.
-  // - Alternatively, we could try to do findExactMatch() first, if not found,
-  // then do lookup().
   shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.lookup(interest.getName());
   BOOST_ASSERT(static_cast<bool>(nameTreeEntry));
 
-  const std::vector<shared_ptr<pit::Entry> >& pitEntries = nameTreeEntry->getPitEntries();
+  const std::vector<shared_ptr<pit::Entry>>& pitEntries = nameTreeEntry->getPitEntries();
 
   // then check if this Interest is already in the PIT entries
-  std::vector<shared_ptr<pit::Entry> >::const_iterator it =
-    std::find_if(pitEntries.begin(), pitEntries.end(),
-                 bind(&predicate_PitEntry_similar_Interest, _1, cref(interest)));
+  auto it = std::find_if(pitEntries.begin(), pitEntries.end(),
+                         [&interest] (const shared_ptr<pit::Entry>& entry) {
+                           return entry->getInterest().getName() == interest.getName() &&
+                                  entry->getInterest().getSelectors() == interest.getSelectors();
+                         });
+  if (it != pitEntries.end()) {
+    return { *it, false };
+  }
 
-  if (it != pitEntries.end())
-    {
-      return std::make_pair(*it, false);
-    }
-  else
-    {
-      shared_ptr<pit::Entry> entry = make_shared<pit::Entry>(interest);
-      nameTreeEntry->insertPitEntry(entry);
-
-      // Increase m_nItmes only if we create a new PIT Entry
-      m_nItems++;
-
-      return std::make_pair(entry, true);
-    }
+  shared_ptr<pit::Entry> entry = make_shared<pit::Entry>(interest);
+  nameTreeEntry->insertPitEntry(entry);
+  m_nItems++;
+  return { entry, true };
 }
 
-shared_ptr<pit::DataMatchResult>
+pit::DataMatchResult
 Pit::findAllDataMatches(const Data& data) const
 {
-  shared_ptr<pit::DataMatchResult> result = make_shared<pit::DataMatchResult>();
+  pit::DataMatchResult matches;
 
-  for (NameTree::const_iterator it =
-       m_nameTree.findAllMatches(data.getName(), &predicate_NameTreeEntry_hasPitEntry);
-       it != m_nameTree.end(); it++)
-    {
-      const std::vector<shared_ptr<pit::Entry> >& pitEntries = it->getPitEntries();
-      for (size_t i = 0; i < pitEntries.size(); i++)
-        {
-          if (pitEntries[i]->getInterest().matchesData(data))
-            result->push_back(pitEntries[i]);
-        }
+  auto allMatchesBegin = m_nameTree.findAllMatches(data.getName(),
+    [] (const name_tree::Entry& entry) { return entry.hasPitEntries(); });
+  // TODO: change to range-based for, after #2155
+  for (auto it = allMatchesBegin; it != m_nameTree.end(); ++it) {
+    for (const shared_ptr<pit::Entry>& pitEntry : it->getPitEntries()) {
+      if (pitEntry->getInterest().matchesData(data))
+        matches.emplace_back(pitEntry);
     }
+  }
 
-  return result;
+  return matches;
 }
 
 void
diff --git a/daemon/table/pit.hpp b/daemon/table/pit.hpp
index 41cf520..00d90ca 100644
--- a/daemon/table/pit.hpp
+++ b/daemon/table/pit.hpp
@@ -1,11 +1,12 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014  Regents of the University of California,
- *                     Arizona Board of Regents,
- *                     Colorado State University,
- *                     University Pierre & Marie Curie, Sorbonne University,
- *                     Washington University in St. Louis,
- *                     Beijing Institute of Technology
+ * Copyright (c) 2014,  Regents of the University of California,
+ *                      Arizona Board of Regents,
+ *                      Colorado State University,
+ *                      University Pierre & Marie Curie, Sorbonne University,
+ *                      Washington University in St. Louis,
+ *                      Beijing Institute of Technology,
+ *                      The University of Memphis
  *
  * This file is part of NFD (Named Data Networking Forwarding Daemon).
  * See AUTHORS.md for complete list of NFD authors and contributors.
@@ -20,7 +21,7 @@
  *
  * You should have received a copy of the GNU General Public License along with
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
+ */
 
 #ifndef NFD_DAEMON_TABLE_PIT_HPP
 #define NFD_DAEMON_TABLE_PIT_HPP
@@ -33,16 +34,16 @@
 
 /** \class DataMatchResult
  *  \brief an unordered iterable of all PIT entries matching Data
+ *
  *  This type shall support:
  *    iterator<shared_ptr<pit::Entry>> begin()
  *    iterator<shared_ptr<pit::Entry>> end()
  */
-typedef std::vector<shared_ptr<pit::Entry> > DataMatchResult;
+typedef std::vector<shared_ptr<pit::Entry>> DataMatchResult;
 
 } // namespace pit
 
-/** \class Pit
- *  \brief represents the PIT
+/** \brief represents the Interest Table
  */
 class Pit : noncopyable
 {
@@ -52,27 +53,27 @@
 
   ~Pit();
 
-  /**
-   *  \brief Get the number of items stored in the PIT.
+  /** \return number of entries
    */
   size_t
   size() const;
 
-  /** \brief inserts a PIT entry for prefix
+  /** \brief inserts a PIT entry for Interest
+   *
    *  If an entry for exact same name and selectors exists, that entry is returned.
-   *  \return{ the entry, and true for new entry, false for existing entry }
+   *  \return the entry, and true for new entry, false for existing entry
    */
   std::pair<shared_ptr<pit::Entry>, bool>
   insert(const Interest& interest);
 
   /** \brief performs a Data match
-   *  \return{ an iterable of all PIT entries matching data }
+   *  \return an iterable of all PIT entries matching data
    */
-  shared_ptr<pit::DataMatchResult>
+  pit::DataMatchResult
   findAllDataMatches(const Data& data) const;
 
   /**
-   *  \brief Erase a PIT Entry
+   *  \brief erases a PIT Entry
    */
   void
   erase(shared_ptr<pit::Entry> pitEntry);