@@ -48,6 +48,7 @@ struct ${node} {
4848 * @dev Lookup the root element of the heap.
4949 */
5050function peek(${ struct } storage self) internal view returns (${ valueType } ) {
51+ // self.data[0] will \`ARRAY_ACCESS_OUT_OF_BOUNDS\` panic if heap is empty.
5152 return _unsafeNodeAccess(self, self.data[0].index).value;
5253}
5354
@@ -71,45 +72,46 @@ function pop(
7172 ${ struct } storage self,
7273 function(uint256, uint256) view returns (bool) comp
7374) internal returns (${ valueType } ) {
74- ${ indexType } size = length(self);
75-
76- if (size == 0) Panic.panic(Panic.EMPTY_ARRAY_POP);
75+ unchecked {
76+ ${ indexType } size = length(self);
77+ if (size == 0) Panic.panic(Panic.EMPTY_ARRAY_POP);
7778
78- ${ indexType } last = size - 1; // could be unchecked (check above)
79+ ${ indexType } last = size - 1;
7980
80- // get root location (in the data array) and value
81- ${ node } storage rootNode = _unsafeNodeAccess(self, 0);
82- ${ indexType } rootIdx = rootNode.index;
83- ${ node } storage rootData = _unsafeNodeAccess(self, rootIdx);
84- ${ node } storage lastNode = _unsafeNodeAccess(self, last);
85- ${ valueType } rootDataValue = rootData.value;
81+ // get root location (in the data array) and value
82+ ${ node } storage rootNode = _unsafeNodeAccess(self, 0);
83+ ${ indexType } rootIdx = rootNode.index;
84+ ${ node } storage rootData = _unsafeNodeAccess(self, rootIdx);
85+ ${ node } storage lastNode = _unsafeNodeAccess(self, last);
86+ ${ valueType } rootDataValue = rootData.value;
8687
87- // if root is not the last element of the data array (that will get pop-ed), reorder the data array.
88- if (rootIdx != last) {
89- // get details about the value stored in the last element of the array (that will get pop-ed)
90- ${ indexType } lastDataIdx = lastNode.lookup;
91- ${ valueType } lastDataValue = lastNode.value;
92- // copy these values to the location of the root (that is safe, and that we no longer use)
93- rootData.value = lastDataValue;
94- rootData.lookup = lastDataIdx;
95- // update the tree node that used to point to that last element (value now located where the root was)
96- _unsafeNodeAccess(self, lastDataIdx).index = rootIdx;
97- }
88+ // if root is not the last element of the data array (that will get pop-ed), reorder the data array.
89+ if (rootIdx != last) {
90+ // get details about the value stored in the last element of the array (that will get pop-ed)
91+ ${ indexType } lastDataIdx = lastNode.lookup;
92+ ${ valueType } lastDataValue = lastNode.value;
93+ // copy these values to the location of the root (that is safe, and that we no longer use)
94+ rootData.value = lastDataValue;
95+ rootData.lookup = lastDataIdx;
96+ // update the tree node that used to point to that last element (value now located where the root was)
97+ _unsafeNodeAccess(self, lastDataIdx).index = rootIdx;
98+ }
9899
99- // get last leaf location (in the data array) and value
100- ${ indexType } lastIdx = lastNode.index;
101- ${ valueType } lastValue = _unsafeNodeAccess(self, lastIdx).value;
100+ // get last leaf location (in the data array) and value
101+ ${ indexType } lastIdx = lastNode.index;
102+ ${ valueType } lastValue = _unsafeNodeAccess(self, lastIdx).value;
102103
103- // move the last leaf to the root, pop last leaf ...
104- rootNode.index = lastIdx;
105- _unsafeNodeAccess(self, lastIdx).lookup = 0;
106- self.data.pop();
104+ // move the last leaf to the root, pop last leaf ...
105+ rootNode.index = lastIdx;
106+ _unsafeNodeAccess(self, lastIdx).lookup = 0;
107+ self.data.pop();
107108
108- // ... and heapify
109- _siftDown(self, last, 0, lastValue, comp);
109+ // ... and heapify
110+ _siftDown(self, last, 0, lastValue, comp);
110111
111- // return root value
112- return rootDataValue;
112+ // return root value
113+ return rootDataValue;
114+ }
113115}
114116
115117/**
@@ -134,9 +136,8 @@ function insert(
134136 function(uint256, uint256) view returns (bool) comp
135137) internal {
136138 ${ indexType } size = length(self);
137- if (size == type(${ indexType } ).max) {
138- Panic.panic(Panic.RESOURCE_ERROR);
139- }
139+ if (size == type(${ indexType } ).max) Panic.panic(Panic.RESOURCE_ERROR);
140+
140141 self.data.push(${ struct } Node({index: size, lookup: size, value: value}));
141142 _siftUp(self, size, value, comp);
142143}
0 commit comments