util: specialize std::hash<> for ethernet::Address

Change-Id: Id1263b8716d242f36e563b9aebbd2bb695fd4e5b
diff --git a/src/util/ethernet.cpp b/src/util/ethernet.cpp
index ae52005..34420b3 100644
--- a/src/util/ethernet.cpp
+++ b/src/util/ethernet.cpp
@@ -27,6 +27,8 @@
 
 #include "ethernet.hpp"
 
+#include <boost/functional/hash.hpp>
+
 #include <cstdio>
 #include <ostream>
 
@@ -137,3 +139,12 @@
 } // namespace ethernet
 } // namespace util
 } // namespace ndn
+
+
+using ndn::util::ethernet::Address;
+
+std::size_t
+std::hash<Address>::operator()(const Address& a) const noexcept
+{
+  return boost::hash_range(a.cbegin(), a.cend());
+}
diff --git a/src/util/ethernet.hpp b/src/util/ethernet.hpp
index ac7cb94..ef227d4 100644
--- a/src/util/ethernet.hpp
+++ b/src/util/ethernet.hpp
@@ -30,6 +30,7 @@
 
 #include <array>
 #include <cstdint>
+#include <functional>
 #include <string>
 
 namespace ndn {
@@ -111,4 +112,17 @@
 } // namespace util
 } // namespace ndn
 
+
+namespace std {
+
+// specialize std::hash<> for ethernet::Address
+template<>
+struct hash<ndn::util::ethernet::Address>
+{
+  size_t
+  operator()(const ndn::util::ethernet::Address& a) const noexcept;
+};
+
+} // namespace std
+
 #endif // NDN_UTIL_ETHERNET_HPP
diff --git a/tests/unit-tests/util/ethernet.cpp b/tests/unit-tests/util/ethernet.cpp
index 2077f5a..35c0dee 100644
--- a/tests/unit-tests/util/ethernet.cpp
+++ b/tests/unit-tests/util/ethernet.cpp
@@ -102,6 +102,13 @@
                     ethernet::Address());
 }
 
+BOOST_AUTO_TEST_CASE(StdHash)
+{
+  // make sure we can use ethernet::Address as key type in std::unordered_map
+  std::hash<ethernet::Address> h;
+  BOOST_CHECK_NO_THROW(h(ethernet::getDefaultMulticastAddress()));
+}
+
 BOOST_AUTO_TEST_SUITE_END()
 
 } // namespace util