core_func_common.cpp 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462
  1. #define GLM_FORCE_EXPLICIT_CTOR
  2. #include <glm/gtc/constants.hpp>
  3. #include <glm/gtc/random.hpp>
  4. #include <glm/gtc/vec1.hpp>
  5. #include <glm/ext/scalar_relational.hpp>
  6. #include <glm/ext/vector_relational.hpp>
  7. #include <glm/ext/vector_float1.hpp>
  8. #include <glm/common.hpp>
  9. #include <glm/vec4.hpp>
  10. #include <glm/vec3.hpp>
  11. #include <glm/vec2.hpp>
  12. #include <vector>
  13. #include <cstdio>
  14. #include <cmath>
  15. #include <ctime>
  16. // This file has divisions by zero to test isnan
  17. #if GLM_COMPILER & GLM_COMPILER_VC
  18. # pragma warning(push)
  19. # pragma warning(disable : 4723)
  20. #endif
  21. namespace floor_
  22. {
  23. static int test()
  24. {
  25. int Error = 0;
  26. {
  27. float A = 1.1f;
  28. float B = glm::floor(A);
  29. Error += glm::equal(B, 1.f, 0.0001f) ? 0 : 1;
  30. }
  31. {
  32. double A = 1.1;
  33. double B = glm::floor(A);
  34. Error += glm::equal(B, 1.0, 0.0001) ? 0 : 1;
  35. }
  36. {
  37. glm::vec1 A(1.1f);
  38. glm::vec1 B = glm::floor(A);
  39. Error += glm::all(glm::equal(B, glm::vec1(1.0), 0.0001f)) ? 0 : 1;
  40. }
  41. {
  42. glm::dvec1 A(1.1);
  43. glm::dvec1 B = glm::floor(A);
  44. Error += glm::all(glm::equal(B, glm::dvec1(1.0), 0.0001)) ? 0 : 1;
  45. }
  46. {
  47. glm::vec2 A(1.1f);
  48. glm::vec2 B = glm::floor(A);
  49. Error += glm::all(glm::equal(B, glm::vec2(1.0), 0.0001f)) ? 0 : 1;
  50. }
  51. {
  52. glm::dvec2 A(1.1);
  53. glm::dvec2 B = glm::floor(A);
  54. Error += glm::all(glm::equal(B, glm::dvec2(1.0), 0.0001)) ? 0 : 1;
  55. }
  56. {
  57. glm::vec3 A(1.1f);
  58. glm::vec3 B = glm::floor(A);
  59. Error += glm::all(glm::equal(B, glm::vec3(1.0), 0.0001f)) ? 0 : 1;
  60. }
  61. {
  62. glm::dvec3 A(1.1);
  63. glm::dvec3 B = glm::floor(A);
  64. Error += glm::all(glm::equal(B, glm::dvec3(1.0), 0.0001)) ? 0 : 1;
  65. }
  66. {
  67. glm::vec4 A(1.1f);
  68. glm::vec4 B = glm::floor(A);
  69. Error += glm::all(glm::equal(B, glm::vec4(1.0), 0.0001f)) ? 0 : 1;
  70. }
  71. {
  72. glm::dvec4 A(1.1);
  73. glm::dvec4 B = glm::floor(A);
  74. Error += glm::all(glm::equal(B, glm::dvec4(1.0), 0.0001)) ? 0 : 1;
  75. }
  76. return Error;
  77. }
  78. }//namespace floor
  79. namespace modf_
  80. {
  81. static int test()
  82. {
  83. int Error(0);
  84. {
  85. float X(1.5f);
  86. float I(0.0f);
  87. float A = glm::modf(X, I);
  88. Error += glm::equal(I, 1.0f, 0.0001f) ? 0 : 1;
  89. Error += glm::equal(A, 0.5f, 0.0001f) ? 0 : 1;
  90. }
  91. {
  92. glm::vec4 X(1.1f, 1.2f, 1.5f, 1.7f);
  93. glm::vec4 I(0.0f);
  94. glm::vec4 A = glm::modf(X, I);
  95. Error += glm::ivec4(I) == glm::ivec4(1) ? 0 : 1;
  96. Error += glm::all(glm::equal(A, glm::vec4(0.1f, 0.2f, 0.5f, 0.7f), 0.00001f)) ? 0 : 1;
  97. }
  98. {
  99. glm::dvec4 X(1.1, 1.2, 1.5, 1.7);
  100. glm::dvec4 I(0.0);
  101. glm::dvec4 A = glm::modf(X, I);
  102. Error += glm::ivec4(I) == glm::ivec4(1) ? 0 : 1;
  103. Error += glm::all(glm::equal(A, glm::dvec4(0.1, 0.2, 0.5, 0.7), 0.000000001)) ? 0 : 1;
  104. }
  105. {
  106. double X(1.5);
  107. double I(0.0);
  108. double A = glm::modf(X, I);
  109. Error += glm::equal(I, 1.0, 0.0001) ? 0 : 1;
  110. Error += glm::equal(A, 0.5, 0.0001) ? 0 : 1;
  111. }
  112. return Error;
  113. }
  114. }//namespace modf
  115. namespace mod_
  116. {
  117. static int test()
  118. {
  119. int Error(0);
  120. {
  121. float A(1.5f);
  122. float B(1.0f);
  123. float C = glm::mod(A, B);
  124. Error += glm::equal(C, 0.5f, 0.00001f) ? 0 : 1;
  125. }
  126. {
  127. float A(-0.2f);
  128. float B(1.0f);
  129. float C = glm::mod(A, B);
  130. Error += glm::equal(C, 0.8f, 0.00001f) ? 0 : 1;
  131. }
  132. {
  133. float A(3.0);
  134. float B(2.0f);
  135. float C = glm::mod(A, B);
  136. Error += glm::equal(C, 1.0f, 0.00001f) ? 0 : 1;
  137. }
  138. {
  139. glm::vec4 A(3.0);
  140. float B(2.0f);
  141. glm::vec4 C = glm::mod(A, B);
  142. Error += glm::all(glm::equal(C, glm::vec4(1.0f), 0.00001f)) ? 0 : 1;
  143. }
  144. {
  145. glm::vec4 A(3.0);
  146. glm::vec4 B(2.0f);
  147. glm::vec4 C = glm::mod(A, B);
  148. Error += glm::all(glm::equal(C, glm::vec4(1.0f), 0.00001f)) ? 0 : 1;
  149. }
  150. return Error;
  151. }
  152. }//namespace mod_
  153. namespace floatBitsToInt
  154. {
  155. static int test()
  156. {
  157. int Error = 0;
  158. {
  159. float A = 1.0f;
  160. int B = glm::floatBitsToInt(A);
  161. float C = glm::intBitsToFloat(B);
  162. Error += glm::equal(A, C, 0.0001f) ? 0 : 1;
  163. }
  164. {
  165. glm::vec2 A(1.0f, 2.0f);
  166. glm::ivec2 B = glm::floatBitsToInt(A);
  167. glm::vec2 C = glm::intBitsToFloat(B);
  168. Error += glm::all(glm::equal(A, C, 0.0001f)) ? 0 : 1;
  169. }
  170. {
  171. glm::vec3 A(1.0f, 2.0f, 3.0f);
  172. glm::ivec3 B = glm::floatBitsToInt(A);
  173. glm::vec3 C = glm::intBitsToFloat(B);
  174. Error += glm::all(glm::equal(A, C, 0.0001f)) ? 0 : 1;
  175. }
  176. {
  177. glm::vec4 A(1.0f, 2.0f, 3.0f, 4.0f);
  178. glm::ivec4 B = glm::floatBitsToInt(A);
  179. glm::vec4 C = glm::intBitsToFloat(B);
  180. Error += glm::all(glm::equal(A, C, 0.0001f)) ? 0 : 1;
  181. }
  182. return Error;
  183. }
  184. }//namespace floatBitsToInt
  185. namespace floatBitsToUint
  186. {
  187. static int test()
  188. {
  189. int Error = 0;
  190. {
  191. float A = 1.0f;
  192. glm::uint B = glm::floatBitsToUint(A);
  193. float C = glm::uintBitsToFloat(B);
  194. Error += glm::equal(A, C, 0.0001f) ? 0 : 1;
  195. }
  196. {
  197. glm::vec2 A(1.0f, 2.0f);
  198. glm::uvec2 B = glm::floatBitsToUint(A);
  199. glm::vec2 C = glm::uintBitsToFloat(B);
  200. Error += glm::all(glm::equal(A, C, 0.0001f)) ? 0 : 1;
  201. }
  202. {
  203. glm::vec3 A(1.0f, 2.0f, 3.0f);
  204. glm::uvec3 B = glm::floatBitsToUint(A);
  205. glm::vec3 C = glm::uintBitsToFloat(B);
  206. Error += glm::all(glm::equal(A, C, 0.0001f)) ? 0 : 1;
  207. }
  208. {
  209. glm::vec4 A(1.0f, 2.0f, 3.0f, 4.0f);
  210. glm::uvec4 B = glm::floatBitsToUint(A);
  211. glm::vec4 C = glm::uintBitsToFloat(B);
  212. Error += glm::all(glm::equal(A, C, 0.0001f)) ? 0 : 1;
  213. }
  214. return Error;
  215. }
  216. }//namespace floatBitsToUint
  217. namespace min_
  218. {
  219. static int test()
  220. {
  221. int Error = 0;
  222. glm::vec1 A0 = glm::min(glm::vec1(1), glm::vec1(1));
  223. bool A1 = glm::all(glm::equal(A0, glm::vec1(1), glm::epsilon<float>()));
  224. Error += A1 ? 0 : 1;
  225. glm::vec2 B0 = glm::min(glm::vec2(1), glm::vec2(1));
  226. glm::vec2 B1 = glm::min(glm::vec2(1), 1.0f);
  227. bool B2 = glm::all(glm::equal(B0, B1, glm::epsilon<float>()));
  228. Error += B2 ? 0 : 1;
  229. glm::vec3 C0 = glm::min(glm::vec3(1), glm::vec3(1));
  230. glm::vec3 C1 = glm::min(glm::vec3(1), 1.0f);
  231. bool C2 = glm::all(glm::equal(C0, C1, glm::epsilon<float>()));
  232. Error += C2 ? 0 : 1;
  233. glm::vec4 D0 = glm::min(glm::vec4(1), glm::vec4(1));
  234. glm::vec4 D1 = glm::min(glm::vec4(1), 1.0f);
  235. bool D2 = glm::all(glm::equal(D0, D1, glm::epsilon<float>()));
  236. Error += D2 ? 0 : 1;
  237. return Error;
  238. }
  239. #if GLM_HAS_CONSTEXPR
  240. static int test_constexpr()
  241. {
  242. constexpr glm::vec1 A0 = glm::min(glm::vec1(1), glm::vec1(1));
  243. static_assert(glm::all(glm::equal(A0, glm::vec1(1), glm::epsilon<float>())), "GLM: Failed constexpr");
  244. constexpr glm::vec2 B0 = glm::min(glm::vec2(1), glm::vec2(1));
  245. constexpr glm::vec2 B1 = glm::min(glm::vec2(1), 1.0f);
  246. static_assert(glm::all(glm::equal(B0, B1, glm::epsilon<float>())), "GLM: Failed constexpr");
  247. constexpr glm::vec3 C0 = glm::min(glm::vec3(1), glm::vec3(1));
  248. constexpr glm::vec3 C1 = glm::min(glm::vec3(1), 1.0f);
  249. static_assert(glm::all(glm::equal(C0, C1, glm::epsilon<float>())), "GLM: Failed constexpr");
  250. constexpr glm::vec4 D0 = glm::min(glm::vec4(1), glm::vec4(1));
  251. constexpr glm::vec4 D1 = glm::min(glm::vec4(1), 1.0f);
  252. static_assert(glm::all(glm::equal(D0, D1, glm::epsilon<float>())), "GLM: Failed constexpr");
  253. return 0;
  254. }
  255. #endif
  256. static int min_tern(int a, int b)
  257. {
  258. return a < b ? a : b;
  259. }
  260. static int min_int(int x, int y)
  261. {
  262. return y ^ ((x ^ y) & -(x < y));
  263. }
  264. static int perf(std::size_t Count)
  265. {
  266. std::vector<int> A(Count);
  267. std::vector<int> B(Count);
  268. std::size_t const InternalCount = 200000;
  269. for(std::size_t i = 0; i < Count; ++i)
  270. {
  271. A[i] = glm::linearRand(-1000, 1000);
  272. B[i] = glm::linearRand(-1000, 1000);
  273. }
  274. int Error = 0;
  275. glm::int32 SumA = 0;
  276. {
  277. std::clock_t Timestamp0 = std::clock();
  278. for (std::size_t j = 0; j < InternalCount; ++j)
  279. for (std::size_t i = 0; i < Count; ++i)
  280. SumA += min_tern(A[i], B[i]);
  281. std::clock_t Timestamp1 = std::clock();
  282. std::printf("min_tern Time %d clocks\n", static_cast<int>(Timestamp1 - Timestamp0));
  283. }
  284. glm::int32 SumB = 0;
  285. {
  286. std::clock_t Timestamp0 = std::clock();
  287. for (std::size_t j = 0; j < InternalCount; ++j)
  288. for (std::size_t i = 0; i < Count; ++i)
  289. SumB += min_int(A[i], B[i]);
  290. std::clock_t Timestamp1 = std::clock();
  291. std::printf("min_int Time %d clocks\n", static_cast<int>(Timestamp1 - Timestamp0));
  292. }
  293. Error += SumA == SumB ? 0 : 1;
  294. return Error;
  295. }
  296. }//namespace min_
  297. namespace max_
  298. {
  299. static int test()
  300. {
  301. int Error = 0;
  302. glm::vec1 A0 = glm::max(glm::vec1(1), glm::vec1(1));
  303. bool A1 = glm::all(glm::equal(A0, glm::vec1(1), glm::epsilon<float>()));
  304. Error += A1 ? 0 : 1;
  305. glm::vec2 B0 = glm::max(glm::vec2(1), glm::vec2(1));
  306. glm::vec2 B1 = glm::max(glm::vec2(1), 1.0f);
  307. bool B2 = glm::all(glm::equal(B0, B1, glm::epsilon<float>()));
  308. Error += B2 ? 0 : 1;
  309. glm::vec3 C0 = glm::max(glm::vec3(1), glm::vec3(1));
  310. glm::vec3 C1 = glm::max(glm::vec3(1), 1.0f);
  311. bool C2 = glm::all(glm::equal(C0, C1, glm::epsilon<float>()));
  312. Error += C2 ? 0 : 1;
  313. glm::vec4 D0 = glm::max(glm::vec4(1), glm::vec4(1));
  314. glm::vec4 D1 = glm::max(glm::vec4(1), 1.0f);
  315. bool D2 = glm::all(glm::equal(D0, D1, glm::epsilon<float>()));
  316. Error += D2 ? 0 : 1;
  317. return Error;
  318. }
  319. #if GLM_HAS_CONSTEXPR
  320. static int test_constexpr()
  321. {
  322. constexpr glm::vec1 A0 = glm::max(glm::vec1(1), glm::vec1(1));
  323. static_assert(glm::all(glm::equal(A0, glm::vec1(1), glm::epsilon<float>())), "GLM: Failed constexpr");
  324. constexpr glm::vec2 B0 = glm::max(glm::vec2(1), glm::vec2(1));
  325. constexpr glm::vec2 B1 = glm::max(glm::vec2(1), 1.0f);
  326. static_assert(glm::all(glm::equal(B0, B1, glm::epsilon<float>())), "GLM: Failed constexpr");
  327. constexpr glm::vec3 C0 = glm::max(glm::vec3(1), glm::vec3(1));
  328. constexpr glm::vec3 C1 = glm::max(glm::vec3(1), 1.0f);
  329. static_assert(glm::all(glm::equal(C0, C1, glm::epsilon<float>())), "GLM: Failed constexpr");
  330. constexpr glm::vec4 D0 = glm::max(glm::vec4(1), glm::vec4(1));
  331. constexpr glm::vec4 D1 = glm::max(glm::vec4(1), 1.0f);
  332. static_assert(glm::all(glm::equal(D0, D1, glm::epsilon<float>())), "GLM: Failed constexpr");
  333. return 0;
  334. }
  335. #endif
  336. }//namespace max_
  337. namespace clamp_
  338. {
  339. static int test()
  340. {
  341. int Error = 0;
  342. return Error;
  343. }
  344. }//namespace clamp_
  345. namespace mix_
  346. {
  347. #if GLM_COMPILER & GLM_COMPILER_CLANG
  348. # pragma clang diagnostic push
  349. # pragma clang diagnostic ignored "-Wpadded"
  350. #endif
  351. template<typename T, typename B>
  352. struct entry
  353. {
  354. T x;
  355. T y;
  356. B a;
  357. T Result;
  358. };
  359. #if GLM_COMPILER & GLM_COMPILER_CLANG
  360. # pragma clang diagnostic pop
  361. #endif
  362. #if GLM_COMPILER & GLM_COMPILER_CLANG
  363. # pragma clang diagnostic push
  364. # pragma clang diagnostic ignored "-Wglobal-constructors"
  365. #endif
  366. static entry<float, bool> const TestBool[] =
  367. {
  368. {0.0f, 1.0f, false, 0.0f},
  369. {0.0f, 1.0f, true, 1.0f},
  370. {-1.0f, 1.0f, false, -1.0f},
  371. {-1.0f, 1.0f, true, 1.0f}
  372. };
  373. static entry<float, float> const TestFloat[] =
  374. {
  375. {0.0f, 1.0f, 0.0f, 0.0f},
  376. {0.0f, 1.0f, 1.0f, 1.0f},
  377. {-1.0f, 1.0f, 0.0f, -1.0f},
  378. {-1.0f, 1.0f, 1.0f, 1.0f}
  379. };
  380. static entry<glm::vec2, bool> const TestVec2Bool[] =
  381. {
  382. {glm::vec2(0.0f), glm::vec2(1.0f), false, glm::vec2(0.0f)},
  383. {glm::vec2(0.0f), glm::vec2(1.0f), true, glm::vec2(1.0f)},
  384. {glm::vec2(-1.0f), glm::vec2(1.0f), false, glm::vec2(-1.0f)},
  385. {glm::vec2(-1.0f), glm::vec2(1.0f), true, glm::vec2(1.0f)}
  386. };
  387. static entry<glm::vec2, glm::bvec2> const TestBVec2[] =
  388. {
  389. {glm::vec2(0.0f), glm::vec2(1.0f), glm::bvec2(false), glm::vec2(0.0f)},
  390. {glm::vec2(0.0f), glm::vec2(1.0f), glm::bvec2(true), glm::vec2(1.0f)},
  391. {glm::vec2(-1.0f), glm::vec2(1.0f), glm::bvec2(false), glm::vec2(-1.0f)},
  392. {glm::vec2(-1.0f), glm::vec2(1.0f), glm::bvec2(true), glm::vec2(1.0f)},
  393. {glm::vec2(-1.0f), glm::vec2(1.0f), glm::bvec2(true, false), glm::vec2(1.0f, -1.0f)}
  394. };
  395. static entry<glm::vec3, bool> const TestVec3Bool[] =
  396. {
  397. {glm::vec3(0.0f), glm::vec3(1.0f), false, glm::vec3(0.0f)},
  398. {glm::vec3(0.0f), glm::vec3(1.0f), true, glm::vec3(1.0f)},
  399. {glm::vec3(-1.0f), glm::vec3(1.0f), false, glm::vec3(-1.0f)},
  400. {glm::vec3(-1.0f), glm::vec3(1.0f), true, glm::vec3(1.0f)}
  401. };
  402. static entry<glm::vec3, glm::bvec3> const TestBVec3[] =
  403. {
  404. {glm::vec3(0.0f), glm::vec3(1.0f), glm::bvec3(false), glm::vec3(0.0f)},
  405. {glm::vec3(0.0f), glm::vec3(1.0f), glm::bvec3(true), glm::vec3(1.0f)},
  406. {glm::vec3(-1.0f), glm::vec3(1.0f), glm::bvec3(false), glm::vec3(-1.0f)},
  407. {glm::vec3(-1.0f), glm::vec3(1.0f), glm::bvec3(true), glm::vec3(1.0f)},
  408. {glm::vec3(1.0f, 2.0f, 3.0f), glm::vec3(4.0f, 5.0f, 6.0f), glm::bvec3(true, false, true), glm::vec3(4.0f, 2.0f, 6.0f)}
  409. };
  410. static entry<glm::vec4, bool> const TestVec4Bool[] =
  411. {
  412. {glm::vec4(0.0f), glm::vec4(1.0f), false, glm::vec4(0.0f)},
  413. {glm::vec4(0.0f), glm::vec4(1.0f), true, glm::vec4(1.0f)},
  414. {glm::vec4(-1.0f), glm::vec4(1.0f), false, glm::vec4(-1.0f)},
  415. {glm::vec4(-1.0f), glm::vec4(1.0f), true, glm::vec4(1.0f)}
  416. };
  417. static entry<glm::vec4, glm::bvec4> const TestBVec4[] =
  418. {
  419. {glm::vec4(0.0f, 0.0f, 1.0f, 1.0f), glm::vec4(2.0f, 2.0f, 3.0f, 3.0f), glm::bvec4(false, true, false, true), glm::vec4(0.0f, 2.0f, 1.0f, 3.0f)},
  420. {glm::vec4(0.0f), glm::vec4(1.0f), glm::bvec4(true), glm::vec4(1.0f)},
  421. {glm::vec4(-1.0f), glm::vec4(1.0f), glm::bvec4(false), glm::vec4(-1.0f)},
  422. {glm::vec4(-1.0f), glm::vec4(1.0f), glm::bvec4(true), glm::vec4(1.0f)},
  423. {glm::vec4(1.0f, 2.0f, 3.0f, 4.0f), glm::vec4(5.0f, 6.0f, 7.0f, 8.0f), glm::bvec4(true, false, true, false), glm::vec4(5.0f, 2.0f, 7.0f, 4.0f)}
  424. };
  425. #if GLM_COMPILER & GLM_COMPILER_CLANG
  426. # pragma clang diagnostic pop
  427. #endif
  428. static int test()
  429. {
  430. int Error = 0;
  431. // Float with bool
  432. {
  433. for(std::size_t i = 0; i < sizeof(TestBool) / sizeof(entry<float, bool>); ++i)
  434. {
  435. float Result = glm::mix(TestBool[i].x, TestBool[i].y, TestBool[i].a);
  436. Error += glm::equal(Result, TestBool[i].Result, glm::epsilon<float>()) ? 0 : 1;
  437. }
  438. }
  439. // Float with float
  440. {
  441. for(std::size_t i = 0; i < sizeof(TestFloat) / sizeof(entry<float, float>); ++i)
  442. {
  443. float Result = glm::mix(TestFloat[i].x, TestFloat[i].y, TestFloat[i].a);
  444. Error += glm::equal(Result, TestFloat[i].Result, glm::epsilon<float>()) ? 0 : 1;
  445. }
  446. }
  447. // vec2 with bool
  448. {
  449. for(std::size_t i = 0; i < sizeof(TestVec2Bool) / sizeof(entry<glm::vec2, bool>); ++i)
  450. {
  451. glm::vec2 Result = glm::mix(TestVec2Bool[i].x, TestVec2Bool[i].y, TestVec2Bool[i].a);
  452. Error += glm::equal(Result.x, TestVec2Bool[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  453. Error += glm::equal(Result.y, TestVec2Bool[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  454. }
  455. }
  456. // vec2 with bvec2
  457. {
  458. for(std::size_t i = 0; i < sizeof(TestBVec2) / sizeof(entry<glm::vec2, glm::bvec2>); ++i)
  459. {
  460. glm::vec2 Result = glm::mix(TestBVec2[i].x, TestBVec2[i].y, TestBVec2[i].a);
  461. Error += glm::equal(Result.x, TestBVec2[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  462. Error += glm::equal(Result.y, TestBVec2[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  463. }
  464. }
  465. // vec3 with bool
  466. {
  467. for(std::size_t i = 0; i < sizeof(TestVec3Bool) / sizeof(entry<glm::vec3, bool>); ++i)
  468. {
  469. glm::vec3 Result = glm::mix(TestVec3Bool[i].x, TestVec3Bool[i].y, TestVec3Bool[i].a);
  470. Error += glm::equal(Result.x, TestVec3Bool[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  471. Error += glm::equal(Result.y, TestVec3Bool[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  472. Error += glm::equal(Result.z, TestVec3Bool[i].Result.z, glm::epsilon<float>()) ? 0 : 1;
  473. }
  474. }
  475. // vec3 with bvec3
  476. {
  477. for(std::size_t i = 0; i < sizeof(TestBVec3) / sizeof(entry<glm::vec3, glm::bvec3>); ++i)
  478. {
  479. glm::vec3 Result = glm::mix(TestBVec3[i].x, TestBVec3[i].y, TestBVec3[i].a);
  480. Error += glm::equal(Result.x, TestBVec3[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  481. Error += glm::equal(Result.y, TestBVec3[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  482. Error += glm::equal(Result.z, TestBVec3[i].Result.z, glm::epsilon<float>()) ? 0 : 1;
  483. }
  484. }
  485. // vec4 with bool
  486. {
  487. for(std::size_t i = 0; i < sizeof(TestVec4Bool) / sizeof(entry<glm::vec4, bool>); ++i)
  488. {
  489. glm::vec4 Result = glm::mix(TestVec4Bool[i].x, TestVec4Bool[i].y, TestVec4Bool[i].a);
  490. Error += glm::equal(Result.x, TestVec4Bool[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  491. Error += glm::equal(Result.y, TestVec4Bool[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  492. Error += glm::equal(Result.z, TestVec4Bool[i].Result.z, glm::epsilon<float>()) ? 0 : 1;
  493. Error += glm::equal(Result.w, TestVec4Bool[i].Result.w, glm::epsilon<float>()) ? 0 : 1;
  494. }
  495. }
  496. // vec4 with bvec4
  497. {
  498. for(std::size_t i = 0; i < sizeof(TestBVec4) / sizeof(entry<glm::vec4, glm::bvec4>); ++i)
  499. {
  500. glm::vec4 Result = glm::mix(TestBVec4[i].x, TestBVec4[i].y, TestBVec4[i].a);
  501. Error += glm::equal(Result.x, TestBVec4[i].Result.x, glm::epsilon<float>()) ? 0 : 1;
  502. Error += glm::equal(Result.y, TestBVec4[i].Result.y, glm::epsilon<float>()) ? 0 : 1;
  503. Error += glm::equal(Result.z, TestBVec4[i].Result.z, glm::epsilon<float>()) ? 0 : 1;
  504. Error += glm::equal(Result.w, TestBVec4[i].Result.w, glm::epsilon<float>()) ? 0 : 1;
  505. }
  506. }
  507. return Error;
  508. }
  509. }//namespace mix_
  510. namespace step_
  511. {
  512. template<typename EDGE, typename VEC>
  513. struct entry
  514. {
  515. EDGE edge;
  516. VEC x;
  517. VEC result;
  518. };
  519. #if GLM_COMPILER & GLM_COMPILER_CLANG
  520. # pragma clang diagnostic push
  521. # pragma clang diagnostic ignored "-Wglobal-constructors"
  522. #endif
  523. static const entry<float, glm::vec4> TestVec4Scalar [] =
  524. {
  525. { 1.0f, glm::vec4(1.0f, 2.0f, 3.0f, 4.0f), glm::vec4(1.0f) },
  526. { 0.0f, glm::vec4(1.0f, 2.0f, 3.0f, 4.0f), glm::vec4(1.0f) },
  527. { 0.0f, glm::vec4(-1.0f, -2.0f, -3.0f, -4.0f), glm::vec4(0.0f) }
  528. };
  529. static const entry<glm::vec4, glm::vec4> TestVec4Vector [] =
  530. {
  531. { glm::vec4(-1.0f, -2.0f, -3.0f, -4.0f), glm::vec4(-2.0f, -3.0f, -4.0f, -5.0f), glm::vec4(0.0f) },
  532. { glm::vec4( 0.0f, 1.0f, 2.0f, 3.0f), glm::vec4( 1.0f, 2.0f, 3.0f, 4.0f), glm::vec4(1.0f) },
  533. { glm::vec4( 2.0f, 3.0f, 4.0f, 5.0f), glm::vec4( 1.0f, 2.0f, 3.0f, 4.0f), glm::vec4(0.0f) },
  534. { glm::vec4( 0.0f, 1.0f, 2.0f, 3.0f), glm::vec4(-1.0f,-2.0f,-3.0f,-4.0f), glm::vec4(0.0f) }
  535. };
  536. #if GLM_COMPILER & GLM_COMPILER_CLANG
  537. # pragma clang diagnostic pop
  538. #endif
  539. static int test()
  540. {
  541. int Error = 0;
  542. // scalar
  543. {
  544. float const Edge = 2.0f;
  545. float const A = glm::step(Edge, 1.0f);
  546. Error += glm::equal(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  547. float const B = glm::step(Edge, 3.0f);
  548. Error += glm::equal(B, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  549. float const C = glm::step(Edge, 2.0f);
  550. Error += glm::equal(C, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  551. }
  552. // vec4 and float
  553. {
  554. for (std::size_t i = 0; i < sizeof(TestVec4Scalar) / sizeof(entry<float, glm::vec4>); ++i)
  555. {
  556. glm::vec4 Result = glm::step(TestVec4Scalar[i].edge, TestVec4Scalar[i].x);
  557. Error += glm::all(glm::equal(Result, TestVec4Scalar[i].result, glm::epsilon<float>())) ? 0 : 1;
  558. }
  559. }
  560. // vec4 and vec4
  561. {
  562. for (std::size_t i = 0; i < sizeof(TestVec4Vector) / sizeof(entry<glm::vec4, glm::vec4>); ++i)
  563. {
  564. glm::vec4 Result = glm::step(TestVec4Vector[i].edge, TestVec4Vector[i].x);
  565. Error += glm::all(glm::equal(Result, TestVec4Vector[i].result, glm::epsilon<float>())) ? 0 : 1;
  566. }
  567. }
  568. return Error;
  569. }
  570. }//namespace step_
  571. namespace smoothstep_
  572. {
  573. static int test()
  574. {
  575. int Error = 0;
  576. float const Edge = 2.0f;
  577. // scalar
  578. {
  579. float const A = glm::smoothstep(0.0f, Edge, 1.0f);
  580. Error += glm::equal(A, 0.5f, glm::epsilon<float>()) ? 0 : 1;
  581. float const B = glm::smoothstep(0.0f, Edge, 1.0f);
  582. Error += glm::equal(B, 0.5f, glm::epsilon<float>()) ? 0 : 1;
  583. float const C = glm::smoothstep(0.0f, Edge, 1.0f);
  584. Error += glm::equal(C, 0.5f, glm::epsilon<float>()) ? 0 : 1;
  585. }
  586. // vec4 and float
  587. {
  588. glm::vec4 Result = glm::smoothstep(0.0f, Edge, glm::vec4(1.0f));
  589. Error += glm::all(glm::equal(Result, glm::vec4(0.5f), glm::epsilon<float>())) ? 0 : 1;
  590. }
  591. // vec4 and vec4
  592. {
  593. glm::vec4 Result = glm::smoothstep(glm::vec4(0.0f), glm::vec4(Edge), glm::vec4(1.0f));
  594. Error += glm::all(glm::equal(Result, glm::vec4(0.5f), glm::epsilon<float>())) ? 0 : 1;
  595. }
  596. return Error;
  597. }
  598. }//namespace smoothstep_
  599. namespace round_
  600. {
  601. static int test()
  602. {
  603. int Error = 0;
  604. {
  605. float A = glm::round(0.0f);
  606. Error += glm::equal(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  607. float B = glm::round(0.5f);
  608. Error += (glm::equal(B, 1.0f, glm::epsilon<float>()) || glm::equal(B, 0.0f, glm::epsilon<float>())) ? 0 : 1;
  609. float C = glm::round(1.0f);
  610. Error += glm::equal(C, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  611. float D = glm::round(0.1f);
  612. Error += glm::equal(D, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  613. float E = glm::round(0.9f);
  614. Error += glm::equal(E, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  615. float F = glm::round(1.5f);
  616. Error += glm::equal(F, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  617. float G = glm::round(1.9f);
  618. Error += glm::equal(G, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  619. }
  620. {
  621. float A = glm::round(-0.0f);
  622. Error += glm::equal(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  623. float B = glm::round(-0.5f);
  624. Error += (glm::equal(B, -1.0f, glm::epsilon<float>()) || glm::equal(B, 0.0f, glm::epsilon<float>())) ? 0 : 1;
  625. float C = glm::round(-1.0f);
  626. Error += glm::equal(C, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  627. float D = glm::round(-0.1f);
  628. Error += glm::equal(D, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  629. float E = glm::round(-0.9f);
  630. Error += glm::equal(E, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  631. float F = glm::round(-1.5f);
  632. Error += glm::equal(F, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  633. float G = glm::round(-1.9f);
  634. Error += glm::equal(G, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  635. }
  636. return Error;
  637. }
  638. }//namespace round_
  639. namespace roundEven
  640. {
  641. static int test()
  642. {
  643. int Error = 0;
  644. {
  645. float A1 = glm::roundEven(-1.5f);
  646. Error += glm::equal(A1, -2.0f, 0.0001f) ? 0 : 1;
  647. float A2 = glm::roundEven(1.5f);
  648. Error += glm::equal(A2, 2.0f, 0.0001f) ? 0 : 1;
  649. float A5 = glm::roundEven(-2.5f);
  650. Error += glm::equal(A5, -2.0f, 0.0001f) ? 0 : 1;
  651. float A6 = glm::roundEven(2.5f);
  652. Error += glm::equal(A6, 2.0f, 0.0001f) ? 0 : 1;
  653. float A3 = glm::roundEven(-3.5f);
  654. Error += glm::equal(A3, -4.0f, 0.0001f) ? 0 : 1;
  655. float A4 = glm::roundEven(3.5f);
  656. Error += glm::equal(A4, 4.0f, 0.0001f) ? 0 : 1;
  657. float C7 = glm::roundEven(-4.5f);
  658. Error += glm::equal(C7, -4.0f, 0.0001f) ? 0 : 1;
  659. float C8 = glm::roundEven(4.5f);
  660. Error += glm::equal(C8, 4.0f, 0.0001f) ? 0 : 1;
  661. float C1 = glm::roundEven(-5.5f);
  662. Error += glm::equal(C1, -6.0f, 0.0001f) ? 0 : 1;
  663. float C2 = glm::roundEven(5.5f);
  664. Error += glm::equal(C2, 6.0f, 0.0001f) ? 0 : 1;
  665. float C3 = glm::roundEven(-6.5f);
  666. Error += glm::equal(C3, -6.0f, 0.0001f) ? 0 : 1;
  667. float C4 = glm::roundEven(6.5f);
  668. Error += glm::equal(C4, 6.0f, 0.0001f) ? 0 : 1;
  669. float C5 = glm::roundEven(-7.5f);
  670. Error += glm::equal(C5, -8.0f, 0.0001f) ? 0 : 1;
  671. float C6 = glm::roundEven(7.5f);
  672. Error += glm::equal(C6, 8.0f, 0.0001f) ? 0 : 1;
  673. Error += 0;
  674. }
  675. {
  676. float A7 = glm::roundEven(-2.4f);
  677. Error += glm::equal(A7, -2.0f, 0.0001f) ? 0 : 1;
  678. float A8 = glm::roundEven(2.4f);
  679. Error += glm::equal(A8, 2.0f, 0.0001f) ? 0 : 1;
  680. float B1 = glm::roundEven(-2.6f);
  681. Error += glm::equal(B1, -3.0f, 0.0001f) ? 0 : 1;
  682. float B2 = glm::roundEven(2.6f);
  683. Error += glm::equal(B2, 3.0f, 0.0001f) ? 0 : 1;
  684. float B3 = glm::roundEven(-2.0f);
  685. Error += glm::equal(B3, -2.0f, 0.0001f) ? 0 : 1;
  686. float B4 = glm::roundEven(2.0f);
  687. Error += glm::equal(B4, 2.0f, 0.0001f) ? 0 : 1;
  688. Error += 0;
  689. }
  690. {
  691. float A = glm::roundEven(0.0f);
  692. Error += glm::equal(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  693. float B = glm::roundEven(0.5f);
  694. Error += glm::equal(B, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  695. float C = glm::roundEven(1.0f);
  696. Error += glm::equal(C, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  697. float D = glm::roundEven(0.1f);
  698. Error += glm::equal(D, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  699. float E = glm::roundEven(0.9f);
  700. Error += glm::equal(E, 1.0f, glm::epsilon<float>()) ? 0 : 1;
  701. float F = glm::roundEven(1.5f);
  702. Error += glm::equal(F, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  703. float G = glm::roundEven(1.9f);
  704. Error += glm::equal(G, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  705. }
  706. {
  707. float A = glm::roundEven(-0.0f);
  708. Error += glm::equal(A, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  709. float B = glm::roundEven(-0.5f);
  710. Error += glm::equal(B, -0.0f, glm::epsilon<float>()) ? 0 : 1;
  711. float C = glm::roundEven(-1.0f);
  712. Error += glm::equal(C, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  713. float D = glm::roundEven(-0.1f);
  714. Error += glm::equal(D, 0.0f, glm::epsilon<float>()) ? 0 : 1;
  715. float E = glm::roundEven(-0.9f);
  716. Error += glm::equal(E, -1.0f, glm::epsilon<float>()) ? 0 : 1;
  717. float F = glm::roundEven(-1.5f);
  718. Error += glm::equal(F, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  719. float G = glm::roundEven(-1.9f);
  720. Error += glm::equal(G, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  721. }
  722. {
  723. float A = glm::roundEven(1.5f);
  724. Error += glm::equal(A, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  725. float B = glm::roundEven(2.5f);
  726. Error += glm::equal(B, 2.0f, glm::epsilon<float>()) ? 0 : 1;
  727. float C = glm::roundEven(3.5f);
  728. Error += glm::equal(C, 4.0f, glm::epsilon<float>()) ? 0 : 1;
  729. float D = glm::roundEven(4.5f);
  730. Error += glm::equal(D, 4.0f, glm::epsilon<float>()) ? 0 : 1;
  731. float E = glm::roundEven(5.5f);
  732. Error += glm::equal(E, 6.0f, glm::epsilon<float>()) ? 0 : 1;
  733. float F = glm::roundEven(6.5f);
  734. Error += glm::equal(F, 6.0f, glm::epsilon<float>()) ? 0 : 1;
  735. float G = glm::roundEven(7.5f);
  736. Error += glm::equal(G, 8.0f, glm::epsilon<float>()) ? 0 : 1;
  737. }
  738. {
  739. float A = glm::roundEven(-1.5f);
  740. Error += glm::equal(A, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  741. float B = glm::roundEven(-2.5f);
  742. Error += glm::equal(B, -2.0f, glm::epsilon<float>()) ? 0 : 1;
  743. float C = glm::roundEven(-3.5f);
  744. Error += glm::equal(C, -4.0f, glm::epsilon<float>()) ? 0 : 1;
  745. float D = glm::roundEven(-4.5f);
  746. Error += glm::equal(D, -4.0f, glm::epsilon<float>()) ? 0 : 1;
  747. float E = glm::roundEven(-5.5f);
  748. Error += glm::equal(E, -6.0f, glm::epsilon<float>()) ? 0 : 1;
  749. float F = glm::roundEven(-6.5f);
  750. Error += glm::equal(F, -6.0f, glm::epsilon<float>()) ? 0 : 1;
  751. float G = glm::roundEven(-7.5f);
  752. Error += glm::equal(G, -8.0f, glm::epsilon<float>()) ? 0 : 1;
  753. }
  754. return Error;
  755. }
  756. }//namespace roundEven
  757. namespace isnan_
  758. {
  759. static int test()
  760. {
  761. int Error = 0;
  762. float Zero_f = 0.0;
  763. double Zero_d = 0.0;
  764. {
  765. Error += true == glm::isnan(0.0/Zero_d) ? 0 : 1;
  766. Error += true == glm::any(glm::isnan(glm::dvec2(0.0 / Zero_d))) ? 0 : 1;
  767. Error += true == glm::any(glm::isnan(glm::dvec3(0.0 / Zero_d))) ? 0 : 1;
  768. Error += true == glm::any(glm::isnan(glm::dvec4(0.0 / Zero_d))) ? 0 : 1;
  769. }
  770. {
  771. Error += true == glm::isnan(0.0f/Zero_f) ? 0 : 1;
  772. Error += true == glm::any(glm::isnan(glm::vec2(0.0f/Zero_f))) ? 0 : 1;
  773. Error += true == glm::any(glm::isnan(glm::vec3(0.0f/Zero_f))) ? 0 : 1;
  774. Error += true == glm::any(glm::isnan(glm::vec4(0.0f/Zero_f))) ? 0 : 1;
  775. }
  776. return Error;
  777. }
  778. }//namespace isnan_
  779. namespace isinf_
  780. {
  781. static int test()
  782. {
  783. int Error = 0;
  784. float Zero_f = 0.0;
  785. double Zero_d = 0.0;
  786. {
  787. Error += true == glm::isinf( 1.0/Zero_d) ? 0 : 1;
  788. Error += true == glm::isinf(-1.0/Zero_d) ? 0 : 1;
  789. Error += true == glm::any(glm::isinf(glm::dvec2( 1.0/Zero_d))) ? 0 : 1;
  790. Error += true == glm::any(glm::isinf(glm::dvec2(-1.0/Zero_d))) ? 0 : 1;
  791. Error += true == glm::any(glm::isinf(glm::dvec3( 1.0/Zero_d))) ? 0 : 1;
  792. Error += true == glm::any(glm::isinf(glm::dvec3(-1.0/Zero_d))) ? 0 : 1;
  793. Error += true == glm::any(glm::isinf(glm::dvec4( 1.0/Zero_d))) ? 0 : 1;
  794. Error += true == glm::any(glm::isinf(glm::dvec4(-1.0/Zero_d))) ? 0 : 1;
  795. }
  796. {
  797. Error += true == glm::isinf( 1.0f/Zero_f) ? 0 : 1;
  798. Error += true == glm::isinf(-1.0f/Zero_f) ? 0 : 1;
  799. Error += true == glm::any(glm::isinf(glm::vec2( 1.0f/Zero_f))) ? 0 : 1;
  800. Error += true == glm::any(glm::isinf(glm::vec2(-1.0f/Zero_f))) ? 0 : 1;
  801. Error += true == glm::any(glm::isinf(glm::vec3( 1.0f/Zero_f))) ? 0 : 1;
  802. Error += true == glm::any(glm::isinf(glm::vec3(-1.0f/Zero_f))) ? 0 : 1;
  803. Error += true == glm::any(glm::isinf(glm::vec4( 1.0f/Zero_f))) ? 0 : 1;
  804. Error += true == glm::any(glm::isinf(glm::vec4(-1.0f/Zero_f))) ? 0 : 1;
  805. }
  806. return Error;
  807. }
  808. }//namespace isinf_
  809. namespace sign
  810. {
  811. template<typename genFIType>
  812. GLM_FUNC_QUALIFIER genFIType sign_if(genFIType x)
  813. {
  814. static_assert(
  815. std::numeric_limits<genFIType>::is_iec559 ||
  816. (std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer), "'sign' only accept signed inputs");
  817. genFIType result;
  818. if(x > genFIType(0))
  819. result = genFIType(1);
  820. else if(x < genFIType(0))
  821. result = genFIType(-1);
  822. else
  823. result = genFIType(0);
  824. return result;
  825. }
  826. #if GLM_COMPILER & GLM_COMPILER_CLANG
  827. # pragma clang diagnostic push
  828. # pragma clang diagnostic ignored "-Wsign-conversion"
  829. #endif
  830. template<typename genFIType>
  831. GLM_FUNC_QUALIFIER genFIType sign_alu1(genFIType x)
  832. {
  833. static_assert(
  834. std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer,
  835. "'sign' only accept integer inputs");
  836. return (x >> 31) | (static_cast<unsigned>(-x) >> 31);
  837. }
  838. #if GLM_COMPILER & GLM_COMPILER_CLANG
  839. # pragma clang diagnostic pop
  840. #endif
  841. GLM_FUNC_QUALIFIER int sign_alu2(int x)
  842. {
  843. static_assert(std::numeric_limits<int>::is_signed && std::numeric_limits<int>::is_integer, "'sign' only accept integer inputs");
  844. # if GLM_COMPILER & GLM_COMPILER_VC
  845. # pragma warning(push)
  846. # pragma warning(disable : 4146) //cast truncates constant value
  847. # endif
  848. return -(static_cast<unsigned>(x) >> 31) | (-static_cast<unsigned>(x) >> 31);
  849. # if GLM_COMPILER & GLM_COMPILER_VC
  850. # pragma warning(pop)
  851. # endif
  852. }
  853. template<typename genFIType>
  854. GLM_FUNC_QUALIFIER genFIType sign_sub(genFIType x)
  855. {
  856. static_assert(
  857. std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer,
  858. "'sign' only accept integer inputs");
  859. return (static_cast<unsigned>(-x) >> 31) - (static_cast<unsigned>(x) >> 31);
  860. }
  861. template<typename genFIType>
  862. GLM_FUNC_QUALIFIER genFIType sign_cmp(genFIType x)
  863. {
  864. static_assert(
  865. std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer,
  866. "'sign' only accept integer inputs");
  867. return (x > 0) - (x < 0);
  868. }
  869. template<typename genType>
  870. struct type
  871. {
  872. genType Value;
  873. genType Return;
  874. };
  875. static int test_int32()
  876. {
  877. type<glm::int32> const Data[] =
  878. {
  879. { std::numeric_limits<glm::int32>::max(), 1},
  880. { std::numeric_limits<glm::int32>::min(), -1},
  881. { 0, 0},
  882. { 1, 1},
  883. { 2, 1},
  884. { 3, 1},
  885. {-1,-1},
  886. {-2,-1},
  887. {-3,-1}
  888. };
  889. int Error = 0;
  890. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  891. {
  892. glm::int32 Result = glm::sign(Data[i].Value);
  893. Error += Data[i].Return == Result ? 0 : 1;
  894. }
  895. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  896. {
  897. glm::int32 Result = sign_cmp(Data[i].Value);
  898. Error += Data[i].Return == Result ? 0 : 1;
  899. }
  900. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  901. {
  902. glm::int32 Result = sign_if(Data[i].Value);
  903. Error += Data[i].Return == Result ? 0 : 1;
  904. }
  905. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  906. {
  907. glm::int32 Result = sign_alu1(Data[i].Value);
  908. Error += Data[i].Return == Result ? 0 : 1;
  909. }
  910. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
  911. {
  912. glm::int32 Result = sign_alu2(Data[i].Value);
  913. Error += Data[i].Return == Result ? 0 : 1;
  914. }
  915. return Error;
  916. }
  917. static int test_i32vec4()
  918. {
  919. type<glm::ivec4> const Data[] =
  920. {
  921. {glm::ivec4( 1), glm::ivec4( 1)},
  922. {glm::ivec4( 0), glm::ivec4( 0)},
  923. {glm::ivec4( 2), glm::ivec4( 1)},
  924. {glm::ivec4( 3), glm::ivec4( 1)},
  925. {glm::ivec4(-1), glm::ivec4(-1)},
  926. {glm::ivec4(-2), glm::ivec4(-1)},
  927. {glm::ivec4(-3), glm::ivec4(-1)}
  928. };
  929. int Error = 0;
  930. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::ivec4>); ++i)
  931. {
  932. glm::ivec4 Result = glm::sign(Data[i].Value);
  933. Error += glm::all(glm::equal(Data[i].Return, Result)) ? 0 : 1;
  934. }
  935. return Error;
  936. }
  937. static int test_f32vec4()
  938. {
  939. type<glm::vec4> const Data[] =
  940. {
  941. {glm::vec4( 1), glm::vec4( 1)},
  942. {glm::vec4( 0), glm::vec4( 0)},
  943. {glm::vec4( 2), glm::vec4( 1)},
  944. {glm::vec4( 3), glm::vec4( 1)},
  945. {glm::vec4(-1), glm::vec4(-1)},
  946. {glm::vec4(-2), glm::vec4(-1)},
  947. {glm::vec4(-3), glm::vec4(-1)}
  948. };
  949. int Error = 0;
  950. for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::vec4>); ++i)
  951. {
  952. glm::vec4 Result = glm::sign(Data[i].Value);
  953. Error += glm::all(glm::equal(Data[i].Return, Result, glm::epsilon<float>())) ? 0 : 1;
  954. }
  955. return Error;
  956. }
  957. static int test()
  958. {
  959. int Error = 0;
  960. Error += test_int32();
  961. Error += test_i32vec4();
  962. Error += test_f32vec4();
  963. return Error;
  964. }
  965. static int perf_rand(std::size_t Samples)
  966. {
  967. int Error = 0;
  968. std::size_t const Count = Samples;
  969. std::vector<glm::int32> Input, Output;
  970. Input.resize(Count);
  971. Output.resize(Count);
  972. for(std::size_t i = 0; i < Count; ++i)
  973. Input[i] = static_cast<glm::int32>(glm::linearRand(-65536.f, 65536.f));
  974. std::clock_t Timestamp0 = std::clock();
  975. for(std::size_t i = 0; i < Count; ++i)
  976. Output[i] = sign_cmp(Input[i]);
  977. std::clock_t Timestamp1 = std::clock();
  978. for(std::size_t i = 0; i < Count; ++i)
  979. Output[i] = sign_if(Input[i]);
  980. std::clock_t Timestamp2 = std::clock();
  981. for(std::size_t i = 0; i < Count; ++i)
  982. Output[i] = sign_alu1(Input[i]);
  983. std::clock_t Timestamp3 = std::clock();
  984. for(std::size_t i = 0; i < Count; ++i)
  985. Output[i] = sign_alu2(Input[i]);
  986. std::clock_t Timestamp4 = std::clock();
  987. for(std::size_t i = 0; i < Count; ++i)
  988. Output[i] = sign_sub(Input[i]);
  989. std::clock_t Timestamp5 = std::clock();
  990. for(std::size_t i = 0; i < Count; ++i)
  991. Output[i] = glm::sign(Input[i]);
  992. std::clock_t Timestamp6 = std::clock();
  993. std::printf("sign_cmp(rand) Time %d clocks\n", static_cast<int>(Timestamp1 - Timestamp0));
  994. std::printf("sign_if(rand) Time %d clocks\n", static_cast<int>(Timestamp2 - Timestamp1));
  995. std::printf("sign_alu1(rand) Time %d clocks\n", static_cast<int>(Timestamp3 - Timestamp2));
  996. std::printf("sign_alu2(rand) Time %d clocks\n", static_cast<int>(Timestamp4 - Timestamp3));
  997. std::printf("sign_sub(rand) Time %d clocks\n", static_cast<int>(Timestamp5 - Timestamp4));
  998. std::printf("glm::sign(rand) Time %d clocks\n", static_cast<int>(Timestamp6 - Timestamp5));
  999. return Error;
  1000. }
  1001. static int perf_linear(std::size_t Samples)
  1002. {
  1003. int Error = 0;
  1004. std::size_t const Count = Samples;
  1005. std::vector<glm::int32> Input, Output;
  1006. Input.resize(Count);
  1007. Output.resize(Count);
  1008. for(std::size_t i = 0; i < Count; ++i)
  1009. Input[i] = static_cast<glm::int32>(i);
  1010. std::clock_t Timestamp0 = std::clock();
  1011. for(std::size_t i = 0; i < Count; ++i)
  1012. Output[i] = sign_cmp(Input[i]);
  1013. std::clock_t Timestamp1 = std::clock();
  1014. for(std::size_t i = 0; i < Count; ++i)
  1015. Output[i] = sign_if(Input[i]);
  1016. std::clock_t Timestamp2 = std::clock();
  1017. for(std::size_t i = 0; i < Count; ++i)
  1018. Output[i] = sign_alu1(Input[i]);
  1019. std::clock_t Timestamp3 = std::clock();
  1020. for(std::size_t i = 0; i < Count; ++i)
  1021. Output[i] = sign_alu2(Input[i]);
  1022. std::clock_t Timestamp4 = std::clock();
  1023. for(std::size_t i = 0; i < Count; ++i)
  1024. Output[i] = sign_sub(Input[i]);
  1025. std::clock_t Timestamp5 = std::clock();
  1026. std::printf("sign_cmp(linear) Time %d clocks\n", static_cast<int>(Timestamp1 - Timestamp0));
  1027. std::printf("sign_if(linear) Time %d clocks\n", static_cast<int>(Timestamp2 - Timestamp1));
  1028. std::printf("sign_alu1(linear) Time %d clocks\n", static_cast<int>(Timestamp3 - Timestamp2));
  1029. std::printf("sign_alu2(linear) Time %d clocks\n", static_cast<int>(Timestamp4 - Timestamp3));
  1030. std::printf("sign_sub(linear) Time %d clocks\n", static_cast<int>(Timestamp5 - Timestamp4));
  1031. return Error;
  1032. }
  1033. static int perf_linear_cal(std::size_t Samples)
  1034. {
  1035. int Error = 0;
  1036. glm::int32 const Count = static_cast<glm::int32>(Samples);
  1037. std::clock_t Timestamp0 = std::clock();
  1038. glm::int32 Sum = 0;
  1039. for(glm::int32 i = 1; i < Count; ++i)
  1040. Sum += sign_cmp(i);
  1041. std::clock_t Timestamp1 = std::clock();
  1042. for(glm::int32 i = 1; i < Count; ++i)
  1043. Sum += sign_if(i);
  1044. std::clock_t Timestamp2 = std::clock();
  1045. for(glm::int32 i = 1; i < Count; ++i)
  1046. Sum += sign_alu1(i);
  1047. std::clock_t Timestamp3 = std::clock();
  1048. for(glm::int32 i = 1; i < Count; ++i)
  1049. Sum += sign_alu2(i);
  1050. std::clock_t Timestamp4 = std::clock();
  1051. for(glm::int32 i = 1; i < Count; ++i)
  1052. Sum += sign_sub(i);
  1053. std::clock_t Timestamp5 = std::clock();
  1054. std::printf("Sum %d\n", static_cast<int>(Sum));
  1055. std::printf("sign_cmp(linear_cal) Time %d clocks\n", static_cast<int>(Timestamp1 - Timestamp0));
  1056. std::printf("sign_if(linear_cal) Time %d clocks\n", static_cast<int>(Timestamp2 - Timestamp1));
  1057. std::printf("sign_alu1(linear_cal) Time %d clocks\n", static_cast<int>(Timestamp3 - Timestamp2));
  1058. std::printf("sign_alu2(linear_cal) Time %d clocks\n", static_cast<int>(Timestamp4 - Timestamp3));
  1059. std::printf("sign_sub(linear_cal) Time %d clocks\n", static_cast<int>(Timestamp5 - Timestamp4));
  1060. return Error;
  1061. }
  1062. static int perf(std::size_t Samples)
  1063. {
  1064. int Error(0);
  1065. Error += perf_linear_cal(Samples);
  1066. Error += perf_linear(Samples);
  1067. Error += perf_rand(Samples);
  1068. return Error;
  1069. }
  1070. }//namespace sign
  1071. namespace frexp_
  1072. {
  1073. static int test()
  1074. {
  1075. int Error = 0;
  1076. {
  1077. glm::vec1 const x(1024);
  1078. glm::ivec1 exp;
  1079. glm::vec1 A = glm::frexp(x, exp);
  1080. Error += glm::all(glm::equal(A, glm::vec1(0.5), glm::epsilon<float>())) ? 0 : 1;
  1081. Error += glm::all(glm::equal(exp, glm::ivec1(11))) ? 0 : 1;
  1082. }
  1083. {
  1084. glm::vec2 const x(1024, 0.24);
  1085. glm::ivec2 exp;
  1086. glm::vec2 A = glm::frexp(x, exp);
  1087. Error += glm::all(glm::equal(A, glm::vec2(0.5, 0.96), glm::epsilon<float>())) ? 0 : 1;
  1088. Error += glm::all(glm::equal(exp, glm::ivec2(11, -2))) ? 0 : 1;
  1089. }
  1090. {
  1091. glm::vec3 const x(1024, 0.24, 0);
  1092. glm::ivec3 exp;
  1093. glm::vec3 A = glm::frexp(x, exp);
  1094. Error += glm::all(glm::equal(A, glm::vec3(0.5, 0.96, 0.0), glm::epsilon<float>())) ? 0 : 1;
  1095. Error += glm::all(glm::equal(exp, glm::ivec3(11, -2, 0))) ? 0 : 1;
  1096. }
  1097. {
  1098. glm::vec4 const x(1024, 0.24, 0, -1.33);
  1099. glm::ivec4 exp;
  1100. glm::vec4 A = glm::frexp(x, exp);
  1101. Error += glm::all(glm::equal(A, glm::vec4(0.5, 0.96, 0.0, -0.665), glm::epsilon<float>())) ? 0 : 1;
  1102. Error += glm::all(glm::equal(exp, glm::ivec4(11, -2, 0, 1))) ? 0 : 1;
  1103. }
  1104. return Error;
  1105. }
  1106. }//namespace frexp_
  1107. namespace ldexp_
  1108. {
  1109. static int test()
  1110. {
  1111. int Error = 0;
  1112. {
  1113. glm::vec1 A = glm::vec1(0.5);
  1114. glm::ivec1 exp = glm::ivec1(11);
  1115. glm::vec1 x = glm::ldexp(A, exp);
  1116. Error += glm::all(glm::equal(x, glm::vec1(1024),0.00001f)) ? 0 : 1;
  1117. }
  1118. {
  1119. glm::vec2 A = glm::vec2(0.5, 0.96);
  1120. glm::ivec2 exp = glm::ivec2(11, -2);
  1121. glm::vec2 x = glm::ldexp(A, exp);
  1122. Error += glm::all(glm::equal(x, glm::vec2(1024, .24),0.00001f)) ? 0 : 1;
  1123. }
  1124. {
  1125. glm::vec3 A = glm::vec3(0.5, 0.96, 0.0);
  1126. glm::ivec3 exp = glm::ivec3(11, -2, 0);
  1127. glm::vec3 x = glm::ldexp(A, exp);
  1128. Error += glm::all(glm::equal(x, glm::vec3(1024, .24, 0),0.00001f)) ? 0 : 1;
  1129. }
  1130. {
  1131. glm::vec4 A = glm::vec4(0.5, 0.96, 0.0, -0.665);
  1132. glm::ivec4 exp = glm::ivec4(11, -2, 0, 1);
  1133. glm::vec4 x = glm::ldexp(A, exp);
  1134. Error += glm::all(glm::equal(x, glm::vec4(1024, .24, 0, -1.33),0.00001f)) ? 0 : 1;
  1135. }
  1136. return Error;
  1137. }
  1138. }//namespace ldexp_
  1139. int main()
  1140. {
  1141. int Error = 0;
  1142. Error += sign::test();
  1143. Error += floor_::test();
  1144. Error += mod_::test();
  1145. Error += modf_::test();
  1146. Error += floatBitsToInt::test();
  1147. Error += floatBitsToUint::test();
  1148. Error += mix_::test();
  1149. Error += step_::test();
  1150. Error += smoothstep_::test();
  1151. Error += max_::test();
  1152. #if GLM_HAS_CONSTEXPR
  1153. Error += max_::test_constexpr();
  1154. #endif
  1155. Error += min_::test();
  1156. #if GLM_HAS_CONSTEXPR
  1157. Error += min_::test_constexpr();
  1158. #endif
  1159. Error += clamp_::test();
  1160. Error += round_::test();
  1161. Error += roundEven::test();
  1162. Error += isnan_::test();
  1163. Error += isinf_::test();
  1164. Error += frexp_::test();
  1165. Error += ldexp_::test();
  1166. # ifdef NDEBUG
  1167. std::size_t Samples = 1000;
  1168. # else
  1169. std::size_t Samples = 1;
  1170. # endif
  1171. Error += sign::perf(Samples);
  1172. Error += min_::perf(Samples);
  1173. return Error;
  1174. }
  1175. #if(GLM_COMPILER & GLM_COMPILER_VC)
  1176. # pragma warning(pop)
  1177. #endif