28 #ifndef INCLUDED_TypeSafeIdHash_h_GUID_1F2936E7_99CB_4D82_9B8D_1D994E2E17F0
29 #define INCLUDED_TypeSafeIdHash_h_GUID_1F2936E7_99CB_4D82_9B8D_1D994E2E17F0
40 #include <type_traits>
45 template <
typename Tag>
struct hash<
osvr::util::TypeSafeId<Tag>> {
46 using TypeSafeIdKeyType = osvr::util::TypeSafeId<Tag>;
47 using WrappedType =
typename TypeSafeIdKeyType::wrapped_type;
48 size_t operator()(
const TypeSafeIdKeyType &x)
const {
49 return std::hash<WrappedType>{}(x.value());
57 template <
typename NewType>
class IntegerComposition {
59 template <
typename T>
void operator+=(T newVal) {
60 auto extendedNewVal =
static_cast<NewType
>(newVal);
63 "Can't compose another integer when we're already full!");
66 m_val = extendedNewVal;
70 m_val = (m_val << (CHAR_BIT *
sizeof(T))) ^ extendedNewVal;
74 assert(!overfull() &&
"Composition resulted in losing high "
75 "order bits - we're overfull!");
77 NewType
get()
const {
return m_val; }
78 bool full()
const {
return m_bytes >=
sizeof(NewType); }
79 bool overfull()
const {
return m_bytes >
sizeof(NewType); }
83 std::size_t m_bytes = 0;
100 template <
typename FirstTag,
typename SecondTag>
102 std::pair<TypeSafeId<FirstTag>, TypeSafeId<SecondTag>>> {
103 using PairType = std::pair<TypeSafeId<FirstTag>, TypeSafeId<SecondTag>>;
105 using First = TypeSafeId<FirstTag>;
106 static_assert(std::is_same<First, typename PairType::first_type>::value,
107 "Internal consistency error");
109 using Second = TypeSafeId<SecondTag>;
111 std::is_same<Second, typename PairType::second_type>::value,
112 "Internal consistency error");
114 using FirstWrapped =
typename First::wrapped_type;
115 using SecondWrapped =
typename Second::wrapped_type;
119 sizeof(FirstWrapped) +
sizeof(SecondWrapped) <=
sizeof(NewType),
120 "New type cannot accommodate the combined bits from both IDs!");
122 size_t operator()(
const PairType &x)
const {
126 auto compose = detail::IntegerComposition<NewType>{};
127 compose += x.first.value();
128 compose += x.second.value();
129 return std::hash<NewType>{}(compose.get());
136 #endif // INCLUDED_TypeSafeIdHash_h_GUID_1F2936E7_99CB_4D82_9B8D_1D994E2E17F0
The main namespace for all C++ elements of the framework, internal and external.
Header providing an integer type by size.
typename detail::sized_int< minBytes, isSigned >::type sized_int_t