summaryrefslogtreecommitdiff
path: root/thirdparty/basis_universal/transcoder/basisu_containers.h
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/basis_universal/transcoder/basisu_containers.h')
-rw-r--r--thirdparty/basis_universal/transcoder/basisu_containers.h83
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.