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 }