diff options
Diffstat (limited to 'thirdparty/basis_universal/transcoder/basisu_containers.h')
-rw-r--r-- | thirdparty/basis_universal/transcoder/basisu_containers.h | 83 |
1 files changed, 79 insertions, 4 deletions
diff --git a/thirdparty/basis_universal/transcoder/basisu_containers.h b/thirdparty/basis_universal/transcoder/basisu_containers.h index 1ca4bab307..d3e14369ba 100644 --- a/thirdparty/basis_universal/transcoder/basisu_containers.h +++ b/thirdparty/basis_universal/transcoder/basisu_containers.h @@ -12,6 +12,12 @@ #define HAS_MALLOC_USABLE_SIZE 1 #endif +// Set to 1 to always check vector operator[], front(), and back() even in release. +#define BASISU_VECTOR_FORCE_CHECKING 0 + +// If 1, the vector container will not query the CRT to get the size of resized memory blocks. +#define BASISU_VECTOR_DETERMINISTIC 1 + #ifdef _MSC_VER #define BASISU_FORCE_INLINE __forceinline #else @@ -279,7 +285,10 @@ namespace basisu m_size = other.m_size; if (BASISU_IS_BITWISE_COPYABLE(T)) - memcpy(m_p, other.m_p, m_size * sizeof(T)); + { + if ((m_p) && (other.m_p)) + memcpy(m_p, other.m_p, m_size * sizeof(T)); + } else { T* pDst = m_p; @@ -320,7 +329,10 @@ namespace basisu } if (BASISU_IS_BITWISE_COPYABLE(T)) - memcpy(m_p, other.m_p, other.m_size * sizeof(T)); + { + if ((m_p) && (other.m_p)) + memcpy(m_p, other.m_p, other.m_size * sizeof(T)); + } else { T* pDst = m_p; @@ -348,20 +360,81 @@ namespace basisu // operator[] will assert on out of range indices, but in final builds there is (and will never be) any range checking on this method. //BASISU_FORCE_INLINE const T& operator[] (uint32_t i) const { assert(i < m_size); return m_p[i]; } //BASISU_FORCE_INLINE T& operator[] (uint32_t i) { assert(i < m_size); return m_p[i]; } - + +#if !BASISU_VECTOR_FORCE_CHECKING BASISU_FORCE_INLINE const T& operator[] (size_t i) const { assert(i < m_size); return m_p[i]; } BASISU_FORCE_INLINE T& operator[] (size_t i) { assert(i < m_size); return m_p[i]; } +#else + BASISU_FORCE_INLINE const T& operator[] (size_t i) const + { + if (i >= m_size) + { + fprintf(stderr, "operator[] invalid index: %u, max entries %u, type size %u\n", (uint32_t)i, m_size, (uint32_t)sizeof(T)); + abort(); + } + return m_p[i]; + } + BASISU_FORCE_INLINE T& operator[] (size_t i) + { + if (i >= m_size) + { + fprintf(stderr, "operator[] invalid index: %u, max entries %u, type size %u\n", (uint32_t)i, m_size, (uint32_t)sizeof(T)); + abort(); + } + return m_p[i]; + } +#endif // at() always includes range checking, even in final builds, unlike operator []. // The first element is returned if the index is out of range. BASISU_FORCE_INLINE const T& at(size_t i) const { assert(i < m_size); return (i >= m_size) ? m_p[0] : m_p[i]; } BASISU_FORCE_INLINE T& at(size_t i) { assert(i < m_size); return (i >= m_size) ? m_p[0] : m_p[i]; } - + +#if !BASISU_VECTOR_FORCE_CHECKING BASISU_FORCE_INLINE const T& front() const { assert(m_size); return m_p[0]; } BASISU_FORCE_INLINE T& front() { assert(m_size); return m_p[0]; } BASISU_FORCE_INLINE const T& back() const { assert(m_size); return m_p[m_size - 1]; } BASISU_FORCE_INLINE T& back() { assert(m_size); return m_p[m_size - 1]; } +#else + BASISU_FORCE_INLINE const T& front() const + { + if (!m_size) + { + fprintf(stderr, "front: vector is empty, type size %u\n", (uint32_t)sizeof(T)); + abort(); + } + return m_p[0]; + } + BASISU_FORCE_INLINE T& front() + { + if (!m_size) + { + fprintf(stderr, "front: vector is empty, type size %u\n", (uint32_t)sizeof(T)); + abort(); + } + return m_p[0]; + } + + BASISU_FORCE_INLINE const T& back() const + { + if(!m_size) + { + fprintf(stderr, "back: vector is empty, type size %u\n", (uint32_t)sizeof(T)); + abort(); + } + return m_p[m_size - 1]; + } + BASISU_FORCE_INLINE T& back() + { + if (!m_size) + { + fprintf(stderr, "back: vector is empty, type size %u\n", (uint32_t)sizeof(T)); + abort(); + } + return m_p[m_size - 1]; + } +#endif BASISU_FORCE_INLINE const T* get_ptr() const { return m_p; } BASISU_FORCE_INLINE T* get_ptr() { return m_p; } @@ -952,6 +1025,8 @@ namespace basisu // Caller is granting ownership of the indicated heap block. // Block must have size constructed elements, and have enough room for capacity elements. + // The block must have been allocated using malloc(). + // Important: This method is used in Basis Universal. If you change how this container allocates memory, you'll need to change any users of this method. inline bool grant_ownership(T* p, uint32_t size, uint32_t capacity) { // To to prevent the caller from obviously shooting themselves in the foot. |