MathFu
An open source project by FPL.
 All Classes Namespaces Files Functions Variables Typedefs Friends Groups Pages
utilities.h
Go to the documentation of this file.
1 /*
2 * Copyright 2014 Google Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #ifndef MATHFU_UTILITIES_H_
17 #define MATHFU_UTILITIES_H_
18 
19 #include <assert.h>
20 #include <math.h>
21 #include <stdint.h>
22 #include <stdlib.h>
23 
24 #include <algorithm>
25 #include <memory>
26 
27 /// @file mathfu/utilities.h Utilities
28 /// @brief Utility macros and functions.
29 
30 /// @addtogroup mathfu_build_config
31 ///
32 /// By default MathFu will attempt to build with SIMD optimizations enabled
33 /// based upon the target architecture and compiler options. However, it's
34 /// possible to change the default build configuration using the following
35 /// macros:
36 ///
37 /// @li @ref MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT
38 /// @li @ref MATHFU_COMPILE_FORCE_PADDING
39 ///
40 /// <table>
41 /// <tr>
42 /// <th>MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT</th>
43 /// <th>MATHFU_COMPILE_FORCE_PADDING</th>
44 /// <th>Configuration</th>
45 /// </tr>
46 /// <tr>
47 /// <td><em>undefined</em></td>
48 /// <td><em>undefined</em> or 1</td>
49 /// <td>Default build configuration, SIMD optimization is enabled based upon
50 /// the target architecture, compiler options and MathFu library
51 /// support.</td>
52 /// </tr>
53 /// <tr>
54 /// <td><em>undefined</em></td>
55 /// <td>0</td>
56 /// <td>If SIMD is supported, padding of data structures is disabled. See
57 /// @ref MATHFU_COMPILE_FORCE_PADDING for more information.</td>
58 /// </tr>
59 /// <tr>
60 /// <td><em>defined</em></td>
61 /// <td><em>undefined/0/1</em></td>
62 /// <td>Builds MathFu with explicit SIMD optimization disabled. The compiler
63 /// could still potentially optimize some code paths with SIMD
64 /// instructions based upon the compiler options.</td>
65 /// </tr>
66 /// </table>
67 
68 #ifdef DOXYGEN
69 /// @addtogroup mathfu_build_config
70 /// @{
71 /// @def MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT
72 /// @brief Disable SIMD build configuration.
73 ///
74 /// When defined, this macro <b>disables</b> the default behavior of trying to
75 /// build the library with SIMD enabled based upon the target architecture
76 /// and compiler options.
77 ///
78 /// To use this build option, this macro <b>must</b> be defined in all modules
79 /// of the project.
80 #define MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT
81 /// @}
82 #endif // DOXYGEN
83 #if !defined(MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT)
84 #if defined(__SSE__)
85 #define MATHFU_COMPILE_WITH_SIMD
86 #elif defined(__ARM_NEON__)
87 #define MATHFU_COMPILE_WITH_SIMD
88 #elif defined(_M_IX86_FP) // MSVC
89 #if _M_IX86_FP >= 1 // SSE enabled
90 #define MATHFU_COMPILE_WITH_SIMD
91 #endif // _M_IX86_FP >= 1
92 #endif
93 #endif // !defined(MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT)
94 
95 #ifdef DOXYGEN
96 /// @addtogroup mathfu_build_config
97 /// @{
98 /// @def MATHFU_COMPILE_FORCE_PADDING
99 /// @brief Enable / disable padding of data structures.
100 ///
101 /// By default, when @ref MATHFU_COMPILE_FORCE_PADDING is <b>not</b> defined,
102 /// data structures are padded when SIMD is enabled
103 /// (i.e when @ref MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT is also not defined).
104 ///
105 /// If @ref MATHFU_COMPILE_FORCE_PADDING is defined as <b>1</b>, all data
106 /// structures are padded to a power of 2 size which enables more efficient
107 /// SIMD operations. This is the default build configuration when SIMD is
108 /// enabled.
109 ///
110 /// If @ref MATHFU_COMPILE_FORCE_PADDING is defined as <b>0</b>, all data
111 /// structures are packed by the compiler (with no padding) even when the SIMD
112 /// build configuration is enabled. This build option can be useful in the
113 /// rare occasion an application is CPU memory bandwidth constrained, at the
114 /// expense of additional instructions to copy to / from SIMD registers.
115 ///
116 /// To use this build option, this macro <b>must</b> be defined in all modules
117 /// of the project.
118 ///
119 /// @see MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT
120 #define MATHFU_COMPILE_FORCE_PADDING
121 /// @}
122 #endif // DOXYGEN
123 
124 #ifdef MATHFU_COMPILE_WITH_SIMD
125 /// @cond MATHFU_INTERNAL
126 /// @addtogroup mathfu_build_config
127 /// @{
128 /// @def MATHFU_COMPILE_WITH_PADDING
129 /// @brief Enable padding of data structures to be efficient with SIMD.
130 ///
131 /// When defined, this option enables padding of some data structures (e.g
132 /// @ref vec3) to be more efficient with SIMD operations. This option is
133 /// only applicable when @ref MATHFU_COMPILE_WITHOUT_SIMD is not defined and
134 /// the target architecture and compiler support SIMD.
135 ///
136 /// To use this build option, this macro <b>must</b> be defined in all modules
137 /// of the project.
138 /// @see MATHFU_COMPILE_FORCE_PADDING
139 #define MATHFU_COMPILE_WITH_PADDING
140 /// @}
141 #if defined(MATHFU_COMPILE_FORCE_PADDING)
142 #if MATHFU_COMPILE_FORCE_PADDING == 1
143 #if !defined(MATHFU_COMPILE_WITH_PADDING)
144 #define MATHFU_COMPILE_WITH_PADDING
145 #endif // !defined(MATHFU_COMPILE_WITH_PADDING)
146 #else
147 #if defined(MATHFU_COMPILE_WITH_PADDING)
148 #undef MATHFU_COMPILE_WITH_PADDING
149 #endif // MATHFU_COMPILE_WITH_PADDING
150 #endif // MATHFU_COMPILE_FORCE_PADDING == 1
151 #endif // MATHFU_COMPILE_FORCE_PADDING
152 /// @endcond
153 #endif // MATHFU_COMPILE_WITH_SIMD
154 
155 /// @addtogroup mathfu_version
156 /// @{
157 
158 /// @def MATHFU_VERSION_MAJOR
159 /// @brief Major version number of the library.
160 /// @see kMathFuVersionString
161 #define MATHFU_VERSION_MAJOR 1
162 /// @def MATHFU_VERSION_MINOR
163 /// @brief Minor version number of the library.
164 /// @see kMathFuVersionString
165 #define MATHFU_VERSION_MINOR 1
166 /// @def MATHFU_VERSION_REVISION
167 /// @brief Revision number of the library.
168 /// @see kMathFuVersionString
169 #define MATHFU_VERSION_REVISION 0
170 
171 /// @}
172 
173 /// @cond MATHFU_INTERNAL
174 #define MATHFU_STRING_EXPAND(X) #X
175 #define MATHFU_STRING(X) MATHFU_STRING_EXPAND(X)
176 /// @endcond
177 
178 /// @cond MATHFU_INTERNAL
179 // Generate string which contains build options for the library.
180 #if defined(MATHFU_COMPILE_WITH_SIMD)
181 #define MATHFU_BUILD_OPTIONS_SIMD "[simd]"
182 #else
183 #define MATHFU_BUILD_OPTIONS_SIMD "[no simd]"
184 #endif // defined(MATHFU_COMPILE_WITH_SIMD)
185 #if defined(MATHFU_COMPILE_WITH_PADDING)
186 #define MATHFU_BUILD_OPTIONS_PADDING "[padding]"
187 #else
188 #define MATHFU_BUILD_OPTIONS_PADDING "[no padding]"
189 #endif // defined(MATHFU_COMPILE_WITH_PADDING)
190 /// @endcond
191 
192 /// @addtogroup mathfu_version
193 /// @{
194 /// @def MATHFU_BUILD_OPTIONS_STRING
195 /// @brief String that describes the library's build configuration.
196 #define MATHFU_BUILD_OPTIONS_STRING \
197  (MATHFU_BUILD_OPTIONS_SIMD " " MATHFU_BUILD_OPTIONS_PADDING)
198 /// @}
199 
200 // Weak linkage is culled by VS & doesn't work on cygwin.
201 #if !defined(_WIN32) && !defined(__CYGWIN__)
202 
203 extern volatile __attribute__((weak)) const char *kMathFuVersionString;
204 /// @addtogroup mathfu_version
205 /// @{
206 
207 /// @var kMathFuVersionString
208 /// @brief String which identifies the current version of MathFu.
209 ///
210 /// @ref kMathFuVersionString is used by Google developers to identify which
211 /// applications uploaded to Google Play are using this library. This allows
212 /// the development team at Google to determine the popularity of the library.
213 /// How it works: Applications that are uploaded to the Google Play Store are
214 /// scanned for this version string. We track which applications are using it
215 /// to measure popularity. You are free to remove it (of course) but we would
216 /// appreciate if you left it in.
217 ///
218 /// @see MATHFU_VERSION_MAJOR
219 /// @see MATHFU_VERSION_MINOR
220 /// @see MATHFU_VERSION_REVISION
221 volatile __attribute__((weak)) const char *kMathFuVersionString =
222  "MathFu " MATHFU_STRING(MATHFU_VERSION_MAJOR) "." MATHFU_STRING(
223  MATHFU_VERSION_MINOR) "." MATHFU_STRING(MATHFU_VERSION_REVISION);
224 /// @}
225 
226 #endif // !defined(_WIN32) && !defined(__CYGWIN__)
227 
228 /// @cond MATHFU_INTERNAL
229 template <bool>
230 struct static_assert_util;
231 template <>
232 struct static_assert_util<true> {};
233 /// @endcond
234 
235 /// @addtogroup mathfu_utilities
236 /// @{
237 /// @def MATHFU_STATIC_ASSERT
238 /// @brief Compile time assert for pre-C++11 compilers.
239 ///
240 /// For example:
241 /// <blockquote><code>
242 /// MATHFU_STATIC_ASSERT(0 == 1);
243 /// </code></blockquote> will result in a compile error.
244 #define MATHFU_STATIC_ASSERT(x) static_assert_util<(x)>()
245 /// @}
246 
247 /// @cond MATHFU_INTERNAL
248 /// Unroll an loop up to 4 iterations, where iterator is the identifier
249 /// used in each operation (e.g "i"), number_of_iterations is a constant which
250 /// specifies the number of times to perform the operation and "operation" is
251 /// the statement to execute for each iteration of the loop (e.g data[i] = v).
252 #define MATHFU_UNROLLED_LOOP(iterator, number_of_iterations, operation) \
253  { \
254  const int iterator = 0; \
255  { operation; } \
256  if ((number_of_iterations) > 1) { \
257  const int iterator = 1; \
258  { operation; } \
259  if ((number_of_iterations) > 2) { \
260  const int iterator = 2; \
261  { operation; } \
262  if ((number_of_iterations) > 3) { \
263  const int iterator = 3; \
264  { operation; } \
265  if ((number_of_iterations) > 4) { \
266  for (int iterator = 4; iterator < (number_of_iterations); \
267  ++iterator) { \
268  operation; \
269  } \
270  } \
271  } \
272  } \
273  } \
274  }
275 /// @endcond
276 
277 namespace mathfu {
278 
279 /// @addtogroup mathfu_utilities
280 /// @{
281 
282 /// @brief Clamp x within [lower, upper].
283 /// @anchor mathfu_Clamp
284 ///
285 /// @note Results are undefined if lower > upper.
286 ///
287 /// @param x Value to clamp.
288 /// @param lower Lower value of the range.
289 /// @param upper Upper value of the range.
290 /// @returns Clamped value.
291 template <class T>
292 T Clamp(const T &x, const T &lower, const T &upper) {
293  return std::max<T>(lower, std::min<T>(x, upper));
294 }
295 
296 /// @brief Linearly interpolate between range_start and range_end, based on
297 /// percent.
298 /// @anchor mathfu_Lerp
299 ///
300 /// @param range_start Start of the range.
301 /// @param range_end End of the range.
302 /// @param percent Value between 0.0 and 1.0 used to interpolate between
303 /// range_start and range_end. Where a value of 0.0 results in a return
304 /// value of range_start and 1.0 results in a return value of range_end.
305 /// @return Value between range_start and range_end.
306 ///
307 /// @tparam T Type of the range to interpolate over.
308 /// @tparam T2 Type of the value used to perform interpolation
309 /// (e.g float or double).
310 template <class T, class T2>
311 T Lerp(const T &range_start, const T &range_end, const T2 &percent) {
312  const T2 one_minus_percent = static_cast<T2>(1.0) - percent;
313  return range_start * one_minus_percent + range_end * percent;
314 }
315 
316 /// @brief Linearly interpolate between range_start and range_end, based on
317 /// percent.
318 /// @anchor mathfu_Lerp2
319 ///
320 /// @param range_start Start of the range.
321 /// @param range_end End of the range.
322 /// @param percent Value between 0.0 and 1.0 used to interpolate between
323 /// range_start and range_end. Where a value of 0.0 results in a return
324 /// value of range_start and 1.0 results in a return value of range_end.
325 /// @return Value between range_start and range_end.
326 ///
327 /// @tparam T Type of the range to interpolate over.
328 template <class T>
329 T Lerp(const T &range_start, const T &range_end, const T &percent) {
330  return Lerp<T, T>(range_start, range_end, percent);
331 }
332 
333 /// @brief Check if val is within [range_start..range_end).
334 /// @anchor mathfu_InRange
335 ///
336 /// @param val Value to be tested.
337 /// @param range_start Starting point of the range (inclusive).
338 /// @param range_end Ending point of the range (non-inclusive).
339 /// @return Bool indicating success.
340 ///
341 /// @tparam T Type of values to test.
342 template <class T>
343 bool InRange(T val, T range_start, T range_end) {
344  return val >= range_start && val < range_end;
345 }
346 
347 /// @brief Generate a random value of type T.
348 /// @anchor mathfu_Random
349 ///
350 /// This method generates a random value of type T, greater than or equal to
351 /// 0.0 and less than 1.0.
352 ///
353 /// This function uses the standard C library function rand() from math.h to
354 /// generate the random number.
355 ///
356 /// @returns Random number greater than or equal to 0.0 and less than 1.0.
357 ///
358 /// @see RandomRange()
359 /// @see RandomInRange()
360 template <class T>
361 inline T Random() {
362  return static_cast<T>(rand()) / static_cast<T>(RAND_MAX);
363 }
364 
365 /// @cond MATHFU_INTERNAL
366 template <>
367 inline float Random() {
368  return static_cast<float>(rand() >> 8) /
369  (static_cast<float>((RAND_MAX >> 8) + 1));
370 }
371 /// @endcond
372 
373 /// @cond MATHFU_INTERNAL
374 template <>
375 inline double Random() {
376  return static_cast<double>(rand()) / (static_cast<double>(RAND_MAX + 1LL));
377 }
378 /// @endcond
379 
380 /// @brief Generate a random value of type T in the range -range...+range
381 /// @anchor mathfu_RandomRange
382 ///
383 /// This function uses the standard C library function rand() from math.h to
384 /// generate the random number.
385 ///
386 /// @param range Range of the random value to generate.
387 /// @return Random value in the range -range to +range
388 ///
389 /// @see Random()
390 template <class T>
391 inline T RandomRange(T range) {
392  return (Random<T>() * range * 2) - range;
393 }
394 
395 /// @brief Generate a random number between [range_start, range_end]
396 /// @anchor mathfu_RandomInRange
397 ///
398 /// This function uses the standard C library function rand() from math.h to
399 /// generate the random number.
400 ///
401 /// @param range_start Minimum value.
402 /// @param range_end Maximum value.
403 /// @return Random value in the range [range_start, range_end].
404 ///
405 /// @see Lerp()
406 /// @see Random()
407 template <class T>
408 inline T RandomInRange(T range_start, T range_end) {
409  return Lerp(range_start, range_end, Random<T>());
410 }
411 
412 /// @cond MATHFU_INTERNAL
413 template <>
414 inline int RandomInRange<int>(int range_start, int range_end) {
415  return static_cast<int>(RandomInRange<float>(static_cast<float>(range_start),
416  static_cast<float>(range_end)));
417 }
418 /// @endcond
419 
420 /// @brief Round a value up to the nearest power of 2.
421 ///
422 /// @param x Value to round up.
423 /// @returns Value rounded up to the nearest power of 2.
424 template <class T>
426  return static_cast<T>(
427  pow(static_cast<T>(2), ceil(log(x) / log(static_cast<T>(2)))));
428 }
429 
430 /// @brief Specialized version of RoundUpToPowerOf2 for int32_t.
431 template <>
432 inline int32_t RoundUpToPowerOf2<>(int32_t x) {
433  x--;
434  x |= x >> 1;
435  x |= x >> 2;
436  x |= x >> 4;
437  x |= x >> 8;
438  x |= x >> 16;
439  x++;
440  return x;
441 }
442 
443 /// @brief Round a value up to the type's size boundary.
444 ///
445 /// @param v Value to round up.
446 /// @returns Value rounded up to the type's size boundary.
447 template <typename T>
448 uint32_t RoundUpToTypeBoundary(uint32_t v) {
449  return (v + sizeof(T) - 1) & ~(sizeof(T) - 1);
450 }
451 
452 /// @}
453 
454 /// @addtogroup mathfu_allocator
455 ///
456 /// If you use MathFu with SIMD (SSE in particular), you need to have all
457 /// your allocations be 16-byte aligned (which isn't the case with the default
458 /// allocators on most platforms except OS X).
459 ///
460 /// You can either use simd_allocator, which solves the problem for
461 /// any STL containers, but not for manual dynamic allocations or the
462 /// new/delete override MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE will
463 /// solve it for all allocations, at the cost of MATHFU_ALIGNMENT bytes per
464 /// allocation.
465 
466 /// @addtogroup mathfu_allocator
467 /// @{
468 
469 /// @def MATHFU_ALIGNMENT
470 /// @brief Alignment (in bytes) of memory allocated by AllocateAligned.
471 ///
472 /// @see mathfu::AllocateAligned()
473 /// @see mathfu::simd_allocator
474 #define MATHFU_ALIGNMENT 16
475 
476 /// @brief Allocate an aligned block of memory.
477 /// @anchor mathfu_AllocateAligned
478 ///
479 /// This function allocates a block of memory aligned to MATHFU_ALIGNMENT
480 /// bytes.
481 ///
482 /// @param n Size of memory to allocate.
483 /// @return Pointer to aligned block of allocated memory or NULL if
484 /// allocation failed.
485 inline void *AllocateAligned(size_t n) {
486 #if defined(_MSC_VER) && _MSC_VER >= 1900 // MSVC 2015
487  return _aligned_malloc(n, MATHFU_ALIGNMENT);
488 #else
489  // We need to allocate extra bytes to guarantee alignment,
490  // and to store the pointer to the original buffer.
491  uint8_t *buf = reinterpret_cast<uint8_t *>(malloc(n + MATHFU_ALIGNMENT));
492  if (!buf) return NULL;
493  // Align to next higher multiple of MATHFU_ALIGNMENT.
494  uint8_t *aligned_buf = reinterpret_cast<uint8_t *>(
495  (reinterpret_cast<size_t>(buf) + MATHFU_ALIGNMENT) &
496  ~(MATHFU_ALIGNMENT - 1));
497  // Write out original buffer pointer before aligned buffer.
498  // The assert will fail if the allocator granularity is less than the pointer
499  // size, or if MATHFU_ALIGNMENT doesn't fit two pointers.
500  assert(static_cast<size_t>(aligned_buf - buf) > sizeof(void *));
501  *(reinterpret_cast<uint8_t **>(aligned_buf) - 1) = buf;
502  return aligned_buf;
503 #endif // defined(_MSC_VER) && _MSC_VER >= 1900 // MSVC 2015
504 }
505 
506 /// @brief Deallocate a block of memory allocated with AllocateAligned().
507 /// @anchor mathfu_FreeAligned
508 ///
509 /// @param p Pointer to memory to deallocate.
510 inline void FreeAligned(void *p) {
511 #if defined(_MSC_VER) && _MSC_VER >= 1900 // MSVC 2015
512  _aligned_free(p);
513 #else
514  if (p == NULL) return;
515  free(*(reinterpret_cast<uint8_t **>(p) - 1));
516 #endif // defined(_MSC_VER) && _MSC_VER >= 1900 // MSVC 2015
517 }
518 
519 /// @brief SIMD-safe memory allocator, for use with STL types like std::vector.
520 ///
521 /// For example:
522 /// <blockquote><code><pre>
523 /// std::vector<vec4, mathfu::simd_allocator<vec4>> myvector;
524 /// </pre></code></blockquote>
525 ///
526 /// @see MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE
527 /// @tparam T type allocated by this object.
528 template <typename T>
529 class simd_allocator : public std::allocator<T> {
530  public:
531  /// Size type.
532  typedef size_t size_type;
533  /// Pointer of type T.
534  typedef T *pointer;
535  /// Const pointer of type T.
536  typedef const T *const_pointer;
537 
538  /// Constructs a simd_allocator.
539  simd_allocator() throw() : std::allocator<T>() {}
540  /// @brief Constructs and copies a simd_allocator.
541  ///
542  /// @param a Allocator to copy.
543  simd_allocator(const simd_allocator &a) throw() : std::allocator<T>(a) {}
544  /// @brief Constructs and copies a simd_allocator.
545  ///
546  /// @param a Allocator to copy.
547  /// @tparam U type of the object allocated by the allocator to copy.
548  template <class U>
549  simd_allocator(const simd_allocator<U> &a) throw() : std::allocator<T>(a) {}
550  /// @brief Destructs a simd_allocator.
551  ~simd_allocator() throw() {}
552 
553  /// @brief Obtains an allocator of a different type.
554  ///
555  /// @tparam _Tp1 type of the new allocator.
556  template <typename _Tp1>
557  struct rebind {
558  /// @brief Allocator of type _Tp1.
560  };
561 
562  /// @brief Allocate memory for object T.
563  ///
564  /// @param n Number of types to allocate.
565  /// @return Pointer to the newly allocated memory.
567  return reinterpret_cast<pointer>(AllocateAligned(n * sizeof(T)));
568  }
569 
570  /// Deallocate memory referenced by pointer p.
571  ///
572  /// @param p Pointer to memory to deallocate.
574 };
575 
576 #if defined(_MSC_VER)
577 #if _MSC_VER <= 1800 // MSVC 2013
578 #if !defined(noexcept)
579 #define noexcept
580 #endif // !defined(noexcept)
581 #endif // _MSC_VER <= 1800
582 #endif // defined(_MSC_VER)
583 
584 /// @def MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE
585 /// @brief Macro which overrides the default new and delete allocators.
586 ///
587 /// To globally override new and delete, simply add the line:
588 /// <blockquote><code><pre>
589 /// MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE
590 /// </pre></code></blockquote>
591 /// to the end of your main .cpp file.
592 #define MATHFU_DEFINE_GLOBAL_SIMD_AWARE_NEW_DELETE \
593  void *operator new(std::size_t n) { return mathfu::AllocateAligned(n); } \
594  void *operator new[](std::size_t n) { return mathfu::AllocateAligned(n); } \
595  void operator delete(void *p) noexcept { mathfu::FreeAligned(p); } \
596  void operator delete[](void *p) noexcept { mathfu::FreeAligned(p); }
597 
598 /// @def MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE
599 /// @brief Macro which defines the new and delete for MathFu classes.
600 #define MATHFU_DEFINE_CLASS_SIMD_AWARE_NEW_DELETE \
601  static void *operator new(std::size_t n) { \
602  return mathfu::AllocateAligned(n); \
603  } \
604  static void *operator new[](std::size_t n) { \
605  return mathfu::AllocateAligned(n); \
606  } \
607  static void *operator new(std::size_t /*n*/, void *p) { return p; } \
608  static void *operator new[](std::size_t /*n*/, void *p) { return p; } \
609  static void operator delete(void *p) { mathfu::FreeAligned(p); } \
610  static void operator delete[](void *p) { mathfu::FreeAligned(p); } \
611  static void operator delete(void * /*p*/, void * /*place*/) {} \
612  static void operator delete[](void * /*p*/, void * /*place*/) {}
613 
614 /// @}
615 
616 } // namespace mathfu
617 
618 #endif // MATHFU_UTILITIES_H_
Obtains an allocator of a different type.
Definition: utilities.h:557
void deallocate(pointer p, size_type)
Definition: utilities.h:573
T RoundUpToPowerOf2(T x)
Round a value up to the nearest power of 2.
Definition: utilities.h:425
void * AllocateAligned(size_t n)
Allocate an aligned block of memory.
Definition: utilities.h:485
uint32_t RoundUpToTypeBoundary(uint32_t v)
Round a value up to the type's size boundary.
Definition: utilities.h:448
simd_allocator(const simd_allocator &a)
Constructs and copies a simd_allocator.
Definition: utilities.h:543
#define MATHFU_VERSION_MINOR
Minor version number of the library.
Definition: utilities.h:165
#define MATHFU_ALIGNMENT
Alignment (in bytes) of memory allocated by AllocateAligned.
Definition: utilities.h:474
const T * const_pointer
Const pointer of type T.
Definition: utilities.h:536
volatile const char * kMathFuVersionString
String which identifies the current version of MathFu.
Definition: utilities.h:221
T RandomRange(T range)
Generate a random value of type T in the range -range...+range.
Definition: utilities.h:391
SIMD-safe memory allocator, for use with STL types like std::vector.
Definition: utilities.h:529
~simd_allocator()
Destructs a simd_allocator.
Definition: utilities.h:551
void FreeAligned(void *p)
Deallocate a block of memory allocated with AllocateAligned().
Definition: utilities.h:510
simd_allocator()
Constructs a simd_allocator.
Definition: utilities.h:539
simd_allocator(const simd_allocator< U > &a)
Constructs and copies a simd_allocator.
Definition: utilities.h:549
bool InRange(T val, T range_start, T range_end)
Check if val is within [range_start..range_end).
Definition: utilities.h:343
size_t size_type
Size type.
Definition: utilities.h:532
T Clamp(const T &x, const T &lower, const T &upper)
Clamp x within [lower, upper].
Definition: utilities.h:292
T Random()
Generate a random value of type T.
Definition: utilities.h:361
T * pointer
Pointer of type T.
Definition: utilities.h:534
simd_allocator< _Tp1 > other
Allocator of type _Tp1.
Definition: utilities.h:559
#define MATHFU_VERSION_REVISION
Revision number of the library.
Definition: utilities.h:169
T Lerp(const T &range_start, const T &range_end, const T2 &percent)
Linearly interpolate between range_start and range_end, based on percent.
Definition: utilities.h:311
T RandomInRange(T range_start, T range_end)
Generate a random number between [range_start, range_end].
Definition: utilities.h:408
pointer allocate(size_type n)
Allocate memory for object T.
Definition: utilities.h:566
#define MATHFU_VERSION_MAJOR
Major version number of the library.
Definition: utilities.h:161