1f554add5SHoward Hinnant //===-------------------------- debug.cpp ---------------------------------===// 2f554add5SHoward Hinnant // 3f554add5SHoward Hinnant // The LLVM Compiler Infrastructure 4f554add5SHoward Hinnant // 5f554add5SHoward Hinnant // This file is dual licensed under the MIT and the University of Illinois Open 6f554add5SHoward Hinnant // Source Licenses. See LICENSE.TXT for details. 7f554add5SHoward Hinnant // 8f554add5SHoward Hinnant //===----------------------------------------------------------------------===// 9f554add5SHoward Hinnant 10cec9af9eSHoward Hinnant #define _LIBCPP_DEBUG2 1 11cec9af9eSHoward Hinnant #include "__config" 12f554add5SHoward Hinnant #include "__debug" 13f554add5SHoward Hinnant #include "functional" 14f554add5SHoward Hinnant #include "algorithm" 15f554add5SHoward Hinnant #include "__hash_table" 16f554add5SHoward Hinnant #include "mutex" 17f554add5SHoward Hinnant 18f554add5SHoward Hinnant _LIBCPP_BEGIN_NAMESPACE_STD 19f554add5SHoward Hinnant 206e41256fSHoward Hinnant _LIBCPP_FUNC_VIS 21f554add5SHoward Hinnant __libcpp_db* 22f554add5SHoward Hinnant __get_db() 23f554add5SHoward Hinnant { 24f554add5SHoward Hinnant static __libcpp_db db; 25f554add5SHoward Hinnant return &db; 26267e3e1eSHoward Hinnant } 27f554add5SHoward Hinnant 286e41256fSHoward Hinnant _LIBCPP_FUNC_VIS 29f554add5SHoward Hinnant const __libcpp_db* 30f554add5SHoward Hinnant __get_const_db() 31f554add5SHoward Hinnant { 32f554add5SHoward Hinnant return __get_db(); 33f554add5SHoward Hinnant } 34f554add5SHoward Hinnant 35f554add5SHoward Hinnant namespace 36f554add5SHoward Hinnant { 37f554add5SHoward Hinnant 38f554add5SHoward Hinnant typedef mutex mutex_type; 39f554add5SHoward Hinnant typedef lock_guard<mutex_type> WLock; 40f554add5SHoward Hinnant typedef lock_guard<mutex_type> RLock; 41f554add5SHoward Hinnant 42f554add5SHoward Hinnant mutex_type& 43f554add5SHoward Hinnant mut() 44f554add5SHoward Hinnant { 45f554add5SHoward Hinnant static mutex_type m; 46f554add5SHoward Hinnant return m; 47f554add5SHoward Hinnant } 48f554add5SHoward Hinnant 49f554add5SHoward Hinnant } // unnamed namespace 50f554add5SHoward Hinnant 51f554add5SHoward Hinnant __i_node::~__i_node() 52f554add5SHoward Hinnant { 53f554add5SHoward Hinnant if (__next_) 54f554add5SHoward Hinnant { 55f554add5SHoward Hinnant __next_->~__i_node(); 56f554add5SHoward Hinnant free(__next_); 57f554add5SHoward Hinnant } 58f554add5SHoward Hinnant } 59f554add5SHoward Hinnant 60f554add5SHoward Hinnant __c_node::~__c_node() 61f554add5SHoward Hinnant { 62f554add5SHoward Hinnant free(beg_); 63f554add5SHoward Hinnant if (__next_) 64f554add5SHoward Hinnant { 65f554add5SHoward Hinnant __next_->~__c_node(); 66f554add5SHoward Hinnant free(__next_); 67f554add5SHoward Hinnant } 68f554add5SHoward Hinnant } 69f554add5SHoward Hinnant 70f554add5SHoward Hinnant __libcpp_db::__libcpp_db() 71f554add5SHoward Hinnant : __cbeg_(nullptr), 72f554add5SHoward Hinnant __cend_(nullptr), 73f554add5SHoward Hinnant __csz_(0), 74f554add5SHoward Hinnant __ibeg_(nullptr), 75f554add5SHoward Hinnant __iend_(nullptr), 76f554add5SHoward Hinnant __isz_(0) 77f554add5SHoward Hinnant { 78f554add5SHoward Hinnant } 79f554add5SHoward Hinnant 80f554add5SHoward Hinnant __libcpp_db::~__libcpp_db() 81f554add5SHoward Hinnant { 82f554add5SHoward Hinnant if (__cbeg_) 83f554add5SHoward Hinnant { 84f554add5SHoward Hinnant for (__c_node** p = __cbeg_; p != __cend_; ++p) 85f554add5SHoward Hinnant { 86f554add5SHoward Hinnant if (*p != nullptr) 87f554add5SHoward Hinnant { 88f554add5SHoward Hinnant (*p)->~__c_node(); 89f554add5SHoward Hinnant free(*p); 90f554add5SHoward Hinnant } 91f554add5SHoward Hinnant } 92f554add5SHoward Hinnant free(__cbeg_); 93f554add5SHoward Hinnant } 94f554add5SHoward Hinnant if (__ibeg_) 95f554add5SHoward Hinnant { 96f554add5SHoward Hinnant for (__i_node** p = __ibeg_; p != __iend_; ++p) 97f554add5SHoward Hinnant { 98f554add5SHoward Hinnant if (*p != nullptr) 99f554add5SHoward Hinnant { 100f554add5SHoward Hinnant (*p)->~__i_node(); 101f554add5SHoward Hinnant free(*p); 102f554add5SHoward Hinnant } 103f554add5SHoward Hinnant } 104f554add5SHoward Hinnant free(__ibeg_); 105f554add5SHoward Hinnant } 106f554add5SHoward Hinnant } 107f554add5SHoward Hinnant 108f554add5SHoward Hinnant void* 109f554add5SHoward Hinnant __libcpp_db::__find_c_from_i(void* __i) const 110f554add5SHoward Hinnant { 111f554add5SHoward Hinnant RLock _(mut()); 112f554add5SHoward Hinnant __i_node* i = __find_iterator(__i); 113f7509231SHoward Hinnant _LIBCPP_ASSERT(i != nullptr, "iterator not found in debug database."); 114c36bfc49SHoward Hinnant return i->__c_ != nullptr ? i->__c_->__c_ : nullptr; 115f554add5SHoward Hinnant } 116f554add5SHoward Hinnant 117f554add5SHoward Hinnant void 118f554add5SHoward Hinnant __libcpp_db::__insert_ic(void* __i, const void* __c) 119f554add5SHoward Hinnant { 120f554add5SHoward Hinnant WLock _(mut()); 121*fc88dbd2SHoward Hinnant if (__cbeg_ == __cend_) 122*fc88dbd2SHoward Hinnant return; 123c206366fSHoward Hinnant size_t hc = hash<const void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); 124f554add5SHoward Hinnant __c_node* c = __cbeg_[hc]; 125*fc88dbd2SHoward Hinnant if (c == nullptr) 126*fc88dbd2SHoward Hinnant return; 127f554add5SHoward Hinnant while (c->__c_ != __c) 128f554add5SHoward Hinnant { 129f554add5SHoward Hinnant c = c->__next_; 130*fc88dbd2SHoward Hinnant if (c == nullptr) 131*fc88dbd2SHoward Hinnant return; 132f554add5SHoward Hinnant } 133*fc88dbd2SHoward Hinnant __i_node* i = __insert_iterator(__i); 134f554add5SHoward Hinnant c->__add(i); 135f554add5SHoward Hinnant i->__c_ = c; 136f554add5SHoward Hinnant } 137f554add5SHoward Hinnant 138f554add5SHoward Hinnant __c_node* 139f554add5SHoward Hinnant __libcpp_db::__insert_c(void* __c) 140f554add5SHoward Hinnant { 141f554add5SHoward Hinnant WLock _(mut()); 142c206366fSHoward Hinnant if (__csz_ + 1 > static_cast<size_t>(__cend_ - __cbeg_)) 143f554add5SHoward Hinnant { 144c206366fSHoward Hinnant size_t nc = __next_prime(2*static_cast<size_t>(__cend_ - __cbeg_) + 1); 14585ad6c99SJoerg Sonnenberger __c_node** cbeg = static_cast<__c_node**>(calloc(nc, sizeof(void*))); 146f554add5SHoward Hinnant if (cbeg == nullptr) 1477b838f53SHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS 148f554add5SHoward Hinnant throw bad_alloc(); 1497b838f53SHoward Hinnant #else 1507b838f53SHoward Hinnant abort(); 1517b838f53SHoward Hinnant #endif 152f554add5SHoward Hinnant for (__c_node** p = __cbeg_; p != __cend_; ++p) 153f554add5SHoward Hinnant { 154f554add5SHoward Hinnant __c_node* q = *p; 155f554add5SHoward Hinnant while (q != nullptr) 156f554add5SHoward Hinnant { 157f554add5SHoward Hinnant size_t h = hash<void*>()(q->__c_) % nc; 158f554add5SHoward Hinnant __c_node* r = q->__next_; 159f554add5SHoward Hinnant q->__next_ = cbeg[h]; 160f554add5SHoward Hinnant cbeg[h] = q; 161f554add5SHoward Hinnant q = r; 162f554add5SHoward Hinnant } 163f554add5SHoward Hinnant } 164f554add5SHoward Hinnant free(__cbeg_); 165f554add5SHoward Hinnant __cbeg_ = cbeg; 166f554add5SHoward Hinnant __cend_ = __cbeg_ + nc; 167f554add5SHoward Hinnant } 168c206366fSHoward Hinnant size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); 169f554add5SHoward Hinnant __c_node* p = __cbeg_[hc]; 17085ad6c99SJoerg Sonnenberger __c_node* r = __cbeg_[hc] = 17185ad6c99SJoerg Sonnenberger static_cast<__c_node*>(malloc(sizeof(__c_node))); 172f554add5SHoward Hinnant if (__cbeg_[hc] == nullptr) 1737b838f53SHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS 174f554add5SHoward Hinnant throw bad_alloc(); 1757b838f53SHoward Hinnant #else 1767b838f53SHoward Hinnant abort(); 1777b838f53SHoward Hinnant #endif 178f554add5SHoward Hinnant r->__c_ = __c; 179f554add5SHoward Hinnant r->__next_ = p; 180f554add5SHoward Hinnant ++__csz_; 181f554add5SHoward Hinnant return r; 182f554add5SHoward Hinnant } 183f554add5SHoward Hinnant 184f554add5SHoward Hinnant void 185f554add5SHoward Hinnant __libcpp_db::__erase_i(void* __i) 186f554add5SHoward Hinnant { 187f554add5SHoward Hinnant WLock _(mut()); 188f554add5SHoward Hinnant if (__ibeg_ != __iend_) 189f554add5SHoward Hinnant { 190c206366fSHoward Hinnant size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_); 191f554add5SHoward Hinnant __i_node* p = __ibeg_[hi]; 192f554add5SHoward Hinnant if (p != nullptr) 193f554add5SHoward Hinnant { 194f554add5SHoward Hinnant __i_node* q = nullptr; 195f554add5SHoward Hinnant while (p->__i_ != __i) 196f554add5SHoward Hinnant { 197f554add5SHoward Hinnant q = p; 198f554add5SHoward Hinnant p = p->__next_; 199f554add5SHoward Hinnant if (p == nullptr) 200f554add5SHoward Hinnant return; 201f554add5SHoward Hinnant } 202f554add5SHoward Hinnant if (q == nullptr) 203f554add5SHoward Hinnant __ibeg_[hi] = p->__next_; 204f554add5SHoward Hinnant else 205f554add5SHoward Hinnant q->__next_ = p->__next_; 206f554add5SHoward Hinnant __c_node* c = p->__c_; 207f554add5SHoward Hinnant free(p); 208f554add5SHoward Hinnant --__isz_; 209f554add5SHoward Hinnant if (c != nullptr) 210f554add5SHoward Hinnant c->__remove(p); 211f554add5SHoward Hinnant } 212f554add5SHoward Hinnant } 213f554add5SHoward Hinnant } 214f554add5SHoward Hinnant 215f554add5SHoward Hinnant void 216f554add5SHoward Hinnant __libcpp_db::__invalidate_all(void* __c) 217f554add5SHoward Hinnant { 218f554add5SHoward Hinnant WLock _(mut()); 219*fc88dbd2SHoward Hinnant if (__cend_ != __cbeg_) 220*fc88dbd2SHoward Hinnant { 221c206366fSHoward Hinnant size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); 222f554add5SHoward Hinnant __c_node* p = __cbeg_[hc]; 223*fc88dbd2SHoward Hinnant if (p == nullptr) 224*fc88dbd2SHoward Hinnant return; 225f554add5SHoward Hinnant while (p->__c_ != __c) 226f554add5SHoward Hinnant { 227f554add5SHoward Hinnant p = p->__next_; 228*fc88dbd2SHoward Hinnant if (p == nullptr) 229*fc88dbd2SHoward Hinnant return; 230f554add5SHoward Hinnant } 231f554add5SHoward Hinnant while (p->end_ != p->beg_) 232f554add5SHoward Hinnant { 233f554add5SHoward Hinnant --p->end_; 234f554add5SHoward Hinnant (*p->end_)->__c_ = nullptr; 235f554add5SHoward Hinnant } 236f554add5SHoward Hinnant } 237*fc88dbd2SHoward Hinnant } 238f554add5SHoward Hinnant 239f554add5SHoward Hinnant __c_node* 240f554add5SHoward Hinnant __libcpp_db::__find_c_and_lock(void* __c) const 241f554add5SHoward Hinnant { 242f554add5SHoward Hinnant mut().lock(); 243*fc88dbd2SHoward Hinnant if (__cend_ == __cbeg_) 244*fc88dbd2SHoward Hinnant { 245*fc88dbd2SHoward Hinnant mut().unlock(); 246*fc88dbd2SHoward Hinnant return nullptr; 247*fc88dbd2SHoward Hinnant } 248c206366fSHoward Hinnant size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); 249f554add5SHoward Hinnant __c_node* p = __cbeg_[hc]; 250*fc88dbd2SHoward Hinnant if (p == nullptr) 251*fc88dbd2SHoward Hinnant { 252*fc88dbd2SHoward Hinnant mut().unlock(); 253*fc88dbd2SHoward Hinnant return nullptr; 254*fc88dbd2SHoward Hinnant } 255f554add5SHoward Hinnant while (p->__c_ != __c) 256f554add5SHoward Hinnant { 257f554add5SHoward Hinnant p = p->__next_; 258*fc88dbd2SHoward Hinnant if (p == nullptr) 259*fc88dbd2SHoward Hinnant { 260*fc88dbd2SHoward Hinnant mut().unlock(); 261*fc88dbd2SHoward Hinnant return nullptr; 262*fc88dbd2SHoward Hinnant } 263f554add5SHoward Hinnant } 264f554add5SHoward Hinnant return p; 265f554add5SHoward Hinnant } 266f554add5SHoward Hinnant 267920b56caSHoward Hinnant __c_node* 268920b56caSHoward Hinnant __libcpp_db::__find_c(void* __c) const 269920b56caSHoward Hinnant { 270c206366fSHoward Hinnant size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); 271920b56caSHoward Hinnant __c_node* p = __cbeg_[hc]; 272920b56caSHoward Hinnant _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c A"); 273920b56caSHoward Hinnant while (p->__c_ != __c) 274920b56caSHoward Hinnant { 275920b56caSHoward Hinnant p = p->__next_; 276920b56caSHoward Hinnant _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c B"); 277920b56caSHoward Hinnant } 278920b56caSHoward Hinnant return p; 279920b56caSHoward Hinnant } 280920b56caSHoward Hinnant 281f554add5SHoward Hinnant void 282f554add5SHoward Hinnant __libcpp_db::unlock() const 283f554add5SHoward Hinnant { 284f554add5SHoward Hinnant mut().unlock(); 285f554add5SHoward Hinnant } 286f554add5SHoward Hinnant 287f554add5SHoward Hinnant void 288f554add5SHoward Hinnant __libcpp_db::__erase_c(void* __c) 289f554add5SHoward Hinnant { 290f554add5SHoward Hinnant WLock _(mut()); 291*fc88dbd2SHoward Hinnant if (__cend_ != __cbeg_) 292*fc88dbd2SHoward Hinnant { 293c206366fSHoward Hinnant size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_); 294f554add5SHoward Hinnant __c_node* p = __cbeg_[hc]; 295*fc88dbd2SHoward Hinnant if (p == nullptr) 296*fc88dbd2SHoward Hinnant return; 297f554add5SHoward Hinnant __c_node* q = nullptr; 298f554add5SHoward Hinnant _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c A"); 299f554add5SHoward Hinnant while (p->__c_ != __c) 300f554add5SHoward Hinnant { 301f554add5SHoward Hinnant q = p; 302f554add5SHoward Hinnant p = p->__next_; 303*fc88dbd2SHoward Hinnant if (p == nullptr) 304*fc88dbd2SHoward Hinnant return; 305f554add5SHoward Hinnant _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c B"); 306f554add5SHoward Hinnant } 307f554add5SHoward Hinnant if (q == nullptr) 308f554add5SHoward Hinnant __cbeg_[hc] = p->__next_; 309f554add5SHoward Hinnant else 310f554add5SHoward Hinnant q->__next_ = p->__next_; 311f554add5SHoward Hinnant while (p->end_ != p->beg_) 312f554add5SHoward Hinnant { 313f554add5SHoward Hinnant --p->end_; 314f554add5SHoward Hinnant (*p->end_)->__c_ = nullptr; 315f554add5SHoward Hinnant } 316f554add5SHoward Hinnant free(p->beg_); 317f554add5SHoward Hinnant free(p); 318f554add5SHoward Hinnant --__csz_; 319f554add5SHoward Hinnant } 320*fc88dbd2SHoward Hinnant } 321f554add5SHoward Hinnant 322f554add5SHoward Hinnant void 323f554add5SHoward Hinnant __libcpp_db::__iterator_copy(void* __i, const void* __i0) 324f554add5SHoward Hinnant { 325f554add5SHoward Hinnant WLock _(mut()); 326f554add5SHoward Hinnant __i_node* i = __find_iterator(__i); 327f554add5SHoward Hinnant __i_node* i0 = __find_iterator(__i0); 328f554add5SHoward Hinnant __c_node* c0 = i0 != nullptr ? i0->__c_ : nullptr; 329f7509231SHoward Hinnant if (i == nullptr && i0 != nullptr) 330f554add5SHoward Hinnant i = __insert_iterator(__i); 331f554add5SHoward Hinnant __c_node* c = i != nullptr ? i->__c_ : nullptr; 332f554add5SHoward Hinnant if (c != c0) 333f554add5SHoward Hinnant { 334f554add5SHoward Hinnant if (c != nullptr) 335f554add5SHoward Hinnant c->__remove(i); 336f554add5SHoward Hinnant if (i != nullptr) 337f554add5SHoward Hinnant { 338f554add5SHoward Hinnant i->__c_ = nullptr; 339f554add5SHoward Hinnant if (c0 != nullptr) 340f554add5SHoward Hinnant { 341f554add5SHoward Hinnant i->__c_ = c0; 342f554add5SHoward Hinnant i->__c_->__add(i); 343f554add5SHoward Hinnant } 344f554add5SHoward Hinnant } 345f554add5SHoward Hinnant } 346f554add5SHoward Hinnant } 347f554add5SHoward Hinnant 348f554add5SHoward Hinnant bool 349f554add5SHoward Hinnant __libcpp_db::__dereferenceable(const void* __i) const 350f554add5SHoward Hinnant { 351f554add5SHoward Hinnant RLock _(mut()); 352f554add5SHoward Hinnant __i_node* i = __find_iterator(__i); 353f554add5SHoward Hinnant return i != nullptr && i->__c_ != nullptr && i->__c_->__dereferenceable(__i); 354f554add5SHoward Hinnant } 355f554add5SHoward Hinnant 356f554add5SHoward Hinnant bool 357f554add5SHoward Hinnant __libcpp_db::__decrementable(const void* __i) const 358f554add5SHoward Hinnant { 359f554add5SHoward Hinnant RLock _(mut()); 360f554add5SHoward Hinnant __i_node* i = __find_iterator(__i); 361f554add5SHoward Hinnant return i != nullptr && i->__c_ != nullptr && i->__c_->__decrementable(__i); 362f554add5SHoward Hinnant } 363f554add5SHoward Hinnant 364f554add5SHoward Hinnant bool 365f554add5SHoward Hinnant __libcpp_db::__addable(const void* __i, ptrdiff_t __n) const 366f554add5SHoward Hinnant { 367f554add5SHoward Hinnant RLock _(mut()); 368f554add5SHoward Hinnant __i_node* i = __find_iterator(__i); 369f554add5SHoward Hinnant return i != nullptr && i->__c_ != nullptr && i->__c_->__addable(__i, __n); 370f554add5SHoward Hinnant } 371f554add5SHoward Hinnant 372f554add5SHoward Hinnant bool 373f554add5SHoward Hinnant __libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const 374f554add5SHoward Hinnant { 375f554add5SHoward Hinnant RLock _(mut()); 376f554add5SHoward Hinnant __i_node* i = __find_iterator(__i); 377f554add5SHoward Hinnant return i != nullptr && i->__c_ != nullptr && i->__c_->__subscriptable(__i, __n); 378f554add5SHoward Hinnant } 379f554add5SHoward Hinnant 380f554add5SHoward Hinnant bool 38142a3046eSHoward Hinnant __libcpp_db::__less_than_comparable(const void* __i, const void* __j) const 382f554add5SHoward Hinnant { 383f554add5SHoward Hinnant RLock _(mut()); 384f554add5SHoward Hinnant __i_node* i = __find_iterator(__i); 385f554add5SHoward Hinnant __i_node* j = __find_iterator(__j); 386f554add5SHoward Hinnant __c_node* ci = i != nullptr ? i->__c_ : nullptr; 387f554add5SHoward Hinnant __c_node* cj = j != nullptr ? j->__c_ : nullptr; 388f554add5SHoward Hinnant return ci != nullptr && ci == cj; 389f554add5SHoward Hinnant } 390f554add5SHoward Hinnant 391f554add5SHoward Hinnant void 392f554add5SHoward Hinnant __libcpp_db::swap(void* c1, void* c2) 393f554add5SHoward Hinnant { 394f554add5SHoward Hinnant WLock _(mut()); 395c206366fSHoward Hinnant size_t hc = hash<void*>()(c1) % static_cast<size_t>(__cend_ - __cbeg_); 396f554add5SHoward Hinnant __c_node* p1 = __cbeg_[hc]; 397f554add5SHoward Hinnant _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap A"); 398f554add5SHoward Hinnant while (p1->__c_ != c1) 399f554add5SHoward Hinnant { 400f554add5SHoward Hinnant p1 = p1->__next_; 401f554add5SHoward Hinnant _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap B"); 402f554add5SHoward Hinnant } 403c206366fSHoward Hinnant hc = hash<void*>()(c2) % static_cast<size_t>(__cend_ - __cbeg_); 404f554add5SHoward Hinnant __c_node* p2 = __cbeg_[hc]; 405f554add5SHoward Hinnant _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap C"); 406f554add5SHoward Hinnant while (p2->__c_ != c2) 407f554add5SHoward Hinnant { 408f554add5SHoward Hinnant p2 = p2->__next_; 409f554add5SHoward Hinnant _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap D"); 410f554add5SHoward Hinnant } 411f554add5SHoward Hinnant std::swap(p1->beg_, p2->beg_); 412f554add5SHoward Hinnant std::swap(p1->end_, p2->end_); 413f554add5SHoward Hinnant std::swap(p1->cap_, p2->cap_); 414f554add5SHoward Hinnant for (__i_node** p = p1->beg_; p != p1->end_; ++p) 415f554add5SHoward Hinnant (*p)->__c_ = p1; 416f554add5SHoward Hinnant for (__i_node** p = p2->beg_; p != p2->end_; ++p) 417f554add5SHoward Hinnant (*p)->__c_ = p2; 418f554add5SHoward Hinnant } 419f554add5SHoward Hinnant 420c36bfc49SHoward Hinnant void 421c36bfc49SHoward Hinnant __libcpp_db::__insert_i(void* __i) 422c36bfc49SHoward Hinnant { 423c36bfc49SHoward Hinnant WLock _(mut()); 424c36bfc49SHoward Hinnant __insert_iterator(__i); 425c36bfc49SHoward Hinnant } 426c36bfc49SHoward Hinnant 427920b56caSHoward Hinnant void 428920b56caSHoward Hinnant __c_node::__add(__i_node* i) 429920b56caSHoward Hinnant { 430920b56caSHoward Hinnant if (end_ == cap_) 431920b56caSHoward Hinnant { 432c206366fSHoward Hinnant size_t nc = 2*static_cast<size_t>(cap_ - beg_); 433920b56caSHoward Hinnant if (nc == 0) 434920b56caSHoward Hinnant nc = 1; 43585ad6c99SJoerg Sonnenberger __i_node** beg = 43685ad6c99SJoerg Sonnenberger static_cast<__i_node**>(malloc(nc * sizeof(__i_node*))); 437920b56caSHoward Hinnant if (beg == nullptr) 4387b838f53SHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS 439920b56caSHoward Hinnant throw bad_alloc(); 4407b838f53SHoward Hinnant #else 4417b838f53SHoward Hinnant abort(); 4427b838f53SHoward Hinnant #endif 443920b56caSHoward Hinnant if (nc > 1) 444920b56caSHoward Hinnant memcpy(beg, beg_, nc/2*sizeof(__i_node*)); 445920b56caSHoward Hinnant free(beg_); 446920b56caSHoward Hinnant beg_ = beg; 447920b56caSHoward Hinnant end_ = beg_ + nc/2; 448920b56caSHoward Hinnant cap_ = beg_ + nc; 449920b56caSHoward Hinnant } 450920b56caSHoward Hinnant *end_++ = i; 451920b56caSHoward Hinnant } 452920b56caSHoward Hinnant 453f554add5SHoward Hinnant // private api 454f554add5SHoward Hinnant 455f554add5SHoward Hinnant _LIBCPP_HIDDEN 456f554add5SHoward Hinnant __i_node* 457f554add5SHoward Hinnant __libcpp_db::__insert_iterator(void* __i) 458f554add5SHoward Hinnant { 459c206366fSHoward Hinnant if (__isz_ + 1 > static_cast<size_t>(__iend_ - __ibeg_)) 460f554add5SHoward Hinnant { 461c206366fSHoward Hinnant size_t nc = __next_prime(2*static_cast<size_t>(__iend_ - __ibeg_) + 1); 46285ad6c99SJoerg Sonnenberger __i_node** ibeg = static_cast<__i_node**>(calloc(nc, sizeof(void*))); 463f554add5SHoward Hinnant if (ibeg == nullptr) 4647b838f53SHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS 465f554add5SHoward Hinnant throw bad_alloc(); 4667b838f53SHoward Hinnant #else 4677b838f53SHoward Hinnant abort(); 4687b838f53SHoward Hinnant #endif 469f554add5SHoward Hinnant for (__i_node** p = __ibeg_; p != __iend_; ++p) 470f554add5SHoward Hinnant { 471f554add5SHoward Hinnant __i_node* q = *p; 472f554add5SHoward Hinnant while (q != nullptr) 473f554add5SHoward Hinnant { 474f554add5SHoward Hinnant size_t h = hash<void*>()(q->__i_) % nc; 475f554add5SHoward Hinnant __i_node* r = q->__next_; 476f554add5SHoward Hinnant q->__next_ = ibeg[h]; 477f554add5SHoward Hinnant ibeg[h] = q; 478f554add5SHoward Hinnant q = r; 479f554add5SHoward Hinnant } 480f554add5SHoward Hinnant } 481f554add5SHoward Hinnant free(__ibeg_); 482f554add5SHoward Hinnant __ibeg_ = ibeg; 483f554add5SHoward Hinnant __iend_ = __ibeg_ + nc; 484f554add5SHoward Hinnant } 485c206366fSHoward Hinnant size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_); 486f554add5SHoward Hinnant __i_node* p = __ibeg_[hi]; 48785ad6c99SJoerg Sonnenberger __i_node* r = __ibeg_[hi] = 48885ad6c99SJoerg Sonnenberger static_cast<__i_node*>(malloc(sizeof(__i_node))); 489f554add5SHoward Hinnant if (r == nullptr) 4907b838f53SHoward Hinnant #ifndef _LIBCPP_NO_EXCEPTIONS 491f554add5SHoward Hinnant throw bad_alloc(); 4927b838f53SHoward Hinnant #else 4937b838f53SHoward Hinnant abort(); 4947b838f53SHoward Hinnant #endif 495f554add5SHoward Hinnant ::new(r) __i_node(__i, p, nullptr); 496f554add5SHoward Hinnant ++__isz_; 497f554add5SHoward Hinnant return r; 498f554add5SHoward Hinnant } 499f554add5SHoward Hinnant 500f554add5SHoward Hinnant _LIBCPP_HIDDEN 501f554add5SHoward Hinnant __i_node* 502f554add5SHoward Hinnant __libcpp_db::__find_iterator(const void* __i) const 503f554add5SHoward Hinnant { 504f554add5SHoward Hinnant __i_node* r = nullptr; 505f554add5SHoward Hinnant if (__ibeg_ != __iend_) 506f554add5SHoward Hinnant { 507c206366fSHoward Hinnant size_t h = hash<const void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_); 508f554add5SHoward Hinnant for (__i_node* nd = __ibeg_[h]; nd != nullptr; nd = nd->__next_) 509f554add5SHoward Hinnant { 510f554add5SHoward Hinnant if (nd->__i_ == __i) 511f554add5SHoward Hinnant { 512f554add5SHoward Hinnant r = nd; 513f554add5SHoward Hinnant break; 514f554add5SHoward Hinnant } 515f554add5SHoward Hinnant } 516f554add5SHoward Hinnant } 517f554add5SHoward Hinnant return r; 518f554add5SHoward Hinnant } 519f554add5SHoward Hinnant 520f554add5SHoward Hinnant _LIBCPP_HIDDEN 521f554add5SHoward Hinnant void 522f554add5SHoward Hinnant __c_node::__remove(__i_node* p) 523f554add5SHoward Hinnant { 524f554add5SHoward Hinnant __i_node** r = find(beg_, end_, p); 525f554add5SHoward Hinnant _LIBCPP_ASSERT(r != end_, "debug mode internal logic error __c_node::__remove"); 526f554add5SHoward Hinnant if (--end_ != r) 527c206366fSHoward Hinnant memmove(r, r+1, static_cast<size_t>(end_ - r)*sizeof(__i_node*)); 528f554add5SHoward Hinnant } 529f554add5SHoward Hinnant 530f554add5SHoward Hinnant _LIBCPP_END_NAMESPACE_STD 531