17a984708SDavid Chisnall //===-------------------------- debug.cpp ---------------------------------===// 27a984708SDavid Chisnall // 37a984708SDavid Chisnall // The LLVM Compiler Infrastructure 47a984708SDavid Chisnall // 57a984708SDavid Chisnall // This file is dual licensed under the MIT and the University of Illinois Open 67a984708SDavid Chisnall // Source Licenses. See LICENSE.TXT for details. 77a984708SDavid Chisnall // 87a984708SDavid Chisnall //===----------------------------------------------------------------------===// 97a984708SDavid Chisnall 107a984708SDavid Chisnall #define _LIBCPP_DEBUG2 1 117a984708SDavid Chisnall #include "__config" 127a984708SDavid Chisnall #include "__debug" 137a984708SDavid Chisnall #include "functional" 147a984708SDavid Chisnall #include "algorithm" 157a984708SDavid Chisnall #include "__hash_table" 167a984708SDavid Chisnall #include "mutex" 177a984708SDavid Chisnall 187a984708SDavid Chisnall _LIBCPP_BEGIN_NAMESPACE_STD 197a984708SDavid Chisnall 207a984708SDavid Chisnall _LIBCPP_VISIBLE 217a984708SDavid Chisnall __libcpp_db* 227a984708SDavid Chisnall __get_db() 237a984708SDavid Chisnall { 247a984708SDavid Chisnall static __libcpp_db db; 257a984708SDavid Chisnall return &db; 26*cfdf2879SDavid Chisnall } 277a984708SDavid Chisnall 287a984708SDavid Chisnall _LIBCPP_VISIBLE 297a984708SDavid Chisnall const __libcpp_db* 307a984708SDavid Chisnall __get_const_db() 317a984708SDavid Chisnall { 327a984708SDavid Chisnall return __get_db(); 337a984708SDavid Chisnall } 347a984708SDavid Chisnall 357a984708SDavid Chisnall namespace 367a984708SDavid Chisnall { 377a984708SDavid Chisnall 387a984708SDavid Chisnall typedef mutex mutex_type; 397a984708SDavid Chisnall typedef lock_guard<mutex_type> WLock; 407a984708SDavid Chisnall typedef lock_guard<mutex_type> RLock; 417a984708SDavid Chisnall 427a984708SDavid Chisnall mutex_type& 437a984708SDavid Chisnall mut() 447a984708SDavid Chisnall { 457a984708SDavid Chisnall static mutex_type m; 467a984708SDavid Chisnall return m; 477a984708SDavid Chisnall } 487a984708SDavid Chisnall 497a984708SDavid Chisnall } // unnamed namespace 507a984708SDavid Chisnall 517a984708SDavid Chisnall __i_node::~__i_node() 527a984708SDavid Chisnall { 537a984708SDavid Chisnall if (__next_) 547a984708SDavid Chisnall { 557a984708SDavid Chisnall __next_->~__i_node(); 567a984708SDavid Chisnall free(__next_); 577a984708SDavid Chisnall } 587a984708SDavid Chisnall } 597a984708SDavid Chisnall 607a984708SDavid Chisnall __c_node::~__c_node() 617a984708SDavid Chisnall { 627a984708SDavid Chisnall free(beg_); 637a984708SDavid Chisnall if (__next_) 647a984708SDavid Chisnall { 657a984708SDavid Chisnall __next_->~__c_node(); 667a984708SDavid Chisnall free(__next_); 677a984708SDavid Chisnall } 687a984708SDavid Chisnall } 697a984708SDavid Chisnall 707a984708SDavid Chisnall __libcpp_db::__libcpp_db() 717a984708SDavid Chisnall : __cbeg_(nullptr), 727a984708SDavid Chisnall __cend_(nullptr), 737a984708SDavid Chisnall __csz_(0), 747a984708SDavid Chisnall __ibeg_(nullptr), 757a984708SDavid Chisnall __iend_(nullptr), 767a984708SDavid Chisnall __isz_(0) 777a984708SDavid Chisnall { 787a984708SDavid Chisnall } 797a984708SDavid Chisnall 807a984708SDavid Chisnall __libcpp_db::~__libcpp_db() 817a984708SDavid Chisnall { 827a984708SDavid Chisnall if (__cbeg_) 837a984708SDavid Chisnall { 847a984708SDavid Chisnall for (__c_node** p = __cbeg_; p != __cend_; ++p) 857a984708SDavid Chisnall { 867a984708SDavid Chisnall if (*p != nullptr) 877a984708SDavid Chisnall { 887a984708SDavid Chisnall (*p)->~__c_node(); 897a984708SDavid Chisnall free(*p); 907a984708SDavid Chisnall } 917a984708SDavid Chisnall } 927a984708SDavid Chisnall free(__cbeg_); 937a984708SDavid Chisnall } 947a984708SDavid Chisnall if (__ibeg_) 957a984708SDavid Chisnall { 967a984708SDavid Chisnall for (__i_node** p = __ibeg_; p != __iend_; ++p) 977a984708SDavid Chisnall { 987a984708SDavid Chisnall if (*p != nullptr) 997a984708SDavid Chisnall { 1007a984708SDavid Chisnall (*p)->~__i_node(); 1017a984708SDavid Chisnall free(*p); 1027a984708SDavid Chisnall } 1037a984708SDavid Chisnall } 1047a984708SDavid Chisnall free(__ibeg_); 1057a984708SDavid Chisnall } 1067a984708SDavid Chisnall } 1077a984708SDavid Chisnall 1087a984708SDavid Chisnall void* 1097a984708SDavid Chisnall __libcpp_db::__find_c_from_i(void* __i) const 1107a984708SDavid Chisnall { 1117a984708SDavid Chisnall RLock _(mut()); 1127a984708SDavid Chisnall __i_node* i = __find_iterator(__i); 1137a984708SDavid Chisnall _LIBCPP_ASSERT(i != nullptr, "iterator constructed in translation unit with debug mode not enabled." 1147a984708SDavid Chisnall " #define _LIBCPP_DEBUG2 1 for that translation unit."); 1157a984708SDavid Chisnall return i->__c_ != nullptr ? i->__c_->__c_ : nullptr; 1167a984708SDavid Chisnall } 1177a984708SDavid Chisnall 1187a984708SDavid Chisnall void 1197a984708SDavid Chisnall __libcpp_db::__insert_ic(void* __i, const void* __c) 1207a984708SDavid Chisnall { 1217a984708SDavid Chisnall WLock _(mut()); 1227a984708SDavid Chisnall __i_node* i = __insert_iterator(__i); 1237a984708SDavid Chisnall const char* errmsg = 1247a984708SDavid Chisnall "Container constructed in a translation unit with debug mode disabled." 1257a984708SDavid Chisnall " But it is being used in a translation unit with debug mode enabled." 1267a984708SDavid Chisnall " Enable it in the other translation unit with #define _LIBCPP_DEBUG2 1"; 1277a984708SDavid Chisnall _LIBCPP_ASSERT(__cbeg_ != __cend_, errmsg); 12894e3ee44SDavid Chisnall size_t hc = hash<const void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); 1297a984708SDavid Chisnall __c_node* c = __cbeg_[hc]; 1307a984708SDavid Chisnall _LIBCPP_ASSERT(c != nullptr, errmsg); 1317a984708SDavid Chisnall while (c->__c_ != __c) 1327a984708SDavid Chisnall { 1337a984708SDavid Chisnall c = c->__next_; 1347a984708SDavid Chisnall _LIBCPP_ASSERT(c != nullptr, errmsg); 1357a984708SDavid Chisnall } 1367a984708SDavid Chisnall c->__add(i); 1377a984708SDavid Chisnall i->__c_ = c; 1387a984708SDavid Chisnall } 1397a984708SDavid Chisnall 1407a984708SDavid Chisnall __c_node* 1417a984708SDavid Chisnall __libcpp_db::__insert_c(void* __c) 1427a984708SDavid Chisnall { 1437a984708SDavid Chisnall WLock _(mut()); 14494e3ee44SDavid Chisnall if (__csz_ + 1 > static_cast<size_t>(__cend_ - __cbeg_)) 1457a984708SDavid Chisnall { 14694e3ee44SDavid Chisnall size_t nc = __next_prime(2*static_cast<size_t>(__cend_ - __cbeg_) + 1); 1477a984708SDavid Chisnall __c_node** cbeg = (__c_node**)calloc(nc, sizeof(void*)); 1487a984708SDavid Chisnall if (cbeg == nullptr) 149936e9439SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS 1507a984708SDavid Chisnall throw bad_alloc(); 151936e9439SDimitry Andric #else 152936e9439SDimitry Andric abort(); 153936e9439SDimitry Andric #endif 1547a984708SDavid Chisnall for (__c_node** p = __cbeg_; p != __cend_; ++p) 1557a984708SDavid Chisnall { 1567a984708SDavid Chisnall __c_node* q = *p; 1577a984708SDavid Chisnall while (q != nullptr) 1587a984708SDavid Chisnall { 1597a984708SDavid Chisnall size_t h = hash<void*>()(q->__c_) % nc; 1607a984708SDavid Chisnall __c_node* r = q->__next_; 1617a984708SDavid Chisnall q->__next_ = cbeg[h]; 1627a984708SDavid Chisnall cbeg[h] = q; 1637a984708SDavid Chisnall q = r; 1647a984708SDavid Chisnall } 1657a984708SDavid Chisnall } 1667a984708SDavid Chisnall free(__cbeg_); 1677a984708SDavid Chisnall __cbeg_ = cbeg; 1687a984708SDavid Chisnall __cend_ = __cbeg_ + nc; 1697a984708SDavid Chisnall } 17094e3ee44SDavid Chisnall size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); 1717a984708SDavid Chisnall __c_node* p = __cbeg_[hc]; 1727a984708SDavid Chisnall __c_node* r = __cbeg_[hc] = (__c_node*)malloc(sizeof(__c_node)); 1737a984708SDavid Chisnall if (__cbeg_[hc] == nullptr) 174936e9439SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS 1757a984708SDavid Chisnall throw bad_alloc(); 176936e9439SDimitry Andric #else 177936e9439SDimitry Andric abort(); 178936e9439SDimitry Andric #endif 1797a984708SDavid Chisnall r->__c_ = __c; 1807a984708SDavid Chisnall r->__next_ = p; 1817a984708SDavid Chisnall ++__csz_; 1827a984708SDavid Chisnall return r; 1837a984708SDavid Chisnall } 1847a984708SDavid Chisnall 1857a984708SDavid Chisnall void 1867a984708SDavid Chisnall __libcpp_db::__erase_i(void* __i) 1877a984708SDavid Chisnall { 1887a984708SDavid Chisnall WLock _(mut()); 1897a984708SDavid Chisnall if (__ibeg_ != __iend_) 1907a984708SDavid Chisnall { 19194e3ee44SDavid Chisnall size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_); 1927a984708SDavid Chisnall __i_node* p = __ibeg_[hi]; 1937a984708SDavid Chisnall if (p != nullptr) 1947a984708SDavid Chisnall { 1957a984708SDavid Chisnall __i_node* q = nullptr; 1967a984708SDavid Chisnall while (p->__i_ != __i) 1977a984708SDavid Chisnall { 1987a984708SDavid Chisnall q = p; 1997a984708SDavid Chisnall p = p->__next_; 2007a984708SDavid Chisnall if (p == nullptr) 2017a984708SDavid Chisnall return; 2027a984708SDavid Chisnall } 2037a984708SDavid Chisnall if (q == nullptr) 2047a984708SDavid Chisnall __ibeg_[hi] = p->__next_; 2057a984708SDavid Chisnall else 2067a984708SDavid Chisnall q->__next_ = p->__next_; 2077a984708SDavid Chisnall __c_node* c = p->__c_; 2087a984708SDavid Chisnall free(p); 2097a984708SDavid Chisnall --__isz_; 2107a984708SDavid Chisnall if (c != nullptr) 2117a984708SDavid Chisnall c->__remove(p); 2127a984708SDavid Chisnall } 2137a984708SDavid Chisnall } 2147a984708SDavid Chisnall } 2157a984708SDavid Chisnall 2167a984708SDavid Chisnall void 2177a984708SDavid Chisnall __libcpp_db::__invalidate_all(void* __c) 2187a984708SDavid Chisnall { 2197a984708SDavid Chisnall WLock _(mut()); 22094e3ee44SDavid Chisnall size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); 2217a984708SDavid Chisnall __c_node* p = __cbeg_[hc]; 2227a984708SDavid Chisnall _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __invalidate_all A"); 2237a984708SDavid Chisnall while (p->__c_ != __c) 2247a984708SDavid Chisnall { 2257a984708SDavid Chisnall p = p->__next_; 2267a984708SDavid Chisnall _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __invalidate_all B"); 2277a984708SDavid Chisnall } 2287a984708SDavid Chisnall while (p->end_ != p->beg_) 2297a984708SDavid Chisnall { 2307a984708SDavid Chisnall --p->end_; 2317a984708SDavid Chisnall (*p->end_)->__c_ = nullptr; 2327a984708SDavid Chisnall } 2337a984708SDavid Chisnall } 2347a984708SDavid Chisnall 2357a984708SDavid Chisnall __c_node* 2367a984708SDavid Chisnall __libcpp_db::__find_c_and_lock(void* __c) const 2377a984708SDavid Chisnall { 2387a984708SDavid Chisnall mut().lock(); 23994e3ee44SDavid Chisnall size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); 2407a984708SDavid Chisnall __c_node* p = __cbeg_[hc]; 2417a984708SDavid Chisnall _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c_and_lock A"); 2427a984708SDavid Chisnall while (p->__c_ != __c) 2437a984708SDavid Chisnall { 2447a984708SDavid Chisnall p = p->__next_; 2457a984708SDavid Chisnall _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c_and_lock B"); 2467a984708SDavid Chisnall } 2477a984708SDavid Chisnall return p; 2487a984708SDavid Chisnall } 2497a984708SDavid Chisnall 2507a984708SDavid Chisnall __c_node* 2517a984708SDavid Chisnall __libcpp_db::__find_c(void* __c) const 2527a984708SDavid Chisnall { 25394e3ee44SDavid Chisnall size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); 2547a984708SDavid Chisnall __c_node* p = __cbeg_[hc]; 2557a984708SDavid Chisnall _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c A"); 2567a984708SDavid Chisnall while (p->__c_ != __c) 2577a984708SDavid Chisnall { 2587a984708SDavid Chisnall p = p->__next_; 2597a984708SDavid Chisnall _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c B"); 2607a984708SDavid Chisnall } 2617a984708SDavid Chisnall return p; 2627a984708SDavid Chisnall } 2637a984708SDavid Chisnall 2647a984708SDavid Chisnall void 2657a984708SDavid Chisnall __libcpp_db::unlock() const 2667a984708SDavid Chisnall { 2677a984708SDavid Chisnall mut().unlock(); 2687a984708SDavid Chisnall } 2697a984708SDavid Chisnall 2707a984708SDavid Chisnall void 2717a984708SDavid Chisnall __libcpp_db::__erase_c(void* __c) 2727a984708SDavid Chisnall { 2737a984708SDavid Chisnall WLock _(mut()); 27494e3ee44SDavid Chisnall size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); 2757a984708SDavid Chisnall __c_node* p = __cbeg_[hc]; 2767a984708SDavid Chisnall __c_node* q = nullptr; 2777a984708SDavid Chisnall _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c A"); 2787a984708SDavid Chisnall while (p->__c_ != __c) 2797a984708SDavid Chisnall { 2807a984708SDavid Chisnall q = p; 2817a984708SDavid Chisnall p = p->__next_; 2827a984708SDavid Chisnall _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c B"); 2837a984708SDavid Chisnall } 2847a984708SDavid Chisnall if (q == nullptr) 2857a984708SDavid Chisnall __cbeg_[hc] = p->__next_; 2867a984708SDavid Chisnall else 2877a984708SDavid Chisnall q->__next_ = p->__next_; 2887a984708SDavid Chisnall while (p->end_ != p->beg_) 2897a984708SDavid Chisnall { 2907a984708SDavid Chisnall --p->end_; 2917a984708SDavid Chisnall (*p->end_)->__c_ = nullptr; 2927a984708SDavid Chisnall } 2937a984708SDavid Chisnall free(p->beg_); 2947a984708SDavid Chisnall free(p); 2957a984708SDavid Chisnall --__csz_; 2967a984708SDavid Chisnall } 2977a984708SDavid Chisnall 2987a984708SDavid Chisnall void 2997a984708SDavid Chisnall __libcpp_db::__iterator_copy(void* __i, const void* __i0) 3007a984708SDavid Chisnall { 3017a984708SDavid Chisnall WLock _(mut()); 3027a984708SDavid Chisnall __i_node* i = __find_iterator(__i); 3037a984708SDavid Chisnall __i_node* i0 = __find_iterator(__i0); 3047a984708SDavid Chisnall __c_node* c0 = i0 != nullptr ? i0->__c_ : nullptr; 3057a984708SDavid Chisnall if (i == nullptr && c0 != nullptr) 3067a984708SDavid Chisnall i = __insert_iterator(__i); 3077a984708SDavid Chisnall __c_node* c = i != nullptr ? i->__c_ : nullptr; 3087a984708SDavid Chisnall if (c != c0) 3097a984708SDavid Chisnall { 3107a984708SDavid Chisnall if (c != nullptr) 3117a984708SDavid Chisnall c->__remove(i); 3127a984708SDavid Chisnall if (i != nullptr) 3137a984708SDavid Chisnall { 3147a984708SDavid Chisnall i->__c_ = nullptr; 3157a984708SDavid Chisnall if (c0 != nullptr) 3167a984708SDavid Chisnall { 3177a984708SDavid Chisnall i->__c_ = c0; 3187a984708SDavid Chisnall i->__c_->__add(i); 3197a984708SDavid Chisnall } 3207a984708SDavid Chisnall } 3217a984708SDavid Chisnall } 3227a984708SDavid Chisnall } 3237a984708SDavid Chisnall 3247a984708SDavid Chisnall bool 3257a984708SDavid Chisnall __libcpp_db::__dereferenceable(const void* __i) const 3267a984708SDavid Chisnall { 3277a984708SDavid Chisnall RLock _(mut()); 3287a984708SDavid Chisnall __i_node* i = __find_iterator(__i); 3297a984708SDavid Chisnall return i != nullptr && i->__c_ != nullptr && i->__c_->__dereferenceable(__i); 3307a984708SDavid Chisnall } 3317a984708SDavid Chisnall 3327a984708SDavid Chisnall bool 3337a984708SDavid Chisnall __libcpp_db::__decrementable(const void* __i) const 3347a984708SDavid Chisnall { 3357a984708SDavid Chisnall RLock _(mut()); 3367a984708SDavid Chisnall __i_node* i = __find_iterator(__i); 3377a984708SDavid Chisnall return i != nullptr && i->__c_ != nullptr && i->__c_->__decrementable(__i); 3387a984708SDavid Chisnall } 3397a984708SDavid Chisnall 3407a984708SDavid Chisnall bool 3417a984708SDavid Chisnall __libcpp_db::__addable(const void* __i, ptrdiff_t __n) const 3427a984708SDavid Chisnall { 3437a984708SDavid Chisnall RLock _(mut()); 3447a984708SDavid Chisnall __i_node* i = __find_iterator(__i); 3457a984708SDavid Chisnall return i != nullptr && i->__c_ != nullptr && i->__c_->__addable(__i, __n); 3467a984708SDavid Chisnall } 3477a984708SDavid Chisnall 3487a984708SDavid Chisnall bool 3497a984708SDavid Chisnall __libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const 3507a984708SDavid Chisnall { 3517a984708SDavid Chisnall RLock _(mut()); 3527a984708SDavid Chisnall __i_node* i = __find_iterator(__i); 3537a984708SDavid Chisnall return i != nullptr && i->__c_ != nullptr && i->__c_->__subscriptable(__i, __n); 3547a984708SDavid Chisnall } 3557a984708SDavid Chisnall 3567a984708SDavid Chisnall bool 3577a984708SDavid Chisnall __libcpp_db::__comparable(const void* __i, const void* __j) const 3587a984708SDavid Chisnall { 3597a984708SDavid Chisnall RLock _(mut()); 3607a984708SDavid Chisnall __i_node* i = __find_iterator(__i); 3617a984708SDavid Chisnall __i_node* j = __find_iterator(__j); 3627a984708SDavid Chisnall __c_node* ci = i != nullptr ? i->__c_ : nullptr; 3637a984708SDavid Chisnall __c_node* cj = j != nullptr ? j->__c_ : nullptr; 3647a984708SDavid Chisnall return ci != nullptr && ci == cj; 3657a984708SDavid Chisnall } 3667a984708SDavid Chisnall 3677a984708SDavid Chisnall void 3687a984708SDavid Chisnall __libcpp_db::swap(void* c1, void* c2) 3697a984708SDavid Chisnall { 3707a984708SDavid Chisnall WLock _(mut()); 37194e3ee44SDavid Chisnall size_t hc = hash<void*>()(c1) % static_cast<size_t>(__cend_ - __cbeg_); 3727a984708SDavid Chisnall __c_node* p1 = __cbeg_[hc]; 3737a984708SDavid Chisnall _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap A"); 3747a984708SDavid Chisnall while (p1->__c_ != c1) 3757a984708SDavid Chisnall { 3767a984708SDavid Chisnall p1 = p1->__next_; 3777a984708SDavid Chisnall _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap B"); 3787a984708SDavid Chisnall } 37994e3ee44SDavid Chisnall hc = hash<void*>()(c2) % static_cast<size_t>(__cend_ - __cbeg_); 3807a984708SDavid Chisnall __c_node* p2 = __cbeg_[hc]; 3817a984708SDavid Chisnall _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap C"); 3827a984708SDavid Chisnall while (p2->__c_ != c2) 3837a984708SDavid Chisnall { 3847a984708SDavid Chisnall p2 = p2->__next_; 3857a984708SDavid Chisnall _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap D"); 3867a984708SDavid Chisnall } 3877a984708SDavid Chisnall std::swap(p1->beg_, p2->beg_); 3887a984708SDavid Chisnall std::swap(p1->end_, p2->end_); 3897a984708SDavid Chisnall std::swap(p1->cap_, p2->cap_); 3907a984708SDavid Chisnall for (__i_node** p = p1->beg_; p != p1->end_; ++p) 3917a984708SDavid Chisnall (*p)->__c_ = p1; 3927a984708SDavid Chisnall for (__i_node** p = p2->beg_; p != p2->end_; ++p) 3937a984708SDavid Chisnall (*p)->__c_ = p2; 3947a984708SDavid Chisnall } 3957a984708SDavid Chisnall 3967a984708SDavid Chisnall void 3977a984708SDavid Chisnall __libcpp_db::__insert_i(void* __i) 3987a984708SDavid Chisnall { 3997a984708SDavid Chisnall WLock _(mut()); 4007a984708SDavid Chisnall __insert_iterator(__i); 4017a984708SDavid Chisnall } 4027a984708SDavid Chisnall 4037a984708SDavid Chisnall void 4047a984708SDavid Chisnall __c_node::__add(__i_node* i) 4057a984708SDavid Chisnall { 4067a984708SDavid Chisnall if (end_ == cap_) 4077a984708SDavid Chisnall { 40894e3ee44SDavid Chisnall size_t nc = 2*static_cast<size_t>(cap_ - beg_); 4097a984708SDavid Chisnall if (nc == 0) 4107a984708SDavid Chisnall nc = 1; 4117a984708SDavid Chisnall __i_node** beg = (__i_node**)malloc(nc * sizeof(__i_node*)); 4127a984708SDavid Chisnall if (beg == nullptr) 413936e9439SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS 4147a984708SDavid Chisnall throw bad_alloc(); 415936e9439SDimitry Andric #else 416936e9439SDimitry Andric abort(); 417936e9439SDimitry Andric #endif 4187a984708SDavid Chisnall if (nc > 1) 4197a984708SDavid Chisnall memcpy(beg, beg_, nc/2*sizeof(__i_node*)); 4207a984708SDavid Chisnall free(beg_); 4217a984708SDavid Chisnall beg_ = beg; 4227a984708SDavid Chisnall end_ = beg_ + nc/2; 4237a984708SDavid Chisnall cap_ = beg_ + nc; 4247a984708SDavid Chisnall } 4257a984708SDavid Chisnall *end_++ = i; 4267a984708SDavid Chisnall } 4277a984708SDavid Chisnall 4287a984708SDavid Chisnall // private api 4297a984708SDavid Chisnall 4307a984708SDavid Chisnall _LIBCPP_HIDDEN 4317a984708SDavid Chisnall __i_node* 4327a984708SDavid Chisnall __libcpp_db::__insert_iterator(void* __i) 4337a984708SDavid Chisnall { 43494e3ee44SDavid Chisnall if (__isz_ + 1 > static_cast<size_t>(__iend_ - __ibeg_)) 4357a984708SDavid Chisnall { 43694e3ee44SDavid Chisnall size_t nc = __next_prime(2*static_cast<size_t>(__iend_ - __ibeg_) + 1); 4377a984708SDavid Chisnall __i_node** ibeg = (__i_node**)calloc(nc, sizeof(void*)); 4387a984708SDavid Chisnall if (ibeg == nullptr) 439936e9439SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS 4407a984708SDavid Chisnall throw bad_alloc(); 441936e9439SDimitry Andric #else 442936e9439SDimitry Andric abort(); 443936e9439SDimitry Andric #endif 4447a984708SDavid Chisnall for (__i_node** p = __ibeg_; p != __iend_; ++p) 4457a984708SDavid Chisnall { 4467a984708SDavid Chisnall __i_node* q = *p; 4477a984708SDavid Chisnall while (q != nullptr) 4487a984708SDavid Chisnall { 4497a984708SDavid Chisnall size_t h = hash<void*>()(q->__i_) % nc; 4507a984708SDavid Chisnall __i_node* r = q->__next_; 4517a984708SDavid Chisnall q->__next_ = ibeg[h]; 4527a984708SDavid Chisnall ibeg[h] = q; 4537a984708SDavid Chisnall q = r; 4547a984708SDavid Chisnall } 4557a984708SDavid Chisnall } 4567a984708SDavid Chisnall free(__ibeg_); 4577a984708SDavid Chisnall __ibeg_ = ibeg; 4587a984708SDavid Chisnall __iend_ = __ibeg_ + nc; 4597a984708SDavid Chisnall } 46094e3ee44SDavid Chisnall size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_); 4617a984708SDavid Chisnall __i_node* p = __ibeg_[hi]; 4627a984708SDavid Chisnall __i_node* r = __ibeg_[hi] = (__i_node*)malloc(sizeof(__i_node)); 4637a984708SDavid Chisnall if (r == nullptr) 464936e9439SDimitry Andric #ifndef _LIBCPP_NO_EXCEPTIONS 4657a984708SDavid Chisnall throw bad_alloc(); 466936e9439SDimitry Andric #else 467936e9439SDimitry Andric abort(); 468936e9439SDimitry Andric #endif 4697a984708SDavid Chisnall ::new(r) __i_node(__i, p, nullptr); 4707a984708SDavid Chisnall ++__isz_; 4717a984708SDavid Chisnall return r; 4727a984708SDavid Chisnall } 4737a984708SDavid Chisnall 4747a984708SDavid Chisnall _LIBCPP_HIDDEN 4757a984708SDavid Chisnall __i_node* 4767a984708SDavid Chisnall __libcpp_db::__find_iterator(const void* __i) const 4777a984708SDavid Chisnall { 4787a984708SDavid Chisnall __i_node* r = nullptr; 4797a984708SDavid Chisnall if (__ibeg_ != __iend_) 4807a984708SDavid Chisnall { 48194e3ee44SDavid Chisnall size_t h = hash<const void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_); 4827a984708SDavid Chisnall for (__i_node* nd = __ibeg_[h]; nd != nullptr; nd = nd->__next_) 4837a984708SDavid Chisnall { 4847a984708SDavid Chisnall if (nd->__i_ == __i) 4857a984708SDavid Chisnall { 4867a984708SDavid Chisnall r = nd; 4877a984708SDavid Chisnall break; 4887a984708SDavid Chisnall } 4897a984708SDavid Chisnall } 4907a984708SDavid Chisnall } 4917a984708SDavid Chisnall return r; 4927a984708SDavid Chisnall } 4937a984708SDavid Chisnall 4947a984708SDavid Chisnall _LIBCPP_HIDDEN 4957a984708SDavid Chisnall void 4967a984708SDavid Chisnall __c_node::__remove(__i_node* p) 4977a984708SDavid Chisnall { 4987a984708SDavid Chisnall __i_node** r = find(beg_, end_, p); 4997a984708SDavid Chisnall _LIBCPP_ASSERT(r != end_, "debug mode internal logic error __c_node::__remove"); 5007a984708SDavid Chisnall if (--end_ != r) 50194e3ee44SDavid Chisnall memmove(r, r+1, static_cast<size_t>(end_ - r)*sizeof(__i_node*)); 5027a984708SDavid Chisnall } 5037a984708SDavid Chisnall 5047a984708SDavid Chisnall _LIBCPP_END_NAMESPACE_STD 505