// basisu_containers.h
#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <algorithm>

#if defined(__linux__) && !defined(ANDROID)
// Only for malloc_usable_size() in basisu_containers_impl.h
#include <malloc.h>
#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
#define BASISU_FORCE_INLINE inline
#endif

namespace basisu
{
   enum { cInvalidIndex = -1 };

   namespace helpers
   {
      inline bool is_power_of_2(uint32_t x) { return x && ((x & (x - 1U)) == 0U); }
      inline bool is_power_of_2(uint64_t x) { return x && ((x & (x - 1U)) == 0U); }
      template<class T> const T& minimum(const T& a, const T& b) { return (b < a) ? b : a; }
      template<class T> const T& maximum(const T& a, const T& b) { return (a < b) ? b : a; }

      inline uint32_t floor_log2i(uint32_t v)
      {
         uint32_t l = 0;
         while (v > 1U)
         {
            v >>= 1;
            l++;
         }
         return l;
      }

      inline uint32_t next_pow2(uint32_t val)
      {
         val--;
         val |= val >> 16;
         val |= val >> 8;
         val |= val >> 4;
         val |= val >> 2;
         val |= val >> 1;
         return val + 1;
      }

      inline uint64_t next_pow2(uint64_t val)
      {
         val--;
         val |= val >> 32;
         val |= val >> 16;
         val |= val >> 8;
         val |= val >> 4;
         val |= val >> 2;
         val |= val >> 1;
         return val + 1;
      }
   } // namespace helpers

   template <typename T>
   inline T* construct(T* p)
   {
      return new (static_cast<void*>(p)) T;
   }

   template <typename T, typename U>
   inline T* construct(T* p, const U& init)
   {
      return new (static_cast<void*>(p)) T(init);
   }

   template <typename T>
   inline void construct_array(T* p, size_t n)
   {
      T* q = p + n;
      for (; p != q; ++p)
         new (static_cast<void*>(p)) T;
   }

   template <typename T, typename U>
   inline void construct_array(T* p, size_t n, const U& init)
   {
      T* q = p + n;
      for (; p != q; ++p)
         new (static_cast<void*>(p)) T(init);
   }

   template <typename T>
   inline void destruct(T* p)
   {
      (void)p;
      p->~T();
   }

   template <typename T> inline void destruct_array(T* p, size_t n)
   {
      T* q = p + n;
      for (; p != q; ++p)
         p->~T();
   }

   template<typename T> struct int_traits { enum { cMin = INT32_MIN, cMax = INT32_MAX, cSigned = true }; };

   template<> struct int_traits<int8_t> { enum { cMin = INT8_MIN, cMax = INT8_MAX, cSigned = true }; };
   template<> struct int_traits<int16_t> { enum { cMin = INT16_MIN, cMax = INT16_MAX, cSigned = true }; };
   template<> struct int_traits<int32_t> { enum { cMin = INT32_MIN, cMax = INT32_MAX, cSigned = true }; };

   template<> struct int_traits<uint8_t> { enum { cMin = 0, cMax = UINT8_MAX, cSigned = false }; };
   template<> struct int_traits<uint16_t> { enum { cMin = 0, cMax = UINT16_MAX, cSigned = false }; };
   template<> struct int_traits<uint32_t> { enum { cMin = 0, cMax = UINT32_MAX, cSigned = false }; };

   template<typename T>
   struct scalar_type
   {
      enum { cFlag = false };
      static inline void construct(T* p) { basisu::construct(p); }
      static inline void construct(T* p, const T& init) { basisu::construct(p, init); }
      static inline void construct_array(T* p, size_t n) { basisu::construct_array(p, n); }
      static inline void destruct(T* p) { basisu::destruct(p); }
      static inline void destruct_array(T* p, size_t n) { basisu::destruct_array(p, n); }
   };

   template<typename T> struct scalar_type<T*>
   {
      enum { cFlag = true };
      static inline void construct(T** p) { memset(p, 0, sizeof(T*)); }
      static inline void construct(T** p, T* init) { *p = init; }
      static inline void construct_array(T** p, size_t n) { memset(p, 0, sizeof(T*) * n); }
      static inline void destruct(T** p) { p; }
      static inline void destruct_array(T** p, size_t n) { p, n; }
   };

#define BASISU_DEFINE_BUILT_IN_TYPE(X) \
   template<> struct scalar_type<X> { \
   enum { cFlag = true }; \
   static inline void construct(X* p) { memset(p, 0, sizeof(X)); } \
   static inline void construct(X* p, const X& init) { memcpy(p, &init, sizeof(X)); } \
   static inline void construct_array(X* p, size_t n) { memset(p, 0, sizeof(X) * n); } \
   static inline void destruct(X* p) { p; } \
   static inline void destruct_array(X* p, size_t n) { p, n; } };

   BASISU_DEFINE_BUILT_IN_TYPE(bool)
   BASISU_DEFINE_BUILT_IN_TYPE(char)
   BASISU_DEFINE_BUILT_IN_TYPE(unsigned char)
   BASISU_DEFINE_BUILT_IN_TYPE(short)
   BASISU_DEFINE_BUILT_IN_TYPE(unsigned short)
   BASISU_DEFINE_BUILT_IN_TYPE(int)
   BASISU_DEFINE_BUILT_IN_TYPE(unsigned int)
   BASISU_DEFINE_BUILT_IN_TYPE(long)
   BASISU_DEFINE_BUILT_IN_TYPE(unsigned long)
#ifdef __GNUC__
   BASISU_DEFINE_BUILT_IN_TYPE(long long)
   BASISU_DEFINE_BUILT_IN_TYPE(unsigned long long)
#else
   BASISU_DEFINE_BUILT_IN_TYPE(__int64)
   BASISU_DEFINE_BUILT_IN_TYPE(unsigned __int64)
#endif
   BASISU_DEFINE_BUILT_IN_TYPE(float)
   BASISU_DEFINE_BUILT_IN_TYPE(double)
   BASISU_DEFINE_BUILT_IN_TYPE(long double)

#undef BASISU_DEFINE_BUILT_IN_TYPE

