1 //===-------------------------- debug.cpp ---------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #define _LIBCPP_DEBUG2 1
15 #include "__hash_table"
18 _LIBCPP_BEGIN_NAMESPACE_STD
24 static __libcpp_db db;
38 typedef mutex mutex_type;
39 typedef lock_guard<mutex_type> WLock;
40 typedef lock_guard<mutex_type> RLock;
49 } // unnamed namespace
70 __libcpp_db::__libcpp_db()
80 __libcpp_db::~__libcpp_db()
84 for (__c_node** p = __cbeg_; p != __cend_; ++p)
96 for (__i_node** p = __ibeg_; p != __iend_; ++p)
109 __libcpp_db::__find_c_from_i(void* __i) const
112 __i_node* i = __find_iterator(__i);
113 _LIBCPP_ASSERT(i != nullptr, "iterator constructed in translation unit with debug mode not enabled."
114 " #define _LIBCPP_DEBUG2 1 for that translation unit.");
115 return i->__c_ != nullptr ? i->__c_->__c_ : nullptr;
119 __libcpp_db::__insert_ic(void* __i, const void* __c)
122 __i_node* i = __insert_iterator(__i);
124 "Container constructed in a translation unit with debug mode disabled."
125 " But it is being used in a translation unit with debug mode enabled."
126 " Enable it in the other translation unit with #define _LIBCPP_DEBUG2 1";
127 _LIBCPP_ASSERT(__cbeg_ != __cend_, errmsg);
128 size_t hc = hash<const void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
129 __c_node* c = __cbeg_[hc];
130 _LIBCPP_ASSERT(c != nullptr, errmsg);
131 while (c->__c_ != __c)
134 _LIBCPP_ASSERT(c != nullptr, errmsg);
141 __libcpp_db::__insert_c(void* __c)
144 if (__csz_ + 1 > static_cast<size_t>(__cend_ - __cbeg_))
146 size_t nc = __next_prime(2*static_cast<size_t>(__cend_ - __cbeg_) + 1);
147 __c_node** cbeg = (__c_node**)calloc(nc, sizeof(void*));
150 for (__c_node** p = __cbeg_; p != __cend_; ++p)
155 size_t h = hash<void*>()(q->__c_) % nc;
156 __c_node* r = q->__next_;
157 q->__next_ = cbeg[h];
164 __cend_ = __cbeg_ + nc;
166 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
167 __c_node* p = __cbeg_[hc];
168 __c_node* r = __cbeg_[hc] = (__c_node*)malloc(sizeof(__c_node));
169 if (__cbeg_[hc] == nullptr)
178 __libcpp_db::__erase_i(void* __i)
181 if (__ibeg_ != __iend_)
183 size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
184 __i_node* p = __ibeg_[hi];
187 __i_node* q = nullptr;
188 while (p->__i_ != __i)
196 __ibeg_[hi] = p->__next_;
198 q->__next_ = p->__next_;
199 __c_node* c = p->__c_;
209 __libcpp_db::__invalidate_all(void* __c)
212 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
213 __c_node* p = __cbeg_[hc];
214 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __invalidate_all A");
215 while (p->__c_ != __c)
218 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __invalidate_all B");
220 while (p->end_ != p->beg_)
223 (*p->end_)->__c_ = nullptr;
228 __libcpp_db::__find_c_and_lock(void* __c) const
231 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
232 __c_node* p = __cbeg_[hc];
233 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c_and_lock A");
234 while (p->__c_ != __c)
237 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c_and_lock B");
243 __libcpp_db::__find_c(void* __c) const
245 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
246 __c_node* p = __cbeg_[hc];
247 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c A");
248 while (p->__c_ != __c)
251 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c B");
257 __libcpp_db::unlock() const
263 __libcpp_db::__erase_c(void* __c)
266 size_t hc = hash<void*>()(__c) % static_cast<size_t>(__cend_ - __cbeg_);
267 __c_node* p = __cbeg_[hc];
268 __c_node* q = nullptr;
269 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c A");
270 while (p->__c_ != __c)
274 _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c B");
277 __cbeg_[hc] = p->__next_;
279 q->__next_ = p->__next_;
280 while (p->end_ != p->beg_)
283 (*p->end_)->__c_ = nullptr;
291 __libcpp_db::__iterator_copy(void* __i, const void* __i0)
294 __i_node* i = __find_iterator(__i);
295 __i_node* i0 = __find_iterator(__i0);
296 __c_node* c0 = i0 != nullptr ? i0->__c_ : nullptr;
297 if (i == nullptr && c0 != nullptr)
298 i = __insert_iterator(__i);
299 __c_node* c = i != nullptr ? i->__c_ : nullptr;
317 __libcpp_db::__dereferenceable(const void* __i) const
320 __i_node* i = __find_iterator(__i);
321 return i != nullptr && i->__c_ != nullptr && i->__c_->__dereferenceable(__i);
325 __libcpp_db::__decrementable(const void* __i) const
328 __i_node* i = __find_iterator(__i);
329 return i != nullptr && i->__c_ != nullptr && i->__c_->__decrementable(__i);
333 __libcpp_db::__addable(const void* __i, ptrdiff_t __n) const
336 __i_node* i = __find_iterator(__i);
337 return i != nullptr && i->__c_ != nullptr && i->__c_->__addable(__i, __n);
341 __libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const
344 __i_node* i = __find_iterator(__i);
345 return i != nullptr && i->__c_ != nullptr && i->__c_->__subscriptable(__i, __n);
349 __libcpp_db::__comparable(const void* __i, const void* __j) const
352 __i_node* i = __find_iterator(__i);
353 __i_node* j = __find_iterator(__j);
354 __c_node* ci = i != nullptr ? i->__c_ : nullptr;
355 __c_node* cj = j != nullptr ? j->__c_ : nullptr;
356 return ci != nullptr && ci == cj;
360 __libcpp_db::swap(void* c1, void* c2)
363 size_t hc = hash<void*>()(c1) % static_cast<size_t>(__cend_ - __cbeg_);
364 __c_node* p1 = __cbeg_[hc];
365 _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap A");
366 while (p1->__c_ != c1)
369 _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap B");
371 hc = hash<void*>()(c2) % static_cast<size_t>(__cend_ - __cbeg_);
372 __c_node* p2 = __cbeg_[hc];
373 _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap C");
374 while (p2->__c_ != c2)
377 _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap D");
379 std::swap(p1->beg_, p2->beg_);
380 std::swap(p1->end_, p2->end_);
381 std::swap(p1->cap_, p2->cap_);
382 for (__i_node** p = p1->beg_; p != p1->end_; ++p)
384 for (__i_node** p = p2->beg_; p != p2->end_; ++p)
389 __libcpp_db::__insert_i(void* __i)
392 __insert_iterator(__i);
396 __c_node::__add(__i_node* i)
400 size_t nc = 2*static_cast<size_t>(cap_ - beg_);
403 __i_node** beg = (__i_node**)malloc(nc * sizeof(__i_node*));
407 memcpy(beg, beg_, nc/2*sizeof(__i_node*));
420 __libcpp_db::__insert_iterator(void* __i)
422 if (__isz_ + 1 > static_cast<size_t>(__iend_ - __ibeg_))
424 size_t nc = __next_prime(2*static_cast<size_t>(__iend_ - __ibeg_) + 1);
425 __i_node** ibeg = (__i_node**)calloc(nc, sizeof(void*));
428 for (__i_node** p = __ibeg_; p != __iend_; ++p)
433 size_t h = hash<void*>()(q->__i_) % nc;
434 __i_node* r = q->__next_;
435 q->__next_ = ibeg[h];
442 __iend_ = __ibeg_ + nc;
444 size_t hi = hash<void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
445 __i_node* p = __ibeg_[hi];
446 __i_node* r = __ibeg_[hi] = (__i_node*)malloc(sizeof(__i_node));
449 ::new(r) __i_node(__i, p, nullptr);
456 __libcpp_db::__find_iterator(const void* __i) const
458 __i_node* r = nullptr;
459 if (__ibeg_ != __iend_)
461 size_t h = hash<const void*>()(__i) % static_cast<size_t>(__iend_ - __ibeg_);
462 for (__i_node* nd = __ibeg_[h]; nd != nullptr; nd = nd->__next_)
476 __c_node::__remove(__i_node* p)
478 __i_node** r = find(beg_, end_, p);
479 _LIBCPP_ASSERT(r != end_, "debug mode internal logic error __c_node::__remove");
481 memmove(r, r+1, static_cast<size_t>(end_ - r)*sizeof(__i_node*));
484 _LIBCPP_END_NAMESPACE_STD