OSVR-Core
TypeSafeIdHash.h
Go to the documentation of this file.
1 
14 // Copyright 2016 Sensics, Inc.
15 //
16 // Licensed under the Apache License, Version 2.0 (the "License");
17 // you may not use this file except in compliance with the License.
18 // You may obtain a copy of the License at
19 //
20 // http://www.apache.org/licenses/LICENSE-2.0
21 //
22 // Unless required by applicable law or agreed to in writing, software
23 // distributed under the License is distributed on an "AS IS" BASIS,
24 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 // See the License for the specific language governing permissions and
26 // limitations under the License.
27 
28 #ifndef INCLUDED_TypeSafeIdHash_h_GUID_1F2936E7_99CB_4D82_9B8D_1D994E2E17F0
29 #define INCLUDED_TypeSafeIdHash_h_GUID_1F2936E7_99CB_4D82_9B8D_1D994E2E17F0
30 
31 // Internal Includes
32 #include <osvr/Util/TypeSafeId.h>
33 #include <osvr/Util/SizedInt.h>
34 
35 // Library/third-party includes
36 // - none
37 
38 // Standard includes
39 #include <functional>
40 #include <type_traits>
41 #include <cassert>
42 #include <climits>
43 
44 namespace std {
45 template <typename Tag> struct hash<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());
50  }
51 };
52 } // namespace std
53 
54 namespace osvr {
55 namespace util {
56  namespace detail {
57  template <typename NewType> class IntegerComposition {
58  public:
59  template <typename T> void operator+=(T newVal) {
60  auto extendedNewVal = static_cast<NewType>(newVal);
61  assert(
62  !full() &&
63  "Can't compose another integer when we're already full!");
64  if (0 == m_bytes) {
65  // first value
66  m_val = extendedNewVal;
67  } else {
68  // not the first - shift then xor (for safety in case the
69  // shifts are goofed up.)
70  m_val = (m_val << (CHAR_BIT * sizeof(T))) ^ extendedNewVal;
71  }
72  m_bytes += sizeof(T);
73 
74  assert(!overfull() && "Composition resulted in losing high "
75  "order bits - we're overfull!");
76  }
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); }
80 
81  private:
82  NewType m_val = 0;
83  std::size_t m_bytes = 0;
84  };
85  } // namespace detail
98  template <typename IdAggregate> struct HashIdAggregate;
99 
100  template <typename FirstTag, typename SecondTag>
102  std::pair<TypeSafeId<FirstTag>, TypeSafeId<SecondTag>>> {
103  using PairType = std::pair<TypeSafeId<FirstTag>, TypeSafeId<SecondTag>>;
104 
105  using First = TypeSafeId<FirstTag>; // PairType::first_type;
106  static_assert(std::is_same<First, typename PairType::first_type>::value,
107  "Internal consistency error");
108 
109  using Second = TypeSafeId<SecondTag>; // PairType::second_type;
110  static_assert(
111  std::is_same<Second, typename PairType::second_type>::value,
112  "Internal consistency error");
113 
114  using FirstWrapped = typename First::wrapped_type;
115  using SecondWrapped = typename Second::wrapped_type;
116  using NewType =
118  static_assert(
119  sizeof(FirstWrapped) + sizeof(SecondWrapped) <= sizeof(NewType),
120  "New type cannot accommodate the combined bits from both IDs!");
121 
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());
130  }
131  };
132 
133 } // namespace util
134 } // namespace osvr
135 
136 #endif // INCLUDED_TypeSafeIdHash_h_GUID_1F2936E7_99CB_4D82_9B8D_1D994E2E17F0
Definition: TypeSafeIdHash.h:57
Definition: RunLoopManager.h:42
The main namespace for all C++ elements of the framework, internal and external.
Definition: namespace_osvr.dox:3
Header providing an integer type by size.
Definition: TypeSafeIdHash.h:44
Definition: TypeSafeId.h:41
Template specialized for common aggregates of TypeSafeIds, with the intent that you can simply open n...
Definition: TypeSafeIdHash.h:98
typename detail::sized_int< minBytes, isSigned >::type sized_int_t
Alias providing an integer type (signed or unsigned, your choice) containing at least as many bytes a...
Definition: SizedInt.h:80
Definition: newuoa.h:1888
Definition: hash_map.h:20
size_t operator()(const PairType &x) const
Definition: TypeSafeIdHash.h:122
Header.