   template<typename T>
   struct bitwise_movable { enum { cFlag = false }; };

#define BASISU_DEFINE_BITWISE_MOVABLE(Q) template<> struct bitwise_movable<Q> { enum { cFlag = true }; };

   template<typename T>
   struct bitwise_copyable { enum { cFlag = false }; };

#define BASISU_DEFINE_BITWISE_COPYABLE(Q) template<> struct bitwise_copyable<Q> { enum { cFlag = true }; };

#define BASISU_IS_POD(T) __is_pod(T)

#define BASISU_IS_SCALAR_TYPE(T) (scalar_type<T>::cFlag)

#if defined(__GNUC__) && __GNUC__<5
   #define BASISU_IS_TRIVIALLY_COPYABLE(...) __has_trivial_copy(__VA_ARGS__)
#else
   #define BASISU_IS_TRIVIALLY_COPYABLE(...) std::is_trivially_copyable<__VA_ARGS__>::value
#endif

// TODO: clean this up
#define BASISU_IS_BITWISE_COPYABLE(T) (BASISU_IS_SCALAR_TYPE(T) || BASISU_IS_POD(T) || BASISU_IS_TRIVIALLY_COPYABLE(T) || (bitwise_copyable<T>::cFlag))

#define BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(T) (BASISU_IS_BITWISE_COPYABLE(T) || (bitwise_movable<T>::cFlag))

#define BASISU_HAS_DESTRUCTOR(T) ((!scalar_type<T>::cFlag) && (!__is_pod(T)))

   typedef char(&yes_t)[1];
   typedef char(&no_t)[2];

   template <class U> yes_t class_test(int U::*);
   template <class U> no_t class_test(...);

   template <class T> struct is_class
   {
      enum { value = (sizeof(class_test<T>(0)) == sizeof(yes_t)) };
   };

   template <typename T> struct is_pointer
   {
      enum { value = false };
   };

   template <typename T> struct is_pointer<T*>
   {
      enum { value = true };
   };

   struct empty_type { };

   BASISU_DEFINE_BITWISE_COPYABLE(empty_type);
   BASISU_DEFINE_BITWISE_MOVABLE(empty_type);

   template<typename T> struct rel_ops
   {
      friend bool operator!=(const T& x, const T& y) { return (!(x == y)); }
      friend bool operator> (const T& x, const T& y) { return (y < x); }
      friend bool operator<=(const T& x, const T& y) { return (!(y < x)); }
      friend bool operator>=(const T& x, const T& y) { return (!(x < y)); }
   };

   struct elemental_vector
   {
      void* m_p;
      uint32_t m_size;
      uint32_t m_capacity;

      typedef void (*object_mover)(void* pDst, void* pSrc, uint32_t num);

      bool increase_capacity(uint32_t min_new_capacity, bool grow_hint, uint32_t element_size, object_mover pRelocate, bool nofail);
   };

   template<typename T>
   class vector : public rel_ops< vector<T> >
   {
   public:
      typedef T* iterator;
      typedef const T* const_iterator;
      typedef T value_type;
      typedef T& reference;
      typedef const T& const_reference;
      typedef T* pointer;
      typedef const T* const_pointer;

      inline vector() :
         m_p(NULL),
         m_size(0),
         m_capacity(0)
      {
      }

      inline vector(uint32_t n, const T& init) :
         m_p(NULL),
         m_size(0),
         m_capacity(0)
      {
         increase_capacity(n, false);
         construct_array(m_p, n, init);
         m_size = n;
      }

      inline vector(const vector& other) :
         m_p(NULL),
         m_size(0),
         m_capacity(0)
      {
         increase_capacity(other.m_size, false);

         m_size = other.m_size;

         if (BASISU_IS_BITWISE_COPYABLE(T))
            memcpy(m_p, other.m_p, m_size * sizeof(T));
         else
         {
            T* pDst = m_p;
            const T* pSrc = other.m_p;
            for (uint32_t i = m_size; i > 0; i--)
               construct(pDst++, *pSrc++);
         }
      }

      inline explicit vector(size_t size) :
         m_p(NULL),
         m_size(0),
         m_capacity(0)
      {
         resize(size);
      }

      inline ~vector()
      {
         if (m_p)
         {
            scalar_type<T>::destruct_array(m_p, m_size);
            free(m_p);
         }
      }

      inline vector& operator= (const vector& other)
      {
         if (this == &other)
            return *this;

         if (m_capacity >= other.m_size)
            resize(0);
         else
         {
            clear();
            increase_capacity(other.m_size, false);
         }

         if (BASISU_IS_BITWISE_COPYABLE(T))
            memcpy(m_p, other.m_p, other.m_size * sizeof(T));
         else
         {
            T* pDst = m_p;
            const T* pSrc = other.m_p;
            for (uint32_t i = other.m_size; i > 0; i--)
               construct(pDst++, *pSrc++);
         }

         m_size = other.m_size;

         return *this;
      }

      BASISU_FORCE_INLINE const T* begin() const { return m_p; }
      BASISU_FORCE_INLINE T* begin() { return m_p; }

      BASISU_FORCE_INLINE const T* end() const { return m_p + m_size; }
      BASISU_FORCE_INLINE T* end() { return m_p + m_size; }

      BASISU_FORCE_INLINE bool empty() const { return !m_size; }
      BASISU_FORCE_INLINE uint32_t size() const { return m_size; }
      BASISU_FORCE_INLINE uint32_t size_in_bytes() const { return m_size * sizeof(T); }
      BASISU_FORCE_INLINE uint32_t capacity() const { return m_capacity; }

      // 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; }

      BASISU_FORCE_INLINE const T* data() const { return m_p; }
      BASISU_FORCE_INLINE T* data() { return m_p; }

      // clear() sets the container to empty, then frees the allocated block.
      inline void clear()
      {
         if (m_p)
         {
            scalar_type<T>::destruct_array(m_p, m_size);
            free(m_p);
            m_p = NULL;
            m_size = 0;
            m_capacity = 0;
         }
      }

      inline void clear_no_destruction()
      {
         if (m_p)
         {
            free(m_p);
            m_p = NULL;
            m_size = 0;
            m_capacity = 0;
         }
      }

