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