#pragma once #include #include "allocator.h" #include "template_tools.h" namespace stingray_plugin_foundation { // A replacement for std::pair that is allocator aware, so that any // of the pair members that need to be constructed with an allocator is. // // The default template implementation is used when none of the types // are allocator aware. template struct Pair { typedef Pair this_type; typedef FIRST first_type; typedef SECOND second_type; Pair() : first(first_type()), second(second_type()) {} Pair(Allocator &) : first(first_type()), second(second_type()) {} Pair(const this_type &t) : first(t.first), second(t.second) {} Pair(const first_type &f, const second_type &s) : first(f), second(s) {} void swap(this_type &right) { std::swap(first, right.first); std::swap(second, right.second); } template void serialize(STREAM &s) {s & first & second;} first_type first; second_type second; }; // Template specialization to use when the first type is allocator aware. template struct Pair { ALLOCATOR_AWARE; typedef Pair this_type; typedef FIRST first_type; typedef SECOND second_type; Pair(Allocator &a) : first(a), second(second_type()) {} Pair(const first_type &f, const second_type &s) : first(f), second(s) {} void swap(this_type &right) { std::swap(first, right.first); std::swap(second, right.second); } template void serialize(STREAM &s) {s & first & second;} first_type first; second_type second; }; // Template specialization to use when the second type is allocator aware. template struct Pair { ALLOCATOR_AWARE; typedef Pair this_type; typedef FIRST first_type; typedef SECOND second_type; Pair(Allocator &a) : first(first_type()), second(a) {} Pair(const first_type &f, const second_type &s) : first(f), second(s) {} void swap(this_type &right) { std::swap(first, right.first); std::swap(second, right.second); } template void serialize(STREAM &s) {s & first & second;} first_type first; second_type second; }; // Template specialization to use when both types are allocator aware. template struct Pair { ALLOCATOR_AWARE; typedef Pair this_type; typedef FIRST first_type; typedef SECOND second_type; Pair(Allocator &a) : first(a), second(a) {} Pair(const first_type &f, const second_type &s) : first(f), second(s) {} void swap(this_type &right) { std::swap(first, right.first); std::swap(second, right.second); } template void serialize(STREAM &s) {s & first & second;} first_type first; second_type second; }; // Comparison operators. template bool operator==(const Pair &left, const Pair &right) { return left.first == right.first && left.second == right.second; } template bool operator!=(const Pair &left, const Pair &right) { return !(left == right); } template bool operator<(const Pair &left, const Pair &right) { return left.first < right.first || (!(right.first < left.first) && left.second < right.second); } template bool operator>(const Pair &left, const Pair &right) { return (right < left); } template bool operator<=(const Pair &left, const Pair &right) { return !(right < left); } template bool operator>=(const Pair &left, const Pair &right) { return !(left < right); } // make_pair function that constructs a Pair of the right type template Pair make_pair(const FIRST &f, const SECOND &s) { return Pair(f, s); } // swap implementation for Pair template void swap(const Pair &left, const Pair &right) { left.swap(right); } // Declaration needed for GCC-based compilers unsigned murmur_hash( const void * key, int len, unsigned seed ); // Pair hashing template struct pair_hash { template unsigned operator()(const Pair &pair) const { HASH_FIRST hash_first; HASH_SECOND hash_second; const unsigned result[2] = { hash_first(pair.first), hash_second(pair.second) }; const unsigned hash = murmur_hash(&result[0], sizeof(result), 0); return hash; } }; } // namespace stingray_plugin_foundation