      inline void reserve(size_t new_capacity_size_t)
      {
         if (new_capacity_size_t > UINT32_MAX)
         {
            assert(0);
            return;
         }

         uint32_t new_capacity = (uint32_t)new_capacity_size_t;

         if (new_capacity > m_capacity)
            increase_capacity(new_capacity, false);
         else if (new_capacity < m_capacity)
         {
            // Must work around the lack of a "decrease_capacity()" method.
            // This case is rare enough in practice that it's probably not worth implementing an optimized in-place resize.
            vector tmp;
            tmp.increase_capacity(helpers::maximum(m_size, new_capacity), false);
            tmp = *this;
            swap(tmp);
         }
      }

      inline bool try_reserve(size_t new_capacity_size_t)
      {
         if (new_capacity_size_t > UINT32_MAX)
         {
            assert(0);
            return false;
         }

         uint32_t new_capacity = (uint32_t)new_capacity_size_t;

         if (new_capacity > m_capacity)
         {
            if (!increase_capacity(new_capacity, false))
               return false;
         }
         else if (new_capacity < m_capacity)
         {
            // Must work around the lack of a "decrease_capacity()" method.
            // This case is rare enough in practice that it's probably not worth implementing an optimized in-place resize.
            vector tmp;
            tmp.increase_capacity(helpers::maximum(m_size, new_capacity), false);
            tmp = *this;
            swap(tmp);
         }

         return true;
      }

      // resize(0) sets the container to empty, but does not free the allocated block.
      inline void resize(size_t new_size_size_t, bool grow_hint = false)
      {
         if (new_size_size_t > UINT32_MAX)
         {
            assert(0);
            return;
         }

         uint32_t new_size = (uint32_t)new_size_size_t;

         if (m_size != new_size)
         {
            if (new_size < m_size)
               scalar_type<T>::destruct_array(m_p + new_size, m_size - new_size);
            else
            {
               if (new_size > m_capacity)
                  increase_capacity(new_size, (new_size == (m_size + 1)) || grow_hint);

               scalar_type<T>::construct_array(m_p + m_size, new_size - m_size);
            }

            m_size = new_size;
         }
      }

      inline bool try_resize(size_t new_size_size_t, bool grow_hint = false)
      {
         if (new_size_size_t > UINT32_MAX)
         {
            assert(0);
            return false;
         }

         uint32_t new_size = (uint32_t)new_size_size_t;

         if (m_size != new_size)
         {
            if (new_size < m_size)
               scalar_type<T>::destruct_array(m_p + new_size, m_size - new_size);
            else
            {
               if (new_size > m_capacity)
               {
                  if (!increase_capacity(new_size, (new_size == (m_size + 1)) || grow_hint, true))
                     return false;
               }

               scalar_type<T>::construct_array(m_p + m_size, new_size - m_size);
            }

            m_size = new_size;
         }

         return true;
      }

      // If size >= capacity/2, reset() sets the container's size to 0 but doesn't free the allocated block (because the container may be similarly loaded in the future).
      // Otherwise it blows away the allocated block. See http://www.codercorner.com/blog/?p=494
      inline void reset()
      {
         if (m_size >= (m_capacity >> 1))
            resize(0);
         else
            clear();
      }

      inline T* enlarge(uint32_t i)
      {
         uint32_t cur_size = m_size;
         resize(cur_size + i, true);
         return get_ptr() + cur_size;
      }

      inline T* try_enlarge(uint32_t i)
      {
         uint32_t cur_size = m_size;
         if (!try_resize(cur_size + i, true))
            return NULL;
         return get_ptr() + cur_size;
      }

      BASISU_FORCE_INLINE void push_back(const T& obj)
      {
         assert(!m_p || (&obj < m_p) || (&obj >= (m_p + m_size)));

         if (m_size >= m_capacity)
            increase_capacity(m_size + 1, true);

         scalar_type<T>::construct(m_p + m_size, obj);
         m_size++;
      }

      inline bool try_push_back(const T& obj)
      {
         assert(!m_p || (&obj < m_p) || (&obj >= (m_p + m_size)));

         if (m_size >= m_capacity)
         {
            if (!increase_capacity(m_size + 1, true, true))
               return false;
         }

         scalar_type<T>::construct(m_p + m_size, obj);
         m_size++;

         return true;
      }

      inline void push_back_value(T obj)
      {
         if (m_size >= m_capacity)
            increase_capacity(m_size + 1, true);

         scalar_type<T>::construct(m_p + m_size, obj);
         m_size++;
      }

      inline void pop_back()
      {
         assert(m_size);

         if (m_size)
         {
            m_size--;
            scalar_type<T>::destruct(&m_p[m_size]);
         }
      }

      inline void insert(uint32_t index, const T* p, uint32_t n)
      {
         assert(index <= m_size);
         if (!n)
            return;

         const uint32_t orig_size = m_size;
         resize(m_size + n, true);

         const uint32_t num_to_move = orig_size - index;

         if (BASISU_IS_BITWISE_COPYABLE(T))
         {
            // This overwrites the destination object bits, but bitwise copyable means we don't need to worry about destruction.
            memmove(m_p + index + n, m_p + index, sizeof(T) * num_to_move);
         }
         else
         {
            const T* pSrc = m_p + orig_size - 1;
            T* pDst = const_cast<T*>(pSrc) + n;

            for (uint32_t i = 0; i < num_to_move; i++)
            {
               assert((pDst - m_p) < (int)m_size);
               *pDst-- = *pSrc--;
            }
         }

         T* pDst = m_p + index;

         if (BASISU_IS_BITWISE_COPYABLE(T))
         {
            // This copies in the new bits, overwriting the existing objects, which is OK for copyable types that don't need destruction.
            memcpy(pDst, p, sizeof(T) * n);
         }
         else
         {
            for (uint32_t i = 0; i < n; i++)
            {
               assert((pDst - m_p) < (int)m_size);
               *pDst++ = *p++;
            }
         }
      }

      inline void insert(T* p, const T& obj)
      {
         int64_t ofs = p - begin();
         if ((ofs < 0) || (ofs > UINT32_MAX))
         {
            assert(0);
            return;
         }

         insert((uint32_t)ofs, &obj, 1);
      }

