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