|
47 | 47 | _LIBCPP_PUSH_MACROS
|
48 | 48 | #include <__undef_macros>
|
49 | 49 |
|
| 50 | +_LIBCPP_DIAGNOSTIC_PUSH |
| 51 | +// GCC complains about the backslashes at the end, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121528 |
| 52 | +_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wcomment") |
| 53 | +// __tree is a red-black-tree implementation used for the associative containers (i.e. (multi)map/set). It stores |
| 54 | +// - (1) a pointer to the node with the smallest (i.e. leftmost) element, namely __begin_node_ |
| 55 | +// - (2) the number of nodes in the tree, namely __size_ |
| 56 | +// - (3) a pointer to the root of the tree, namely __end_node_ |
| 57 | +// |
| 58 | +// Storing (1) and (2) is required to allow for constant time lookups. A tree looks like this in memory: |
| 59 | +// |
| 60 | +// __end_node_ |
| 61 | +// | |
| 62 | +// root |
| 63 | +// / \ |
| 64 | +// l1 r1 |
| 65 | +// / \ / \ |
| 66 | +// ... ... ... ... |
| 67 | +// |
| 68 | +// All nodes except __end_node_ have a __left_ and __right_ pointer as well as a __parent_ pointer. |
| 69 | +// __end_node_ only contains a __left_ pointer, which points to the root of the tree. |
| 70 | +// This layout allows for iteration through the tree without a need for special handling of the end node. See |
| 71 | +// __tree_next_iter and __tree_prev_iter for more details. |
| 72 | +_LIBCPP_DIAGNOSTIC_POP |
| 73 | + |
50 | 74 | _LIBCPP_BEGIN_NAMESPACE_STD
|
51 | 75 |
|
52 | 76 | template <class _Pointer>
|
@@ -167,6 +191,11 @@ _LIBCPP_HIDE_FROM_ABI _NodePtr __tree_next(_NodePtr __x) _NOEXCEPT {
|
167 | 191 | return __x->__parent_unsafe();
|
168 | 192 | }
|
169 | 193 |
|
| 194 | +// __tree_next_iter and __tree_prev_iter implement iteration through the tree. The order is as follows: |
| 195 | +// left sub-tree -> node -> right sub-tree. When the right-most node of a sub-tree is reached, we walk up the tree until |
| 196 | +// we find a node where we were in the left sub-tree. We are _always_ in a left sub-tree, since the __end_node_ points |
| 197 | +// to the actual root of the tree through a __left_ pointer. Incrementing the end() pointer is UB, so we can assume that |
| 198 | +// never happens. |
170 | 199 | template <class _EndNodePtr, class _NodePtr>
|
171 | 200 | inline _LIBCPP_HIDE_FROM_ABI _EndNodePtr __tree_next_iter(_NodePtr __x) _NOEXCEPT {
|
172 | 201 | _LIBCPP_ASSERT_INTERNAL(__x != nullptr, "node shouldn't be null");
|
|
0 commit comments