      // push_front() isn't going to be very fast - it's only here for usability.
      inline void push_front(const T& obj)
      {
         insert(0, &obj, 1);
      }

      vector& append(const vector& other)
      {
         if (other.m_size)
            insert(m_size, &other[0], other.m_size);
         return *this;
      }

      vector& append(const T* p, uint32_t n)
      {
         if (n)
            insert(m_size, p, n);
         return *this;
      }
            
      inline void erase(uint32_t start, uint32_t n)
      {
         assert((start + n) <= m_size);
         if ((start + n) > m_size)
            return;

         if (!n)
            return;

         const uint32_t num_to_move = m_size - (start + n);

         T* pDst = m_p + start;

         const T* pSrc = m_p + start + n;

         if (BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(T))
         {
            // This test is overly cautious.
            if ((!BASISU_IS_BITWISE_COPYABLE(T)) || (BASISU_HAS_DESTRUCTOR(T)))
            {
               // Type has been marked explictly as bitwise movable, which means we can move them around but they may need to be destructed.
               // First destroy the erased objects.
               scalar_type<T>::destruct_array(pDst, n);
            }

            // Copy "down" the objects to preserve, filling in the empty slots.
            memmove(pDst, pSrc, num_to_move * sizeof(T));
         }
         else
         {
            // Type is not bitwise copyable or movable. 
            // Move them down one at a time by using the equals operator, and destroying anything that's left over at the end.
            T* pDst_end = pDst + num_to_move;
            while (pDst != pDst_end)
               *pDst++ = *pSrc++;

            scalar_type<T>::destruct_array(pDst_end, n);
         }

         m_size -= n;
      }

      inline void erase(uint32_t index)
      {
         erase(index, 1);
      }

      inline void erase(T* p)
      {
         assert((p >= m_p) && (p < (m_p + m_size)));
         erase(static_cast<uint32_t>(p - m_p));
      }

      inline void erase(T *pFirst, T *pEnd)
      {
         assert(pFirst <= pEnd);
         assert(pFirst >= begin() && pFirst <= end());
         assert(pEnd >= begin() && pEnd <= end());

         int64_t ofs = pFirst - begin();
         if ((ofs < 0) || (ofs > UINT32_MAX))
         {
            assert(0);
            return;
         }

         int64_t n = pEnd - pFirst;
         if ((n < 0) || (n > UINT32_MAX))
         {
            assert(0);
            return;
         }

         erase((uint32_t)ofs, (uint32_t)n);
      }

      void erase_unordered(uint32_t index)
      {
         assert(index < m_size);

         if ((index + 1) < m_size)
            (*this)[index] = back();

         pop_back();
      }

      inline bool operator== (const vector& rhs) const
      {
         if (m_size != rhs.m_size)
            return false;
         else if (m_size)
         {
            if (scalar_type<T>::cFlag)
               return memcmp(m_p, rhs.m_p, sizeof(T) * m_size) == 0;
            else
            {
               const T* pSrc = m_p;
               const T* pDst = rhs.m_p;
               for (uint32_t i = m_size; i; i--)
                  if (!(*pSrc++ == *pDst++))
                     return false;
            }
         }

         return true;
      }

      inline bool operator< (const vector& rhs) const
      {
         const uint32_t min_size = helpers::minimum(m_size, rhs.m_size);

         const T* pSrc = m_p;
         const T* pSrc_end = m_p + min_size;
         const T* pDst = rhs.m_p;

         while ((pSrc < pSrc_end) && (*pSrc == *pDst))
         {
            pSrc++;
            pDst++;
         }

         if (pSrc < pSrc_end)
            return *pSrc < *pDst;

         return m_size < rhs.m_size;
      }

      inline void swap(vector& other)
      {
         std::swap(m_p, other.m_p);
         std::swap(m_size, other.m_size);
         std::swap(m_capacity, other.m_capacity);
      }

      inline void sort()
      {
         std::sort(begin(), end());
      }

      inline void unique()
      {
         if (!empty())
         {
            sort();

            resize(std::unique(begin(), end()) - begin());
         }
      }

      inline void reverse()
      {
         uint32_t j = m_size >> 1;
         for (uint32_t i = 0; i < j; i++)
            std::swap(m_p[i], m_p[m_size - 1 - i]);
      }

      inline int find(const T& key) const
      {
         const T* p = m_p;
         const T* p_end = m_p + m_size;

         uint32_t index = 0;

         while (p != p_end)
         {
            if (key == *p)
               return index;

            p++;
            index++;
         }

         return cInvalidIndex;
      }

      inline int find_sorted(const T& key) const
      {
         if (m_size)
         {
            // Uniform binary search - Knuth Algorithm 6.2.1 U, unrolled twice.
            int i = ((m_size + 1) >> 1) - 1;
            int m = m_size;

            for (; ; )
            {
               assert(i >= 0 && i < (int)m_size);
               const T* pKey_i = m_p + i;
               int cmp = key < *pKey_i;
#if defined(_DEBUG) || defined(DEBUG)
               int cmp2 = *pKey_i < key;
               assert((cmp != cmp2) || (key == *pKey_i));
#endif
               if ((!cmp) && (key == *pKey_i)) return i;
               m >>= 1;
               if (!m) break;
               cmp = -cmp;
               i += (((m + 1) >> 1) ^ cmp) - cmp;
               if (i < 0)
                  break;

               assert(i >= 0 && i < (int)m_size);
               pKey_i = m_p + i;
               cmp = key < *pKey_i;
#if defined(_DEBUG) || defined(DEBUG)
               cmp2 = *pKey_i < key;
               assert((cmp != cmp2) || (key == *pKey_i));
#endif
               if ((!cmp) && (key == *pKey_i)) return i;
               m >>= 1;
               if (!m) break;
               cmp = -cmp;
               i += (((m + 1) >> 1) ^ cmp) - cmp;
               if (i < 0)
                  break;
            }
         }

         return cInvalidIndex;
      }

