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

#ifdef _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();
         }

#ifdef _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
