1 /**
2 Copyright: Copyright (c) 2015-2017 Andrey Penechko.
3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 
7 module voxelman.math.utils;
8 
9 import std.traits : isFloatingPoint;
10 import voxelman.math;
11 import std.algorithm : std_clamp = clamp;
12 
13 Vector!(T, n) abs(T, size_t n)(Vector!(T, n) vector) pure nothrow
14 {
15 	Vector!(T, n) result;
16 	foreach(i, elem; vector.arrayof)
17 		result[i] = elem < 0 ? -elem : elem;
18 	return result;
19 }
20 
21 Vector!(T, n) clamp(T, size_t n)(Vector!(T, n) vector, Vector!(T, n) lower, Vector!(T, n) upper) pure nothrow
22 {
23 	Vector!(T, n) result;
24 	foreach(i, ref elem; result.arrayof)
25 		elem = std_clamp(vector.arrayof[i], lower.arrayof[i], upper.arrayof[i]);
26 	return result;
27 }
28 
29 void nansToZero(T, int size)(ref Vector!(T, size) vector) pure nothrow
30 	if (isFloatingPoint!T)
31 {
32 	foreach(ref item; vector.arrayof)
33 	{
34 		item = isNaN(item) ? 0 : item;
35 	}
36 }
37 
38 void nansToZero(T, int size)(ref T[size] vector) pure nothrow
39 	if (isFloatingPoint!T)
40 {
41 	foreach(ref item; vector)
42 	{
43 		item = isNaN(item) ? 0 : item;
44 	}
45 }
46 
47 T nextPOT(T)(T x) pure nothrow {
48 	--x;
49 	x |= x >> 1;
50 	x |= x >> 2;
51 	x |= x >> 4;
52 	static if (T.sizeof >= 16) x |= x >>  8;
53 	static if (T.sizeof >= 32) x |= x >> 16;
54 	static if (T.sizeof >= 64) x |= x >> 32;
55 	++x;
56 
57 	return x;
58 }
59 
60 unittest {
61 	assert(nextPOT(1) == 1);
62 	assert(nextPOT(2) == 2);
63 	assert(nextPOT(3) == 4);
64 	assert(nextPOT(4) == 4);
65 	assert(nextPOT(5) == 8);
66 	assert(nextPOT(10) == 16);
67 	assert(nextPOT(30) == 32);
68 	assert(nextPOT(250) == 256);
69 	assert(nextPOT(1<<15+1) == 1<<16);
70 	assert(nextPOT(1UL<<31+1) == 1UL<<32);
71 	assert(nextPOT(1UL<<49+1) == 1UL<<50);
72 }