• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1///////////////////////////////////////////////////////////////////////////////////////////////////
2// OpenGL Mathematics Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
3///////////////////////////////////////////////////////////////////////////////////////////////////
4// Created : 2007-03-14
5// Updated : 2013-12-25
6// Licence : This source is under MIT License
7// File    : glm/gtx/bit.inl
8///////////////////////////////////////////////////////////////////////////////////////////////////
9
10#include "../detail/_vectorize.hpp"
11#include <limits>
12
13namespace glm
14{
15	template <typename genIType>
16	GLM_FUNC_QUALIFIER genIType mask
17	(
18		genIType const & count
19	)
20	{
21		return ((genIType(1) << (count)) - genIType(1));
22	}
23
24	VECTORIZE_VEC(mask)
25
26	// highestBitValue
27	template <typename genType>
28	GLM_FUNC_QUALIFIER genType highestBitValue
29	(
30		genType const & value
31	)
32	{
33		genType tmp = value;
34		genType result = genType(0);
35		while(tmp)
36		{
37			result = (tmp & (~tmp + 1)); // grab lowest bit
38			tmp &= ~result; // clear lowest bit
39		}
40		return result;
41	}
42
43	template <typename T, precision P>
44	GLM_FUNC_QUALIFIER detail::tvec2<int, P> highestBitValue
45	(
46		detail::tvec2<T, P> const & value
47	)
48	{
49		return detail::tvec2<int, P>(
50			highestBitValue(value[0]),
51			highestBitValue(value[1]));
52	}
53
54	template <typename T, precision P>
55	GLM_FUNC_QUALIFIER detail::tvec3<int, P> highestBitValue
56	(
57		detail::tvec3<T, P> const & value
58	)
59	{
60		return detail::tvec3<int, P>(
61			highestBitValue(value[0]),
62			highestBitValue(value[1]),
63			highestBitValue(value[2]));
64	}
65
66	template <typename T, precision P>
67	GLM_FUNC_QUALIFIER detail::tvec4<int, P> highestBitValue
68	(
69		detail::tvec4<T, P> const & value
70	)
71	{
72		return detail::tvec4<int, P>(
73			highestBitValue(value[0]),
74			highestBitValue(value[1]),
75			highestBitValue(value[2]),
76			highestBitValue(value[3]));
77	}
78
79	// isPowerOfTwo
80	template <typename genType>
81	GLM_FUNC_QUALIFIER bool isPowerOfTwo(genType const & Value)
82	{
83		//detail::If<std::numeric_limits<genType>::is_signed>::apply(abs, Value);
84		//return !(Value & (Value - 1));
85
86		// For old complier?
87		genType Result = Value;
88		if(std::numeric_limits<genType>::is_signed)
89			Result = abs(Result);
90		return !(Result & (Result - 1));
91	}
92
93	template <typename T, precision P>
94	GLM_FUNC_QUALIFIER detail::tvec2<bool, P> isPowerOfTwo
95	(
96		detail::tvec2<T, P> const & value
97	)
98	{
99		return detail::tvec2<bool, P>(
100			isPowerOfTwo(value[0]),
101			isPowerOfTwo(value[1]));
102	}
103
104	template <typename T, precision P>
105	GLM_FUNC_QUALIFIER detail::tvec3<bool, P> isPowerOfTwo
106	(
107		detail::tvec3<T, P> const & value
108	)
109	{
110		return detail::tvec3<bool, P>(
111			isPowerOfTwo(value[0]),
112			isPowerOfTwo(value[1]),
113			isPowerOfTwo(value[2]));
114	}
115
116	template <typename T, precision P>
117	GLM_FUNC_QUALIFIER detail::tvec4<bool, P> isPowerOfTwo
118	(
119		detail::tvec4<T, P> const & value
120	)
121	{
122		return detail::tvec4<bool, P>(
123			isPowerOfTwo(value[0]),
124			isPowerOfTwo(value[1]),
125			isPowerOfTwo(value[2]),
126			isPowerOfTwo(value[3]));
127	}
128
129	// powerOfTwoAbove
130	template <typename genType>
131	GLM_FUNC_QUALIFIER genType powerOfTwoAbove(genType const & value)
132	{
133		return isPowerOfTwo(value) ? value : highestBitValue(value) << 1;
134	}
135
136	VECTORIZE_VEC(powerOfTwoAbove)
137
138	// powerOfTwoBelow
139	template <typename genType>
140	GLM_FUNC_QUALIFIER genType powerOfTwoBelow
141	(
142		genType const & value
143	)
144	{
145		return isPowerOfTwo(value) ? value : highestBitValue(value);
146	}
147
148	VECTORIZE_VEC(powerOfTwoBelow)
149
150	// powerOfTwoNearest
151	template <typename genType>
152	GLM_FUNC_QUALIFIER genType powerOfTwoNearest
153	(
154		genType const & value
155	)
156	{
157		if(isPowerOfTwo(value))
158			return value;
159
160		genType prev = highestBitValue(value);
161		genType next = prev << 1;
162		return (next - value) < (value - prev) ? next : prev;
163	}
164
165	VECTORIZE_VEC(powerOfTwoNearest)
166
167	template <typename genType>
168	GLM_FUNC_QUALIFIER genType bitRevert(genType const & In)
169	{
170		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRevert' only accept integer values");
171
172		genType Out = 0;
173		std::size_t BitSize = sizeof(genType) * 8;
174		for(std::size_t i = 0; i < BitSize; ++i)
175			if(In & (genType(1) << i))
176				Out |= genType(1) << (BitSize - 1 - i);
177		return Out;
178	}
179
180	VECTORIZE_VEC(bitRevert)
181
182	template <typename genType>
183	GLM_FUNC_QUALIFIER genType bitRotateRight(genType const & In, std::size_t Shift)
184	{
185		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateRight' only accept integer values");
186
187		std::size_t BitSize = sizeof(genType) * 8;
188		return (In << Shift) | (In >> (BitSize - Shift));
189	}
190
191	template <typename T, precision P>
192	GLM_FUNC_QUALIFIER detail::tvec2<T, P> bitRotateRight
193	(
194		detail::tvec2<T, P> const & Value,
195		std::size_t Shift
196	)
197	{
198		return detail::tvec2<T, P>(
199			bitRotateRight(Value[0], Shift),
200			bitRotateRight(Value[1], Shift));
201	}
202
203	template <typename T, precision P>
204	GLM_FUNC_QUALIFIER detail::tvec3<T, P> bitRotateRight
205	(
206		detail::tvec3<T, P> const & Value,
207		std::size_t Shift
208	)
209	{
210		return detail::tvec3<T, P>(
211			bitRotateRight(Value[0], Shift),
212			bitRotateRight(Value[1], Shift),
213			bitRotateRight(Value[2], Shift));
214	}
215
216	template <typename T, precision P>
217	GLM_FUNC_QUALIFIER detail::tvec4<T, P> bitRotateRight
218	(
219		detail::tvec4<T, P> const & Value,
220		std::size_t Shift
221	)
222	{
223		return detail::tvec4<T, P>(
224			bitRotateRight(Value[0], Shift),
225			bitRotateRight(Value[1], Shift),
226			bitRotateRight(Value[2], Shift),
227			bitRotateRight(Value[3], Shift));
228	}
229
230	template <typename genType>
231	GLM_FUNC_QUALIFIER genType bitRotateLeft(genType const & In, std::size_t Shift)
232	{
233		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateLeft' only accept integer values");
234
235		std::size_t BitSize = sizeof(genType) * 8;
236		return (In >> Shift) | (In << (BitSize - Shift));
237	}
238
239	template <typename T, precision P>
240	GLM_FUNC_QUALIFIER detail::tvec2<T, P> bitRotateLeft
241	(
242		detail::tvec2<T, P> const & Value,
243		std::size_t Shift
244	)
245	{
246		return detail::tvec2<T, P>(
247			bitRotateLeft(Value[0], Shift),
248			bitRotateLeft(Value[1], Shift));
249	}
250
251	template <typename T, precision P>
252	GLM_FUNC_QUALIFIER detail::tvec3<T, P> bitRotateLeft
253	(
254		detail::tvec3<T, P> const & Value,
255		std::size_t Shift
256	)
257	{
258		return detail::tvec3<T, P>(
259			bitRotateLeft(Value[0], Shift),
260			bitRotateLeft(Value[1], Shift),
261			bitRotateLeft(Value[2], Shift));
262	}
263
264	template <typename T, precision P>
265	GLM_FUNC_QUALIFIER detail::tvec4<T, P> bitRotateLeft
266	(
267		detail::tvec4<T, P> const & Value,
268		std::size_t Shift
269	)
270	{
271		return detail::tvec4<T, P>(
272			bitRotateLeft(Value[0], Shift),
273			bitRotateLeft(Value[1], Shift),
274			bitRotateLeft(Value[2], Shift),
275			bitRotateLeft(Value[3], Shift));
276	}
277
278	template <typename genIUType>
279	GLM_FUNC_QUALIFIER genIUType fillBitfieldWithOne
280	(
281		genIUType const & Value,
282		int const & FromBit,
283		int const & ToBit
284	)
285	{
286		assert(FromBit <= ToBit);
287		assert(ToBit <= sizeof(genIUType) * std::size_t(8));
288
289		genIUType Result = Value;
290		for(std::size_t i = 0; i <= ToBit; ++i)
291			Result |= (1 << i);
292		return Result;
293	}
294
295	template <typename genIUType>
296	GLM_FUNC_QUALIFIER genIUType fillBitfieldWithZero
297	(
298		genIUType const & Value,
299		int const & FromBit,
300		int const & ToBit
301	)
302	{
303		assert(FromBit <= ToBit);
304		assert(ToBit <= sizeof(genIUType) * std::size_t(8));
305
306		genIUType Result = Value;
307		for(std::size_t i = 0; i <= ToBit; ++i)
308			Result &= ~(1 << i);
309		return Result;
310	}
311
312	namespace detail
313	{
314		template <typename PARAM, typename RET>
315		GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y);
316
317		template <typename PARAM, typename RET>
318		GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y, PARAM z);
319
320		template <typename PARAM, typename RET>
321		GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y, PARAM z, PARAM w);
322
323/*
324		template <typename PARAM, typename RET>
325		inline RET bitfieldInterleave(PARAM x, PARAM y)
326		{
327			RET Result = 0;
328			for (int i = 0; i < sizeof(PARAM) * 8; i++)
329				Result |= (x & 1U << i) << i | (y & 1U << i) << (i + 1);
330			return Result;
331		}
332
333		template <typename PARAM, typename RET>
334		inline RET bitfieldInterleave(PARAM x, PARAM y, PARAM z)
335		{
336			RET Result = 0;
337			for (RET i = 0; i < sizeof(PARAM) * 8; i++)
338			{
339				Result |= ((RET(x) & (RET(1) << i)) << ((i << 1) + 0));
340				Result |= ((RET(y) & (RET(1) << i)) << ((i << 1) + 1));
341				Result |= ((RET(z) & (RET(1) << i)) << ((i << 1) + 2));
342			}
343			return Result;
344		}
345
346		template <typename PARAM, typename RET>
347		inline RET bitfieldInterleave(PARAM x, PARAM y, PARAM z, PARAM w)
348		{
349			RET Result = 0;
350			for (int i = 0; i < sizeof(PARAM) * 8; i++)
351			{
352				Result |= ((((RET(x) >> i) & RET(1))) << RET((i << 2) + 0));
353				Result |= ((((RET(y) >> i) & RET(1))) << RET((i << 2) + 1));
354				Result |= ((((RET(z) >> i) & RET(1))) << RET((i << 2) + 2));
355				Result |= ((((RET(w) >> i) & RET(1))) << RET((i << 2) + 3));
356			}
357			return Result;
358		}
359*/
360		template <>
361		GLM_FUNC_QUALIFIER glm::uint16 bitfieldInterleave(glm::uint8 x, glm::uint8 y)
362		{
363			glm::uint16 REG1(x);
364			glm::uint16 REG2(y);
365
366			REG1 = ((REG1 <<  4) | REG1) & glm::uint16(0x0F0F);
367			REG2 = ((REG2 <<  4) | REG2) & glm::uint16(0x0F0F);
368
369			REG1 = ((REG1 <<  2) | REG1) & glm::uint16(0x3333);
370			REG2 = ((REG2 <<  2) | REG2) & glm::uint16(0x3333);
371
372			REG1 = ((REG1 <<  1) | REG1) & glm::uint16(0x5555);
373			REG2 = ((REG2 <<  1) | REG2) & glm::uint16(0x5555);
374
375			return REG1 | (REG2 << 1);
376		}
377
378		template <>
379		GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint16 x, glm::uint16 y)
380		{
381			glm::uint32 REG1(x);
382			glm::uint32 REG2(y);
383
384			REG1 = ((REG1 <<  8) | REG1) & glm::uint32(0x00FF00FF);
385			REG2 = ((REG2 <<  8) | REG2) & glm::uint32(0x00FF00FF);
386
387			REG1 = ((REG1 <<  4) | REG1) & glm::uint32(0x0F0F0F0F);
388			REG2 = ((REG2 <<  4) | REG2) & glm::uint32(0x0F0F0F0F);
389
390			REG1 = ((REG1 <<  2) | REG1) & glm::uint32(0x33333333);
391			REG2 = ((REG2 <<  2) | REG2) & glm::uint32(0x33333333);
392
393			REG1 = ((REG1 <<  1) | REG1) & glm::uint32(0x55555555);
394			REG2 = ((REG2 <<  1) | REG2) & glm::uint32(0x55555555);
395
396			return REG1 | (REG2 << 1);
397		}
398
399		template <>
400		GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint32 x, glm::uint32 y)
401		{
402			glm::uint64 REG1(x);
403			glm::uint64 REG2(y);
404
405			REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF);
406			REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF);
407
408			REG1 = ((REG1 <<  8) | REG1) & glm::uint64(0x00FF00FF00FF00FF);
409			REG2 = ((REG2 <<  8) | REG2) & glm::uint64(0x00FF00FF00FF00FF);
410
411			REG1 = ((REG1 <<  4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F);
412			REG2 = ((REG2 <<  4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F);
413
414			REG1 = ((REG1 <<  2) | REG1) & glm::uint64(0x3333333333333333);
415			REG2 = ((REG2 <<  2) | REG2) & glm::uint64(0x3333333333333333);
416
417			REG1 = ((REG1 <<  1) | REG1) & glm::uint64(0x5555555555555555);
418			REG2 = ((REG2 <<  1) | REG2) & glm::uint64(0x5555555555555555);
419
420			return REG1 | (REG2 << 1);
421		}
422
423		template <>
424		GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z)
425		{
426			glm::uint32 REG1(x);
427			glm::uint32 REG2(y);
428			glm::uint32 REG3(z);
429
430			REG1 = ((REG1 << 16) | REG1) & glm::uint32(0x00FF0000FF0000FF);
431			REG2 = ((REG2 << 16) | REG2) & glm::uint32(0x00FF0000FF0000FF);
432			REG3 = ((REG3 << 16) | REG3) & glm::uint32(0x00FF0000FF0000FF);
433
434			REG1 = ((REG1 <<  8) | REG1) & glm::uint32(0xF00F00F00F00F00F);
435			REG2 = ((REG2 <<  8) | REG2) & glm::uint32(0xF00F00F00F00F00F);
436			REG3 = ((REG3 <<  8) | REG3) & glm::uint32(0xF00F00F00F00F00F);
437
438			REG1 = ((REG1 <<  4) | REG1) & glm::uint32(0x30C30C30C30C30C3);
439			REG2 = ((REG2 <<  4) | REG2) & glm::uint32(0x30C30C30C30C30C3);
440			REG3 = ((REG3 <<  4) | REG3) & glm::uint32(0x30C30C30C30C30C3);
441
442			REG1 = ((REG1 <<  2) | REG1) & glm::uint32(0x9249249249249249);
443			REG2 = ((REG2 <<  2) | REG2) & glm::uint32(0x9249249249249249);
444			REG3 = ((REG3 <<  2) | REG3) & glm::uint32(0x9249249249249249);
445
446			return REG1 | (REG2 << 1) | (REG3 << 2);
447		}
448
449		template <>
450		GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z)
451		{
452			glm::uint64 REG1(x);
453			glm::uint64 REG2(y);
454			glm::uint64 REG3(z);
455
456			REG1 = ((REG1 << 32) | REG1) & glm::uint64(0xFFFF00000000FFFF);
457			REG2 = ((REG2 << 32) | REG2) & glm::uint64(0xFFFF00000000FFFF);
458			REG3 = ((REG3 << 32) | REG3) & glm::uint64(0xFFFF00000000FFFF);
459
460			REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x00FF0000FF0000FF);
461			REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x00FF0000FF0000FF);
462			REG3 = ((REG3 << 16) | REG3) & glm::uint64(0x00FF0000FF0000FF);
463
464			REG1 = ((REG1 <<  8) | REG1) & glm::uint64(0xF00F00F00F00F00F);
465			REG2 = ((REG2 <<  8) | REG2) & glm::uint64(0xF00F00F00F00F00F);
466			REG3 = ((REG3 <<  8) | REG3) & glm::uint64(0xF00F00F00F00F00F);
467
468			REG1 = ((REG1 <<  4) | REG1) & glm::uint64(0x30C30C30C30C30C3);
469			REG2 = ((REG2 <<  4) | REG2) & glm::uint64(0x30C30C30C30C30C3);
470			REG3 = ((REG3 <<  4) | REG3) & glm::uint64(0x30C30C30C30C30C3);
471
472			REG1 = ((REG1 <<  2) | REG1) & glm::uint64(0x9249249249249249);
473			REG2 = ((REG2 <<  2) | REG2) & glm::uint64(0x9249249249249249);
474			REG3 = ((REG3 <<  2) | REG3) & glm::uint64(0x9249249249249249);
475
476			return REG1 | (REG2 << 1) | (REG3 << 2);
477		}
478
479		template <>
480		GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint32 x, glm::uint32 y, glm::uint32 z)
481		{
482			glm::uint64 REG1(x);
483			glm::uint64 REG2(y);
484			glm::uint64 REG3(z);
485
486			REG1 = ((REG1 << 32) | REG1) & glm::uint64(0xFFFF00000000FFFF);
487			REG2 = ((REG2 << 32) | REG2) & glm::uint64(0xFFFF00000000FFFF);
488			REG3 = ((REG3 << 32) | REG3) & glm::uint64(0xFFFF00000000FFFF);
489
490			REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x00FF0000FF0000FF);
491			REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x00FF0000FF0000FF);
492			REG3 = ((REG3 << 16) | REG3) & glm::uint64(0x00FF0000FF0000FF);
493
494			REG1 = ((REG1 <<  8) | REG1) & glm::uint64(0xF00F00F00F00F00F);
495			REG2 = ((REG2 <<  8) | REG2) & glm::uint64(0xF00F00F00F00F00F);
496			REG3 = ((REG3 <<  8) | REG3) & glm::uint64(0xF00F00F00F00F00F);
497
498			REG1 = ((REG1 <<  4) | REG1) & glm::uint64(0x30C30C30C30C30C3);
499			REG2 = ((REG2 <<  4) | REG2) & glm::uint64(0x30C30C30C30C30C3);
500			REG3 = ((REG3 <<  4) | REG3) & glm::uint64(0x30C30C30C30C30C3);
501
502			REG1 = ((REG1 <<  2) | REG1) & glm::uint64(0x9249249249249249);
503			REG2 = ((REG2 <<  2) | REG2) & glm::uint64(0x9249249249249249);
504			REG3 = ((REG3 <<  2) | REG3) & glm::uint64(0x9249249249249249);
505
506			return REG1 | (REG2 << 1) | (REG3 << 2);
507		}
508
509		template <>
510		GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z, glm::uint8 w)
511		{
512			glm::uint32 REG1(x);
513			glm::uint32 REG2(y);
514			glm::uint32 REG3(z);
515			glm::uint32 REG4(w);
516
517			REG1 = ((REG1 << 12) | REG1) & glm::uint32(0x000F000F000F000F);
518			REG2 = ((REG2 << 12) | REG2) & glm::uint32(0x000F000F000F000F);
519			REG3 = ((REG3 << 12) | REG3) & glm::uint32(0x000F000F000F000F);
520			REG4 = ((REG4 << 12) | REG4) & glm::uint32(0x000F000F000F000F);
521
522			REG1 = ((REG1 <<  6) | REG1) & glm::uint32(0x0303030303030303);
523			REG2 = ((REG2 <<  6) | REG2) & glm::uint32(0x0303030303030303);
524			REG3 = ((REG3 <<  6) | REG3) & glm::uint32(0x0303030303030303);
525			REG4 = ((REG4 <<  6) | REG4) & glm::uint32(0x0303030303030303);
526
527			REG1 = ((REG1 <<  3) | REG1) & glm::uint32(0x1111111111111111);
528			REG2 = ((REG2 <<  3) | REG2) & glm::uint32(0x1111111111111111);
529			REG3 = ((REG3 <<  3) | REG3) & glm::uint32(0x1111111111111111);
530			REG4 = ((REG4 <<  3) | REG4) & glm::uint32(0x1111111111111111);
531
532			return REG1 | (REG2 << 1) | (REG3 << 2) | (REG4 << 3);
533		}
534
535		template <>
536		GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z, glm::uint16 w)
537		{
538			glm::uint64 REG1(x);
539			glm::uint64 REG2(y);
540			glm::uint64 REG3(z);
541			glm::uint64 REG4(w);
542
543			REG1 = ((REG1 << 24) | REG1) & glm::uint64(0x000000FF000000FF);
544			REG2 = ((REG2 << 24) | REG2) & glm::uint64(0x000000FF000000FF);
545			REG3 = ((REG3 << 24) | REG3) & glm::uint64(0x000000FF000000FF);
546			REG4 = ((REG4 << 24) | REG4) & glm::uint64(0x000000FF000000FF);
547
548			REG1 = ((REG1 << 12) | REG1) & glm::uint64(0x000F000F000F000F);
549			REG2 = ((REG2 << 12) | REG2) & glm::uint64(0x000F000F000F000F);
550			REG3 = ((REG3 << 12) | REG3) & glm::uint64(0x000F000F000F000F);
551			REG4 = ((REG4 << 12) | REG4) & glm::uint64(0x000F000F000F000F);
552
553			REG1 = ((REG1 <<  6) | REG1) & glm::uint64(0x0303030303030303);
554			REG2 = ((REG2 <<  6) | REG2) & glm::uint64(0x0303030303030303);
555			REG3 = ((REG3 <<  6) | REG3) & glm::uint64(0x0303030303030303);
556			REG4 = ((REG4 <<  6) | REG4) & glm::uint64(0x0303030303030303);
557
558			REG1 = ((REG1 <<  3) | REG1) & glm::uint64(0x1111111111111111);
559			REG2 = ((REG2 <<  3) | REG2) & glm::uint64(0x1111111111111111);
560			REG3 = ((REG3 <<  3) | REG3) & glm::uint64(0x1111111111111111);
561			REG4 = ((REG4 <<  3) | REG4) & glm::uint64(0x1111111111111111);
562
563			return REG1 | (REG2 << 1) | (REG3 << 2) | (REG4 << 3);
564		}
565	}//namespace detail
566
567	GLM_FUNC_QUALIFIER int16 bitfieldInterleave(int8 x, int8 y)
568	{
569		union sign8
570		{
571			int8 i;
572			uint8 u;
573		} sign_x, sign_y;
574
575		union sign16
576		{
577			int16 i;
578			uint16 u;
579		} result;
580
581		sign_x.i = x;
582		sign_y.i = y;
583		result.u = bitfieldInterleave(sign_x.u, sign_y.u);
584
585		return result.i;
586	}
587
588	GLM_FUNC_QUALIFIER uint16 bitfieldInterleave(uint8 x, uint8 y)
589	{
590		return detail::bitfieldInterleave<uint8, uint16>(x, y);
591	}
592
593	GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int16 x, int16 y)
594	{
595		union sign16
596		{
597			int16 i;
598			uint16 u;
599		} sign_x, sign_y;
600
601		union sign32
602		{
603			int32 i;
604			uint32 u;
605		} result;
606
607		sign_x.i = x;
608		sign_y.i = y;
609		result.u = bitfieldInterleave(sign_x.u, sign_y.u);
610
611		return result.i;
612	}
613
614	GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint16 x, uint16 y)
615	{
616		return detail::bitfieldInterleave<uint16, uint32>(x, y);
617	}
618
619	GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y)
620	{
621		union sign32
622		{
623			int32 i;
624			uint32 u;
625		} sign_x, sign_y;
626
627		union sign64
628		{
629			int64 i;
630			uint64 u;
631		} result;
632
633		sign_x.i = x;
634		sign_y.i = y;
635		result.u = bitfieldInterleave(sign_x.u, sign_y.u);
636
637		return result.i;
638	}
639
640	GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint32 x, uint32 y)
641	{
642		return detail::bitfieldInterleave<uint32, uint64>(x, y);
643	}
644
645	GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z)
646	{
647		union sign8
648		{
649			int8 i;
650			uint8 u;
651		} sign_x, sign_y, sign_z;
652
653		union sign32
654		{
655			int32 i;
656			uint32 u;
657		} result;
658
659		sign_x.i = x;
660		sign_y.i = y;
661		sign_z.i = z;
662		result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u);
663
664		return result.i;
665	}
666
667	GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z)
668	{
669		return detail::bitfieldInterleave<uint8, uint32>(x, y, z);
670	}
671
672	GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int16 x, int16 y, int16 z)
673	{
674		union sign16
675		{
676			int16 i;
677			uint16 u;
678		} sign_x, sign_y, sign_z;
679
680		union sign64
681		{
682			int64 i;
683			uint64 u;
684		} result;
685
686		sign_x.i = x;
687		sign_y.i = y;
688		sign_z.i = z;
689		result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u);
690
691		return result.i;
692	}
693
694	GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z)
695	{
696		return detail::bitfieldInterleave<uint32, uint64>(x, y, z);
697	}
698
699	GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y, int32 z)
700	{
701		union sign16
702		{
703			int32 i;
704			uint32 u;
705		} sign_x, sign_y, sign_z;
706
707		union sign64
708		{
709			int64 i;
710			uint64 u;
711		} result;
712
713		sign_x.i = x;
714		sign_y.i = y;
715		sign_z.i = z;
716		result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u);
717
718		return result.i;
719	}
720
721	GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint32 x, uint32 y, uint32 z)
722	{
723		return detail::bitfieldInterleave<uint32, uint64>(x, y, z);
724	}
725
726	GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z, int8 w)
727	{
728		union sign8
729		{
730			int8 i;
731			uint8 u;
732		} sign_x, sign_y, sign_z, sign_w;
733
734		union sign32
735		{
736			int32 i;
737			uint32 u;
738		} result;
739
740		sign_x.i = x;
741		sign_y.i = y;
742		sign_z.i = z;
743		sign_w.i = w;
744		result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u, sign_w.u);
745
746		return result.i;
747	}
748
749	GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z, uint8 w)
750	{
751		return detail::bitfieldInterleave<uint8, uint32>(x, y, z, w);
752	}
753
754	GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int16 x, int16 y, int16 z, int16 w)
755	{
756		union sign16
757		{
758			int16 i;
759			uint16 u;
760		} sign_x, sign_y, sign_z, sign_w;
761
762		union sign64
763		{
764			int64 i;
765			uint64 u;
766		} result;
767
768		sign_x.i = x;
769		sign_y.i = y;
770		sign_z.i = z;
771		sign_w.i = w;
772		result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u, sign_w.u);
773
774		return result.i;
775	}
776
777	GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z, uint16 w)
778	{
779		return detail::bitfieldInterleave<uint16, uint64>(x, y, z, w);
780	}
781
782}//namespace glm
783