blob: 7b5bfb3f8378c96366ffbfa7fcbf31bd921e86fe [file] [log] [blame]
Howard Hinnant27e0e772011-09-14 18:33:51 +00001// -*- C++ -*-
2//===--------------------------- __debug ----------------------------------===//
3//
Chandler Carruthd2012102019-01-19 10:56:40 +00004// 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
Howard Hinnant27e0e772011-09-14 18:33:51 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_DEBUG_H
11#define _LIBCPP_DEBUG_H
12
Eric Fiselier14b6de92014-08-10 23:53:08 +000013#include <__config>
Eric Fiselier873b8d32019-03-18 21:50:12 +000014#include <iosfwd>
Eric Fiselier14b6de92014-08-10 23:53:08 +000015
Howard Hinnant8ea98242013-08-23 17:37:05 +000016#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17#pragma GCC system_header
18#endif
19
Eric Fiselier02e6fbc2016-12-28 06:15:01 +000020#if defined(_LIBCPP_HAS_NO_NULLPTR)
21# include <cstddef>
22#endif
23
Eric Fiselierfb825432016-12-28 04:58:52 +000024#if _LIBCPP_DEBUG_LEVEL >= 1 || defined(_LIBCPP_BUILDING_LIBRARY)
Howard Hinnant27e0e772011-09-14 18:33:51 +000025# include <cstdlib>
26# include <cstdio>
27# include <cstddef>
Eric Fiselierfb825432016-12-28 04:58:52 +000028#endif
29
Louis Dionneba400782020-10-02 15:02:52 -040030#if _LIBCPP_DEBUG_LEVEL == 0
Eric Fiselierd8f24a42016-07-23 20:36:55 +000031# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0)
Louis Dionneba400782020-10-02 15:02:52 -040032# define _LIBCPP_ASSERT_IMPL(x, m) ((void)0)
33#elif _LIBCPP_DEBUG_LEVEL == 1
34# define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0)
Louis Dionneba400782020-10-02 15:02:52 -040035# define _LIBCPP_ASSERT_IMPL(x, m) ((x) ? (void)0 : _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m)))
36#elif _LIBCPP_DEBUG_LEVEL == 2
37# define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(x, m)
Louis Dionneba400782020-10-02 15:02:52 -040038# define _LIBCPP_ASSERT_IMPL(x, m) ((x) ? (void)0 : _VSTD::__libcpp_debug_function(_VSTD::__libcpp_debug_info(__FILE__, __LINE__, #x, m)))
39#else
40# error _LIBCPP_DEBUG_LEVEL must be one of 0, 1, 2
Eric Fiselierd8f24a42016-07-23 20:36:55 +000041#endif
Louis Dionneba400782020-10-02 15:02:52 -040042
43#if !defined(_LIBCPP_ASSERT)
44# define _LIBCPP_ASSERT(x, m) _LIBCPP_ASSERT_IMPL(x, m)
Eric Fiselierd8f24a42016-07-23 20:36:55 +000045#endif
Howard Hinnanta47c6d52011-09-16 17:29:17 +000046
Howard Hinnant27e0e772011-09-14 18:33:51 +000047_LIBCPP_BEGIN_NAMESPACE_STD
48
Eric Fiselierb5eb1bf2017-01-04 23:56:00 +000049struct _LIBCPP_TEMPLATE_VIS __libcpp_debug_info {
Eric Fiselier3253fff2016-12-28 05:26:56 +000050 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Eric Fiselier30ee6932016-12-28 05:56:16 +000051 __libcpp_debug_info()
52 : __file_(nullptr), __line_(-1), __pred_(nullptr), __msg_(nullptr) {}
53 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Eric Fiselier3253fff2016-12-28 05:26:56 +000054 __libcpp_debug_info(const char* __f, int __l, const char* __p, const char* __m)
55 : __file_(__f), __line_(__l), __pred_(__p), __msg_(__m) {}
Eric Fiselier873b8d32019-03-18 21:50:12 +000056
Arthur O'Dwyer07b22492020-11-27 11:02:06 -050057 _LIBCPP_FUNC_VIS string what() const;
Eric Fiselier873b8d32019-03-18 21:50:12 +000058
Eric Fiselierfb825432016-12-28 04:58:52 +000059 const char* __file_;
60 int __line_;
61 const char* __pred_;
62 const char* __msg_;
63};
64
65/// __libcpp_debug_function_type - The type of the assertion failure handler.
66typedef void(*__libcpp_debug_function_type)(__libcpp_debug_info const&);
67
68/// __libcpp_debug_function - The handler function called when a _LIBCPP_ASSERT
69/// fails.
Louis Dionne5254b372018-10-25 12:13:43 +000070extern _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_function_type __libcpp_debug_function;
Eric Fiselierfb825432016-12-28 04:58:52 +000071
72/// __libcpp_abort_debug_function - A debug handler that aborts when called.
73_LIBCPP_NORETURN _LIBCPP_FUNC_VIS
74void __libcpp_abort_debug_function(__libcpp_debug_info const&);
75
Eric Fiselierfb825432016-12-28 04:58:52 +000076/// __libcpp_set_debug_function - Set the debug handler to the specified
77/// function.
78_LIBCPP_FUNC_VIS
79bool __libcpp_set_debug_function(__libcpp_debug_function_type __func);
80
Louis Dionneba400782020-10-02 15:02:52 -040081#if _LIBCPP_DEBUG_LEVEL == 2 || defined(_LIBCPP_BUILDING_LIBRARY)
Eric Fiselierfb825432016-12-28 04:58:52 +000082
Howard Hinnant8331b762013-03-06 23:30:19 +000083struct _LIBCPP_TYPE_VIS __c_node;
Howard Hinnant27e0e772011-09-14 18:33:51 +000084
Howard Hinnant8331b762013-03-06 23:30:19 +000085struct _LIBCPP_TYPE_VIS __i_node
Howard Hinnant27e0e772011-09-14 18:33:51 +000086{
87 void* __i_;
88 __i_node* __next_;
89 __c_node* __c_;
90
Eric Fiselier2d8515f2017-01-06 20:58:25 +000091#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant27e0e772011-09-14 18:33:51 +000092 __i_node(const __i_node&) = delete;
93 __i_node& operator=(const __i_node&) = delete;
Howard Hinnant8ea98242013-08-23 17:37:05 +000094#else
95private:
96 __i_node(const __i_node&);
97 __i_node& operator=(const __i_node&);
98public:
99#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000100 _LIBCPP_INLINE_VISIBILITY
101 __i_node(void* __i, __i_node* __next, __c_node* __c)
102 : __i_(__i), __next_(__next), __c_(__c) {}
103 ~__i_node();
104};
105
Howard Hinnant8331b762013-03-06 23:30:19 +0000106struct _LIBCPP_TYPE_VIS __c_node
Howard Hinnant27e0e772011-09-14 18:33:51 +0000107{
108 void* __c_;
109 __c_node* __next_;
110 __i_node** beg_;
111 __i_node** end_;
112 __i_node** cap_;
113
Eric Fiselier2d8515f2017-01-06 20:58:25 +0000114#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant27e0e772011-09-14 18:33:51 +0000115 __c_node(const __c_node&) = delete;
116 __c_node& operator=(const __c_node&) = delete;
Howard Hinnant8ea98242013-08-23 17:37:05 +0000117#else
118private:
119 __c_node(const __c_node&);
120 __c_node& operator=(const __c_node&);
121public:
122#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000123 _LIBCPP_INLINE_VISIBILITY
124 __c_node(void* __c, __c_node* __next)
125 : __c_(__c), __next_(__next), beg_(nullptr), end_(nullptr), cap_(nullptr) {}
126 virtual ~__c_node();
127
128 virtual bool __dereferenceable(const void*) const = 0;
129 virtual bool __decrementable(const void*) const = 0;
130 virtual bool __addable(const void*, ptrdiff_t) const = 0;
131 virtual bool __subscriptable(const void*, ptrdiff_t) const = 0;
132
Howard Hinnantb399c602011-09-27 23:55:03 +0000133 void __add(__i_node* __i);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000134 _LIBCPP_HIDDEN void __remove(__i_node* __i);
135};
136
137template <class _Cont>
138struct _C_node
139 : public __c_node
140{
141 _C_node(void* __c, __c_node* __n)
142 : __c_node(__c, __n) {}
143
144 virtual bool __dereferenceable(const void*) const;
145 virtual bool __decrementable(const void*) const;
146 virtual bool __addable(const void*, ptrdiff_t) const;
147 virtual bool __subscriptable(const void*, ptrdiff_t) const;
148};
149
150template <class _Cont>
Eric Fiselierfb825432016-12-28 04:58:52 +0000151inline bool
Howard Hinnant27e0e772011-09-14 18:33:51 +0000152_C_node<_Cont>::__dereferenceable(const void* __i) const
153{
154 typedef typename _Cont::const_iterator iterator;
155 const iterator* __j = static_cast<const iterator*>(__i);
Howard Hinnantc834c512011-11-29 18:15:50 +0000156 _Cont* _Cp = static_cast<_Cont*>(__c_);
157 return _Cp->__dereferenceable(__j);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000158}
159
160template <class _Cont>
Eric Fiselierfb825432016-12-28 04:58:52 +0000161inline bool
Howard Hinnant27e0e772011-09-14 18:33:51 +0000162_C_node<_Cont>::__decrementable(const void* __i) const
163{
164 typedef typename _Cont::const_iterator iterator;
165 const iterator* __j = static_cast<const iterator*>(__i);
Howard Hinnantc834c512011-11-29 18:15:50 +0000166 _Cont* _Cp = static_cast<_Cont*>(__c_);
167 return _Cp->__decrementable(__j);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000168}
169
170template <class _Cont>
Eric Fiselierfb825432016-12-28 04:58:52 +0000171inline bool
Howard Hinnant27e0e772011-09-14 18:33:51 +0000172_C_node<_Cont>::__addable(const void* __i, ptrdiff_t __n) const
173{
174 typedef typename _Cont::const_iterator iterator;
175 const iterator* __j = static_cast<const iterator*>(__i);
Howard Hinnantc834c512011-11-29 18:15:50 +0000176 _Cont* _Cp = static_cast<_Cont*>(__c_);
177 return _Cp->__addable(__j, __n);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000178}
179
180template <class _Cont>
Eric Fiselierfb825432016-12-28 04:58:52 +0000181inline bool
Howard Hinnant27e0e772011-09-14 18:33:51 +0000182_C_node<_Cont>::__subscriptable(const void* __i, ptrdiff_t __n) const
183{
184 typedef typename _Cont::const_iterator iterator;
185 const iterator* __j = static_cast<const iterator*>(__i);
Howard Hinnantc834c512011-11-29 18:15:50 +0000186 _Cont* _Cp = static_cast<_Cont*>(__c_);
187 return _Cp->__subscriptable(__j, __n);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000188}
189
Howard Hinnant8331b762013-03-06 23:30:19 +0000190class _LIBCPP_TYPE_VIS __libcpp_db
Howard Hinnant27e0e772011-09-14 18:33:51 +0000191{
192 __c_node** __cbeg_;
193 __c_node** __cend_;
194 size_t __csz_;
195 __i_node** __ibeg_;
196 __i_node** __iend_;
197 size_t __isz_;
198
199 __libcpp_db();
200public:
Eric Fiselier2d8515f2017-01-06 20:58:25 +0000201#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant27e0e772011-09-14 18:33:51 +0000202 __libcpp_db(const __libcpp_db&) = delete;
203 __libcpp_db& operator=(const __libcpp_db&) = delete;
Howard Hinnant8ea98242013-08-23 17:37:05 +0000204#else
205private:
206 __libcpp_db(const __libcpp_db&);
207 __libcpp_db& operator=(const __libcpp_db&);
208public:
209#endif
Howard Hinnant27e0e772011-09-14 18:33:51 +0000210 ~__libcpp_db();
211
212 class __db_c_iterator;
213 class __db_c_const_iterator;
214 class __db_i_iterator;
215 class __db_i_const_iterator;
216
217 __db_c_const_iterator __c_end() const;
218 __db_i_const_iterator __i_end() const;
219
Eric Fiselieraed4eab2019-03-05 02:10:31 +0000220 typedef __c_node*(_InsertConstruct)(void*, void*, __c_node*);
221
222 template <class _Cont>
223 _LIBCPP_INLINE_VISIBILITY static __c_node* __create_C_node(void *__mem, void *__c, __c_node *__next) {
Arthur O'Dwyer0c4472a2020-12-11 20:30:28 -0500224 return ::new (__mem) _C_node<_Cont>(__c, __next);
Eric Fiselieraed4eab2019-03-05 02:10:31 +0000225 }
226
Howard Hinnant27e0e772011-09-14 18:33:51 +0000227 template <class _Cont>
228 _LIBCPP_INLINE_VISIBILITY
229 void __insert_c(_Cont* __c)
230 {
Eric Fiselieraed4eab2019-03-05 02:10:31 +0000231 __insert_c(static_cast<void*>(__c), &__create_C_node<_Cont>);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000232 }
233
Howard Hinnantc90aa632011-09-16 19:52:23 +0000234 void __insert_i(void* __i);
Eric Fiselieraed4eab2019-03-05 02:10:31 +0000235 void __insert_c(void* __c, _InsertConstruct* __fn);
Howard Hinnant27e0e772011-09-14 18:33:51 +0000236 void __erase_c(void* __c);
237
238 void __insert_ic(void* __i, const void* __c);
239 void __iterator_copy(void* __i, const void* __i0);
240 void __erase_i(void* __i);
241
242 void* __find_c_from_i(void* __i) const;
243 void __invalidate_all(void* __c);
244 __c_node* __find_c_and_lock(void* __c) const;
Howard Hinnantb399c602011-09-27 23:55:03 +0000245 __c_node* __find_c(void* __c) const;
Howard Hinnant27e0e772011-09-14 18:33:51 +0000246 void unlock() const;
247
248 void swap(void* __c1, void* __c2);
249
250
251 bool __dereferenceable(const void* __i) const;
252 bool __decrementable(const void* __i) const;
253 bool __addable(const void* __i, ptrdiff_t __n) const;
254 bool __subscriptable(const void* __i, ptrdiff_t __n) const;
Howard Hinnante6ff0b62013-08-02 00:26:35 +0000255 bool __less_than_comparable(const void* __i, const void* __j) const;
Howard Hinnant27e0e772011-09-14 18:33:51 +0000256private:
257 _LIBCPP_HIDDEN
258 __i_node* __insert_iterator(void* __i);
259 _LIBCPP_HIDDEN
260 __i_node* __find_iterator(const void* __i) const;
261
Howard Hinnant8331b762013-03-06 23:30:19 +0000262 friend _LIBCPP_FUNC_VIS __libcpp_db* __get_db();
Howard Hinnant27e0e772011-09-14 18:33:51 +0000263};
264
Howard Hinnant8331b762013-03-06 23:30:19 +0000265_LIBCPP_FUNC_VIS __libcpp_db* __get_db();
266_LIBCPP_FUNC_VIS const __libcpp_db* __get_const_db();
Howard Hinnant27e0e772011-09-14 18:33:51 +0000267
268
Louis Dionneba400782020-10-02 15:02:52 -0400269#endif // _LIBCPP_DEBUG_LEVEL == 2 || defined(_LIBCPP_BUILDING_LIBRARY)
Howard Hinnant27e0e772011-09-14 18:33:51 +0000270
Eric Fiselierfb825432016-12-28 04:58:52 +0000271_LIBCPP_END_NAMESPACE_STD
Howard Hinnanta47c6d52011-09-16 17:29:17 +0000272
Howard Hinnant27e0e772011-09-14 18:33:51 +0000273#endif // _LIBCPP_DEBUG_H