// basisu_containers_impl.h
// Do not include directly

#ifdef _MSC_VER
#pragma warning (disable:4127) // warning C4127: conditional expression is constant
#endif

namespace basisu
{
   bool elemental_vector::increase_capacity(uint32_t min_new_capacity, bool grow_hint, uint32_t element_size, object_mover pMover, bool nofail)
   {
      assert(m_size <= m_capacity);

      if (sizeof(void *) == sizeof(uint64_t))
         assert(min_new_capacity < (0x400000000ULL / element_size));
      else
         assert(min_new_capacity < (0x7FFF0000U / element_size));

      if (m_capacity >= min_new_capacity)
         return true;

      size_t new_capacity = min_new_capacity;
      if ((grow_hint) && (!helpers::is_power_of_2((uint64_t)new_capacity)))
      {
         new_capacity = (size_t)helpers::next_pow2((uint64_t)new_capacity);

         assert(new_capacity && (new_capacity > m_capacity));

         if (new_capacity < min_new_capacity)
         {
            if (nofail)
               return false;
            fprintf(stderr, "vector too large\n");
            abort();
         }
      }
            
      const size_t desired_size = element_size * new_capacity;
      size_t actual_size = 0;
      if (!pMover)
      {
         void* new_p = realloc(m_p, desired_size);
         if (!new_p)
         {
            if (nofail)
               return false;

            char buf[256];
#ifdef _MSC_VER
            sprintf_s(buf, sizeof(buf), "vector: realloc() failed allocating %u bytes", (uint32_t)desired_size);
#else
            sprintf(buf, "vector: realloc() failed allocating %u bytes", (uint32_t)desired_size);
#endif
            fprintf(stderr, "%s", buf);
            abort();
         }

#if BASISU_VECTOR_DETERMINISTIC
         actual_size = desired_size;
#elif defined(_MSC_VER)
         actual_size = _msize(new_p);
#elif HAS_MALLOC_USABLE_SIZE
         actual_size = malloc_usable_size(new_p);
#else
         actual_size = desired_size;
#endif
         m_p = new_p;
      }
      else
      {
         void* new_p = malloc(desired_size);
         if (!new_p)
         {
            if (nofail)
               return false;

            char buf[256];
#ifdef _MSC_VER
            sprintf_s(buf, sizeof(buf), "vector: malloc() failed allocating %u bytes", (uint32_t)desired_size);
#else
            sprintf(buf, "vector: malloc() failed allocating %u bytes", (uint32_t)desired_size);
#endif
            fprintf(stderr, "%s", buf);
            abort();
         }

#if BASISU_VECTOR_DETERMINISTIC
         actual_size = desired_size;
#elif defined(_MSC_VER)
         actual_size = _msize(new_p);
#elif HAS_MALLOC_USABLE_SIZE
         actual_size = malloc_usable_size(new_p);
#else
         actual_size = desired_size;
#endif

         (*pMover)(new_p, m_p, m_size);

         if (m_p)
            free(m_p);
         
         m_p = new_p;
      }

      if (actual_size > desired_size)
         m_capacity = static_cast<uint32_t>(actual_size / element_size);
      else
         m_capacity = static_cast<uint32_t>(new_capacity);

      return true;
   }

#if BASISU_HASHMAP_TEST

#define HASHMAP_TEST_VERIFY(c) do { if (!(c)) handle_hashmap_test_verify_failure(__LINE__); } while(0)

   static void handle_hashmap_test_verify_failure(int line)
   {
      fprintf(stderr, "HASHMAP_TEST_VERIFY() faild on line %i\n", line);
      abort();
   }

   class counted_obj
   {
   public:
      counted_obj(uint32_t v = 0) :
         m_val(v)
      {
         m_count++;
      }

      counted_obj(const counted_obj& obj) :
         m_val(obj.m_val)
      {
         m_count++;
      }

      ~counted_obj()
      {
         assert(m_count > 0);
         m_count--;
      }

      static uint32_t m_count;

      uint32_t m_val;

      operator size_t() const { return m_val; }

      bool operator== (const counted_obj& rhs) const { return m_val == rhs.m_val; }
      bool operator== (const uint32_t rhs) const { return m_val == rhs; }

   };

   uint32_t counted_obj::m_count;

   static uint32_t urand32()
   {
      uint32_t a = rand();
      uint32_t b = rand() << 15;
      uint32_t c = rand() << (32 - 15);
      return a ^ b ^ c;
   }

