1// -*- C++ -*- 2//===----------------------------------------------------------------------===// 3// 4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5// See https://llvm.org/LICENSE.txt for license information. 6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef _LIBCPP___DEBUG 11#define _LIBCPP___DEBUG 12 13#include <__assert> 14#include <__config> 15#include <cstddef> 16#include <type_traits> 17 18#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 19# pragma GCC system_header 20#endif 21 22// Catch invalid uses of the legacy _LIBCPP_DEBUG toggle. 23#if defined(_LIBCPP_DEBUG) && _LIBCPP_DEBUG != 0 && !defined(_LIBCPP_ENABLE_DEBUG_MODE) 24# error "Enabling the debug mode now requires having configured the library with support for the debug mode" 25#endif 26 27#if defined(_LIBCPP_ENABLE_DEBUG_MODE) && !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY) 28# define _LIBCPP_DEBUG_RANDOMIZE_UNSPECIFIED_STABILITY 29#endif 30 31#ifdef _LIBCPP_ENABLE_DEBUG_MODE 32# define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(::std::__libcpp_is_constant_evaluated() || (x), m) 33#else 34# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0) 35#endif 36 37#if defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY) 38 39_LIBCPP_BEGIN_NAMESPACE_STD 40 41struct _LIBCPP_TYPE_VIS __c_node; 42 43struct _LIBCPP_TYPE_VIS __i_node 44{ 45 void* __i_; 46 __i_node* __next_; 47 __c_node* __c_; 48 49 __i_node(const __i_node&) = delete; 50 __i_node& operator=(const __i_node&) = delete; 51 52 _LIBCPP_INLINE_VISIBILITY 53 __i_node(void* __i, __i_node* __next, __c_node* __c) 54 : __i_(__i), __next_(__next), __c_(__c) {} 55 ~__i_node(); 56}; 57 58struct _LIBCPP_TYPE_VIS __c_node 59{ 60 void* __c_; 61 __c_node* __next_; 62 __i_node** beg_; 63 __i_node** end_; 64 __i_node** cap_; 65 66 __c_node(const __c_node&) = delete; 67 __c_node& operator=(const __c_node&) = delete; 68 69 _LIBCPP_INLINE_VISIBILITY 70 explicit __c_node(void* __c, __c_node* __next) 71 : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {} 72 virtual ~__c_node(); 73 74 virtual bool __dereferenceable(const void*) const = 0; 75 virtual bool __decrementable(const void*) const = 0; 76 virtual bool __addable(const void*, ptrdiff_t) const = 0; 77 virtual bool __subscriptable(const void*, ptrdiff_t) const = 0; 78 79 void __add(__i_node* __i); 80 _LIBCPP_HIDDEN void __remove(__i_node* __i); 81}; 82 83template <class _Cont> 84struct _C_node 85 : public __c_node 86{ 87 explicit _C_node(void* __c, __c_node* __n) 88 : __c_node(__c, __n) {} 89 90 virtual bool __dereferenceable(const void*) const; 91 virtual bool __decrementable(const void*) const; 92 virtual bool __addable(const void*, ptrdiff_t) const; 93 virtual bool __subscriptable(const void*, ptrdiff_t) const; 94}; 95 96template <class _Cont> 97inline bool 98_C_node<_Cont>::__dereferenceable(const void* __i) const 99{ 100 typedef typename _Cont::const_iterator iterator; 101 const iterator* __j = static_cast<const iterator*>(__i); 102 _Cont* _Cp = static_cast<_Cont*>(__c_); 103 return _Cp->__dereferenceable(__j); 104} 105 106template <class _Cont> 107inline bool 108_C_node<_Cont>::__decrementable(const void* __i) const 109{ 110 typedef typename _Cont::const_iterator iterator; 111 const iterator* __j = static_cast<const iterator*>(__i); 112 _Cont* _Cp = static_cast<_Cont*>(__c_); 113 return _Cp->__decrementable(__j); 114} 115 116template <class _Cont> 117inline bool 118_C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const 119{ 120 typedef typename _Cont::const_iterator iterator; 121 const iterator* __j = static_cast<const iterator*>(__i); 122 _Cont* _Cp = static_cast<_Cont*>(__c_); 123 return _Cp->__addable(__j, __n); 124} 125 126template <class _Cont> 127inline bool 128_C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const 129{ 130 typedef typename _Cont::const_iterator iterator; 131 const iterator* __j = static_cast<const iterator*>(__i); 132 _Cont* _Cp = static_cast<_Cont*>(__c_); 133 return _Cp->__subscriptable(__j, __n); 134} 135 136class _LIBCPP_TYPE_VIS __libcpp_db 137{ 138 __c_node** __cbeg_; 139 __c_node** __cend_; 140 size_t __csz_; 141 __i_node** __ibeg_; 142 __i_node** __iend_; 143 size_t __isz_; 144 145 explicit __libcpp_db(); 146public: 147 __libcpp_db(const __libcpp_db&) = delete; 148 __libcpp_db& operator=(const __libcpp_db&) = delete; 149 150 ~__libcpp_db(); 151 152 class __db_c_iterator; 153 class __db_c_const_iterator; 154 class __db_i_iterator; 155 class __db_i_const_iterator; 156 157 __db_c_const_iterator __c_end() const; 158 __db_i_const_iterator __i_end() const; 159 160 typedef __c_node*(_InsertConstruct)(void*, void*, __c_node*); 161 162 template <class _Cont> 163 _LIBCPP_INLINE_VISIBILITY static __c_node* __create_C_node(void *__mem, void *__c, __c_node *__next) { 164 return ::new (__mem) _C_node<_Cont>(__c, __next); 165 } 166 167 template <class _Cont> 168 _LIBCPP_INLINE_VISIBILITY 169 void __insert_c(_Cont* __c) 170 { 171 __insert_c(static_cast<void*>(__c), &__create_C_node<_Cont>); 172 } 173 174 void __insert_i(void* __i); 175 void __insert_c(void* __c, _InsertConstruct* __fn); 176 void __erase_c(void* __c); 177 178 void __insert_ic(void* __i, const void* __c); 179 void __iterator_copy(void* __i, const void* __i0); 180 void __erase_i(void* __i); 181 182 void* __find_c_from_i(void* __i) const; 183 void __invalidate_all(void* __c); 184 __c_node* __find_c_and_lock(void* __c) const; 185 __c_node* __find_c(void* __c) const; 186 void unlock() const; 187 188 void swap(void* __c1, void* __c2); 189 190 191 bool __dereferenceable(const void* __i) const; 192 bool __decrementable(const void* __i) const; 193 bool __addable(const void* __i, ptrdiff_t __n) const; 194 bool __subscriptable(const void* __i, ptrdiff_t __n) const; 195 bool __less_than_comparable(const void* __i, const void* __j) const; 196private: 197 _LIBCPP_HIDDEN 198 __i_node* __insert_iterator(void* __i); 199 _LIBCPP_HIDDEN 200 __i_node* __find_iterator(const void* __i) const; 201 202 friend _LIBCPP_FUNC_VIS __libcpp_db* __get_db(); 203}; 204 205_LIBCPP_FUNC_VIS __libcpp_db* __get_db(); 206_LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db(); 207 208_LIBCPP_END_NAMESPACE_STD 209 210#endif // defined(_LIBCPP_ENABLE_DEBUG_MODE) || defined(_LIBCPP_BUILDING_LIBRARY) 211 212_LIBCPP_BEGIN_NAMESPACE_STD 213 214template <class _Tp> 215_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_insert_c(_Tp* __c) { 216#ifdef _LIBCPP_ENABLE_DEBUG_MODE 217 if (!__libcpp_is_constant_evaluated()) 218 __get_db()->__insert_c(__c); 219#else 220 (void)(__c); 221#endif 222} 223 224template <class _Tp> 225_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_insert_i(_Tp* __i) { 226#ifdef _LIBCPP_ENABLE_DEBUG_MODE 227 if (!__libcpp_is_constant_evaluated()) 228 __get_db()->__insert_i(__i); 229#else 230 (void)(__i); 231#endif 232} 233 234template <class _Tp> 235_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_erase_c(_Tp* __c) { 236#ifdef _LIBCPP_ENABLE_DEBUG_MODE 237 if (!__libcpp_is_constant_evaluated()) 238 __get_db()->__erase_c(__c); 239#else 240 (void)(__c); 241#endif 242} 243 244template <class _Tp> 245_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_swap(_Tp* __lhs, _Tp* __rhs) { 246#ifdef _LIBCPP_ENABLE_DEBUG_MODE 247 if (!__libcpp_is_constant_evaluated()) 248 __get_db()->swap(__lhs, __rhs); 249#else 250 (void)(__lhs); 251 (void)(__rhs); 252#endif 253} 254 255template <class _Tp> 256_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11 inline void __debug_db_invalidate_all(_Tp* __c) { 257#ifdef _LIBCPP_ENABLE_DEBUG_MODE 258 if (!__libcpp_is_constant_evaluated()) 259 __get_db()->__invalidate_all(__c); 260#else 261 (void)(__c); 262#endif 263} 264 265_LIBCPP_END_NAMESPACE_STD 266 267#endif // _LIBCPP___DEBUG 268