diff --git a/libcxx/include/__config b/libcxx/include/__config index fffcfaaabc67..27516199ec51 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -309,4 +309,10 @@ template struct __static_assert_check {}; #define _LIBCPP_WCTYPE_IS_MASK #endif +#ifdef _LIBCPP_DEBUG2 +# include <__debug> +#else +# define _LIBCPP_ASSERT(x, m) ((void)0) +#endif + #endif // _LIBCPP_CONFIG diff --git a/libcxx/include/__debug b/libcxx/include/__debug new file mode 100644 index 000000000000..e7d027add155 --- /dev/null +++ b/libcxx/include/__debug @@ -0,0 +1,181 @@ +// -*- C++ -*- +//===--------------------------- __debug ----------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_DEBUG_H +#define _LIBCPP_DEBUG_H + +# include +# include +# include +# define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (_VSTD::printf("%s\n", m), _VSTD::abort())) + +_LIBCPP_BEGIN_NAMESPACE_STD + +struct _LIBCPP_VISIBLE __c_node; + +struct _LIBCPP_VISIBLE __i_node +{ + void* __i_; + __i_node* __next_; + __c_node* __c_; + + __i_node(const __i_node&) = delete; + __i_node& operator=(const __i_node&) = delete; + _LIBCPP_INLINE_VISIBILITY + __i_node(void* __i, __i_node* __next, __c_node* __c) + : __i_(__i), __next_(__next), __c_(__c) {} + ~__i_node(); +}; + +struct _LIBCPP_VISIBLE __c_node +{ + void* __c_; + __c_node* __next_; + __i_node** beg_; + __i_node** end_; + __i_node** cap_; + + __c_node(const __c_node&) = delete; + __c_node& operator=(const __c_node&) = delete; + _LIBCPP_INLINE_VISIBILITY + __c_node(void* __c, __c_node* __next) + : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {} + virtual ~__c_node(); + + virtual bool __dereferenceable(const void*) const = 0; + virtual bool __decrementable(const void*) const = 0; + virtual bool __addable(const void*, ptrdiff_t) const = 0; + virtual bool __subscriptable(const void*, ptrdiff_t) const = 0; + + _LIBCPP_HIDDEN void __add(__i_node* __i); + _LIBCPP_HIDDEN void __remove(__i_node* __i); +}; + +template +struct _C_node + : public __c_node +{ + _C_node(void* __c, __c_node* __n) + : __c_node(__c, __n) {} + + virtual bool __dereferenceable(const void*) const; + virtual bool __decrementable(const void*) const; + virtual bool __addable(const void*, ptrdiff_t) const; + virtual bool __subscriptable(const void*, ptrdiff_t) const; +}; + +template +bool +_C_node<_Cont>::__dereferenceable(const void* __i) const +{ + typedef typename _Cont::const_iterator iterator; + const iterator* __j = static_cast(__i); + _Cont* _C = static_cast<_Cont*>(__c_); + return _C->__dereferenceable(__j); +} + +template +bool +_C_node<_Cont>::__decrementable(const void* __i) const +{ + typedef typename _Cont::const_iterator iterator; + const iterator* __j = static_cast(__i); + _Cont* _C = static_cast<_Cont*>(__c_); + return _C->__decrementable(__j); +} + +template +bool +_C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const +{ + typedef typename _Cont::const_iterator iterator; + const iterator* __j = static_cast(__i); + _Cont* _C = static_cast<_Cont*>(__c_); + return _C->__addable(__j, __n); +} + +template +bool +_C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const +{ + typedef typename _Cont::const_iterator iterator; + const iterator* __j = static_cast(__i); + _Cont* _C = static_cast<_Cont*>(__c_); + return _C->__subscriptable(__j, __n); +} + +class _LIBCPP_VISIBLE __libcpp_db +{ + __c_node** __cbeg_; + __c_node** __cend_; + size_t __csz_; + __i_node** __ibeg_; + __i_node** __iend_; + size_t __isz_; + + __libcpp_db(); +public: + __libcpp_db(const __libcpp_db&) = delete; + __libcpp_db& operator=(const __libcpp_db&) = delete; + ~__libcpp_db(); + + class __db_c_iterator; + class __db_c_const_iterator; + class __db_i_iterator; + class __db_i_const_iterator; + + __db_c_const_iterator __c_end() const; + __db_i_const_iterator __i_end() const; + + template + _LIBCPP_INLINE_VISIBILITY + void __insert_c(_Cont* __c) + { + __c_node* __n = __insert_c(static_cast(__c)); + ::new(__n) _C_node<_Cont>(__n->__c_, __n->__next_); + } + + __c_node* __insert_c(void* __c); + void __erase_c(void* __c); + + void __insert_ic(void* __i, const void* __c); + void __iterator_copy(void* __i, const void* __i0); + void __erase_i(void* __i); + + void* __find_c_from_i(void* __i) const; + void __invalidate_all(void* __c); + __c_node* __find_c_and_lock(void* __c) const; + void unlock() const; + + void swap(void* __c1, void* __c2); + + + bool __dereferenceable(const void* __i) const; + bool __decrementable(const void* __i) const; + bool __addable(const void* __i, ptrdiff_t __n) const; + bool __subscriptable(const void* __i, ptrdiff_t __n) const; + bool __comparable(const void* __i, const void* __j) const; +private: + _LIBCPP_HIDDEN + __i_node* __insert_iterator(void* __i); + _LIBCPP_HIDDEN + __i_node* __find_iterator(const void* __i) const; + + friend _LIBCPP_VISIBLE __libcpp_db* __get_db(); +}; + +_LIBCPP_VISIBLE __libcpp_db* __get_db(); +_LIBCPP_VISIBLE const __libcpp_db* __get_const_db(); + + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_DEBUG_H + diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm index da9d0fe3c3b0..d6906a209e85 100644 --- a/libcxx/include/algorithm +++ b/libcxx/include/algorithm @@ -593,9 +593,6 @@ template #include #include #include -#ifdef _LIBCPP_DEBUG -#include -#endif #include #pragma GCC system_header @@ -676,7 +673,7 @@ public: bool operator()(const _T1& __x, const _T2& __y) {return !__p_(__x, __y);} }; -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 template struct __debug_less @@ -688,12 +685,12 @@ struct __debug_less { bool __r = __comp_(__x, __y); if (__r) - assert(!__comp_(__y, __x)); + _LIBCPP_ASSERT(!__comp_(__y, __x), "Comparator does not induce a strict weak ordering"); return __r; } }; -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 // Precondition: __x != 0 inline _LIBCPP_INLINE_VISIBILITY unsigned __ctz(unsigned __x) {return __builtin_ctz (__x);} @@ -3641,14 +3638,14 @@ inline _LIBCPP_INLINE_VISIBILITY void sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); __sort<_Comp_ref>(__first, __last, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; __sort<_Comp_ref>(__first, __last, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -3675,6 +3672,15 @@ sort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last) _VSTD::sort(__first.base(), __last.base()); } +template +inline _LIBCPP_INLINE_VISIBILITY +void +sort(__wrap_iter<_Tp*> __first, __wrap_iter<_Tp*> __last, _Compare __comp) +{ + typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; + _VSTD::sort<_Tp*, _Comp_ref>(__first.base(), __last.base(), __comp); +} + extern template void __sort<__less&, char*>(char*, char*, __less&); extern template void __sort<__less&, wchar_t*>(wchar_t*, wchar_t*, __less&); extern template void __sort<__less&, signed char*>(signed char*, signed char*, __less&); @@ -3738,14 +3744,14 @@ inline _LIBCPP_INLINE_VISIBILITY _ForwardIterator lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); return __lower_bound<_Comp_ref>(__first, __last, __value, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; return __lower_bound<_Comp_ref>(__first, __last, __value, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -3786,14 +3792,14 @@ inline _LIBCPP_INLINE_VISIBILITY _ForwardIterator upper_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); return __upper_bound<_Comp_ref>(__first, __last, __value, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; return __upper_bound<_Comp_ref>(__first, __last, __value, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -3846,14 +3852,14 @@ inline _LIBCPP_INLINE_VISIBILITY pair<_ForwardIterator, _ForwardIterator> equal_range(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); return __equal_range<_Comp_ref>(__first, __last, __value, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; return __equal_range<_Comp_ref>(__first, __last, __value, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -3881,14 +3887,14 @@ inline _LIBCPP_INLINE_VISIBILITY bool binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); return __binary_search<_Comp_ref>(__first, __last, __value, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; return __binary_search<_Comp_ref>(__first, __last, __value, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -3931,14 +3937,14 @@ _OutputIterator merge(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; return _VSTD::__merge<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -4105,16 +4111,16 @@ inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _ __buf = _VSTD::get_temporary_buffer(__buf_size); __h.reset(__buf.first); } -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __c, __len1, __len2, __buf.first, __buf.second); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; return _VSTD::__inplace_merge<_Comp_ref>(__first, __middle, __last, __comp, __len1, __len2, __buf.first, __buf.second); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -4316,14 +4322,14 @@ stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compar __buf = _VSTD::get_temporary_buffer(__len); __h.reset(__buf.first); } -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); __stable_sort<_Comp_ref>(__first, __last, __c, __len, __buf.first, __buf.second); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; __stable_sort<_Comp_ref>(__first, __last, __comp, __len, __buf.first, __buf.second); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -4465,14 +4471,14 @@ inline _LIBCPP_INLINE_VISIBILITY void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); __push_heap_back<_Comp_ref>(__first, __last, __c, __last - __first); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; __push_heap_back<_Comp_ref>(__first, __last, __comp, __last - __first); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -4503,14 +4509,14 @@ inline _LIBCPP_INLINE_VISIBILITY void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); __pop_heap<_Comp_ref>(__first, __last, __c, __last - __first); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; __pop_heap<_Comp_ref>(__first, __last, __comp, __last - __first); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -4543,14 +4549,14 @@ inline _LIBCPP_INLINE_VISIBILITY void make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); __make_heap<_Comp_ref>(__first, __last, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; __make_heap<_Comp_ref>(__first, __last, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -4577,14 +4583,14 @@ inline _LIBCPP_INLINE_VISIBILITY void sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); __sort_heap<_Comp_ref>(__first, __last, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; __sort_heap<_Comp_ref>(__first, __last, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -4621,14 +4627,14 @@ void partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); __partial_sort<_Comp_ref>(__first, __middle, __last, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; __partial_sort<_Comp_ref>(__first, __middle, __last, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -4671,14 +4677,14 @@ _RandomAccessIterator partial_sort_copy(_InputIterator __first, _InputIterator __last, _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); return __partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; return __partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -4883,14 +4889,14 @@ inline _LIBCPP_INLINE_VISIBILITY void nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); __nth_element<_Comp_ref>(__first, __nth, __last, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; __nth_element<_Comp_ref>(__first, __nth, __last, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -4924,14 +4930,14 @@ bool includes(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); return __includes<_Comp_ref>(__first1, __last1, __first2, __last2, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; return __includes<_Comp_ref>(__first1, __last1, __first2, __last2, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -4977,14 +4983,14 @@ _OutputIterator set_union(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); return __set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; return __set_union<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -5029,14 +5035,14 @@ _OutputIterator set_intersection(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); return __set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; return __set_intersection<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -5083,14 +5089,14 @@ _OutputIterator set_difference(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); return __set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; return __set_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -5142,14 +5148,14 @@ _OutputIterator set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _OutputIterator __result, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); return __set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; return __set_symmetric_difference<_Comp_ref>(__first1, __last1, __first2, __last2, __result, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -5186,14 +5192,14 @@ bool lexicographical_compare(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _InputIterator2 __last2, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); return __lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; return __lexicographical_compare<_Comp_ref>(__first1, __last1, __first2, __last2, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -5241,14 +5247,14 @@ inline _LIBCPP_INLINE_VISIBILITY bool next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); return __next_permutation<_Comp_ref>(__first, __last, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; return __next_permutation<_Comp_ref>(__first, __last, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template @@ -5294,14 +5300,14 @@ inline _LIBCPP_INLINE_VISIBILITY bool prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref; __debug_less<_Compare> __c(__comp); return __prev_permutation<_Comp_ref>(__first, __last, __c); -#else // _LIBCPP_DEBUG +#else // _LIBCPP_DEBUG2 typedef typename add_lvalue_reference<_Compare>::type _Comp_ref; return __prev_permutation<_Comp_ref>(__first, __last, __comp); -#endif // _LIBCPP_DEBUG +#endif // _LIBCPP_DEBUG2 } template diff --git a/libcxx/include/iterator b/libcxx/include/iterator index b232d09b3e49..ed2d7a713b7c 100644 --- a/libcxx/include/iterator +++ b/libcxx/include/iterator @@ -1066,30 +1066,90 @@ public: _LIBCPP_INLINE_VISIBILITY __wrap_iter() _NOEXCEPT {} template _LIBCPP_INLINE_VISIBILITY __wrap_iter(const __wrap_iter<_Up>& __u, typename enable_if::value>::type* = 0) _NOEXCEPT - : __i(__u.base()) {} - _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT {return *__i;} + : __i(__u.base()) + { +#ifdef _LIBCPP_DEBUG2 + __get_db()->__iterator_copy(this, &__u); +#endif + } +#ifdef _LIBCPP_DEBUG2 + _LIBCPP_INLINE_VISIBILITY + __wrap_iter(const __wrap_iter& __x) + : __i(__x.base()) + { + __get_db()->__iterator_copy(this, &__x); + } + _LIBCPP_INLINE_VISIBILITY + __wrap_iter& operator=(const __wrap_iter& __x) + { + if (this != &__x) + { + __get_db()->__iterator_copy(this, &__x); + __i = __x.__i; + } + return *this; + } + _LIBCPP_INLINE_VISIBILITY + ~__wrap_iter() + { + __get_db()->__erase_i(this); + } +#endif + _LIBCPP_INLINE_VISIBILITY reference operator*() const _NOEXCEPT + { + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to dereference a non-dereferenceable iterator"); + return *__i; + } _LIBCPP_INLINE_VISIBILITY pointer operator->() const _NOEXCEPT {return &(operator*());} - _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator++() _NOEXCEPT {++__i; return *this;} + _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator++() _NOEXCEPT + { + _LIBCPP_ASSERT(__get_const_db()->__dereferenceable(this), + "Attempted to increment non-incrementable iterator"); + ++__i; + return *this; + } _LIBCPP_INLINE_VISIBILITY __wrap_iter operator++(int) _NOEXCEPT - {__wrap_iter __tmp(*this); ++__i; return __tmp;} - _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator--() _NOEXCEPT {--__i; return *this;} + {__wrap_iter __tmp(*this); ++(*this); return __tmp;} + _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator--() _NOEXCEPT + { + _LIBCPP_ASSERT(__get_const_db()->__decrementable(this), + "Attempted to decrement non-decrementable iterator"); + --__i; + return *this; + } _LIBCPP_INLINE_VISIBILITY __wrap_iter operator--(int) _NOEXCEPT - {__wrap_iter __tmp(*this); --__i; return __tmp;} + {__wrap_iter __tmp(*this); --(*this); return __tmp;} _LIBCPP_INLINE_VISIBILITY __wrap_iter operator+ (difference_type __n) const _NOEXCEPT - {return __wrap_iter(__i + __n);} + {__wrap_iter __w(*this); __w += __n; return __w;} _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator+=(difference_type __n) _NOEXCEPT - {__i += __n; return *this;} + { + _LIBCPP_ASSERT(__get_const_db()->__addable(this, __n), + "Attempted to add/subtract iterator outside of valid range"); + __i += __n; + return *this; + } _LIBCPP_INLINE_VISIBILITY __wrap_iter operator- (difference_type __n) const _NOEXCEPT - {return __wrap_iter(__i - __n);} + {return *this + (-__n);} _LIBCPP_INLINE_VISIBILITY __wrap_iter& operator-=(difference_type __n) _NOEXCEPT - {__i -= __n; return *this;} + {*this += -__n; return *this;} _LIBCPP_INLINE_VISIBILITY reference operator[](difference_type __n) const _NOEXCEPT - {return __i[__n];} + { + _LIBCPP_ASSERT(__get_const_db()->__subscriptable(this, __n), + "Attempted to subscript iterator outside of valid range"); + return __i[__n]; + } _LIBCPP_INLINE_VISIBILITY iterator_type base() const _NOEXCEPT {return __i;} private: _LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT : __i(__x) {} +#ifdef _LIBCPP_DEBUG2 + _LIBCPP_INLINE_VISIBILITY __wrap_iter(const void* __p, iterator_type __x) : __i(__x) + { + __get_db()->__insert_ic(this, __p); + } +#endif template friend class __wrap_iter; template friend class basic_string; @@ -1155,6 +1215,8 @@ inline _LIBCPP_INLINE_VISIBILITY bool operator==(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { + _LIBCPP_ASSERT(__get_const_db()->__comparable(&__x, &__y), + "Attempted to compare incomparable iterators"); return __x.base() == __y.base(); } @@ -1163,6 +1225,8 @@ inline _LIBCPP_INLINE_VISIBILITY bool operator<(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { + _LIBCPP_ASSERT(__get_const_db()->__comparable(&__x, &__y), + "Attempted to compare incomparable iterators"); return __x.base() < __y.base(); } @@ -1171,7 +1235,7 @@ inline _LIBCPP_INLINE_VISIBILITY bool operator!=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { - return __x.base() != __y.base(); + return !(__x == __y); } template @@ -1179,7 +1243,7 @@ inline _LIBCPP_INLINE_VISIBILITY bool operator>(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { - return __x.base() > __y.base(); + return __y < __x; } template @@ -1187,7 +1251,7 @@ inline _LIBCPP_INLINE_VISIBILITY bool operator>=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { - return __x.base() >= __y.base(); + return !(__x < __y); } template @@ -1195,7 +1259,7 @@ inline _LIBCPP_INLINE_VISIBILITY bool operator<=(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { - return __x.base() <= __y.base(); + return !(__y < __x); } template @@ -1203,6 +1267,8 @@ inline _LIBCPP_INLINE_VISIBILITY typename __wrap_iter<_Iter1>::difference_type operator-(const __wrap_iter<_Iter1>& __x, const __wrap_iter<_Iter2>& __y) _NOEXCEPT { + _LIBCPP_ASSERT(__get_const_db()->__comparable(&__x, &__y), + "Attempted to subtract incompatible iterators"); return __x.base() - __y.base(); } @@ -1210,9 +1276,10 @@ template inline _LIBCPP_INLINE_VISIBILITY __wrap_iter<_Iter> operator+(typename __wrap_iter<_Iter>::difference_type __n, - const __wrap_iter<_Iter>& __x) _NOEXCEPT + __wrap_iter<_Iter> __x) _NOEXCEPT { - return __wrap_iter<_Iter>(__x.base() + __n); + __x += __n; + return __x; } #ifdef _LIBCPP_DEBUG diff --git a/libcxx/include/vector b/libcxx/include/vector index 348fe4af51c8..d1a67ce281bb 100644 --- a/libcxx/include/vector +++ b/libcxx/include/vector @@ -513,8 +513,18 @@ public: _LIBCPP_INLINE_VISIBILITY vector() _NOEXCEPT_(is_nothrow_default_constructible::value) - {} - _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a) : __base(__a) {} + { +#ifdef _LIBCPP_DEBUG2 + __get_db()->__insert_c(this); +#endif + } + _LIBCPP_INLINE_VISIBILITY explicit vector(const allocator_type& __a) + : __base(__a) + { +#ifdef _LIBCPP_DEBUG2 + __get_db()->__insert_c(this); +#endif + } explicit vector(size_type __n); vector(size_type __n, const_reference __x); vector(size_type __n, const_reference __x, const allocator_type& __a); @@ -538,9 +548,12 @@ public: _LIBCPP_INLINE_VISIBILITY vector(initializer_list __il, const allocator_type& __a); #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 _LIBCPP_INLINE_VISIBILITY - ~vector() {__invalidate_all_iterators();} + ~vector() + { + __get_db()->__erase_c(this); + } #endif vector(const vector& __x); @@ -641,10 +654,26 @@ public: reference at(size_type __n); const_reference at(size_type __n) const; - _LIBCPP_INLINE_VISIBILITY reference front() {return *this->__begin_;} - _LIBCPP_INLINE_VISIBILITY const_reference front() const {return *this->__begin_;} - _LIBCPP_INLINE_VISIBILITY reference back() {return *(this->__end_ - 1);} - _LIBCPP_INLINE_VISIBILITY const_reference back() const {return *(this->__end_ - 1);} + _LIBCPP_INLINE_VISIBILITY reference front() + { + _LIBCPP_ASSERT(!empty(), "front() called for empty vector"); + return *this->__begin_; + } + _LIBCPP_INLINE_VISIBILITY const_reference front() const + { + _LIBCPP_ASSERT(!empty(), "front() called for empty vector"); + return *this->__begin_; + } + _LIBCPP_INLINE_VISIBILITY reference back() + { + _LIBCPP_ASSERT(!empty(), "back() called for empty vector"); + return *(this->__end_ - 1); + } + _LIBCPP_INLINE_VISIBILITY const_reference back() const + { + _LIBCPP_ASSERT(!empty(), "back() called for empty vector"); + return *(this->__end_ - 1); + } _LIBCPP_INLINE_VISIBILITY value_type* data() _NOEXCEPT @@ -698,7 +727,10 @@ public: _LIBCPP_INLINE_VISIBILITY void clear() _NOEXCEPT - {__base::clear();} + { + __base::clear(); + __invalidate_all_iterators(); + } void resize(size_type __sz); void resize(size_type __sz, const_reference __x); @@ -709,6 +741,15 @@ public: bool __invariants() const; +#ifdef _LIBCPP_DEBUG2 + + bool __dereferenceable(const const_iterator* __i) const; + bool __decrementable(const const_iterator* __i) const; + bool __addable(const const_iterator* __i, ptrdiff_t __n) const; + bool __subscriptable(const const_iterator* __i, ptrdiff_t __n) const; + +#endif // _LIBCPP_DEBUG2 + private: _LIBCPP_INLINE_VISIBILITY void __invalidate_all_iterators(); void allocate(size_type __n); @@ -736,6 +777,26 @@ private: void __move_assign(vector& __c, true_type) _NOEXCEPT_(is_nothrow_move_assignable::value); void __move_assign(vector& __c, false_type); + _LIBCPP_INLINE_VISIBILITY + void __destruct_at_end(const_pointer __new_last) _NOEXCEPT + { +#ifdef _LIBCPP_DEBUG2 + __c_node* __c = __get_db()->__find_c_and_lock(this); + for (__i_node** __p = __c->end_; __p != __c->beg_; ) + { + --__p; + const_iterator* __i = static_cast((*__p)->__i_); + if (__i->base() > __new_last) + { + (*__p)->__c_ = nullptr; + if (--__c->end_ != __p) + memmove(__p, __p+1, (__c->end_ - __p)*sizeof(__i_node*)); + } + } + __get_db()->unlock(); +#endif + __base::__destruct_at_end(__new_last); + } }; template @@ -793,7 +854,6 @@ vector<_Tp, _Allocator>::deallocate() _NOEXCEPT { clear(); __alloc_traits::deallocate(this->__alloc(), this->__begin_, capacity()); - __invalidate_all_iterators(); this->__begin_ = this->__end_ = this->__end_cap() = 0; } } @@ -934,6 +994,9 @@ vector<_Tp, _Allocator>::vector(size_type __n) allocate(__n); __construct_at_end(__n); } +#ifdef _LIBCPP_DEBUG2 + __get_db()->__insert_c(this); +#endif } template @@ -944,6 +1007,9 @@ vector<_Tp, _Allocator>::vector(size_type __n, const_reference __x) allocate(__n); __construct_at_end(__n, __x); } +#ifdef _LIBCPP_DEBUG2 + __get_db()->__insert_c(this); +#endif } template @@ -955,6 +1021,9 @@ vector<_Tp, _Allocator>::vector(size_type __n, const_reference __x, const alloca allocate(__n); __construct_at_end(__n, __x); } +#ifdef _LIBCPP_DEBUG2 + __get_db()->__insert_c(this); +#endif } template @@ -965,6 +1034,9 @@ vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, { for (; __first != __last; ++__first) push_back(*__first); +#ifdef _LIBCPP_DEBUG2 + __get_db()->__insert_c(this); +#endif } template @@ -976,6 +1048,9 @@ vector<_Tp, _Allocator>::vector(_InputIterator __first, _InputIterator __last, c { for (; __first != __last; ++__first) push_back(*__first); +#ifdef _LIBCPP_DEBUG2 + __get_db()->__insert_c(this); +#endif } template @@ -989,6 +1064,9 @@ vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __las allocate(__n); __construct_at_end(__first, __last); } +#ifdef _LIBCPP_DEBUG2 + __get_db()->__insert_c(this); +#endif } template @@ -1003,6 +1081,9 @@ vector<_Tp, _Allocator>::vector(_ForwardIterator __first, _ForwardIterator __las allocate(__n); __construct_at_end(__first, __last); } +#ifdef _LIBCPP_DEBUG2 + __get_db()->__insert_c(this); +#endif } template @@ -1015,6 +1096,9 @@ vector<_Tp, _Allocator>::vector(const vector& __x) allocate(__n); __construct_at_end(__x.__begin_, __x.__end_); } +#ifdef _LIBCPP_DEBUG2 + __get_db()->__insert_c(this); +#endif } template @@ -1027,6 +1111,9 @@ vector<_Tp, _Allocator>::vector(const vector& __x, const allocator_type& __a) allocate(__n); __construct_at_end(__x.__begin_, __x.__end_); } +#ifdef _LIBCPP_DEBUG2 + __get_db()->__insert_c(this); +#endif } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES @@ -1041,7 +1128,10 @@ vector<_Tp, _Allocator>::vector(vector&& __x) this->__end_ = __x.__end_; this->__end_cap() = __x.__end_cap(); __x.__begin_ = __x.__end_ = __x.__end_cap() = 0; +#ifdef _LIBCPP_DEBUG2 __x.__invalidate_all_iterators(); + __get_db()->__insert_c(this); +#endif } template @@ -1062,6 +1152,9 @@ vector<_Tp, _Allocator>::vector(vector&& __x, const allocator_type& __a) typedef move_iterator _I; assign(_I(__x.begin()), _I(__x.end())); } +#ifdef _LIBCPP_DEBUG2 + __get_db()->__insert_c(this); +#endif } #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS @@ -1075,6 +1168,9 @@ vector<_Tp, _Allocator>::vector(initializer_list __il) allocate(__il.size()); __construct_at_end(__il.begin(), __il.end()); } +#ifdef _LIBCPP_DEBUG2 + __get_db()->__insert_c(this); +#endif } template @@ -1087,6 +1183,9 @@ vector<_Tp, _Allocator>::vector(initializer_list __il, const allocat allocate(__il.size()); __construct_at_end(__il.begin(), __il.end()); } +#ifdef _LIBCPP_DEBUG2 + __get_db()->__insert_c(this); +#endif } #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS @@ -1220,7 +1319,7 @@ _LIBCPP_INLINE_VISIBILITY inline typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::__make_iter(pointer __p) _NOEXCEPT { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 return iterator(this, __p); #else return iterator(__p); @@ -1232,7 +1331,7 @@ _LIBCPP_INLINE_VISIBILITY inline typename vector<_Tp, _Allocator>::const_iterator vector<_Tp, _Allocator>::__make_iter(const_pointer __p) const _NOEXCEPT { -#ifdef _LIBCPP_DEBUG +#ifdef _LIBCPP_DEBUG2 return const_iterator(this, __p); #else return const_iterator(__p); @@ -1276,9 +1375,7 @@ _LIBCPP_INLINE_VISIBILITY inline typename vector<_Tp, _Allocator>::reference vector<_Tp, _Allocator>::operator[](size_type __n) { -#ifdef _LIBCPP_DEBUG - assert(__n < size()); -#endif + _LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds"); return this->__begin_[__n]; } @@ -1287,9 +1384,7 @@ _LIBCPP_INLINE_VISIBILITY inline typename vector<_Tp, _Allocator>::const_reference vector<_Tp, _Allocator>::operator[](size_type __n) const { -#ifdef _LIBCPP_DEBUG - assert(__n < size()); -#endif + _LIBCPP_ASSERT(__n < size(), "vector[] index out of bounds"); return this->__begin_[__n]; } @@ -1417,6 +1512,7 @@ _LIBCPP_INLINE_VISIBILITY inline void vector<_Tp, _Allocator>::pop_back() { + _LIBCPP_ASSERT(!empty(), "vector::pop_back called for empty vector"); this->__destruct_at_end(this->__end_ - 1); } @@ -1425,6 +1521,9 @@ _LIBCPP_INLINE_VISIBILITY inline typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::erase(const_iterator __position) { + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this, + "vector::erase(iterator) called with an iterator not" + " referring to this vector"); pointer __p = const_cast(&*__position); iterator __r = __make_iter(__p); this->__destruct_at_end(_VSTD::move(__p + 1, this->__end_, __p)); @@ -1435,6 +1534,10 @@ template typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::erase(const_iterator __first, const_iterator __last) { + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__first) == this, + "vector::erase(iterator, iterator) called with an iterator not" + " referring to this vector"); + _LIBCPP_ASSERT(__first <= __last, "vector::erase(first, last) called with invalid range"); pointer __p = this->__begin_ + (__first - begin()); iterator __r = __make_iter(__p); this->__destruct_at_end(_VSTD::move(__p + (__last - __first), this->__end_, __p)); @@ -1458,6 +1561,9 @@ template typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x) { + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this, + "vector::insert(iterator, x) called with an iterator not" + " referring to this vector"); pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { @@ -1492,6 +1598,9 @@ template typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x) { + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this, + "vector::insert(iterator, x) called with an iterator not" + " referring to this vector"); pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { @@ -1525,6 +1634,9 @@ template typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::emplace(const_iterator __position, _Args&&... __args) { + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this, + "vector::emplace(iterator, x) called with an iterator not" + " referring to this vector"); pointer __p = this->__begin_ + (__position - begin()); if (this->__end_ < this->__end_cap()) { @@ -1558,6 +1670,9 @@ template typename vector<_Tp, _Allocator>::iterator vector<_Tp, _Allocator>::insert(const_iterator __position, size_type __n, const_reference __x) { + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this, + "vector::insert(iterator, n, x) called with an iterator not" + " referring to this vector"); pointer __p = this->__begin_ + (__position - begin()); if (__n > 0) { @@ -1601,6 +1716,9 @@ typename enable_if >::type vector<_Tp, _Allocator>::insert(const_iterator __position, _InputIterator __first, _InputIterator __last) { + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this, + "vector::insert(iterator, range) called with an iterator not" + " referring to this vector"); difference_type __off = __position - begin(); pointer __p = this->__begin_ + __off; allocator_type& __a = this->__alloc(); @@ -1648,6 +1766,9 @@ typename enable_if >::type vector<_Tp, _Allocator>::insert(const_iterator __position, _ForwardIterator __first, _ForwardIterator __last) { + _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__position) == this, + "vector::insert(iterator, range) called with an iterator not" + " referring to this vector"); pointer __p = this->__begin_ + (__position - begin()); difference_type __n = _VSTD::distance(__first, __last); if (__n > 0) @@ -1710,13 +1831,16 @@ vector<_Tp, _Allocator>::swap(vector& __x) _NOEXCEPT_(!__alloc_traits::propagate_on_container_swap::value || __is_nothrow_swappable::value) { + _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value || + this->__alloc() == __x.__alloc(), + "vector::swap: Either propagate_on_container_swap must be true" + " or the allocators must compare equal"); _VSTD::swap(this->__begin_, __x.__begin_); _VSTD::swap(this->__end_, __x.__end_); _VSTD::swap(this->__end_cap(), __x.__end_cap()); __base::__swap_alloc(this->__alloc(), __x.__alloc()); -#ifdef _LIBCPP_DEBUG - iterator::swap(this, &__x); - const_iterator::swap(this, &__x); +#ifdef _LIBCPP_DEBUG2 + __get_db()->swap(this, &__x); #endif // _LIBCPP_DEBUG } @@ -1741,16 +1865,49 @@ vector<_Tp, _Allocator>::__invariants() const return true; } +#ifdef _LIBCPP_DEBUG2 + +template +bool +vector<_Tp, _Allocator>::__dereferenceable(const const_iterator* __i) const +{ + return this->__begin_ <= __i->base() && __i->base() < this->__end_; +} + +template +bool +vector<_Tp, _Allocator>::__decrementable(const const_iterator* __i) const +{ + return this->__begin_ < __i->base() && __i->base() <= this->__end_; +} + +template +bool +vector<_Tp, _Allocator>::__addable(const const_iterator* __i, ptrdiff_t __n) const +{ + const_pointer __p = __i->base() + __n; + return this->__begin_ <= __p && __p <= this->__end_; +} + +template +bool +vector<_Tp, _Allocator>::__subscriptable(const const_iterator* __i, ptrdiff_t __n) const +{ + const_pointer __p = __i->base() + __n; + return this->__begin_ <= __p && __p < this->__end_; +} + +#endif // LIBCPP_DEBUG2 + template -#ifndef _LIBCPP_DEBUG _LIBCPP_INLINE_VISIBILITY inline -#endif void vector<_Tp, _Allocator>::__invalidate_all_iterators() { -#ifdef _LIBCPP_DEBUG - iterator::__remove_all(this); - const_iterator::__remove_all(this); +#ifdef _LIBCPP_DEBUG2 + __get_db()->__invalidate_all(this); +// iterator::__remove_all(this); +// const_iterator::__remove_all(this); #endif // _LIBCPP_DEBUG } diff --git a/libcxx/src/debug.cpp b/libcxx/src/debug.cpp new file mode 100644 index 000000000000..42e5edb33463 --- /dev/null +++ b/libcxx/src/debug.cpp @@ -0,0 +1,462 @@ +//===-------------------------- debug.cpp ---------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#define _LIBCPP_DEBUG2 +#include "__debug" +#include "functional" +#include "algorithm" +#include "__hash_table" +#include "mutex" + +_LIBCPP_BEGIN_NAMESPACE_STD + +_LIBCPP_VISIBLE +__libcpp_db* +__get_db() +{ + static __libcpp_db db; + return &db; +}; + +_LIBCPP_VISIBLE +const __libcpp_db* +__get_const_db() +{ + return __get_db(); +} + +namespace +{ + +typedef mutex mutex_type; +// struct mutex_type +// { +// void lock() {} +// void unlock() {}; +// }; +typedef lock_guard WLock; +typedef lock_guard RLock; + +mutex_type& +mut() +{ + static mutex_type m; + return m; +} + +} // unnamed namespace + +__i_node::~__i_node() +{ + if (__next_) + { + __next_->~__i_node(); + free(__next_); + } +} + +__c_node::~__c_node() +{ + free(beg_); + if (__next_) + { + __next_->~__c_node(); + free(__next_); + } +} + +__libcpp_db::__libcpp_db() + : __cbeg_(nullptr), + __cend_(nullptr), + __csz_(0), + __ibeg_(nullptr), + __iend_(nullptr), + __isz_(0) +{ +} + +__libcpp_db::~__libcpp_db() +{ + if (__cbeg_) + { + for (__c_node** p = __cbeg_; p != __cend_; ++p) + { + if (*p != nullptr) + { + (*p)->~__c_node(); + free(*p); + } + } + free(__cbeg_); + } + if (__ibeg_) + { + for (__i_node** p = __ibeg_; p != __iend_; ++p) + { + if (*p != nullptr) + { + (*p)->~__i_node(); + free(*p); + } + } + free(__ibeg_); + } +} + +void* +__libcpp_db::__find_c_from_i(void* __i) const +{ + RLock _(mut()); + __i_node* i = __find_iterator(__i); + return i != nullptr ? (i->__c_ != nullptr ? i->__c_->__c_ : nullptr) : nullptr; +} + +void +__libcpp_db::__insert_ic(void* __i, const void* __c) +{ + WLock _(mut()); + __i_node* i = __insert_iterator(__i); + _LIBCPP_ASSERT(__cbeg_ != __cend_, "debug mode internal logic error __insert_ic A"); + size_t hc = hash()(__c) % (__cend_ - __cbeg_); + __c_node* c = __cbeg_[hc]; + _LIBCPP_ASSERT(c != nullptr, "debug mode internal logic error __insert_ic B"); + while (c->__c_ != __c) + { + c = c->__next_; + _LIBCPP_ASSERT(c != nullptr, "debug mode internal logic error __insert_ic C"); + } + c->__add(i); + i->__c_ = c; +} + +__c_node* +__libcpp_db::__insert_c(void* __c) +{ + WLock _(mut()); + if (__csz_ + 1 > __cend_ - __cbeg_) + { + size_t nc = __next_prime(2*(__cend_ - __cbeg_) + 1); + __c_node** cbeg = (__c_node**)calloc(nc, sizeof(void*)); + if (cbeg == nullptr) + throw bad_alloc(); + for (__c_node** p = __cbeg_; p != __cend_; ++p) + { + __c_node* q = *p; + while (q != nullptr) + { + size_t h = hash()(q->__c_) % nc; + __c_node* r = q->__next_; + q->__next_ = cbeg[h]; + cbeg[h] = q; + q = r; + } + } + free(__cbeg_); + __cbeg_ = cbeg; + __cend_ = __cbeg_ + nc; + } + size_t hc = hash()(__c) % (__cend_ - __cbeg_); + __c_node* p = __cbeg_[hc]; + __c_node* r = __cbeg_[hc] = (__c_node*)malloc(sizeof(__c_node)); + if (__cbeg_[hc] == nullptr) + throw bad_alloc(); + r->__c_ = __c; + r->__next_ = p; + ++__csz_; + return r; +} + +void +__libcpp_db::__erase_i(void* __i) +{ + WLock _(mut()); + if (__ibeg_ != __iend_) + { + size_t hi = hash()(__i) % (__iend_ - __ibeg_); + __i_node* p = __ibeg_[hi]; + if (p != nullptr) + { + __i_node* q = nullptr; + while (p->__i_ != __i) + { + q = p; + p = p->__next_; + if (p == nullptr) + return; + } + if (q == nullptr) + __ibeg_[hi] = p->__next_; + else + q->__next_ = p->__next_; + __c_node* c = p->__c_; + free(p); + --__isz_; + if (c != nullptr) + c->__remove(p); + } + } +} + +void +__libcpp_db::__invalidate_all(void* __c) +{ + WLock _(mut()); + size_t hc = hash()(__c) % (__cend_ - __cbeg_); + __c_node* p = __cbeg_[hc]; + _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __invalidate_all A"); + while (p->__c_ != __c) + { + p = p->__next_; + _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __invalidate_all B"); + } + while (p->end_ != p->beg_) + { + --p->end_; + (*p->end_)->__c_ = nullptr; + } +} + +__c_node* +__libcpp_db::__find_c_and_lock(void* __c) const +{ + mut().lock(); + size_t hc = hash()(__c) % (__cend_ - __cbeg_); + __c_node* p = __cbeg_[hc]; + _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c_and_lock A"); + while (p->__c_ != __c) + { + p = p->__next_; + _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __find_c_and_lock B"); + } + return p; +} + +void +__libcpp_db::unlock() const +{ + mut().unlock(); +} + +void +__libcpp_db::__erase_c(void* __c) +{ + WLock _(mut()); + size_t hc = hash()(__c) % (__cend_ - __cbeg_); + __c_node* p = __cbeg_[hc]; + __c_node* q = nullptr; + _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c A"); + while (p->__c_ != __c) + { + q = p; + p = p->__next_; + _LIBCPP_ASSERT(p != nullptr, "debug mode internal logic error __erase_c B"); + } + if (q == nullptr) + __cbeg_[hc] = p->__next_; + else + q->__next_ = p->__next_; + while (p->end_ != p->beg_) + { + --p->end_; + (*p->end_)->__c_ = nullptr; + } + free(p->beg_); + free(p); + --__csz_; +} + +void +__libcpp_db::__iterator_copy(void* __i, const void* __i0) +{ + WLock _(mut()); + __i_node* i = __find_iterator(__i); + __i_node* i0 = __find_iterator(__i0); + __c_node* c0 = i0 != nullptr ? i0->__c_ : nullptr; + if (i == nullptr && c0 != nullptr) + i = __insert_iterator(__i); + __c_node* c = i != nullptr ? i->__c_ : nullptr; + if (c != c0) + { + if (c != nullptr) + c->__remove(i); + if (i != nullptr) + { + i->__c_ = nullptr; + if (c0 != nullptr) + { + i->__c_ = c0; + i->__c_->__add(i); + } + } + } +} + +bool +__libcpp_db::__dereferenceable(const void* __i) const +{ + RLock _(mut()); + __i_node* i = __find_iterator(__i); + return i != nullptr && i->__c_ != nullptr && i->__c_->__dereferenceable(__i); +} + +bool +__libcpp_db::__decrementable(const void* __i) const +{ + RLock _(mut()); + __i_node* i = __find_iterator(__i); + return i != nullptr && i->__c_ != nullptr && i->__c_->__decrementable(__i); +} + +bool +__libcpp_db::__addable(const void* __i, ptrdiff_t __n) const +{ + RLock _(mut()); + __i_node* i = __find_iterator(__i); + return i != nullptr && i->__c_ != nullptr && i->__c_->__addable(__i, __n); +} + +bool +__libcpp_db::__subscriptable(const void* __i, ptrdiff_t __n) const +{ + RLock _(mut()); + __i_node* i = __find_iterator(__i); + return i != nullptr && i->__c_ != nullptr && i->__c_->__subscriptable(__i, __n); +} + +bool +__libcpp_db::__comparable(const void* __i, const void* __j) const +{ + RLock _(mut()); + __i_node* i = __find_iterator(__i); + __i_node* j = __find_iterator(__j); + __c_node* ci = i != nullptr ? i->__c_ : nullptr; + __c_node* cj = j != nullptr ? j->__c_ : nullptr; + return ci != nullptr && ci == cj; +} + +void +__libcpp_db::swap(void* c1, void* c2) +{ + WLock _(mut()); + size_t hc = hash()(c1) % (__cend_ - __cbeg_); + __c_node* p1 = __cbeg_[hc]; + _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap A"); + while (p1->__c_ != c1) + { + p1 = p1->__next_; + _LIBCPP_ASSERT(p1 != nullptr, "debug mode internal logic error swap B"); + } + hc = hash()(c2) % (__cend_ - __cbeg_); + __c_node* p2 = __cbeg_[hc]; + _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap C"); + while (p2->__c_ != c2) + { + p2 = p2->__next_; + _LIBCPP_ASSERT(p2 != nullptr, "debug mode internal logic error swap D"); + } + std::swap(p1->beg_, p2->beg_); + std::swap(p1->end_, p2->end_); + std::swap(p1->cap_, p2->cap_); + for (__i_node** p = p1->beg_; p != p1->end_; ++p) + (*p)->__c_ = p1; + for (__i_node** p = p2->beg_; p != p2->end_; ++p) + (*p)->__c_ = p2; +} + +// private api + +_LIBCPP_HIDDEN +__i_node* +__libcpp_db::__insert_iterator(void* __i) +{ + if (__isz_ + 1 > __iend_ - __ibeg_) + { + size_t nc = __next_prime(2*(__iend_ - __ibeg_) + 1); + __i_node** ibeg = (__i_node**)calloc(nc, sizeof(void*)); + if (ibeg == nullptr) + throw bad_alloc(); + for (__i_node** p = __ibeg_; p != __iend_; ++p) + { + __i_node* q = *p; + while (q != nullptr) + { + size_t h = hash()(q->__i_) % nc; + __i_node* r = q->__next_; + q->__next_ = ibeg[h]; + ibeg[h] = q; + q = r; + } + } + free(__ibeg_); + __ibeg_ = ibeg; + __iend_ = __ibeg_ + nc; + } + size_t hi = hash()(__i) % (__iend_ - __ibeg_); + __i_node* p = __ibeg_[hi]; + __i_node* r = __ibeg_[hi] = (__i_node*)malloc(sizeof(__i_node)); + if (r == nullptr) + throw bad_alloc(); + ::new(r) __i_node(__i, p, nullptr); + ++__isz_; + return r; +} + +_LIBCPP_HIDDEN +__i_node* +__libcpp_db::__find_iterator(const void* __i) const +{ + __i_node* r = nullptr; + if (__ibeg_ != __iend_) + { + size_t h = hash()(__i) % (__iend_ - __ibeg_); + for (__i_node* nd = __ibeg_[h]; nd != nullptr; nd = nd->__next_) + { + if (nd->__i_ == __i) + { + r = nd; + break; + } + } + } + return r; +} + +_LIBCPP_HIDDEN +void +__c_node::__add(__i_node* i) +{ + if (end_ == cap_) + { + size_t nc = 2*(cap_ - beg_); + if (nc == 0) + nc = 1; + __i_node** beg = (__i_node**)malloc(nc * sizeof(__i_node*)); + if (beg == nullptr) + throw bad_alloc(); + if (nc > 1) + memcpy(beg, beg_, nc/2*sizeof(__i_node*)); + free(beg_); + beg_ = beg; + end_ = beg_ + nc/2; + cap_ = beg_ + nc; + } + *end_++ = i; +} + +_LIBCPP_HIDDEN +void +__c_node::__remove(__i_node* p) +{ + __i_node** r = find(beg_, end_, p); + _LIBCPP_ASSERT(r != end_, "debug mode internal logic error __c_node::__remove"); + if (--end_ != r) + memmove(r, r+1, (end_ - r)*sizeof(__i_node*)); +} + +_LIBCPP_END_NAMESPACE_STD