Clutter Engine 0.0.1
Loading...
Searching...
No Matches
scalar_integer.inl
1#include "../integer.hpp"
2
3namespace glm{
4namespace detail
5{
6 template<length_t L, typename T, qualifier Q, bool compute = false>
8 {
9 GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& v, T)
10 {
11 return v;
12 }
13 };
14
15 template<length_t L, typename T, qualifier Q>
16 struct compute_ceilShift<L, T, Q, true>
17 {
18 GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& v, T Shift)
19 {
20 return v | (v >> Shift);
21 }
22 };
23
24 template<length_t L, typename T, qualifier Q, bool isSigned = true>
26 {
27 GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x)
28 {
29 GLM_STATIC_ASSERT(!std::numeric_limits<T>::is_iec559, "'ceilPowerOfTwo' only accept integer scalar or vector inputs");
30
31 vec<L, T, Q> const Sign(sign(x));
32
33 vec<L, T, Q> v(abs(x));
34
35 v = v - static_cast<T>(1);
36 v = v | (v >> static_cast<T>(1));
37 v = v | (v >> static_cast<T>(2));
38 v = v | (v >> static_cast<T>(4));
39 v = compute_ceilShift<L, T, Q, sizeof(T) >= 2>::call(v, 8);
40 v = compute_ceilShift<L, T, Q, sizeof(T) >= 4>::call(v, 16);
41 v = compute_ceilShift<L, T, Q, sizeof(T) >= 8>::call(v, 32);
42 return (v + static_cast<T>(1)) * Sign;
43 }
44 };
45
46 template<length_t L, typename T, qualifier Q>
47 struct compute_ceilPowerOfTwo<L, T, Q, false>
48 {
49 GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x)
50 {
51 GLM_STATIC_ASSERT(!std::numeric_limits<T>::is_iec559, "'ceilPowerOfTwo' only accept integer scalar or vector inputs");
52
53 vec<L, T, Q> v(x);
54
55 v = v - static_cast<T>(1);
56 v = v | (v >> static_cast<T>(1));
57 v = v | (v >> static_cast<T>(2));
58 v = v | (v >> static_cast<T>(4));
59 v = compute_ceilShift<L, T, Q, sizeof(T) >= 2>::call(v, 8);
60 v = compute_ceilShift<L, T, Q, sizeof(T) >= 4>::call(v, 16);
61 v = compute_ceilShift<L, T, Q, sizeof(T) >= 8>::call(v, 32);
62 return v + static_cast<T>(1);
63 }
64 };
65
66 template<bool is_float, bool is_signed>
68
69 template<>
70 struct compute_ceilMultiple<true, true>
71 {
72 template<typename genType>
73 GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple)
74 {
75 if(Source > genType(0))
76 return Source + (Multiple - std::fmod(Source, Multiple));
77 else
78 return Source + std::fmod(-Source, Multiple);
79 }
80 };
81
82 template<>
83 struct compute_ceilMultiple<false, false>
84 {
85 template<typename genType>
86 GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple)
87 {
88 genType Tmp = Source - genType(1);
89 return Tmp + (Multiple - (Tmp % Multiple));
90 }
91 };
92
93 template<>
94 struct compute_ceilMultiple<false, true>
95 {
96 template<typename genType>
97 GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple)
98 {
99 assert(Multiple > genType(0));
100 if(Source > genType(0))
101 {
102 genType Tmp = Source - genType(1);
103 return Tmp + (Multiple - (Tmp % Multiple));
104 }
105 else
106 return Source + (-Source % Multiple);
107 }
108 };
109
110 template<bool is_float, bool is_signed>
112
113 template<>
114 struct compute_floorMultiple<true, true>
115 {
116 template<typename genType>
117 GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple)
118 {
119 if(Source >= genType(0))
120 return Source - std::fmod(Source, Multiple);
121 else
122 return Source - std::fmod(Source, Multiple) - Multiple;
123 }
124 };
125
126 template<>
127 struct compute_floorMultiple<false, false>
128 {
129 template<typename genType>
130 GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple)
131 {
132 if(Source >= genType(0))
133 return Source - Source % Multiple;
134 else
135 {
136 genType Tmp = Source + genType(1);
137 return Tmp - Tmp % Multiple - Multiple;
138 }
139 }
140 };
141
142 template<>
143 struct compute_floorMultiple<false, true>
144 {
145 template<typename genType>
146 GLM_FUNC_QUALIFIER static genType call(genType Source, genType Multiple)
147 {
148 if(Source >= genType(0))
149 return Source - Source % Multiple;
150 else
151 {
152 genType Tmp = Source + genType(1);
153 return Tmp - Tmp % Multiple - Multiple;
154 }
155 }
156 };
157}//namespace detail
158
159 template<typename genIUType>
160 GLM_FUNC_QUALIFIER bool isPowerOfTwo(genIUType Value)
161 {
162 GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'isPowerOfTwo' only accept integer inputs");
163
164 genIUType const Result = glm::abs(Value);
165 return !(Result & (Result - 1));
166 }
167
168 template<typename genIUType>
169 GLM_FUNC_QUALIFIER genIUType nextPowerOfTwo(genIUType value)
170 {
171 GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'nextPowerOfTwo' only accept integer inputs");
172
174 }
175
176 template<typename genIUType>
177 GLM_FUNC_QUALIFIER genIUType prevPowerOfTwo(genIUType value)
178 {
179 GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'prevPowerOfTwo' only accept integer inputs");
180
181 return isPowerOfTwo(value) ? value : static_cast<genIUType>(static_cast<genIUType>(1) << static_cast<genIUType>(findMSB(value)));
182 }
183
184 template<typename genIUType>
185 GLM_FUNC_QUALIFIER bool isMultiple(genIUType Value, genIUType Multiple)
186 {
187 GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'isMultiple' only accept integer inputs");
188
189 return isMultiple(vec<1, genIUType>(Value), vec<1, genIUType>(Multiple)).x;
190 }
191
192 template<typename genIUType>
193 GLM_FUNC_QUALIFIER genIUType nextMultiple(genIUType Source, genIUType Multiple)
194 {
195 GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'nextMultiple' only accept integer inputs");
196
197 return detail::compute_ceilMultiple<std::numeric_limits<genIUType>::is_iec559, std::numeric_limits<genIUType>::is_signed>::call(Source, Multiple);
198 }
199
200 template<typename genIUType>
201 GLM_FUNC_QUALIFIER genIUType prevMultiple(genIUType Source, genIUType Multiple)
202 {
203 GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'prevMultiple' only accept integer inputs");
204
205 return detail::compute_floorMultiple<std::numeric_limits<genIUType>::is_iec559, std::numeric_limits<genIUType>::is_signed>::call(Source, Multiple);
206 }
207
208 template<typename genIUType>
209 GLM_FUNC_QUALIFIER int findNSB(genIUType x, int significantBitCount)
210 {
211 GLM_STATIC_ASSERT(std::numeric_limits<genIUType>::is_integer, "'findNSB' only accept integer inputs");
212
213 if(bitCount(x) < significantBitCount)
214 return -1;
215
216 genIUType const One = static_cast<genIUType>(1);
217 int bitPos = 0;
218
219 genIUType key = x;
220 int nBitCount = significantBitCount;
221 int Step = sizeof(x) * 8 / 2;
222 while (key > One)
223 {
224 genIUType Mask = static_cast<genIUType>((One << Step) - One);
225 genIUType currentKey = key & Mask;
226 int currentBitCount = bitCount(currentKey);
227 if (nBitCount > currentBitCount)
228 {
229 nBitCount -= currentBitCount;
230 bitPos += Step;
231 key >>= static_cast<genIUType>(Step);
232 }
233 else
234 {
235 key = key & Mask;
236 }
237
238 Step >>= 1;
239 }
240
241 return static_cast<int>(bitPos);
242 }
243}//namespace glm
GLM_FUNC_DECL GLM_CONSTEXPR genType abs(genType x)
GLM_FUNC_DECL vec< L, T, Q > sign(vec< L, T, Q > const &x)
Definition func_common.inl:295
GLM_FUNC_QUALIFIER int findMSB(genIUType v)
Definition func_integer.inl:353
GLM_FUNC_DECL int findNSB(genIUType x, int significantBitCount)
Definition scalar_integer.inl:209
GLM_FUNC_DECL genIUType nextPowerOfTwo(genIUType v)
Definition scalar_integer.inl:169
GLM_FUNC_DECL genIUType prevPowerOfTwo(genIUType v)
Definition scalar_integer.inl:177
GLM_FUNC_DECL genIUType nextMultiple(genIUType v, genIUType Multiple)
Definition scalar_integer.inl:193
GLM_FUNC_DECL genIUType prevMultiple(genIUType v, genIUType Multiple)
Definition scalar_integer.inl:201
GLM_FUNC_DECL bool isPowerOfTwo(genIUType v)
Definition scalar_integer.inl:160
GLM_FUNC_DECL bool isMultiple(genIUType v, genIUType Multiple)
Definition scalar_integer.inl:185
detail namespace with internal helper functions
Definition json.h:249
Core features
Definition common.hpp:21
Definition scalar_integer.inl:67
Definition scalar_integer.inl:26
Definition scalar_integer.inl:8
Definition scalar_integer.inl:111
Definition qualifier.hpp:35