Library of Assembled Shared Sources
basic_ops.inl
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2022 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43#include "../meta/select.h"
44
45// --- implementation details ----------------------------------------------------------------------
46
47// http://pi.lacim.uqam.ca/eng/table_en.html
48#define LASS_NUM_INVLOG2 1.442695040888963407359924681001892137426645954152985934135449406931109219181185079885526622893506344
49#define LASS_NUM_INVLOG10 0.434294481903251827651128918916605082294397005803666566114453783165864649208870774729224949338431748
50
51namespace impl
52{
53
54template <typename T>
55struct IntPow
56{
57 typedef typename NumTraits<T>::signedType TSigned;
58 typedef typename NumTraits<T>::unsignedType TUnsigned;
59 typedef typename meta::Select< meta::Bool< sizeof(T) < sizeof(int) >, int, T >::Type TTemp;
60 typedef typename meta::Select< meta::Bool< sizeof(TUnsigned) < sizeof(unsigned) >, unsigned, TUnsigned >::Type TExponent;
61
62 static T eval(T x, TSigned exponent)
63 {
64 LASS_ASSERT(exponent >= 0);
65 return eval(x, static_cast<TUnsigned>(exponent));
66 }
67
68 static T eval(T x, TUnsigned exponent)
69 {
70 if (exponent == 0)
71 {
72 return 1;
73 }
74
75 TTemp result = 1;
76 TTemp partialPower = 1;
77 TExponent e = exponent;
78 do
79 {
80 partialPower *= x;
81 if (e & 0x1)
82 {
83 result *= partialPower;
84 }
85 e >>= 1;
86 }
87 while (e);
88 return static_cast<T>(result);
89 }
90};
91
92template <typename T>
93struct IntDiv
94{
95 typedef typename NumTraits<T>::signedType TSigned;
96 typedef typename NumTraits<T>::unsignedType TUnsigned;
97
98 static T eval(TSigned x, TSigned m)
99 {
100 LASS_ASSERT(m > 0);
101 const TSigned tempDiv = static_cast<TSigned>(x / m);
102 return x % m >= 0 ? tempDiv : static_cast<TSigned>(tempDiv - 1);
103 }
104
105 static T eval(TSigned x, TUnsigned m)
106 {
107 LASS_ASSERT(m > 0);
108 const TSigned signedMod = static_cast<TSigned>(m);
109 LASS_ASSERT(signedMod >= 0);
110 const TSigned tempDiv = static_cast<TSigned>(x / signedMod);
111 return x % signedMod >= 0 ? tempDiv : static_cast<TSigned>(tempDiv - 1);
112 }
113};
114
115template <typename T>
116struct IntMod
117{
118 typedef typename NumTraits<T>::signedType TSigned;
119 typedef typename NumTraits<T>::unsignedType TUnsigned;
120
121 static T eval(TSigned x, TSigned m)
122 {
123 LASS_ASSERT(m > 0);
124 const TSigned tempMod = static_cast<TSigned>(x % m);
125 return tempMod >= 0 ? tempMod : static_cast<TSigned>(tempMod + m);
126 }
127
128 static TUnsigned eval(TSigned x, TUnsigned m)
129 {
130 LASS_ASSERT(m > 0);
131 const TSigned signedMod = static_cast<TSigned>(m);
132 LASS_ASSERT(signedMod >= 0);
133 const TSigned tempMod = static_cast<TSigned>(x % signedMod);
134 return static_cast<TUnsigned>(tempMod >= 0 ? tempMod : tempMod + signedMod);
135 }
136};
137
138}
139
140// --- generic functions ---------------------------------------------------------------------------
141
142/** if x < 0 return -x, else return x.
143 * @ingroup BasicOps
144 */
145template <typename T> inline T abs(const T& x)
146{
147 return x < T() ? -x : x;
148}
149
150/** if x < 0 return -1, else if x > 0 return 1, else return 0.
151 * @ingroup BasicOps
152 */
153template <typename T> inline T sign(const T& x)
154{
155 const T zero = T();
156 return x > zero ? T(1) : (x < zero ? T(-1) : zero);
157}
158
159/** return x * x
160 * @ingroup BasicOps
161 */
162template <typename T> inline T sqr(const T& x)
163{
164 return x * x;
165}
166
167/** return x * x * x
168 * @ingroup BasicOps
169 */
170template <typename T> inline T cubic(const T& x)
171{
172 return x * x * x;
173}
174
175/** return x ^ -1
176 * @ingroup BasicOps
177 */
178template <typename T> inline T inv(const T& x)
179{
180 return T(1) / x;
181}
182
183/** return exp(p * log(x));
184 * @ingroup BasicOps
185 * @warning GENERIC FUNCTION USES EXP AND LOG!
186 */
187template <typename T> inline T pow(const T& x, const T& p)
188{
189 return exp(p * log(x));
190}
191
192/** return log(x) / log(2)
193 * @ingroup BasicOps
194 */
195template <typename T> inline T log2(const T& x)
196{
197 return T(LASS_NUM_INVLOG2) * log(x);
198}
199
200/** return log(x) / log(10)
201 * @ingroup BasicOps
202 */
203template <typename T> inline T log10(const T& x)
204{
205 return T(LASS_NUM_INVLOG10) * log(x);
206}
207
208/** return norm of x as if x is real part of complex number: sqr(x)
209 * @ingroup BasicOps
210 */
211template <typename T> inline T norm(const T& x)
212{
213 return sqr(x);
214}
215
216/** return conjugate as if x is a complex number: x
217 */
218template <typename T> inline T conj(const T& x)
219{
220 return x;
221}
222
223/** if x < min return min, else if x > max return max, else return x.
224 * @ingroup BasicOps
225 */
226template <typename T> inline const T& clamp(const T& x, const T& min, const T& max)
227{
228 return x < min ? min : (x > max ? max : x);
229}
230
231/** linear interpolation between @a a and @a b
232 * @ingroup BasicOps
233 */
234template <typename T> inline T lerp(const T& a, const T& b, const T& f)
235{
236 return a + f * (b - a);
237}
238
239/** @ingroup BasicOps
240 */
241template<typename T,typename f> T applyFunction(const T& x, f func )
242{
243 return func(x);
244}
245
246
247
248// --- generic inplace rerouters -------------------------------------------------------------------
249
250template <typename T> void inpabs(T& x) { x = num::abs(x); } /**< @ingroup BasicOps */
251template <typename T> void inpsign(T& x) { x = num::sign(x); } /**< @ingroup BasicOps */
252template <typename T> void inpinv(T& x) { x = num::inv(x); } /**< @ingroup BasicOps */
253template <typename T> void inpsqrt(T& x) { x = num::sqrt(x); } /**< @ingroup BasicOps */
254template <typename T> void inpsqr(T& x) { x = num::sqr(x); } /**< @ingroup BasicOps */
255template <typename T> void inpcubic(T& x) { x = num::cubic(x); } /**< @ingroup BasicOps */
256template <typename T> void inppow(T& x, const T& p) { x = num::pow(x, p); } /**< @ingroup BasicOps */
257template <typename T> void inpexp(T& x) { x = num::exp(x); } /**< @ingroup BasicOps */
258template <typename T> void inplog(T& x) { x = num::log(x); } /**< @ingroup BasicOps */
259template <typename T> void inpcos(T& x) { x = num::cos(x); } /**< @ingroup BasicOps */
260template <typename T> void inpsin(T& x) { x = num::sin(x); } /**< @ingroup BasicOps */
261template <typename T> void inptan(T& x) { x = num::tan(x); } /**< @ingroup BasicOps */
262template <typename T> void inpacos(T& x) { x = num::acos(x); } /**< @ingroup BasicOps */
263template <typename T> void inpasin(T& x) { x = num::asin(x); } /**< @ingroup BasicOps */
264template <typename T> void inpatan(T& x) { x = num::atan(x); } /**< @ingroup BasicOps */
265template <typename T> void inpatan2(T& y, const T& x) { y = num::atan2(y, x); } /**< @ingroup BasicOps */
266template <typename T> void inpfloor(T& x) { x = num::floor(x); } /**< @ingroup BasicOps */
267template <typename T> void inpceil(T& x) { x = num::ceil(x); } /**< @ingroup BasicOps */
268template <typename T> void inpround(T& x) { x = num::round(x); } /**< @ingroup BasicOps */
269template <typename T> void inpfractional(T& x) { x -= num::floor(x); } /**< @ingroup BasicOps */
270template <typename T> void inpdiv(T& x, const T& m) { x = num::div(x, m); } /**< @ingroup BasicOps */
271template <typename T> void inpmod(T& x, const T& m) { x = num::mod(x, m); } /**< @ingroup BasicOps */
272template <typename T> void inpclamp(T& x, const T& min, const T& max) { x = num::clamp(x, min, max); } /** @ingroup BasicOps */
273
274template <typename T> void compnorm(const T& x, T& y) { y = num::norm(x); } /**< @ingroup BasicOps */
275template <typename T> void compinv(const T& x, T& y) { y = num::inv(x); } /**< @ingroup BasicOps */
276
277
278
279// --- float ---------------------------------------------------------------------------------------
280
281float abs(float x) { return ::fabsf(x); } /**< @ingroup BasicOps */
282float inv(float x) { return 1.f / x; } /**< @ingroup BasicOps */
283float sqrt(float x) { LASS_ASSERT(!(x < 0.f)); return ::sqrtf(x); } /**< @ingroup BasicOps */
284float pow(float x, float p) { return ::powf(x, p); } /**< @ingroup BasicOps */
285float exp(float x) { return ::expf(x); } /**< @ingroup BasicOps */
286float log(float x) { return ::logf(x); } /**< @ingroup BasicOps */
287float log2(float x) { return float(LASS_NUM_INVLOG2) * ::logf(x); } /**< @ingroup BasicOps */
288float log10(float x) { return ::log10f(x); } /**< @ingroup BasicOps */
289float cos(float x) { return ::cosf(x); } /**< @ingroup BasicOps */
290float sin(float x) { return ::sinf(x); } /**< @ingroup BasicOps */
291float tan(float x) { return ::tanf(x); } /**< @ingroup BasicOps */
292float acos(float x) { return ::acosf(x); } /**< @ingroup BasicOps */
293float asin(float x) { return ::asinf(x); } /**< @ingroup BasicOps */
294float atan(float x) { return ::atanf(x); } /**< @ingroup BasicOps */
295float atan2(float y, float x) { return ::atan2f(y, x); } /**< @ingroup BasicOps */
296float floor(float x) { return ::floorf(x); } /**< @ingroup BasicOps */
297float ceil(float x) { return ::ceilf(x); } /**< @ingroup BasicOps */
298float round(float x) { return ::floorf(x + .5f); } /**< @ingroup BasicOps */
299float fractional(float x) { return x - ::floorf(x); } /**< @ingroup BasicOps */
300
301#if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
302# pragma warning(push)
303# pragma warning(disable: 4723) // potential divide by 0
304#endif
305float sinc(float x) { return ::fabsf(x) < 1e-4f ? 1.f : (::sinf(x) / x); } /**< @ingroup BasicOps */
306#if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
307# pragma warning(pop)
308#endif
309
310/** @ingroup BasicOps */
311float mod(float x, float m)
312{
313 const float result = ::fmodf(x, m);
314 return result < 0.f ? result + m : result;
315}
316
317/** @ingroup BasicOps */
318float fastSin(float x)
319{
320 const float a = 1.2732395447351628f;
321 const float b = -0.4052847345693511f;
322 const float c = 0.2248391028f;
323 const float y = a * x + b * x * fabsf(x);
324 return c * (y * fabsf(y) - y) + y;
325}
326
327/** @ingroup BasicOps */
328float expm1(float x)
329{
330#if LASS_HAVE_EXPM1
331 return ::expm1f(x);
332#else
333 if (num::abs(x) < 1e-4)
334 {
335 return x + .5f * x * x;
336 }
337 return num::exp(x) - 1;
338#endif
339}
340
341/** @ingroup BasicOps */
342float log1p(float x)
343{
344#if LASS_HAVE_EXPM1
345 return ::log1pf(x);
346#else
347 if (num::abs(x) < 1e-4)
348 {
349 return x - .5f * x * x;
350 }
351 return num::log(1 + x);
352#endif
353}
354
355// --- double --------------------------------------------------------------------------------------
356
357double abs(double x) { return ::fabs(x); } /**< @ingroup BasicOps */
358double inv(double x) { return 1. / x; } /**< @ingroup BasicOps */
359double sqrt(double x) { LASS_ASSERT(!(x < 0.)); return ::sqrt(x); } /**< @ingroup BasicOps */
360double pow(double x, double p) { return ::pow(x, p); } /**< @ingroup BasicOps */
361double exp(double x) { return ::exp(x); } /**< @ingroup BasicOps */
362double log(double x) { return ::log(x); } /**< @ingroup BasicOps */
363double log2(double x) { return double(LASS_NUM_INVLOG2) * ::log(x); } /**< @ingroup BasicOps */
364double log10(double x) { return ::log10(x); } /**< @ingroup BasicOps */
365double cos(double x) { return ::cos(x); } /**< @ingroup BasicOps */
366double sin(double x) { return ::sin(x); } /**< @ingroup BasicOps */
367double tan(double x) { return ::tan(x); } /**< @ingroup BasicOps */
368double acos(double x) { return ::acos(x); } /**< @ingroup BasicOps */
369double asin(double x) { return ::asin(x); } /**< @ingroup BasicOps */
370double atan(double x) { return ::atan(x); } /**< @ingroup BasicOps */
371double atan2(double y, double x) { return ::atan2(y, x); } /**< @ingroup BasicOps */
372double floor(double x) { return ::floor(x); } /**< @ingroup BasicOps */
373double ceil(double x) { return ::ceil(x); } /**< @ingroup BasicOps */
374double round(double x) { return ::floor(x + .5); } /**< @ingroup BasicOps */
375double fractional(double x) { return x - ::floor(x); } /**< @ingroup BasicOps */
376
377#if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
378# pragma warning(push)
379# pragma warning(disable: 4723) // potential divide by 0
380#endif
381double sinc(double x) { return ::fabs(x) < 1e-8 ? 1. : (::sin(x) / x); } /**< @ingroup BasicOps */
382#if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
383# pragma warning(pop)
384#endif
385
386/** @ingroup BasicOps */
387double mod(double x, double m)
388{
389 const double result = ::fmod(x, m);
390 return result < 0. ? result + m : result;
391}
392
393/** @ingroup BasicOps */
394double fastSin(double x)
395{
396 const double a = 1.2732395447351628;
397 const double b = -0.4052847345693511;
398 const double c = 0.2248391028;
399 const double y = a * x + b * x * fabs(x);
400 return c * (y * fabs(y) - y) + y;
401}
402
403/** @ingroup BasicOps */
404double expm1(double x)
405{
406#if LASS_HAVE_EXPM1
407 return ::expm1(x);
408#else
409 if (num::abs(x) < 1e-8)
410 {
411 return x + .5 * x * x;
412 }
413 return num::exp(x) - 1;
414#endif
415}
416
417/** @ingroup BasicOps */
418double log1p(double x)
419{
420#if LASS_HAVE_EXPM1
421 return ::log1p(x);
422#else
423 if (num::abs(x) < 1e-8)
424 {
425 return x - .5f * x * x;
426 }
427 return num::log(1 + x);
428#endif
429}
430
431
432// --- long double ---------------------------------------------------------------------------------
433
434#ifdef LASS_NUM_BASIC_OPS_USE_BUILTIN_LONG_DOUBLE
435
436long double abs(long double x) { return __builtin_fabsl(x); } /**< @ingroup BasicOps */
437long double inv(long double x) { return 1. / x; } /**< @ingroup BasicOps */
438long double sqrt(long double x) { LASS_ASSERT(!(x < 0.)); return __builtin_sqrtl(x); } /**< @ingroup BasicOps */
439long double pow(long double x, long double p) { return __builtin_powl(x, p); } /**< @ingroup BasicOps */
440long double exp(long double x) { return __builtin_expl(x); } /**< @ingroup BasicOps */
441long double log(long double x) { return __builtin_logl(x); } /**< @ingroup BasicOps */
442long double log2(long double x) { return (long double)(LASS_NUM_INVLOG2) * __builtin_logl(x); } /**< @ingroup BasicOps */
443long double log10(long double x) { return __builtin_log10l(x); } /**< @ingroup BasicOps */
444long double cos(long double x) { return __builtin_cosl(x); } /**< @ingroup BasicOps */
445long double sin(long double x) { return __builtin_sinl(x); } /**< @ingroup BasicOps */
446long double tan(long double x) { return __builtin_tanl(x); } /**< @ingroup BasicOps */
447long double acos(long double x) { return __builtin_acosl(x); } /**< @ingroup BasicOps */
448long double asin(long double x) { return __builtin_asinl(x); } /**< @ingroup BasicOps */
449long double atan(long double x) { return __builtin_atanl(x); } /**< @ingroup BasicOps */
450long double atan2(long double y, long double x) { return __builtin_atan2l(y, x); } /**< @ingroup BasicOps */
451long double sinc(long double x) { return __builtin_fabsl(x) < 1e-10 ? 1. : (__builtin_sinl(x) / x); } /**< @ingroup BasicOps */
452long double floor(long double x) { return __builtin_floorl(x); } /**< @ingroup BasicOps */
453long double ceil(long double x) { return __builtin_ceill(x); } /**< @ingroup BasicOps */
454long double round(long double x) { return __builtin_floorl(x + .5); } /**< @ingroup BasicOps */
455long double fractional(long double x) { return x - __builtin_floorl(x); } /**< @ingroup BasicOps */
456
457/** @ingroup BasicOps */
458long double mod(long double x, long double m)
459{
460 const long double result = __builtin_fmodl(x, m);
461 return result < 0. ? result + m : result;
462}
463
464#elif LASS_HAVE_LONG_DOUBLE_STD_FUNCTIONS
465
466long double abs(long double x) { return ::fabsl(x); } /**< @ingroup BasicOps */
467long double inv(long double x) { return 1. / x; } /**< @ingroup BasicOps */
468long double sqrt(long double x) { LASS_ASSERT(!(x < 0.)); return ::sqrtl(x); } /**< @ingroup BasicOps */
469long double pow(long double x, long double p) { return ::powl(x, p); } /**< @ingroup BasicOps */
470long double exp(long double x) { return ::expl(x); } /**< @ingroup BasicOps */
471long double log(long double x) { return ::logl(x); } /**< @ingroup BasicOps */
472long double log2(long double x) { return (long double)(LASS_NUM_INVLOG2) * ::logl(x); } /**< @ingroup BasicOps */
473long double log10(long double x) { return ::log10l(x); } /**< @ingroup BasicOps */
474long double cos(long double x) { return ::cosl(x); } /**< @ingroup BasicOps */
475long double sin(long double x) { return ::sinl(x); } /**< @ingroup BasicOps */
476long double tan(long double x) { return ::tanl(x); } /**< @ingroup BasicOps */
477long double acos(long double x) { return ::acosl(x); } /**< @ingroup BasicOps */
478long double asin(long double x) { return ::asinl(x); } /**< @ingroup BasicOps */
479long double atan(long double x) { return ::atanl(x); } /**< @ingroup BasicOps */
480long double atan2(long double y, long double x) { return ::atan2l(y, x); } /**< @ingroup BasicOps */
481long double floor(long double x) { return ::floorl(x); } /**< @ingroup BasicOps */
482long double ceil(long double x) { return ::ceill(x); } /**< @ingroup BasicOps */
483long double round(long double x) { return ::floorl(x + .5); } /**< @ingroup BasicOps */
484long double fractional(long double x) { return x - ::floorl(x); } /**< @ingroup BasicOps */
485
486#if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
487# pragma warning(push)
488# pragma warning(disable: 4723) // potential divide by 0
489#endif
490long double sinc(long double x) { return ::fabsl(x) < 1e-10 ? 1. : (::sinl(x) / x); } /**< @ingroup BasicOps */
491#if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
492# pragma warning(pop)
493#endif
494
495/** @ingroup BasicOps */
496long double mod(long double x, long double m)
497{
498 const long double result = ::fmodl(x, m);
499 return result < 0. ? result + m : result;
500}
501
502#endif
503
504#if LASS_HAVE_LONG_DOUBLE
505
506/** @ingroup BasicOps */
507long double fastSin(long double x)
508{
509 const long double a = 1.2732395447351628;
510 const long double b = -0.4052847345693511;
511 const long double c = 0.2248391028;
512 const long double y = a * x + b * x * num::abs(x);
513 return c * (y * num::abs(y) - y) + y;
514}
515
516/** @ingroup BasicOps */
517long double expm1(long double x)
518{
519 if (num::abs(x) < 1e-10)
520 {
521 return x + .5 * x * x;
522 }
523 return num::exp(x) - 1;
524}
525
526/** @ingroup BasicOps */
527long double log1p(long double x)
528{
529 if (num::abs(x) < 1e-10)
530 {
531 return x - .5f * x * x;
532 }
533 return num::log(1 + x);
534}
535
536#endif
537
538
539// --- char ----------------------------------------------------------------------------------------
540
541#ifdef LASS_CHAR_IS_SIGNED
542
543char pow(char x, char p) { return impl::IntPow<char>::eval(x, static_cast<signed char>(p)); } /**< @ingroup BasicOps */
544char pow(char x, unsigned char p) { return impl::IntPow<char>::eval(x, p); } /**< @ingroup BasicOps */
545char div(char x, char m) { return impl::IntDiv<char>::eval(x, static_cast<signed char>(m)); } /**< @ingroup BasicOps */
546char div(char x, unsigned char m) { return impl::IntDiv<char>::eval(x, m); } /**< @ingroup BasicOps */
547char mod(char x, char m) { return impl::IntMod<char>::eval(x, static_cast<signed char>(m)); } /**< @ingroup BasicOps */
548unsigned char mod(char x, unsigned char m) { return impl::IntMod<char>::eval(x, m); } /**< @ingroup BasicOps */
549
550#else
551
552char abs(char x) { return x; } /**< @ingroup BasicOps */
553char sign(char x) { return x > 0 ? 1 : 0; } /**< @ingroup BasicOps */
554char pow(char x, char p) { return impl::IntPow<char>::eval(x, static_cast<unsigned char>(p)); } /**< @ingroup BasicOps */
555char div(char x, char p) { return x / p; } /**< @ingroup BasicOps */
556char mod(char x, char p) { return x % p; } /**< @ingroup BasicOps */
557
558#endif
559
560char floor(char x) { return x; } /**< @ingroup BasicOps */
561char ceil(char x) { return x; } /**< @ingroup BasicOps */
562char round(char x) { return x; } /**< @ingroup BasicOps */
563char fractional(char /*x*/) { return 0; } /**< @ingroup BasicOps */
564
565void inpfloor(char& /*x*/) {} /**< @ingroup BasicOps */
566void inpceil(char& /*x*/) {} /**< @ingroup BasicOps */
567void inpround(char& /*x*/) {} /**< @ingroup BasicOps */
568void inpfractional(char& x) { x = 0; } /**< @ingroup BasicOps */
569
570// --- signed char ----------------------------------------------------------------------------------
571
572signed char abs(signed char x) { return static_cast<signed char>(::abs(x)); } /**< @ingroup BasicOps */
573signed char pow(signed char x, signed char p) { return impl::IntPow<signed char>::eval(x, p); } /**< @ingroup BasicOps */
574signed char pow(signed char x, unsigned char p) { return impl::IntPow<signed char>::eval(x, p); } /**< @ingroup BasicOps */
575signed char floor(signed char x) { return x; } /**< @ingroup BasicOps */
576signed char ceil(signed char x) { return x; } /**< @ingroup BasicOps */
577signed char round(signed char x) { return x; } /**< @ingroup BasicOps */
578signed char fractional(signed char /*x*/) { return 0; } /**< @ingroup BasicOps */
579signed char div(signed char x, signed char p) { return impl::IntDiv<signed char>::eval(x, p); } /**< @ingroup BasicOps */
580signed char div(signed char x, unsigned char p) { return impl::IntDiv<signed char>::eval(x, p); } /**< @ingroup BasicOps */
581signed char mod(signed char x, signed char p) { return impl::IntMod<signed char>::eval(x, p); } /**< @ingroup BasicOps */
582unsigned char mod(signed char x, unsigned char p) { return impl::IntMod<signed char>::eval(x, p); } /**< @ingroup BasicOps */
583
584void inpfloor(signed char& /*x*/) {} /**< @ingroup BasicOps */
585void inpceil(signed char& /*x*/) {} /**< @ingroup BasicOps */
586void inpround(signed char& /*x*/) {} /**< @ingroup BasicOps */
587void inpfractional(signed char& x) { x = 0; } /**< @ingroup BasicOps */
588
589
590
591// --- unsigned char ----------------------------------------------------------------------------------
592
593unsigned char abs(unsigned char x) { return x; } /**< @ingroup BasicOps */
594unsigned char sign(unsigned char x) { return x > 0 ? 1 : 0; } /**< @ingroup BasicOps */
595unsigned char pow(unsigned char x, unsigned char p) { return impl::IntPow<unsigned char>::eval(x, p); } /**< @ingroup BasicOps */
596unsigned char floor(unsigned char x) { return x; } /**< @ingroup BasicOps */
597unsigned char ceil(unsigned char x) { return x; } /**< @ingroup BasicOps */
598unsigned char round(unsigned char x) { return x; } /**< @ingroup BasicOps */
599unsigned char fractional(unsigned char /*x*/) { return 0; } /**< @ingroup BasicOps */
600unsigned char div(unsigned char x, unsigned char p) { return x / p; } /**< @ingroup BasicOps */
601unsigned char mod(unsigned char x, unsigned char p) { return x % p; } /**< @ingroup BasicOps */
602
603void inpabs(unsigned char& /*x*/) {} /**< @ingroup BasicOps */
604void inpfloor(unsigned char& /*x*/) {} /**< @ingroup BasicOps */
605void inpceil(unsigned char& /*x*/) {} /**< @ingroup BasicOps */
606void inpround(unsigned char& /*x*/) {} /**< @ingroup BasicOps */
607void inpfractional(unsigned char& x) { x = 0; } /**< @ingroup BasicOps */
608
609
610
611// --- signed short ----------------------------------------------------------------------------------
612
613signed short abs(signed short x) { return static_cast<signed short>(::abs(x)); } /**< @ingroup BasicOps */
614signed short pow(signed short x, signed short p) { return impl::IntPow<short>::eval(x, p); } /**< @ingroup BasicOps */
615signed short pow(signed short x, unsigned short p) { return impl::IntPow<short>::eval(x, p); } /**< @ingroup BasicOps */
616signed short floor(signed short x) { return x; } /**< @ingroup BasicOps */
617signed short ceil(signed short x) { return x; } /**< @ingroup BasicOps */
618signed short round(signed short x) { return x; } /**< @ingroup BasicOps */
619signed short fractional(signed short /*x*/) { return 0; } /**< @ingroup BasicOps */
620signed short div(signed short x, signed short p) { return impl::IntDiv<short>::eval(x, p); } /**< @ingroup BasicOps */
621signed short div(signed short x, unsigned short p) { return impl::IntDiv<short>::eval(x, p); } /**< @ingroup BasicOps */
622signed short mod(signed short x, signed short p) { return impl::IntMod<short>::eval(x, p); } /**< @ingroup BasicOps */
623unsigned short mod(signed short x, unsigned short p) { return impl::IntMod<short>::eval(x, p); } /**< @ingroup BasicOps */
624
625void inpfloor(signed short& /*x*/) {} /**< @ingroup BasicOps */
626void inpceil(signed short& /*x*/) {} /**< @ingroup BasicOps */
627void inpround(signed short& /*x*/) {} /**< @ingroup BasicOps */
628void inpfractional(signed short& x) { x = 0; } /**< @ingroup BasicOps */
629
630
631
632// --- unsigned short ----------------------------------------------------------------------------------
633
634unsigned short abs(unsigned short x) { return x; } /**< @ingroup BasicOps */
635unsigned short sign(unsigned short x) { return x > 0 ? 1 : 0; } /**< @ingroup BasicOps */
636unsigned short pow(unsigned short x, unsigned short p) { return impl::IntPow<unsigned short>::eval(x, p); } /**< @ingroup BasicOps */
637unsigned short floor(unsigned short x) { return x; } /**< @ingroup BasicOps */
638unsigned short ceil(unsigned short x) { return x; } /**< @ingroup BasicOps */
639unsigned short round(unsigned short x) { return x; } /**< @ingroup BasicOps */
640unsigned short fractional(unsigned short /*x*/) { return 0; } /**< @ingroup BasicOps */
641unsigned short div(unsigned short x, unsigned short p) { return x / p; } /**< @ingroup BasicOps */
642unsigned short mod(unsigned short x, unsigned short p) { return x % p; } /**< @ingroup BasicOps */
643
644void inpabs(unsigned short& /*x*/) {} /**< @ingroup BasicOps */
645void inpfloor(unsigned short& /*x*/) {} /**< @ingroup BasicOps */
646void inpceil(unsigned short& /*x*/) {} /**< @ingroup BasicOps */
647void inpround(unsigned short& /*x*/) {} /**< @ingroup BasicOps */
648void inpfractional(unsigned short& x) { x = 0; } /**< @ingroup BasicOps */
649
650
651
652// --- signed int ----------------------------------------------------------------------------------
653
654signed int abs(signed int x) { return ::abs(x); } /**< @ingroup BasicOps */
655signed int pow(signed int x, signed int p) { return impl::IntPow<int>::eval(x, p); } /**< @ingroup BasicOps */
656signed int pow(signed int x, unsigned int p) { return impl::IntPow<int>::eval(x, p); } /**< @ingroup BasicOps */
657signed int floor(signed int x) { return x; } /**< @ingroup BasicOps */
658signed int ceil(signed int x) { return x; } /**< @ingroup BasicOps */
659signed int round(signed int x) { return x; } /**< @ingroup BasicOps */
660signed int fractional(signed int /*x*/) { return 0; } /**< @ingroup BasicOps */
661signed int div(signed int x, signed int p) { return impl::IntDiv<int>::eval(x, p); } /**< @ingroup BasicOps */
662signed int div(signed int x, unsigned int p) { return impl::IntDiv<int>::eval(x, p); } /**< @ingroup BasicOps */
663signed int mod(signed int x, signed int p) { return impl::IntMod<int>::eval(x, p); } /**< @ingroup BasicOps */
664unsigned int mod(signed int x, unsigned int p) { return impl::IntMod<int>::eval(x, p); } /**< @ingroup BasicOps */
665
666void inpfloor(signed int& /*x*/) {} /**< @ingroup BasicOps */
667void inpceil(signed int& /*x*/) {} /**< @ingroup BasicOps */
668void inpround(signed int& /*x*/) {} /**< @ingroup BasicOps */
669void inpfractional(signed int& x) { x = 0; } /**< @ingroup BasicOps */
670
671
672
673// --- unsigned int ----------------------------------------------------------------------------------
674
675unsigned int abs(unsigned int x) { return x; } /**< @ingroup BasicOps */
676unsigned int sign(unsigned int x) { return x > 0 ? 1 : 0; } /**< @ingroup BasicOps */
677unsigned int pow(unsigned int x, unsigned int p) { return impl::IntPow<unsigned int>::eval(x, p); } /**< @ingroup BasicOps */
678unsigned int floor(unsigned int x) { return x; } /**< @ingroup BasicOps */
679unsigned int ceil(unsigned int x) { return x; } /**< @ingroup BasicOps */
680unsigned int round(unsigned int x) { return x; } /**< @ingroup BasicOps */
681unsigned int fractional(unsigned int /*x*/) { return 0; } /**< @ingroup BasicOps */
682unsigned int div(unsigned int x, unsigned int p) { return x / p; } /**< @ingroup BasicOps */
683unsigned int mod(unsigned int x, unsigned int p) { return x % p; } /**< @ingroup BasicOps */
684
685void inpabs(unsigned int& /*x*/) {} /**< @ingroup BasicOps */
686void inpfloor(unsigned int& /*x*/) {} /**< @ingroup BasicOps */
687void inpceil(unsigned int& /*x*/) {} /**< @ingroup BasicOps */
688void inpround(unsigned int& /*x*/) {} /**< @ingroup BasicOps */
689void inpfractional(unsigned int& x) { x = 0; } /**< @ingroup BasicOps */
690
691
692
693// --- signed long ----------------------------------------------------------------------------------
694
695signed long abs(signed long x) { return ::labs(x); } /**< @ingroup BasicOps */
696signed long pow(signed long x, signed long p) { return impl::IntPow<long>::eval(x, p); } /**< @ingroup BasicOps */
697signed long pow(signed long x, unsigned long p) { return impl::IntPow<long>::eval(x, p); } /**< @ingroup BasicOps */
698signed long floor(signed long x) { return x; } /**< @ingroup BasicOps */
699signed long ceil(signed long x) { return x; } /**< @ingroup BasicOps */
700signed long round(signed long x) { return x; } /**< @ingroup BasicOps */
701signed long fractional(signed long /*x*/) { return 0; } /**< @ingroup BasicOps */
702signed long div(signed long x, signed long p) { return impl::IntDiv<long>::eval(x, p); } /**< @ingroup BasicOps */
703signed long div(signed long x, unsigned long p) { return impl::IntDiv<long>::eval(x, p); } /**< @ingroup BasicOps */
704signed long mod(signed long x, signed long p) { return impl::IntMod<long>::eval(x, p); } /**< @ingroup BasicOps */
705unsigned long mod(signed long x, unsigned long p) { return impl::IntMod<long>::eval(x, p); } /**< @ingroup BasicOps */
706
707void inpfloor(signed long& /*x*/) {} /**< @ingroup BasicOps */
708void inpceil(signed long& /*x*/) {} /**< @ingroup BasicOps */
709void inpround(signed long& /*x*/) {} /**< @ingroup BasicOps */
710void inpfractional(signed long& x) { x = 0; } /**< @ingroup BasicOps */
711
712
713
714// --- unsigned long ----------------------------------------------------------------------------------
715
716unsigned long abs(unsigned long x) { return x; } /**< @ingroup BasicOps */
717unsigned long sign(unsigned long x) { return x > 0 ? 1 : 0; } /**< @ingroup BasicOps */
718unsigned long pow(unsigned long x, unsigned long p) { return impl::IntPow<unsigned long>::eval(x, p); } /**< @ingroup BasicOps */
719unsigned long floor(unsigned long x) { return x; } /**< @ingroup BasicOps */
720unsigned long ceil(unsigned long x) { return x; } /**< @ingroup BasicOps */
721unsigned long round(unsigned long x) { return x; } /**< @ingroup BasicOps */
722unsigned long fractional(unsigned long /*x*/) { return 0; } /**< @ingroup BasicOps */
723unsigned long div(unsigned long x, unsigned long p) { return x / p; } /**< @ingroup BasicOps */
724unsigned long mod(unsigned long x, unsigned long p) { return x % p; } /**< @ingroup BasicOps */
725
726void inpabs(unsigned long& /*x*/) {} /**< @ingroup BasicOps */
727void inpfloor(unsigned long& /*x*/) {} /**< @ingroup BasicOps */
728void inpceil(unsigned long& /*x*/) {} /**< @ingroup BasicOps */
729void inpround(unsigned long& /*x*/) {} /**< @ingroup BasicOps */
730void inpfractional(unsigned long& x) { x = 0; } /**< @ingroup BasicOps */
731
732
733
734#if LASS_HAVE_LONG_LONG
735
736// --- signed long long ----------------------------------------------------------------------------------
737
738/** @ingroup BasicOps */
739signed long long abs(signed long long x)
740{
741#if LASS_HAVE_LLABS
742 return ::llabs(x);
743#elif LASS_HAVE_ABS64
744 return ::_abs64(x);
745#else
746 return abs<long long>(x);
747#endif
748}
749signed long long pow(signed long long x, signed long long p) { return impl::IntPow<long long>::eval(x, p); } /**< @ingroup BasicOps */
750signed long long pow(signed long long x, unsigned long long p) { return impl::IntPow<long long>::eval(x, p); } /**< @ingroup BasicOps */
751signed long long floor(signed long long x) { return x; } /**< @ingroup BasicOps */
752signed long long ceil(signed long long x) { return x; } /**< @ingroup BasicOps */
753signed long long round(signed long long x) { return x; } /**< @ingroup BasicOps */
754signed long long fractional(signed long long /*x*/) { return 0; } /**< @ingroup BasicOps */
755signed long long div(signed long long x, signed long long p) { return impl::IntDiv<long long>::eval(x, p); } /**< @ingroup BasicOps */
756signed long long div(signed long long x, unsigned long long p) { return impl::IntDiv<long long>::eval(x, p); } /**< @ingroup BasicOps */
757signed long long mod(signed long long x, signed long long p) { return impl::IntMod<long long>::eval(x, p); } /**< @ingroup BasicOps */
758unsigned long long mod(signed long long x, unsigned long long p) { return impl::IntMod<long long>::eval(x, p); } /**< @ingroup BasicOps */
759
760void inpfloor(signed long long& /*x*/) {} /**< @ingroup BasicOps */
761void inpceil(signed long long& /*x*/) {} /**< @ingroup BasicOps */
762void inpround(signed long long& /*x*/) {} /**< @ingroup BasicOps */
763void inpfractional(signed long long& x) { x = 0; } /**< @ingroup BasicOps */
764
765
766
767// --- unsigned long long ----------------------------------------------------------------------------------
768
769unsigned long long abs(unsigned long long x) { return x; } /**< @ingroup BasicOps */
770unsigned long long sign(unsigned long long x) { return x > 0 ? 1 : 0; } /**< @ingroup BasicOps */
771unsigned long long pow(unsigned long long x, unsigned long long p) { return impl::IntPow<unsigned long long>::eval(x, p); } /**< @ingroup BasicOps */
772unsigned long long floor(unsigned long long x) { return x; } /**< @ingroup BasicOps */
773unsigned long long ceil(unsigned long long x) { return x; } /**< @ingroup BasicOps */
774unsigned long long round(unsigned long long x) { return x; } /**< @ingroup BasicOps */
775unsigned long long fractional(unsigned long long /*x*/) { return 0; } /**< @ingroup BasicOps */
776unsigned long long div(unsigned long long x, unsigned long long p) { return x / p; } /**< @ingroup BasicOps */
777unsigned long long mod(unsigned long long x, unsigned long long p) { return x % p; } /**< @ingroup BasicOps */
778
779void inpabs(unsigned long long& /*x*/) {} /**< @ingroup BasicOps */
780void inpfloor(unsigned long long& /*x*/) {} /**< @ingroup BasicOps */
781void inpceil(unsigned long long& /*x*/) {} /**< @ingroup BasicOps */
782void inpround(unsigned long long& /*x*/) {} /**< @ingroup BasicOps */
783void inpfractional(unsigned long long& x) { x = 0; } /**< @ingroup BasicOps */
784
785#endif
786
787
788
789
790// --- complex numbers -----------------------------------------------------------------------------
791
792template <typename T> T abs( const std::complex<T>& x) { return std::abs( x ); } /**< @ingroup BasicOps */
793template <typename T> std::complex<T> inv( const std::complex<T>& x) { return T(1)/x; } /**< @ingroup BasicOps */
794template <typename T> std::complex<T> sqrt( const std::complex<T>& x){ return std::sqrt( x ); } /**< @ingroup BasicOps */
795template <typename T> std::complex<T> pow(const std::complex<T>& x, double p) { return std::pow(x, p); } /**< @ingroup BasicOps */
796template <typename T> std::complex<T> exp( const std::complex<T>& x) { return std::exp( x ); } /**< @ingroup BasicOps */
797template <typename T> std::complex<T> log( const std::complex<T>& x) { return std::log( x ); } /**< @ingroup BasicOps */
798template <typename T> std::complex<T> log2( const std::complex<T>& x) { return T(LASS_NUM_INVLOG2) * std::log( x ); } /**< @ingroup BasicOps */
799template <typename T> std::complex<T> log10( const std::complex<T>& x) { return T(LASS_NUM_INVLOG10) * std::log( x ); } /**< @ingroup BasicOps */
800template <typename T> std::complex<T> cos( const std::complex<T>& x) { return std::cos( x ); } /**< @ingroup BasicOps */
801template <typename T> std::complex<T> sin( const std::complex<T>& x) { return std::sin( x ); } /**< @ingroup BasicOps */
802template <typename T> std::complex<T> tan( const std::complex<T>& x) { return std::tan( x ); } /**< @ingroup BasicOps */
803template <typename T> std::complex<T> acos( const std::complex<T>& x){ return std::acos( x ); } /**< @ingroup BasicOps */
804template <typename T> std::complex<T> asin( const std::complex<T>& x){ return std::asin( x ); } /**< @ingroup BasicOps */
805template <typename T> std::complex<T> atan( const std::complex<T>& x){ return std::atan( x ); } /**< @ingroup BasicOps */
806
807template <typename T> T norm(const std::complex<T>& x) { return std::norm( x ); } /**< @ingroup BasicOps */
808template <typename T> std::complex<T> conj(const std::complex<T>& x) { return std::conj(x); } /**< @ingroup BasicOps */
T conj(const T &x)
return conjugate as if x is a complex number: x
T pow(const T &x, const T &p)
return exp(p * log(x));
T log2(const T &x)
return log(x) / log(2)
T norm(const T &x)
return norm of x as if x is real part of complex number: sqr(x)
T abs(const T &x)
if x < 0 return -x, else return x.
T inv(const T &x)
return x ^ -1
T sqr(const T &x)
return x * x
T lerp(const T &a, const T &b, const T &f)
linear interpolation between a and b
T log10(const T &x)
return log(x) / log(10)
const T & clamp(const T &x, const T &min, const T &max)
if x < min return min, else if x > max return max, else return x.
T sign(const T &x)
if x < 0 return -1, else if x > 0 return 1, else return 0.
T cubic(const T &x)
return x * x * x