1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
4 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 **************************************************************************/
27 // File: vogl_traits.h
30 #include "vogl_core.h"
39 cMin = vogl::cINT32_MIN,
40 cMax = vogl::cINT32_MAX,
46 struct int_traits<int8>
50 cMin = vogl::cINT8_MIN,
51 cMax = vogl::cINT8_MAX,
56 struct int_traits<int16>
60 cMin = vogl::cINT16_MIN,
61 cMax = vogl::cINT16_MAX,
66 struct int_traits<int32>
70 cMin = vogl::cINT32_MIN,
71 cMax = vogl::cINT32_MAX,
77 struct int_traits<uint8>
82 cMax = vogl::cUINT8_MAX,
87 struct int_traits<uint16>
92 cMax = vogl::cUINT16_MAX,
97 struct int_traits<uint32>
102 cMax = vogl::cUINT32_MAX,
107 // scalar_type<T>::construct, construct_array, etc. ensures integral types are initialized to 0 when constructed
108 template <typename T>
115 static inline void construct(T *p)
117 helpers::construct(p);
119 static inline void construct(T *p, const T &init)
121 helpers::construct(p, init);
123 static inline void construct_array(T *p, uint n)
125 helpers::construct_array(p, n);
127 static inline void destruct(T *p)
129 helpers::destruct(p);
131 static inline void destruct_array(T *p, uint n)
133 helpers::destruct_array(p, n);
137 template <typename T>
138 struct scalar_type<T *>
144 static inline void construct(T **p)
146 memset(p, 0, sizeof(T *));
148 static inline void construct(T **p, T *init)
152 static inline void construct_array(T **p, uint n)
154 memset(p, 0, sizeof(T *) * n);
156 static inline void destruct(T **p)
160 static inline void destruct_array(T **p, uint n)
162 VOGL_NOTE_UNUSED(p), VOGL_NOTE_UNUSED(n);
166 #define VOGL_DEFINE_BUILT_IN_TYPE(X) \
167 template <> struct scalar_type<X> \
169 enum { cFlag = true }; \
170 static inline void construct(X *p) \
172 memset(p, 0, sizeof(X)); \
174 static inline void construct(X *p, const X &init) \
176 memcpy(p, &init, sizeof(X)); \
178 static inline void construct_array(X *p, uint n) \
180 memset(p, 0, sizeof(X) * n); \
182 static inline void destruct(X *p) \
184 VOGL_NOTE_UNUSED(p); \
186 static inline void destruct_array(X *p, uint n) \
188 VOGL_NOTE_UNUSED(p), VOGL_NOTE_UNUSED(n); \
192 VOGL_DEFINE_BUILT_IN_TYPE(bool)
193 VOGL_DEFINE_BUILT_IN_TYPE(char)
194 VOGL_DEFINE_BUILT_IN_TYPE(unsigned char)
195 VOGL_DEFINE_BUILT_IN_TYPE(short)
196 VOGL_DEFINE_BUILT_IN_TYPE(unsigned short)
197 VOGL_DEFINE_BUILT_IN_TYPE(int)
198 VOGL_DEFINE_BUILT_IN_TYPE(unsigned int)
199 VOGL_DEFINE_BUILT_IN_TYPE(long)
200 VOGL_DEFINE_BUILT_IN_TYPE(unsigned long)
202 VOGL_DEFINE_BUILT_IN_TYPE(long long)
203 VOGL_DEFINE_BUILT_IN_TYPE(unsigned long long)
205 VOGL_DEFINE_BUILT_IN_TYPE(__int64)
206 VOGL_DEFINE_BUILT_IN_TYPE(unsigned __int64)
208 VOGL_DEFINE_BUILT_IN_TYPE(float)
209 VOGL_DEFINE_BUILT_IN_TYPE(double)
210 VOGL_DEFINE_BUILT_IN_TYPE(long double)
212 #undef VOGL_DEFINE_BUILT_IN_TYPE
214 // See: http://erdani.org/publications/cuj-2004-06.pdf
216 template <typename T>
217 struct bitwise_movable
225 // Defines type Q as bitwise movable. Use with types requiring destruction. DO NOT use with types that contain pointers into themselves.
226 // Bitwise movable: type T may be safely moved to a new location via memcpy, without requiring the old copy to be destructed.
227 // However, the final version of the object (wherever it winds up in memory) must be eventually destructed (a single time, of course).
228 // Bitwise movable is a superset of bitwise copyable (all bitwise copyable types are also bitwise movable).
229 #define VOGL_DEFINE_BITWISE_MOVABLE(Q) \
230 template <> struct bitwise_movable<Q> \
232 enum { cFlag = true }; \
235 template <typename T>
236 struct bitwise_copyable
244 // Defines type Q as bitwise copyable. This is NOT SAFE for use with types that require destruction. DO NOT use with types that contain pointers into themselves.
245 // Bitwise copyable: type T may be safely and freely copied (duplicated) via memcpy, and *does not* require destruction.
246 #define VOGL_DEFINE_BITWISE_COPYABLE(Q) \
247 template <> struct bitwise_copyable<Q> \
249 enum { cFlag = true }; \
252 #define VOGL_IS_POD(T) __is_pod(T)
254 #define VOGL_IS_SCALAR_TYPE(T) (scalar_type<T>::cFlag)
256 #define VOGL_IS_BITWISE_COPYABLE(T) (VOGL_IS_SCALAR_TYPE(T) || VOGL_IS_POD(T) || (bitwise_copyable<T>::cFlag))
258 #define VOGL_IS_BITWISE_COPYABLE_OR_MOVABLE(T) (VOGL_IS_BITWISE_COPYABLE(T) || (bitwise_movable<T>::cFlag))
260 #define VOGL_HAS_DESTRUCTOR(T) ((!scalar_type<T>::cFlag) && (!__is_pod(T)))
262 // From yasli_traits.h:
263 // Credit goes to Boost;
264 // also found in the C++ Templates book by Vandevoorde and Josuttis
266 typedef char (&yes_t)[1];
267 typedef char (&no_t)[2];
270 yes_t class_test(int U::*);
272 no_t class_test(...);
279 value = (sizeof(class_test<T>(0)) == sizeof(yes_t))
283 template <typename T>
292 template <typename T>
293 struct is_pointer<T *>
301 VOGL_DEFINE_BITWISE_COPYABLE(empty_type);
302 VOGL_DEFINE_BITWISE_MOVABLE(empty_type);
306 // dst must be uninitialized memory, src will be destructed
307 template <typename T>
308 inline void move(T &dst, T &src)
310 if (VOGL_IS_BITWISE_COPYABLE_OR_MOVABLE(T))
311 memcpy(&dst, &src, sizeof(T));
314 construct(&dst, src);
319 // pDst must be uninitialized memory, pSrc will be destructed
320 template <typename T>
321 inline void move_array(T *pDst, T *pSrc, uint n)
323 if (VOGL_IS_BITWISE_COPYABLE_OR_MOVABLE(T))
324 memcpy(pDst, pSrc, sizeof(T) * n);
327 for (uint i = 0; i < n; i++)
329 construct(pDst + i, pSrc[i]);
335 // pDst must be uninitialized memory
336 template <typename T>
337 inline void copy_array(T *pDst, const T *pSrc, uint n)
339 if (VOGL_IS_BITWISE_COPYABLE(T))
340 memcpy(pDst, pSrc, sizeof(T) * n);
343 for (uint i = 0; i < n; i++)
344 construct(pDst + i, pSrc[i]);
349 // This doesn't invoke RTTI - but the return name is not portable so only use it for debugging purposes.
350 // You can use vogl::demangle() to demangle the returned string.
351 template <typename T>
352 inline const char *type_name()
354 return typeid(T).name();
357 template <typename T>
358 inline const char *type_name(const T &obj)
360 VOGL_NOTE_UNUSED(obj);
361 return typeid(T).name();