Ocular Engine
VoidCast.hpp
1 
17 #pragma once
18 #ifndef __H__OCULAR_UTILITIES_VOID_CAST__H__
19 #define __H__OCULAR_UTILITIES_VOID_CAST__H__
20 
21 #include <type_traits>
22 
23 //------------------------------------------------------------------------------------------
24 
70 template<typename T>
72 {
73  T var;
74  void* ptr;
75 };
76 
77 template<typename T>
78 static typename std::enable_if<std::is_trivial<T>::value, T>::type void_cast(void* val)
79 {
80  if(sizeof(T) <= sizeof(void*))
81  {
82  union OCULAR_INTERNAL_VoidCast<T> vcintern;
83  vcintern.ptr = val;
84 
85  return vcintern.var;
86  }
87  else
88  {
89  // Hit on double, int64_t, etc. on 32-bit builds
90  return *(T*)(val);
91  }
92 }
93 
94 template<typename T>
95 static typename std::enable_if<std::is_trivial<T>::value, void*>::type void_cast(T const& t)
96 {
97  if(sizeof(T) <= sizeof(void*))
98  {
99  union OCULAR_INTERNAL_VoidCast<T> vcintern;
100  vcintern.var = t;
101 
102  return vcintern.ptr;
103  }
104  else
105  {
106  // Hit on double, int64_t, etc. on 32-bit builds
107  return (void*)(&t);
108  }
109 }
110 
111 template<typename T>
112 static typename std::enable_if<!std::is_trivial<T>::value, T>::type void_cast(void* val)
113 {
114  // Potentially undefined behavior (if sizeof(T) != data size at address pointed to in void*)
115  // But unions only allow trivial members, so no other option
116  return *(T*)(val);
117 }
118 
119 template<typename T>
120 static typename std::enable_if<!std::is_trivial<T>::value, void*>::type void_cast(T const& t)
121 {
122  // Potentially undefined behavior (if sizeof(T) != data size at address pointed to in void*)
123  // But unions only allow trivial members, so no other option
124  return (void*)(&t);
125 }
126 
127 //------------------------------------------------------------------------------------------
128 
129 #endif
Definition: VoidCast.hpp:71