Skip to content

Instantly share code, notes, and snippets.

@PhDP
Last active January 25, 2016 02:18
Show Gist options
  • Save PhDP/85fe01ac7cc4a4a93a74 to your computer and use it in GitHub Desktop.
Save PhDP/85fe01ac7cc4a4a93a74 to your computer and use it in GitHub Desktop.
unordered_set using the shared_ptr's value
#include <iostream>
#include <string>
#include <memory>
#include <unordered_set>
#include <unordered_map>
#include <boost/functional/hash.hpp>
class my_class {
std::string m_name;
double m_a, m_b, m_c; // random stuff
size_t m_hash;
public:
my_class(const std::string name, double a = 0.0, double b = 0.0, double c = 0.0);
auto hash() const -> size_t;
friend auto operator==(const my_class&, const my_class&) -> bool;
friend auto operator!=(const my_class&, const my_class&) -> bool;
friend auto operator<<(std::ostream&, const my_class&) -> std::ostream&;
};
my_class::my_class(const std::string name, double a, double b, double c)
: m_name(name), m_a(a), m_b(b), m_c(c) {
m_hash = 42;
boost::hash_combine(m_hash, m_name);
boost::hash_combine(m_hash, m_a);
boost::hash_combine(m_hash, m_b);
boost::hash_combine(m_hash, m_c);
}
auto my_class::hash() const -> size_t {
return m_hash;
}
auto operator==(const my_class &a, const my_class &b) -> bool {
return a.m_hash == b.m_hash;
}
auto operator!=(const my_class &a, const my_class &b) -> bool {
return a.m_hash != b.m_hash;
}
auto operator<<(std::ostream &os, const my_class &c) -> std::ostream& {
os << c.m_name << '(' << c.m_a << ", " << c.m_b << ", " << c.m_c << ')';
return os;
}
/**
\brief Hashes a pointer to an object using the object's hash method.
*/
template <typename PTR>
struct ptr_hasher {
auto operator()(const PTR &x) const -> size_t {
return x->hash();
}
};
/**
\brief Compares two pointers by their object's value.
*/
template <typename PTR>
struct ptr_eq {
auto operator()(const PTR &x, const PTR &y) const -> bool {
return *x == *y;
}
};
template <typename PTR>
using ptr_hash_set = std::unordered_set<PTR, ptr_hasher<PTR>, ptr_eq<PTR>>;
template <typename PTR, typename T>
using ptr_hash_map = std::unordered_map<PTR, T, ptr_hasher<PTR>, ptr_eq<PTR>>;
auto main() -> int {
auto x = std::make_shared<my_class>(my_class("Foo", 0.5, 0.7));
auto y = std::make_shared<my_class>(my_class("Foo", 0.5, 0.7));
std::cout << "x == y: " << (x == y) << std::endl;
auto elems0 = std::unordered_set<std::shared_ptr<my_class>> { x, y, x };
std::cout << "Size of elems0: " << elems0.size() << std::endl;
auto elems1 = ptr_hash_set<std::shared_ptr<my_class>> { x, y, x };
std::cout << "Size of elems1: " << elems1.size() << std::endl;
auto z = std::make_shared<my_class>(my_class("Foo", 0.5, 0.7, 0.0));
std::cout << "z found in elems0: " << (elems0.find(z) != elems0.end()) << std::endl;
std::cout << "z found in elems1: " << (elems1.find(z) != elems1.end()) << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment