HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GA_Edge.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GA_Edge.h (GA Library, C++)
7  *
8  * COMMENTS: This class represents an edge as two point offsets.
9  * Comparisons treat the edge as undirected.
10  */
11 
12 #pragma once
13 
14 #ifndef __GA_Edge__
15 #define __GA_Edge__
16 
17 #include "GA_API.h"
18 #include "GA_Types.h"
19 #include <SYS/SYS_Hash.h>
20 
21 #include <limits.h>
22 #include <stddef.h>
23 #include <stdint.h>
24 
25 template<typename T,bool DIRECTED>
26 class GA_EdgeT
27 {
28 public:
30 
31  GA_EdgeT() : myP0(T(-1)), myP1(T(-1)) {}
32  GA_EdgeT(T pt0, T pt1) : myP0(pt0), myP1(pt1) {}
33 
34  T p0() const { return myP0; }
35  T &p0() { return myP0; }
36  T p1() const { return myP1; }
37  T &p1() { return myP1; }
38 
40  {
41  return sizeof(*this);
42  }
43 
44  bool isValid() const
45  { return GAisValid(myP0) && GAisValid(myP1); }
46 
47  /// Return whether this edge is the same undirected edge as the given edge.
48  bool operator==(const ThisType & e) const
49  {
50  if (DIRECTED)
51  {
52  return (myP0 == e.myP0 && myP1 == e.myP1);
53  }
54  else
55  {
56  return (myP0 == e.myP0 && myP1 == e.myP1)
57  || (myP0 == e.myP1 && myP1 == e.myP0);
58  }
59  }
60  bool operator!=(const ThisType & e) const
61  {
62  return !(*this == e);
63  }
64 
65  /// Hash function
66  size_t hash() const
67  {
68  size_t hash_val;
69  if (DIRECTED || myP0 < myP1)
70  {
71  hash_val = GA_Size(myP0);
72  GA_EdgeT::hashCombine(hash_val, GA_Size(myP1));
73  }
74  else
75  {
76  hash_val = GA_Size(myP1);
77  GA_EdgeT::hashCombine(hash_val, GA_Size(myP0));
78  }
79  return hash_val;
80  }
81 
82 private:
83 
84  ///
85  /// Old Boost hash_combine() implementation, prior to Boost 1.81.
86  /// For backwards compatibility of edge hash values.
87  ///
88  static void hashCombine(size_t &seed, GA_Size const &value)
89  {
90  auto hash_value = GA_EdgeT::hashValueSigned(value);
91 
92  // On macOS, size_t != hboost::uint64_t
93  const size_t m = UINT64_C(0xc6a4a7935bd1e995);
94  const int r = 47;
95 
96  hash_value *= m;
97  hash_value ^= hash_value >> r;
98  hash_value *= m;
99 
100  seed ^= hash_value;
101  seed *= m;
102 
103  // Completely arbitrary number, to prevent 0's
104  // from hashing to 0.
105  seed += 0xe6546b64;
106  }
107 
108  static size_t hashValueSigned(GA_Size val)
109  {
110  const unsigned int size_t_bits =
111  std::numeric_limits<size_t>::digits;
112  // ceiling(std::numeric_limits<T>::digits / size_t_bits) - 1
113  const int length = (std::numeric_limits<T>::digits - 1)
114  / static_cast<int>(size_t_bits);
115 
116  size_t seed = 0;
117  GA_Size positive = val < 0 ? -1 - val : val;
118 
119  // Hopefully, this loop can be unrolled.
120  for(unsigned int i = length * size_t_bits; i > 0; i -= size_t_bits)
121  {
122  seed ^= (size_t) (positive >> i) + (seed<<6) + (seed>>2);
123  }
124  seed ^= (size_t) val + (seed<<6) + (seed>>2);
125 
126  return seed;
127  }
128 
129  T myP0;
130  T myP1;
131 };
132 
133 template<typename T,bool DIRECTED>
135 {
136  return edge.hash();
137 }
138 
139 // Specialize the GA_EdgeT template for the known edge types
142 
145 
146 namespace std {
147 template<typename T,bool DIRECTED>
148 struct hash<GA_EdgeT<T,DIRECTED> >
149 {
151  typedef size_t result_type;
152 
153  size_t operator()(const GA_EdgeT<T,DIRECTED> &edge) const
154  {
155  return edge.hash();
156  }
157 };
158 }
159 
160 #endif
GA_EdgeT(T pt0, T pt1)
Definition: GA_Edge.h:32
bool operator==(const ThisType &e) const
Return whether this edge is the same undirected edge as the given edge.
Definition: GA_Edge.h:48
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:795
T & p1()
Definition: GA_Edge.h:37
size_t operator()(const GA_EdgeT< T, DIRECTED > &edge) const
Definition: GA_Edge.h:153
SYS_FORCE_INLINE bool GAisValid(GA_Size v)
Definition: GA_Types.h:655
exint GA_Size
Defines the bit width for index and offset types in GA.
Definition: GA_Types.h:236
bool isValid() const
Definition: GA_Edge.h:44
GA_EdgeT< T, DIRECTED > ThisType
Definition: GA_Edge.h:29
T & p0()
Definition: GA_Edge.h:35
GA_EdgeT< T, DIRECTED > argument_type
Definition: GA_Edge.h:150
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
long long int64
Definition: SYS_Types.h:116
T p1() const
Definition: GA_Edge.h:36
SYS_FORCE_INLINE size_t hash_value(const GA_EdgeT< T, DIRECTED > &edge)
Definition: GA_Edge.h:134
size_t hash() const
Hash function.
Definition: GA_Edge.h:66
int64 getMemoryUsage() const
Definition: GA_Edge.h:39
GLuint GLfloat * val
Definition: glcorearb.h:1608
GA_EdgeT()
Definition: GA_Edge.h:31
bool operator!=(const ThisType &e) const
Definition: GA_Edge.h:60
Definition: core.h:1131
T p0() const
Definition: GA_Edge.h:34
GLboolean r
Definition: glcorearb.h:1222