Panda3D
linkedListNode.I
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file linkedListNode.I
10  * @author drose
11  * @date 2006-03-16
12  */
13 
14 /**
15  *
16  */
17 INLINE LinkedListNode::
18 LinkedListNode() {
19 #ifndef NDEBUG
20  _next = nullptr;
21  _prev = nullptr;
22 #endif
23 }
24 
25 /**
26  * This constructor should be invoked for any LinkedListNodes that will be
27  * used to serve as the root of a list. It sets up the pointers as an empty
28  * list.
29  */
30 INLINE LinkedListNode::
31 LinkedListNode(bool) {
32  _next = this;
33  _prev = this;
34 }
35 
36 /**
37  * This move constructor replaces the other link with this one.
38  */
39 INLINE LinkedListNode::
40 LinkedListNode(LinkedListNode &&from) noexcept {
41  if (from._prev != nullptr) {
42  nassertv(from._prev->_next == &from);
43  from._prev->_next = this;
44  }
45  _prev = from._prev;
46  if (from._next != nullptr) {
47  nassertv(from._next->_prev == &from);
48  from._next->_prev = this;
49  }
50  _next = from._next;
51  from._next = nullptr;
52  from._prev = nullptr;
53 }
54 
55 /**
56  *
57  */
58 INLINE LinkedListNode::
59 ~LinkedListNode() {
60  nassertv((_next == nullptr && _prev == nullptr) || (_next == this && _prev == this));
61 }
62 
63 /**
64  * Replaces the given other node with this node.
65  */
66 INLINE LinkedListNode &LinkedListNode::
67 operator = (LinkedListNode &&from) {
68  nassertr((_next == nullptr && _prev == nullptr) || (_next == this && _prev == this), *this);
69  nassertr(from._prev != nullptr && from._next != nullptr, *this);
70  nassertr(from._prev->_next == &from && from._next->_prev == &from, *this);
71  from._prev->_next = this;
72  from._next->_prev = this;
73  _prev = from._prev;
74  _next = from._next;
75  from._next = nullptr;
76  from._prev = nullptr;
77  return *this;
78 }
79 
80 /**
81  * Returns true if the node is member of any list, false if it has been
82  * removed or never added. The head of a list generally appears to to always
83  * be a member of itself.
84  */
85 INLINE bool LinkedListNode::
86 is_on_list() const {
87  return (_next != nullptr);
88 }
89 
90 /**
91  * Removes a LinkedListNode record from the doubly-linked list.
92  */
93 INLINE void LinkedListNode::
94 remove_from_list() {
95  nassertv(_prev != nullptr && _next != nullptr);
96  nassertv(_prev->_next == this && _next->_prev == this);
97  _prev->_next = _next;
98  _next->_prev = _prev;
99 #ifndef NDEBUG
100  _next = nullptr;
101  _prev = nullptr;
102 #endif
103 }
104 
105 /**
106  * Adds a LinkedListNode record before the indicated node in the doubly-linked
107  * list.
108  */
109 INLINE void LinkedListNode::
110 insert_before(LinkedListNode *node) {
111  nassertv(node->_prev != nullptr && node->_prev->_next == node && node->_next->_prev == node);
112  nassertv(_prev == nullptr &&
113  _next == nullptr);
114  _prev = node->_prev;
115  _next = node;
116  _prev->_next = this;
117  node->_prev = this;
118 }
119 
120 /**
121  * Adds a LinkedListNode record after the indicated node in the doubly-linked
122  * list.
123  */
124 INLINE void LinkedListNode::
125 insert_after(LinkedListNode *node) {
126  nassertv(node->_prev != nullptr && node->_prev->_next == node && node->_next->_prev == node);
127  nassertv(_prev == nullptr &&
128  _next == nullptr);
129  _next = node->_next;
130  _prev = node;
131  _next->_prev = this;
132  node->_next = this;
133 }
134 
135 /**
136  * Given that this LinkedListNode represents the root of a list, and the other
137  * pointer represents the root of a different list, move all of the nodes
138  * (except the root itself) from other_root onto this list.
139  */
140 INLINE void LinkedListNode::
141 take_list_from(LinkedListNode *other_root) {
142  other_root->_next->_prev = _prev;
143  _prev->_next = other_root->_next;
144  other_root->_prev->_next = this;
145  _prev = other_root->_prev;
146 
147  other_root->_next = other_root;
148  other_root->_prev = other_root;
149 }
This just stores the pointers to implement a doubly-linked list of some kind of object.