   static int irand32(int l, int h)
   {
      assert(l < h);
      if (l >= h)
         return l;

      uint32_t range = static_cast<uint32_t>(h - l);

      uint32_t rnd = urand32();

      uint32_t rnd_range = static_cast<uint32_t>((((uint64_t)range) * ((uint64_t)rnd)) >> 32U);

      int result = l + rnd_range;
      assert((result >= l) && (result < h));
      return result;
   }

   void hash_map_test()
   {
      {
         basisu::hash_map<uint64_t, uint64_t> k;
         basisu::hash_map<uint64_t, uint64_t> l;
         std::swap(k, l);

         k.begin();
         k.end();
         k.clear();
         k.empty();
         k.erase(0);
         k.insert(0, 1);
         k.find(0);
         k.get_equals();
         k.get_hasher();
         k.get_table_size();
         k.reset();
         k.reserve(1);
         k = l;
         k.set_equals(l.get_equals());
         k.set_hasher(l.get_hasher());
         k.get_table_size();
      }

      uint32_t seed = 0;
      for (; ; )
      {
         seed++;

         typedef basisu::hash_map<counted_obj, counted_obj> my_hash_map;
         my_hash_map m;

         const uint32_t n = irand32(0, 100000);

         printf("%u\n", n);

         srand(seed); // r1.seed(seed);

         basisu::vector<int> q;

         uint32_t count = 0;
         for (uint32_t i = 0; i < n; i++)
         {
            uint32_t v = urand32() & 0x7FFFFFFF;
            my_hash_map::insert_result res = m.insert(counted_obj(v), counted_obj(v ^ 0xdeadbeef));
            if (res.second)
            {
               count++;
               q.push_back(v);
            }
         }

         HASHMAP_TEST_VERIFY(m.size() == count);

         srand(seed);

         my_hash_map cm(m);
         m.clear();
         m = cm;
         cm.reset();

         for (uint32_t i = 0; i < n; i++)
         {
            uint32_t v = urand32() & 0x7FFFFFFF;
            my_hash_map::const_iterator it = m.find(counted_obj(v));
            HASHMAP_TEST_VERIFY(it != m.end());
            HASHMAP_TEST_VERIFY(it->first == v);
            HASHMAP_TEST_VERIFY(it->second == (v ^ 0xdeadbeef));
         }

         for (uint32_t t = 0; t < 2; t++)
         {
            const uint32_t nd = irand32(1, q.size() + 1);
            for (uint32_t i = 0; i < nd; i++)
            {
               uint32_t p = irand32(0, q.size());

               int k = q[p];
               if (k >= 0)
               {
                  q[p] = -k - 1;

                  bool s = m.erase(counted_obj(k));
                  HASHMAP_TEST_VERIFY(s);
               }
            }

            typedef basisu::hash_map<uint32_t, empty_type> uint_hash_set;
            uint_hash_set s;

            for (uint32_t i = 0; i < q.size(); i++)
            {
               int v = q[i];

               if (v >= 0)
               {
                  my_hash_map::const_iterator it = m.find(counted_obj(v));
                  HASHMAP_TEST_VERIFY(it != m.end());
                  HASHMAP_TEST_VERIFY(it->first == (uint32_t)v);
                  HASHMAP_TEST_VERIFY(it->second == ((uint32_t)v ^ 0xdeadbeef));

                  s.insert(v);
               }
               else
               {
                  my_hash_map::const_iterator it = m.find(counted_obj(-v - 1));
                  HASHMAP_TEST_VERIFY(it == m.end());
               }
            }

            uint32_t found_count = 0;
            for (my_hash_map::const_iterator it = m.begin(); it != m.end(); ++it)
            {
               HASHMAP_TEST_VERIFY(it->second == ((uint32_t)it->first ^ 0xdeadbeef));

               uint_hash_set::const_iterator fit(s.find((uint32_t)it->first));
               HASHMAP_TEST_VERIFY(fit != s.end());

               HASHMAP_TEST_VERIFY(fit->first == it->first);

               found_count++;
            }

            HASHMAP_TEST_VERIFY(found_count == s.size());
         }

         HASHMAP_TEST_VERIFY(counted_obj::m_count == m.size() * 2);
      }
   }

#endif // BASISU_HASHMAP_TEST

} // namespace basisu
