adjacency-list: improve constness of equality operator

refs: #4331

Change-Id: Ia57a82859abb2a32b22a7dbff471d1843d8237f0
diff --git a/src/adjacency-list.cpp b/src/adjacency-list.cpp
index f2a8302..eead545 100644
--- a/src/adjacency-list.cpp
+++ b/src/adjacency-list.cpp
@@ -84,32 +84,36 @@
   return adj;
 }
 
-static bool
-compareAdjacent(const Adjacent& adjacent1, const Adjacent& adjacent2)
-{
-  return adjacent1.getName() < adjacent2.getName();
-}
-
 bool
-AdjacencyList::operator==(AdjacencyList& adl)
+AdjacencyList::operator==(AdjacencyList& adl) const
 {
-  if (getSize() != adl.getSize()) {
+  if (m_adjList.size() != adl.getSize()) {
     return false;
   }
-  m_adjList.sort(compareAdjacent);
-  adl.getAdjList().sort(compareAdjacent);
-  uint32_t equalAdjCount = 0;
-  std::list<Adjacent>& adjList2 = adl.getAdjList();
-  std::list<Adjacent>::iterator it1;
-  std::list<Adjacent>::iterator it2;
-  for (it1 = m_adjList.begin(), it2 = adjList2.begin();
-       it1 != m_adjList.end(); it1++, it2++) {
-    if (!((*it1) == (*it2))) {
-      break;
+
+  auto comparator =
+    [] (const Adjacent* lhs, const Adjacent* rhs) {
+      return *lhs < *rhs;
+  };
+
+  std::vector<const Adjacent*> ourList;
+  std::transform(m_adjList.begin(), m_adjList.end(),
+                 std::back_inserter(ourList), std::pointer_traits<const Adjacent*>::pointer_to);
+
+  std::vector<const Adjacent*> theirList;
+  std::transform(adl.getAdjList().begin(), adl.getAdjList().end(),
+                 std::back_inserter(theirList), std::pointer_traits<const Adjacent*>::pointer_to);
+
+  std::sort(ourList.begin(), ourList.end(), std::bind(comparator, _1, _2));
+  std::sort(theirList.begin(), theirList.end(), std::bind(comparator, _1, _2));
+
+  for (size_t i = 0; i < ourList.size(); i++) {
+    if (*(ourList[i]) != *(theirList[i])) {
+      std::cout << *ourList[i] << ":" << *theirList[i];
+      return false;
     }
-    equalAdjCount++;
   }
-  return equalAdjCount == getSize();
+  return true;
 }
 
 int32_t
diff --git a/src/adjacency-list.hpp b/src/adjacency-list.hpp
index 66a2710..5ed5012 100644
--- a/src/adjacency-list.hpp
+++ b/src/adjacency-list.hpp
@@ -126,7 +126,7 @@
   getAdjacent(const ndn::Name& adjName);
 
   bool
-  operator==(AdjacencyList& adl);
+  operator==(AdjacencyList& adl) const;
 
   size_t
   getSize()
diff --git a/src/adjacent.cpp b/src/adjacent.cpp
index 78c71b5..7109f21 100644
--- a/src/adjacent.cpp
+++ b/src/adjacent.cpp
@@ -72,14 +72,26 @@
           std::numeric_limits<double>::epsilon());
 }
 
+bool
+Adjacent::operator<(const Adjacent& adjacent) const
+{
+  return (m_name < adjacent.getName()) ||
+         (m_linkCost < adjacent.getLinkCost());
+}
+
+std::ostream&
+operator<<(std::ostream& os, const Adjacent& adjacent)
+{
+  os << "Adjacent: " << adjacent.m_name << "\n Connecting FaceUri: " << adjacent.m_faceUri
+     << "\n Link cost: " << adjacent.m_linkCost << "\n Status: " << adjacent.m_status
+     << "\n Interest Timed Out: " << adjacent.m_interestTimedOutNo << std::endl;
+  return os;
+}
+
 void
 Adjacent::writeLog()
 {
-  _LOG_DEBUG("Adjacent : " << m_name);
-  _LOG_DEBUG("Connecting FaceUri: " << m_faceUri);
-  _LOG_DEBUG("Link Cost: " << m_linkCost);
-  _LOG_DEBUG("Status: " << m_status);
-  _LOG_DEBUG("Interest Timed out: " << m_interestTimedOutNo);
+  _LOG_DEBUG(*this);
 }
 
 } // namespace nlsr
diff --git a/src/adjacent.hpp b/src/adjacent.hpp
index 499e45e..dcdefc8 100644
--- a/src/adjacent.hpp
+++ b/src/adjacent.hpp
@@ -130,6 +130,15 @@
   bool
   operator==(const Adjacent& adjacent) const;
 
+  bool
+  operator!=(const Adjacent& adjacent) const
+  {
+    return !(*this == adjacent);
+  }
+
+  bool
+  operator<(const Adjacent& adjacent) const;
+
   inline bool
   compare(const ndn::Name& adjacencyName)
   {
@@ -168,8 +177,14 @@
   /*! m_faceId The NFD-assigned ID for the neighbor, used to
    * determine whether a Face is available */
   uint64_t m_faceId;
+
+  friend std::ostream&
+  operator<<(std::ostream& os, const Adjacent& adjacent);
 };
 
+std::ostream&
+operator<<(std::ostream& os, const Adjacent& adjacent);
+
 } // namespace nlsr
 
 #endif // NLSR_ADJACENT_HPP
diff --git a/tests/test-adjacent.cpp b/tests/test-adjacent.cpp
index e494682..8bd0c26 100644
--- a/tests/test-adjacent.cpp
+++ b/tests/test-adjacent.cpp
@@ -46,6 +46,25 @@
   BOOST_CHECK(adjacent1 == adjacent2);
 }
 
+BOOST_AUTO_TEST_CASE(OperatorLessThan)
+{
+  const ndn::Name ADJ_NAME_1 = "name1";
+  const double ADJ_LINK_COST_1 = 1;
+  const ndn::Name ADJ_NAME_2 = "name2";
+  const double ADJ_LINK_COST_2 = 2;
+  Adjacent adjacent1(ADJ_NAME_1);
+  Adjacent adjacent2(ADJ_NAME_1);
+  adjacent1.setLinkCost(ADJ_LINK_COST_1);
+  adjacent2.setLinkCost(ADJ_LINK_COST_2);
+
+  BOOST_CHECK(adjacent1 < adjacent2);
+
+  Adjacent adjacent3(ADJ_NAME_2);
+  adjacent3.setLinkCost(ADJ_LINK_COST_1);
+
+  BOOST_CHECK(adjacent1 < adjacent3);
+}
+
 BOOST_AUTO_TEST_CASE(Accessors)
 {
   const ndn::Name ADJ_NAME_1 = "name1";