      template<typename Q>
      inline int find_sorted(const T& key, Q less_than) const
      {
         if (m_size)
         {
            // Uniform binary search - Knuth Algorithm 6.2.1 U, unrolled twice.
            int i = ((m_size + 1) >> 1) - 1;
            int m = m_size;

            for (; ; )
            {
               assert(i >= 0 && i < (int)m_size);
               const T* pKey_i = m_p + i;
               int cmp = less_than(key, *pKey_i);
               if ((!cmp) && (!less_than(*pKey_i, key))) return i;
               m >>= 1;
               if (!m) break;
               cmp = -cmp;
               i += (((m + 1) >> 1) ^ cmp) - cmp;
               if (i < 0)
                  break;

               assert(i >= 0 && i < (int)m_size);
               pKey_i = m_p + i;
               cmp = less_than(key, *pKey_i);
               if ((!cmp) && (!less_than(*pKey_i, key))) return i;
               m >>= 1;
               if (!m) break;
               cmp = -cmp;
               i += (((m + 1) >> 1) ^ cmp) - cmp;
               if (i < 0) 
                  break;
            }
         }

         return cInvalidIndex;
      }

      inline uint32_t count_occurences(const T& key) const
      {
         uint32_t c = 0;

         const T* p = m_p;
         const T* p_end = m_p + m_size;

         while (p != p_end)
         {
            if (key == *p)
               c++;

            p++;
         }

         return c;
      }

      inline void set_all(const T& o)
      {
         if ((sizeof(T) == 1) && (scalar_type<T>::cFlag))
            memset(m_p, *reinterpret_cast<const uint8_t*>(&o), m_size);
         else
         {
            T* pDst = m_p;
            T* pDst_end = pDst + m_size;
            while (pDst != pDst_end)
               *pDst++ = o;
         }
      }

      // Caller assumes ownership of the heap block associated with the container. Container is cleared.
      inline void* assume_ownership()
      {
         T* p = m_p;
         m_p = NULL;
         m_size = 0;
         m_capacity = 0;
         return p;
      }

      // 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.
         if (((p + capacity) > m_p) && (p < (m_p + m_capacity)))
         {
            // Can grant ownership of a block inside the container itself!
            assert(0);
            return false;
         }

         if (size > capacity)
         {
            assert(0);
            return false;
         }

         if (!p)
         {
            if (capacity)
            {
               assert(0);
               return false;
            }
         }
         else if (!capacity)
         {
            assert(0);
            return false;
         }

         clear();
         m_p = p;
         m_size = size;
         m_capacity = capacity;
         return true;
      }

   private:
      T* m_p;
      uint32_t m_size;
      uint32_t m_capacity;

      template<typename Q> struct is_vector { enum { cFlag = false }; };
      template<typename Q> struct is_vector< vector<Q> > { enum { cFlag = true }; };

      static void object_mover(void* pDst_void, void* pSrc_void, uint32_t num)
      {
         T* pSrc = static_cast<T*>(pSrc_void);
         T* const pSrc_end = pSrc + num;
         T* pDst = static_cast<T*>(pDst_void);

         while (pSrc != pSrc_end)
         {
            // placement new
            new (static_cast<void*>(pDst)) T(*pSrc);
            pSrc->~T();
            ++pSrc;
            ++pDst;
         }
      }

