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