joboccara / NamedType

Implementation of strong types in C++
MIT License
773 stars 85 forks source link

Extending with boost hash to enable pair<NamedType, NamedType> as map key. #20

Open indiosmo opened 6 years ago

indiosmo commented 6 years ago

I have lots of maps with pairs as keys. Here is an example of using boost::hash to use pairs of NamedTypes as map keys if you think it's interesting enough to add to the documentation.


--------- named_type_hash.hpp ---------

#ifndef NAMED_TYPE_HASH_HPP
#define NAMED_TYPE_HASH_HPP

#include <type_traits>
#include <boost/container_hash/hash.hpp>
#include <named_type.hpp>

namespace fluent{

template <typename T, typename Parameter, template<typename> class... Skills>
std::enable_if_t<NamedType<T, Parameter, Skills...>::is_hashable, size_t>
hash_value(const NamedType<T, Parameter, Skills...>& x) {
  boost::hash<T> hasher;
  return hasher(x.get());
}

} // namespace fluent

#endif /* NAMED_TYPE_HASH_HPP */

--------- main.cpp ---------
#include <unordered_map>
#include <iostream>
#include <utility>
#include <named_type.hpp>
#include "named_type_hash.hpp"

int main(int, char**)
{
  using session_id = fluent::NamedType<int, struct SessionIdTag, fluent::Hashable, fluent::Comparable>;
  using order_id = fluent::NamedType<int, struct OrderIdTag, fluent::Hashable, fluent::Comparable>;
  using key = std::pair<session_id, order_id>;
  using map = std::unordered_map<key, std::string, boost::hash<key>>;

  map x;
  session_id a{1};
  order_id b{2};
  key k{a, b};

  x[k] = "test";

  if (auto it = x.find({session_id{1}, order_id{2}}); it != x.end()) { 
    std::cout << it->second << "\n";
  } else { 
    std::cout << "not found\n";
  } 

  return 0;
}