      inline bool increase_capacity(uint32_t min_new_capacity, bool grow_hint, bool nofail = false)
      {
         return reinterpret_cast<elemental_vector*>(this)->increase_capacity(
            min_new_capacity, grow_hint, sizeof(T),
            (BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(T) || (is_vector<T>::cFlag)) ? NULL : object_mover, nofail);
      }
   };

   template<typename T> struct bitwise_movable< vector<T> > { enum { cFlag = true }; };

   // Hash map

   template <typename T>
   struct hasher
   {
      inline size_t operator() (const T& key) const { return static_cast<size_t>(key); }
   };

   template <typename T>
   struct equal_to
   {
      inline bool operator()(const T& a, const T& b) const { return a == b; }
   };

   // Important: The Hasher and Equals objects must be bitwise movable!
   template<typename Key, typename Value = empty_type, typename Hasher = hasher<Key>, typename Equals = equal_to<Key> >
   class hash_map
   {
   public:
      class iterator;
      class const_iterator;
   
   private:
      friend class iterator;
      friend class const_iterator;

      enum state
      {
         cStateInvalid = 0,
         cStateValid = 1
      };

      enum
      {
         cMinHashSize = 4U
      };

   public:
      typedef hash_map<Key, Value, Hasher, Equals> hash_map_type;
      typedef std::pair<Key, Value> value_type;
      typedef Key                   key_type;
      typedef Value                 referent_type;
      typedef Hasher                hasher_type;
      typedef Equals                equals_type;

      hash_map() :
         m_hash_shift(32), m_num_valid(0), m_grow_threshold(0)
      {
      }

      hash_map(const hash_map& other) :
         m_values(other.m_values),
         m_hash_shift(other.m_hash_shift),
         m_hasher(other.m_hasher),
         m_equals(other.m_equals),
         m_num_valid(other.m_num_valid),
         m_grow_threshold(other.m_grow_threshold)
      {
      }

      hash_map& operator= (const hash_map& other)
      {
         if (this == &other)
            return *this;

         clear();

         m_values = other.m_values;
         m_hash_shift = other.m_hash_shift;
         m_num_valid = other.m_num_valid;
         m_grow_threshold = other.m_grow_threshold;
         m_hasher = other.m_hasher;
         m_equals = other.m_equals;

         return *this;
      }

      inline ~hash_map()
      {
         clear();
      }

      const Equals& get_equals() const { return m_equals; }
      Equals& get_equals() { return m_equals; }

      void set_equals(const Equals& equals) { m_equals = equals; }

      const Hasher& get_hasher() const { return m_hasher; }
      Hasher& get_hasher() { return m_hasher; }

      void set_hasher(const Hasher& hasher) { m_hasher = hasher; }

      inline void clear()
      {
         if (!m_values.empty())
         {
            if (BASISU_HAS_DESTRUCTOR(Key) || BASISU_HAS_DESTRUCTOR(Value))
            {
               node* p = &get_node(0);
               node* p_end = p + m_values.size();

               uint32_t num_remaining = m_num_valid;
               while (p != p_end)
               {
                  if (p->state)
                  {
                     destruct_value_type(p);
                     num_remaining--;
                     if (!num_remaining)
                        break;
                  }

                  p++;
               }
            }

            m_values.clear_no_destruction();

            m_hash_shift = 32;
            m_num_valid = 0;
            m_grow_threshold = 0;
         }
      }

      inline void reset()
      {
         if (!m_num_valid)
            return;

         if (BASISU_HAS_DESTRUCTOR(Key) || BASISU_HAS_DESTRUCTOR(Value))
         {
            node* p = &get_node(0);
            node* p_end = p + m_values.size();

            uint32_t num_remaining = m_num_valid;
            while (p != p_end)
            {
               if (p->state)
               {
                  destruct_value_type(p);
                  p->state = cStateInvalid;

                  num_remaining--;
                  if (!num_remaining)
                     break;
               }

               p++;
            }
         }
         else if (sizeof(node) <= 32)
         {
            memset(&m_values[0], 0, m_values.size_in_bytes());
         }
         else
         {
            node* p = &get_node(0);
            node* p_end = p + m_values.size();

            uint32_t num_remaining = m_num_valid;
            while (p != p_end)
            {
               if (p->state)
               {
                  p->state = cStateInvalid;

                  num_remaining--;
                  if (!num_remaining)
                     break;
               }

               p++;
            }
         }

         m_num_valid = 0;
      }

      inline uint32_t size()
      {
         return m_num_valid;
      }

      inline uint32_t get_table_size()
      {
         return m_values.size();
      }

      inline bool empty()
      {
         return !m_num_valid;
      }

      inline void reserve(uint32_t new_capacity)
      {
         uint64_t new_hash_size = helpers::maximum(1U, new_capacity);

         new_hash_size = new_hash_size * 2ULL;

         if (!helpers::is_power_of_2(new_hash_size))
            new_hash_size = helpers::next_pow2(new_hash_size);

         new_hash_size = helpers::maximum<uint64_t>(cMinHashSize, new_hash_size);

         new_hash_size = helpers::minimum<uint64_t>(0x80000000UL, new_hash_size);

         if (new_hash_size > m_values.size())
            rehash((uint32_t)new_hash_size);
      }
            
      class iterator
      {
         friend class hash_map<Key, Value, Hasher, Equals>;
         friend class hash_map<Key, Value, Hasher, Equals>::const_iterator;

      public:
         inline iterator() : m_pTable(NULL), m_index(0) { }
         inline iterator(hash_map_type& table, uint32_t index) : m_pTable(&table), m_index(index) { }
         inline iterator(const iterator& other) : m_pTable(other.m_pTable), m_index(other.m_index) { }

         inline iterator& operator= (const iterator& other)
         {
            m_pTable = other.m_pTable;
            m_index = other.m_index;
            return *this;
         }

         // post-increment
         inline iterator operator++(int)
         {
            iterator result(*this);
            ++*this;
            return result;
         }

         // pre-increment
         inline iterator& operator++()
         {
            probe();
            return *this;
         }

         inline value_type& operator*() const { return *get_cur(); }
         inline value_type* operator->() const { return get_cur(); }

         inline bool operator == (const iterator& b) const { return (m_pTable == b.m_pTable) && (m_index == b.m_index); }
         inline bool operator != (const iterator& b) const { return !(*this == b); }
         inline bool operator == (const const_iterator& b) const { return (m_pTable == b.m_pTable) && (m_index == b.m_index); }
         inline bool operator != (const const_iterator& b) const { return !(*this == b); }

      private:
         hash_map_type* m_pTable;
         uint32_t m_index;

         inline value_type* get_cur() const
         {
            assert(m_pTable && (m_index < m_pTable->m_values.size()));
            assert(m_pTable->get_node_state(m_index) == cStateValid);

            return &m_pTable->get_node(m_index);
         }

         inline void probe()
         {
            assert(m_pTable);
            m_index = m_pTable->find_next(m_index);
         }
      };

      class const_iterator
      {
         friend class hash_map<Key, Value, Hasher, Equals>;
         friend class hash_map<Key, Value, Hasher, Equals>::iterator;

      public:
         inline const_iterator() : m_pTable(NULL), m_index(0) { }
         inline const_iterator(const hash_map_type& table, uint32_t index) : m_pTable(&table), m_index(index) { }
         inline const_iterator(const iterator& other) : m_pTable(other.m_pTable), m_index(other.m_index) { }
         inline const_iterator(const const_iterator& other) : m_pTable(other.m_pTable), m_index(other.m_index) { }

         inline const_iterator& operator= (const const_iterator& other)
         {
            m_pTable = other.m_pTable;
            m_index = other.m_index;
            return *this;
         }

         inline const_iterator& operator= (const iterator& other)
         {
            m_pTable = other.m_pTable;
            m_index = other.m_index;
            return *this;
         }

         // post-increment
         inline const_iterator operator++(int)
         {
            const_iterator result(*this);
            ++*this;
            return result;
         }

         // pre-increment
         inline const_iterator& operator++()
         {
            probe();
            return *this;
         }

         inline const value_type& operator*() const { return *get_cur(); }
         inline const value_type* operator->() const { return get_cur(); }

         inline bool operator == (const const_iterator& b) const { return (m_pTable == b.m_pTable) && (m_index == b.m_index); }
         inline bool operator != (const const_iterator& b) const { return !(*this == b); }
         inline bool operator == (const iterator& b) const { return (m_pTable == b.m_pTable) && (m_index == b.m_index); }
         inline bool operator != (const iterator& b) const { return !(*this == b); }

      private:
         const hash_map_type* m_pTable;
         uint32_t m_index;

         inline const value_type* get_cur() const
         {
            assert(m_pTable && (m_index < m_pTable->m_values.size()));
            assert(m_pTable->get_node_state(m_index) == cStateValid);

            return &m_pTable->get_node(m_index);
         }

         inline void probe()
         {
            assert(m_pTable);
            m_index = m_pTable->find_next(m_index);
         }
      };

      inline const_iterator begin() const
      {
         if (!m_num_valid)
            return end();

         return const_iterator(*this, find_next(UINT32_MAX));
      }

      inline const_iterator end() const
      {
         return const_iterator(*this, m_values.size());
      }

      inline iterator begin()
      {
         if (!m_num_valid)
            return end();

         return iterator(*this, find_next(UINT32_MAX));
      }

      inline iterator end()
      {
         return iterator(*this, m_values.size());
      }

      // insert_result.first will always point to inserted key/value (or the already existing key/value).
      // insert_resutt.second will be true if a new key/value was inserted, or false if the key already existed (in which case first will point to the already existing value).
      typedef std::pair<iterator, bool> insert_result;

      inline insert_result insert(const Key& k, const Value& v = Value())
      {
         insert_result result;
         if (!insert_no_grow(result, k, v))
         {
            grow();

            // This must succeed.
            if (!insert_no_grow(result, k, v))
            {
               fprintf(stderr, "insert() failed");
               abort();
            }
         }

         return result;
      }

      inline insert_result insert(const value_type& v)
      {
         return insert(v.first, v.second);
      }

      inline const_iterator find(const Key& k) const
      {
         return const_iterator(*this, find_index(k));
      }

      inline iterator find(const Key& k)
      {
         return iterator(*this, find_index(k));
      }

      inline bool erase(const Key& k)
      {
         uint32_t i = find_index(k);

         if (i >= m_values.size())
            return false;

         node* pDst = &get_node(i);
         destruct_value_type(pDst);
         pDst->state = cStateInvalid;

         m_num_valid--;

         for (; ; )
         {
            uint32_t r, j = i;

            node* pSrc = pDst;

            do
            {
               if (!i)
               {
                  i = m_values.size() - 1;
                  pSrc = &get_node(i);
               }
               else
               {
                  i--;
                  pSrc--;
               }

               if (!pSrc->state)
                  return true;

               r = hash_key(pSrc->first);

            } while ((i <= r && r < j) || (r < j && j < i) || (j < i && i <= r));

            move_node(pDst, pSrc);

            pDst = pSrc;
         }
      }

      inline void swap(hash_map_type& other)
      {
         m_values.swap(other.m_values);
         std::swap(m_hash_shift, other.m_hash_shift);
         std::swap(m_num_valid, other.m_num_valid);
         std::swap(m_grow_threshold, other.m_grow_threshold);
         std::swap(m_hasher, other.m_hasher);
         std::swap(m_equals, other.m_equals);
      }

   private:
      struct node : public value_type
      {
         uint8_t state;
      };

      static inline void construct_value_type(value_type* pDst, const Key& k, const Value& v)
      {
         if (BASISU_IS_BITWISE_COPYABLE(Key))
            memcpy(&pDst->first, &k, sizeof(Key));
         else
            scalar_type<Key>::construct(&pDst->first, k);

         if (BASISU_IS_BITWISE_COPYABLE(Value))
            memcpy(&pDst->second, &v, sizeof(Value));
         else
            scalar_type<Value>::construct(&pDst->second, v);
      }

      static inline void construct_value_type(value_type* pDst, const value_type* pSrc)
      {
         if ((BASISU_IS_BITWISE_COPYABLE(Key)) && (BASISU_IS_BITWISE_COPYABLE(Value)))
         {
            memcpy(pDst, pSrc, sizeof(value_type));
         }
         else
         {
            if (BASISU_IS_BITWISE_COPYABLE(Key))
               memcpy(&pDst->first, &pSrc->first, sizeof(Key));
            else
               scalar_type<Key>::construct(&pDst->first, pSrc->first);

            if (BASISU_IS_BITWISE_COPYABLE(Value))
               memcpy(&pDst->second, &pSrc->second, sizeof(Value));
            else
               scalar_type<Value>::construct(&pDst->second, pSrc->second);
         }
      }

      static inline void destruct_value_type(value_type* p)
      {
         scalar_type<Key>::destruct(&p->first);
         scalar_type<Value>::destruct(&p->second);
      }

      // Moves *pSrc to *pDst efficiently.
      // pDst should NOT be constructed on entry.
      static inline void move_node(node* pDst, node* pSrc, bool update_src_state = true)
      {
         assert(!pDst->state);

         if (BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(Key) && BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(Value))
         {
            memcpy(pDst, pSrc, sizeof(node));
         }
         else
         {
            if (BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(Key))
               memcpy(&pDst->first, &pSrc->first, sizeof(Key));
            else
            {
               scalar_type<Key>::construct(&pDst->first, pSrc->first);
               scalar_type<Key>::destruct(&pSrc->first);
            }

            if (BASISU_IS_BITWISE_COPYABLE_OR_MOVABLE(Value))
               memcpy(&pDst->second, &pSrc->second, sizeof(Value));
            else
            {
               scalar_type<Value>::construct(&pDst->second, pSrc->second);
               scalar_type<Value>::destruct(&pSrc->second);
            }

            pDst->state = cStateValid;
         }

         if (update_src_state)
            pSrc->state = cStateInvalid;
      }

      struct raw_node
      {
         inline raw_node()
         {
            node* p = reinterpret_cast<node*>(this);
            p->state = cStateInvalid;
         }

         inline ~raw_node()
         {
            node* p = reinterpret_cast<node*>(this);
            if (p->state)
               hash_map_type::destruct_value_type(p);
         }

         inline raw_node(const raw_node& other)
         {
            node* pDst = reinterpret_cast<node*>(this);
            const node* pSrc = reinterpret_cast<const node*>(&other);

            if (pSrc->state)
            {
               hash_map_type::construct_value_type(pDst, pSrc);
               pDst->state = cStateValid;
            }
            else
               pDst->state = cStateInvalid;
         }

         inline raw_node& operator= (const raw_node& rhs)
         {
            if (this == &rhs)
               return *this;

            node* pDst = reinterpret_cast<node*>(this);
            const node* pSrc = reinterpret_cast<const node*>(&rhs);

            if (pSrc->state)
            {
               if (pDst->state)
               {
                  pDst->first = pSrc->first;
                  pDst->second = pSrc->second;
               }
               else
               {
                  hash_map_type::construct_value_type(pDst, pSrc);
                  pDst->state = cStateValid;
               }
            }
            else if (pDst->state)
            {
               hash_map_type::destruct_value_type(pDst);
               pDst->state = cStateInvalid;
            }

            return *this;
         }

         uint8_t m_bits[sizeof(node)];
      };

      typedef basisu::vector<raw_node> node_vector;

      node_vector    m_values;
      uint32_t       m_hash_shift;

      Hasher         m_hasher;
      Equals         m_equals;

      uint32_t       m_num_valid;

      uint32_t       m_grow_threshold;

      inline uint32_t hash_key(const Key& k) const
      {
         assert((1U << (32U - m_hash_shift)) == m_values.size());

         uint32_t hash = static_cast<uint32_t>(m_hasher(k));

         // Fibonacci hashing
         hash = (2654435769U * hash) >> m_hash_shift;

         assert(hash < m_values.size());
         return hash;
      }

      inline const node& get_node(uint32_t index) const
      {
         return *reinterpret_cast<const node*>(&m_values[index]);
      }

      inline node& get_node(uint32_t index)
      {
         return *reinterpret_cast<node*>(&m_values[index]);
      }

      inline state get_node_state(uint32_t index) const
      {
         return static_cast<state>(get_node(index).state);
      }

      inline void set_node_state(uint32_t index, bool valid)
      {
         get_node(index).state = valid;
      }

      inline void grow()
      {
         uint64_t n = m_values.size() * 3ULL; // was * 2
         
         if (!helpers::is_power_of_2(n))
            n = helpers::next_pow2(n);

         if (n > 0x80000000UL)
            n = 0x80000000UL;

         rehash(helpers::maximum<uint32_t>(cMinHashSize, (uint32_t)n));
      }

      inline void rehash(uint32_t new_hash_size)
      {
         assert(new_hash_size >= m_num_valid);
         assert(helpers::is_power_of_2(new_hash_size));

         if ((new_hash_size < m_num_valid) || (new_hash_size == m_values.size()))
            return;

         hash_map new_map;
         new_map.m_values.resize(new_hash_size);
         new_map.m_hash_shift = 32U - helpers::floor_log2i(new_hash_size);
         assert(new_hash_size == (1U << (32U - new_map.m_hash_shift)));
         new_map.m_grow_threshold = UINT_MAX;

         node* pNode = reinterpret_cast<node*>(m_values.begin());
         node* pNode_end = pNode + m_values.size();

         while (pNode != pNode_end)
         {
            if (pNode->state)
            {
               new_map.move_into(pNode);

               if (new_map.m_num_valid == m_num_valid)
                  break;
            }

            pNode++;
         }

         new_map.m_grow_threshold = (new_hash_size + 1U) >> 1U;

         m_values.clear_no_destruction();
         m_hash_shift = 32;

         swap(new_map);
      }

      inline uint32_t find_next(uint32_t index) const
      {
         index++;

         if (index >= m_values.size())
            return index;

         const node* pNode = &get_node(index);

         for (; ; )
         {
            if (pNode->state)
               break;

            if (++index >= m_values.size())
               break;

            pNode++;
         }

         return index;
      }

      inline uint32_t find_index(const Key& k) const
      {
         if (m_num_valid)
         {
            uint32_t index = hash_key(k);
            const node* pNode = &get_node(index);

            if (pNode->state)
            {
               if (m_equals(pNode->first, k))
                  return index;

               const uint32_t orig_index = index;

               for (; ; )
               {
                  if (!index)
                  {
                     index = m_values.size() - 1;
                     pNode = &get_node(index);
                  }
                  else
                  {
                     index--;
                     pNode--;
                  }

                  if (index == orig_index)
                     break;

                  if (!pNode->state)
                     break;

                  if (m_equals(pNode->first, k))
                     return index;
               }
            }
         }

         return m_values.size();
      }

      inline bool insert_no_grow(insert_result& result, const Key& k, const Value& v = Value())
      {
         if (!m_values.size())
            return false;

         uint32_t index = hash_key(k);
         node* pNode = &get_node(index);

         if (pNode->state)
         {
            if (m_equals(pNode->first, k))
            {
               result.first = iterator(*this, index);
               result.second = false;
               return true;
            }

            const uint32_t orig_index = index;

            for (; ; )
            {
               if (!index)
               {
                  index = m_values.size() - 1;
                  pNode = &get_node(index);
               }
               else
               {
                  index--;
                  pNode--;
               }

               if (orig_index == index)
                  return false;

               if (!pNode->state)
                  break;

               if (m_equals(pNode->first, k))
               {
                  result.first = iterator(*this, index);
                  result.second = false;
                  return true;
               }
            }
         }

         if (m_num_valid >= m_grow_threshold)
            return false;

         construct_value_type(pNode, k, v);

         pNode->state = cStateValid;

         m_num_valid++;
         assert(m_num_valid <= m_values.size());

         result.first = iterator(*this, index);
         result.second = true;

         return true;
      }

      inline void move_into(node* pNode)
      {
         uint32_t index = hash_key(pNode->first);
         node* pDst_node = &get_node(index);

         if (pDst_node->state)
         {
            const uint32_t orig_index = index;

            for (; ; )
            {
               if (!index)
               {
                  index = m_values.size() - 1;
                  pDst_node = &get_node(index);
               }
               else
               {
                  index--;
                  pDst_node--;
               }

               if (index == orig_index)
               {
                  assert(false);
                  return;
               }

               if (!pDst_node->state)
                  break;
            }
         }

         move_node(pDst_node, pNode, false);

         m_num_valid++;
      }
   };

   template<typename Key, typename Value, typename Hasher, typename Equals>
   struct bitwise_movable< hash_map<Key, Value, Hasher, Equals> > { enum { cFlag = true }; };
   
#if BASISU_HASHMAP_TEST
   extern void hash_map_test();
#endif
      
} // namespace basisu

namespace std
{
   template<typename T>
   inline void swap(basisu::vector<T>& a, basisu::vector<T>& b)
   {
      a.swap(b);
   }

   template<typename Key, typename Value, typename Hasher, typename Equals>
   inline void swap(basisu::hash_map<Key, Value, Hasher, Equals>& a, basisu::hash_map<Key, Value, Hasher, Equals>& b)
   {
      a.swap(b);
   }

} // namespace std
