table: simplify PIT with C++11 features

refs #2100

Change-Id: I1159761d9439f0a2ff9f6463f89f39372a696e48
diff --git a/.waf-tools/type_traits.py b/.waf-tools/type_traits.py
new file mode 100644
index 0000000..fc1ffbf
--- /dev/null
+++ b/.waf-tools/type_traits.py
@@ -0,0 +1,19 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+#
+# Copyright (c) 2014, Regents of the University of California
+#
+# GPL 3.0 license, see the COPYING.md file for more information
+
+from waflib import Configure
+
+IS_MOVE_CONSTRUCTIBLE_CHECK = '''
+#include <type_traits>
+static_assert(std::is_move_constructible<int>::value, "");
+'''
+
+def configure(conf):
+    if conf.check_cxx(msg='Checking for std::is_move_constructible',
+                      fragment=IS_MOVE_CONSTRUCTIBLE_CHECK,
+                      features='cxx', mandatory=False):
+        conf.define('HAVE_IS_MOVE_CONSTRUCTIBLE', 1)
+        conf.env['HAVE_IS_MOVE_CONSTRUCTIBLE'] = True
diff --git a/daemon/fw/best-route-strategy2.cpp b/daemon/fw/best-route-strategy2.cpp
index 323bb3d..044f5e9 100644
--- a/daemon/fw/best-route-strategy2.cpp
+++ b/daemon/fw/best-route-strategy2.cpp
@@ -63,7 +63,7 @@
 
   if (wantUnused) {
     // NextHop must not have unexpired OutRecord
-    pit::OutRecordCollection::const_iterator outRecord = pitEntry->getOutRecord(upstream);
+    pit::OutRecordCollection::const_iterator outRecord = pitEntry->getOutRecord(*upstream);
     if (outRecord != pitEntry->getOutRecords().end() &&
         outRecord->getExpiry() > now) {
       return false;
@@ -92,7 +92,7 @@
   for (fib::NextHopList::const_iterator it = nexthops.begin(); it != nexthops.end(); ++it) {
     if (!predicate_NextHop_eligible(pitEntry, *it, currentDownstream))
       continue;
-    pit::OutRecordCollection::const_iterator outRecord = pitEntry->getOutRecord(it->getFace());
+    pit::OutRecordCollection::const_iterator outRecord = pitEntry->getOutRecord(*it->getFace());
     BOOST_ASSERT(outRecord != pitEntry->getOutRecords().end());
     if (outRecord->getLastRenewed() < earliestRenewed) {
       found = it;
diff --git a/daemon/fw/forwarder.cpp b/daemon/fw/forwarder.cpp
index d8bc19f..1cd1d16 100644
--- a/daemon/fw/forwarder.cpp
+++ b/daemon/fw/forwarder.cpp
@@ -260,8 +260,8 @@
   }
 
   // PIT match
-  shared_ptr<pit::DataMatchResult> pitMatches = m_pit.findAllDataMatches(data);
-  if (pitMatches->begin() == pitMatches->end()) {
+  pit::DataMatchResult pitMatches = m_pit.findAllDataMatches(data);
+  if (pitMatches.begin() == pitMatches.end()) {
     // goto Data unsolicited pipeline
     this->onDataUnsolicited(inFace, data);
     return;
@@ -272,9 +272,7 @@
 
   std::set<shared_ptr<Face> > pendingDownstreams;
   // foreach PitEntry
-  for (pit::DataMatchResult::iterator it = pitMatches->begin();
-       it != pitMatches->end(); ++it) {
-    shared_ptr<pit::Entry> pitEntry = *it;
+  for (const shared_ptr<pit::Entry>& pitEntry : pitMatches) {
     NFD_LOG_DEBUG("onIncomingData matching=" << pitEntry->getName());
 
     // cancel unsatisfy & straggler timer
@@ -298,7 +296,7 @@
 
     // mark PIT satisfied
     pitEntry->deleteInRecords();
-    pitEntry->deleteOutRecord(inFace.shared_from_this());
+    pitEntry->deleteOutRecord(inFace);
 
     // set PIT straggler timer
     this->setStragglerTimer(pitEntry, true, data.getFreshnessPeriod());
@@ -437,8 +435,7 @@
   }
   else {
     // insert outgoing Nonce of a specific face
-    pit::OutRecordCollection::const_iterator outRecord =
-      pitEntry.getOutRecord(upstream->shared_from_this());
+    pit::OutRecordCollection::const_iterator outRecord = pitEntry.getOutRecord(*upstream);
     if (outRecord != pitEntry.getOutRecords().end()) {
       m_deadNonceList.add(pitEntry.getName(), outRecord->getLastNonce());
     }
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);
diff --git a/tests/daemon/fw/ncc-strategy.cpp b/tests/daemon/fw/ncc-strategy.cpp
index 7d82b5f..09d54be 100644
--- a/tests/daemon/fw/ncc-strategy.cpp
+++ b/tests/daemon/fw/ncc-strategy.cpp
@@ -259,7 +259,7 @@
   shared_ptr<Data> data1 = makeData("ndn:/M4mBXCsd");
   data1->setFreshnessPeriod(time::milliseconds(5));
   strategy->beforeSatisfyInterest(pitEntry1, *face2, *data1);
-  pitEntry1->deleteOutRecord(face2);
+  pitEntry1->deleteOutRecord(*face2);
   pitEntry1->deleteInRecords();
   limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(10));
 
diff --git a/tests/daemon/table/pit.cpp b/tests/daemon/table/pit.cpp
index 8e73a12..dcf5053 100644
--- a/tests/daemon/table/pit.cpp
+++ b/tests/daemon/table/pit.cpp
@@ -77,7 +77,7 @@
   BOOST_CHECK_LE(in1->getExpiry() - in1->getLastRenewed()
                  - interest1->getInterestLifetime(),
                  (after1 - before1));
-  BOOST_CHECK(in1 == entry.getInRecord(face1));
+  BOOST_CHECK(in1 == entry.getInRecord(*face1));
 
   // insert OutRecord
   time::steady_clock::TimePoint before2 = time::steady_clock::now();
@@ -94,7 +94,7 @@
   BOOST_CHECK_LE(out1->getExpiry() - out1->getLastRenewed()
                  - interest1->getInterestLifetime(),
                  (after2 - before2));
-  BOOST_CHECK(out1 == entry.getOutRecord(face1));
+  BOOST_CHECK(out1 == entry.getOutRecord(*face1));
 
   // update InRecord
   time::steady_clock::TimePoint before3 = time::steady_clock::now();
@@ -118,7 +118,7 @@
   BOOST_CHECK_EQUAL(in3->getFace(), face2);
 
   // get InRecord
-  pit::InRecordCollection::const_iterator in4 = entry.getInRecord(face1);
+  pit::InRecordCollection::const_iterator in4 = entry.getInRecord(*face1);
   BOOST_REQUIRE(in4 != entry.getInRecords().end());
   BOOST_CHECK_EQUAL(in4->getFace(), face1);
 
@@ -126,7 +126,7 @@
   entry.deleteInRecords();
   const pit::InRecordCollection& inRecords5 = entry.getInRecords();
   BOOST_CHECK_EQUAL(inRecords5.size(), 0);
-  BOOST_CHECK(entry.getInRecord(face1) == entry.getInRecords().end());
+  BOOST_CHECK(entry.getInRecord(*face1) == entry.getInRecords().end());
 
   // insert another OutRecord
   pit::OutRecordCollection::iterator out2 =
@@ -136,16 +136,16 @@
   BOOST_CHECK_EQUAL(out2->getFace(), face2);
 
   // get OutRecord
-  pit::OutRecordCollection::const_iterator out3 = entry.getOutRecord(face1);
+  pit::OutRecordCollection::const_iterator out3 = entry.getOutRecord(*face1);
   BOOST_REQUIRE(out3 != entry.getOutRecords().end());
   BOOST_CHECK_EQUAL(out3->getFace(), face1);
 
   // delete OutRecord
-  entry.deleteOutRecord(face2);
+  entry.deleteOutRecord(*face2);
   const pit::OutRecordCollection& outRecords4 = entry.getOutRecords();
   BOOST_REQUIRE_EQUAL(outRecords4.size(), 1);
   BOOST_CHECK_EQUAL(outRecords4.begin()->getFace(), face1);
-  BOOST_CHECK(entry.getOutRecord(face2) == entry.getOutRecords().end());
+  BOOST_CHECK(entry.getOutRecord(*face2) == entry.getOutRecords().end());
 }
 
 BOOST_AUTO_TEST_CASE(EntryNonce)
@@ -419,17 +419,15 @@
 
   shared_ptr<Data> data = makeData(nameABCD);
 
-  shared_ptr<pit::DataMatchResult> matches = pit.findAllDataMatches(*data);
+  pit::DataMatchResult matches = pit.findAllDataMatches(*data);
 
   bool hasA   = false;
   bool hasAB  = false;
   bool hasABC = false;
   bool hasD   = false;
 
-  for (pit::DataMatchResult::iterator it = matches->begin();
-       it != matches->end(); ++it) {
+  for (const shared_ptr<pit::Entry>& entry : matches) {
     ++count;
-    shared_ptr<pit::Entry> entry = *it;
 
     if (entry->getName().equals(nameA ))
       hasA   = true;
diff --git a/wscript b/wscript
index dac9432..eb9ca79 100644
--- a/wscript
+++ b/wscript
@@ -36,7 +36,7 @@
     opt.load(['compiler_cxx', 'gnu_dirs'])
     opt.load(['boost', 'unix-socket', 'dependency-checker', 'websocket',
               'default-compiler-flags', 'coverage', 'pch', 'boost-kqueue',
-              'doxygen', 'sphinx_build'],
+              'doxygen', 'sphinx_build', 'type_traits'],
              tooldir=['.waf-tools'])
 
     nfdopt = opt.add_option_group('NFD Options')
@@ -59,7 +59,7 @@
     conf.load(['compiler_cxx', 'gnu_dirs',
                'default-compiler-flags', 'pch', 'boost-kqueue',
                'boost', 'dependency-checker', 'websocket',
-               'doxygen', 'sphinx_build'])
+               'doxygen', 'sphinx_build', 'type_traits'])
 
     conf.find_program('bash', var='BASH')