10b57cec5SDimitry Andric// -*- C++ -*- 20b57cec5SDimitry Andric//===--------------------------- __debug ----------------------------------===// 30b57cec5SDimitry Andric// 40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric// 80b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric#ifndef _LIBCPP_DEBUG_H 110b57cec5SDimitry Andric#define _LIBCPP_DEBUG_H 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric#include <__config> 140b57cec5SDimitry Andric#include <iosfwd> 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 170b57cec5SDimitry Andric#pragma GCC system_header 180b57cec5SDimitry Andric#endif 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric#if defined(_LIBCPP_HAS_NO_NULLPTR) 210b57cec5SDimitry Andric# include <cstddef> 220b57cec5SDimitry Andric#endif 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric#if _LIBCPP_DEBUG_LEVEL >= 1 || defined(_LIBCPP_BUILDING_LIBRARY) 250b57cec5SDimitry Andric# include <cstdlib> 260b57cec5SDimitry Andric# include <cstdio> 270b57cec5SDimitry Andric# include <cstddef> 280b57cec5SDimitry Andric#endif 290b57cec5SDimitry Andric 30*af732203SDimitry Andric#if _LIBCPP_DEBUG_LEVEL == 0 310b57cec5SDimitry Andric# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0) 32*af732203SDimitry Andric# define _LIBCPP_ASSERT_IMPL(x, m) ((void)0) 33*af732203SDimitry Andric#elif _LIBCPP_DEBUG_LEVEL == 1 34*af732203SDimitry Andric# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0) 35*af732203SDimitry Andric# define _LIBCPP_ASSERT_IMPL(x, m) ((x) ? (void)0 : _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m))) 36*af732203SDimitry Andric#elif _LIBCPP_DEBUG_LEVEL == 2 37*af732203SDimitry Andric# define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(x, m) 38*af732203SDimitry Andric# define _LIBCPP_ASSERT_IMPL(x, m) ((x) ? (void)0 : _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m))) 39*af732203SDimitry Andric#else 40*af732203SDimitry Andric# error _LIBCPP_DEBUG_LEVEL must be one of 0, 1, 2 410b57cec5SDimitry Andric#endif 42*af732203SDimitry Andric 43*af732203SDimitry Andric#if !defined(_LIBCPP_ASSERT) 44*af732203SDimitry Andric# define _LIBCPP_ASSERT(x, m) _LIBCPP_ASSERT_IMPL(x, m) 450b57cec5SDimitry Andric#endif 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 480b57cec5SDimitry Andric 490b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS __libcpp_debug_info { 500b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 510b57cec5SDimitry Andric __libcpp_debug_info() 520b57cec5SDimitry Andric : __file_(nullptr), __line_(-1), __pred_(nullptr), __msg_(nullptr) {} 530b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 540b57cec5SDimitry Andric __libcpp_debug_info(const char* __f, int __l, const char* __p, const char* __m) 550b57cec5SDimitry Andric : __file_(__f), __line_(__l), __pred_(__p), __msg_(__m) {} 560b57cec5SDimitry Andric 57*af732203SDimitry Andric _LIBCPP_FUNC_VIS string what() const; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric const char* __file_; 600b57cec5SDimitry Andric int __line_; 610b57cec5SDimitry Andric const char* __pred_; 620b57cec5SDimitry Andric const char* __msg_; 630b57cec5SDimitry Andric}; 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric/// __libcpp_debug_function_type - The type of the assertion failure handler. 660b57cec5SDimitry Andrictypedef void(*__libcpp_debug_function_type)(__libcpp_debug_info const&); 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric/// __libcpp_debug_function - The handler function called when a _LIBCPP_ASSERT 690b57cec5SDimitry Andric/// fails. 700b57cec5SDimitry Andricextern _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_function_type __libcpp_debug_function; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric/// __libcpp_abort_debug_function - A debug handler that aborts when called. 730b57cec5SDimitry Andric_LIBCPP_NORETURN _LIBCPP_FUNC_VIS 740b57cec5SDimitry Andricvoid __libcpp_abort_debug_function(__libcpp_debug_info const&); 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric/// __libcpp_set_debug_function - Set the debug handler to the specified 770b57cec5SDimitry Andric/// function. 780b57cec5SDimitry Andric_LIBCPP_FUNC_VIS 790b57cec5SDimitry Andricbool __libcpp_set_debug_function(__libcpp_debug_function_type __func); 800b57cec5SDimitry Andric 81*af732203SDimitry Andric#if _LIBCPP_DEBUG_LEVEL == 2 || defined(_LIBCPP_BUILDING_LIBRARY) 820b57cec5SDimitry Andric 830b57cec5SDimitry Andricstruct _LIBCPP_TYPE_VIS __c_node; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andricstruct _LIBCPP_TYPE_VIS __i_node 860b57cec5SDimitry Andric{ 870b57cec5SDimitry Andric void* __i_; 880b57cec5SDimitry Andric __i_node* __next_; 890b57cec5SDimitry Andric __c_node* __c_; 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 920b57cec5SDimitry Andric __i_node(const __i_node&) = delete; 930b57cec5SDimitry Andric __i_node& operator=(const __i_node&) = delete; 940b57cec5SDimitry Andric#else 950b57cec5SDimitry Andricprivate: 960b57cec5SDimitry Andric __i_node(const __i_node&); 970b57cec5SDimitry Andric __i_node& operator=(const __i_node&); 980b57cec5SDimitry Andricpublic: 990b57cec5SDimitry Andric#endif 1000b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1010b57cec5SDimitry Andric __i_node(void* __i, __i_node* __next, __c_node* __c) 1020b57cec5SDimitry Andric : __i_(__i), __next_(__next), __c_(__c) {} 1030b57cec5SDimitry Andric ~__i_node(); 1040b57cec5SDimitry Andric}; 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andricstruct _LIBCPP_TYPE_VIS __c_node 1070b57cec5SDimitry Andric{ 1080b57cec5SDimitry Andric void* __c_; 1090b57cec5SDimitry Andric __c_node* __next_; 1100b57cec5SDimitry Andric __i_node** beg_; 1110b57cec5SDimitry Andric __i_node** end_; 1120b57cec5SDimitry Andric __i_node** cap_; 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 1150b57cec5SDimitry Andric __c_node(const __c_node&) = delete; 1160b57cec5SDimitry Andric __c_node& operator=(const __c_node&) = delete; 1170b57cec5SDimitry Andric#else 1180b57cec5SDimitry Andricprivate: 1190b57cec5SDimitry Andric __c_node(const __c_node&); 1200b57cec5SDimitry Andric __c_node& operator=(const __c_node&); 1210b57cec5SDimitry Andricpublic: 1220b57cec5SDimitry Andric#endif 1230b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 1240b57cec5SDimitry Andric __c_node(void* __c, __c_node* __next) 1250b57cec5SDimitry Andric : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {} 1260b57cec5SDimitry Andric virtual ~__c_node(); 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric virtual bool __dereferenceable(const void*) const = 0; 1290b57cec5SDimitry Andric virtual bool __decrementable(const void*) const = 0; 1300b57cec5SDimitry Andric virtual bool __addable(const void*, ptrdiff_t) const = 0; 1310b57cec5SDimitry Andric virtual bool __subscriptable(const void*, ptrdiff_t) const = 0; 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric void __add(__i_node* __i); 1340b57cec5SDimitry Andric _LIBCPP_HIDDEN void __remove(__i_node* __i); 1350b57cec5SDimitry Andric}; 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andrictemplate <class _Cont> 1380b57cec5SDimitry Andricstruct _C_node 1390b57cec5SDimitry Andric : public __c_node 1400b57cec5SDimitry Andric{ 1410b57cec5SDimitry Andric _C_node(void* __c, __c_node* __n) 1420b57cec5SDimitry Andric : __c_node(__c, __n) {} 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric virtual bool __dereferenceable(const void*) const; 1450b57cec5SDimitry Andric virtual bool __decrementable(const void*) const; 1460b57cec5SDimitry Andric virtual bool __addable(const void*, ptrdiff_t) const; 1470b57cec5SDimitry Andric virtual bool __subscriptable(const void*, ptrdiff_t) const; 1480b57cec5SDimitry Andric}; 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andrictemplate <class _Cont> 1510b57cec5SDimitry Andricinline bool 1520b57cec5SDimitry Andric_C_node<_Cont>::__dereferenceable(const void* __i) const 1530b57cec5SDimitry Andric{ 1540b57cec5SDimitry Andric typedef typename _Cont::const_iterator iterator; 1550b57cec5SDimitry Andric const iterator* __j = static_cast<const iterator*>(__i); 1560b57cec5SDimitry Andric _Cont* _Cp = static_cast<_Cont*>(__c_); 1570b57cec5SDimitry Andric return _Cp->__dereferenceable(__j); 1580b57cec5SDimitry Andric} 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andrictemplate <class _Cont> 1610b57cec5SDimitry Andricinline bool 1620b57cec5SDimitry Andric_C_node<_Cont>::__decrementable(const void* __i) const 1630b57cec5SDimitry Andric{ 1640b57cec5SDimitry Andric typedef typename _Cont::const_iterator iterator; 1650b57cec5SDimitry Andric const iterator* __j = static_cast<const iterator*>(__i); 1660b57cec5SDimitry Andric _Cont* _Cp = static_cast<_Cont*>(__c_); 1670b57cec5SDimitry Andric return _Cp->__decrementable(__j); 1680b57cec5SDimitry Andric} 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andrictemplate <class _Cont> 1710b57cec5SDimitry Andricinline bool 1720b57cec5SDimitry Andric_C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const 1730b57cec5SDimitry Andric{ 1740b57cec5SDimitry Andric typedef typename _Cont::const_iterator iterator; 1750b57cec5SDimitry Andric const iterator* __j = static_cast<const iterator*>(__i); 1760b57cec5SDimitry Andric _Cont* _Cp = static_cast<_Cont*>(__c_); 1770b57cec5SDimitry Andric return _Cp->__addable(__j, __n); 1780b57cec5SDimitry Andric} 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andrictemplate <class _Cont> 1810b57cec5SDimitry Andricinline bool 1820b57cec5SDimitry Andric_C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const 1830b57cec5SDimitry Andric{ 1840b57cec5SDimitry Andric typedef typename _Cont::const_iterator iterator; 1850b57cec5SDimitry Andric const iterator* __j = static_cast<const iterator*>(__i); 1860b57cec5SDimitry Andric _Cont* _Cp = static_cast<_Cont*>(__c_); 1870b57cec5SDimitry Andric return _Cp->__subscriptable(__j, __n); 1880b57cec5SDimitry Andric} 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS __libcpp_db 1910b57cec5SDimitry Andric{ 1920b57cec5SDimitry Andric __c_node** __cbeg_; 1930b57cec5SDimitry Andric __c_node** __cend_; 1940b57cec5SDimitry Andric size_t __csz_; 1950b57cec5SDimitry Andric __i_node** __ibeg_; 1960b57cec5SDimitry Andric __i_node** __iend_; 1970b57cec5SDimitry Andric size_t __isz_; 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric __libcpp_db(); 2000b57cec5SDimitry Andricpublic: 2010b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG 2020b57cec5SDimitry Andric __libcpp_db(const __libcpp_db&) = delete; 2030b57cec5SDimitry Andric __libcpp_db& operator=(const __libcpp_db&) = delete; 2040b57cec5SDimitry Andric#else 2050b57cec5SDimitry Andricprivate: 2060b57cec5SDimitry Andric __libcpp_db(const __libcpp_db&); 2070b57cec5SDimitry Andric __libcpp_db& operator=(const __libcpp_db&); 2080b57cec5SDimitry Andricpublic: 2090b57cec5SDimitry Andric#endif 2100b57cec5SDimitry Andric ~__libcpp_db(); 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric class __db_c_iterator; 2130b57cec5SDimitry Andric class __db_c_const_iterator; 2140b57cec5SDimitry Andric class __db_i_iterator; 2150b57cec5SDimitry Andric class __db_i_const_iterator; 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric __db_c_const_iterator __c_end() const; 2180b57cec5SDimitry Andric __db_i_const_iterator __i_end() const; 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric typedef __c_node*(_InsertConstruct)(void*, void*, __c_node*); 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric template <class _Cont> 2230b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY static __c_node* __create_C_node(void *__mem, void *__c, __c_node *__next) { 2240b57cec5SDimitry Andric return ::new (__mem) _C_node<_Cont>(__c, __next); 2250b57cec5SDimitry Andric } 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric template <class _Cont> 2280b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2290b57cec5SDimitry Andric void __insert_c(_Cont* __c) 2300b57cec5SDimitry Andric { 2310b57cec5SDimitry Andric __insert_c(static_cast<void*>(__c), &__create_C_node<_Cont>); 2320b57cec5SDimitry Andric } 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric void __insert_i(void* __i); 2350b57cec5SDimitry Andric void __insert_c(void* __c, _InsertConstruct* __fn); 2360b57cec5SDimitry Andric void __erase_c(void* __c); 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric void __insert_ic(void* __i, const void* __c); 2390b57cec5SDimitry Andric void __iterator_copy(void* __i, const void* __i0); 2400b57cec5SDimitry Andric void __erase_i(void* __i); 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric void* __find_c_from_i(void* __i) const; 2430b57cec5SDimitry Andric void __invalidate_all(void* __c); 2440b57cec5SDimitry Andric __c_node* __find_c_and_lock(void* __c) const; 2450b57cec5SDimitry Andric __c_node* __find_c(void* __c) const; 2460b57cec5SDimitry Andric void unlock() const; 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric void swap(void* __c1, void* __c2); 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric bool __dereferenceable(const void* __i) const; 2520b57cec5SDimitry Andric bool __decrementable(const void* __i) const; 2530b57cec5SDimitry Andric bool __addable(const void* __i, ptrdiff_t __n) const; 2540b57cec5SDimitry Andric bool __subscriptable(const void* __i, ptrdiff_t __n) const; 2550b57cec5SDimitry Andric bool __less_than_comparable(const void* __i, const void* __j) const; 2560b57cec5SDimitry Andricprivate: 2570b57cec5SDimitry Andric _LIBCPP_HIDDEN 2580b57cec5SDimitry Andric __i_node* __insert_iterator(void* __i); 2590b57cec5SDimitry Andric _LIBCPP_HIDDEN 2600b57cec5SDimitry Andric __i_node* __find_iterator(const void* __i) const; 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric friend _LIBCPP_FUNC_VIS __libcpp_db* __get_db(); 2630b57cec5SDimitry Andric}; 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric_LIBCPP_FUNC_VIS __libcpp_db* __get_db(); 2660b57cec5SDimitry Andric_LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db(); 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric 269*af732203SDimitry Andric#endif // _LIBCPP_DEBUG_LEVEL == 2 || defined(_LIBCPP_BUILDING_LIBRARY) 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 2720b57cec5SDimitry Andric 2730b57cec5SDimitry Andric#endif // _LIBCPP_DEBUG_H 274