tree.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. /* $NetBSD: tree.h,v 1.8 2004/03/28 19:38:30 provos Exp $ */
  2. /* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */
  3. /* $FreeBSD$ */
  4. /*-
  5. * Copyright 2002 Niels Provos <provos@citi.umich.edu>
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. #pragma once
  29. /*
  30. * This file defines data structures for red-black trees.
  31. *
  32. * A red-black tree is a binary search tree with the node color as an
  33. * extra attribute. It fulfills a set of conditions:
  34. * - every search path from the root to a leaf consists of the
  35. * same number of black nodes,
  36. * - each red node (except for the root) has a black parent,
  37. * - each leaf node is black.
  38. *
  39. * Every operation on a red-black tree is bounded as O(lg n).
  40. * The maximum height of a red-black tree is 2lg (n+1).
  41. */
  42. namespace Common {
  43. template <typename T>
  44. class RBHead {
  45. public:
  46. [[nodiscard]] T* Root() {
  47. return rbh_root;
  48. }
  49. [[nodiscard]] const T* Root() const {
  50. return rbh_root;
  51. }
  52. void SetRoot(T* root) {
  53. rbh_root = root;
  54. }
  55. [[nodiscard]] bool IsEmpty() const {
  56. return Root() == nullptr;
  57. }
  58. private:
  59. T* rbh_root = nullptr;
  60. };
  61. enum class EntryColor {
  62. Black,
  63. Red,
  64. };
  65. template <typename T>
  66. class RBEntry {
  67. public:
  68. [[nodiscard]] T* Left() {
  69. return rbe_left;
  70. }
  71. [[nodiscard]] const T* Left() const {
  72. return rbe_left;
  73. }
  74. void SetLeft(T* left) {
  75. rbe_left = left;
  76. }
  77. [[nodiscard]] T* Right() {
  78. return rbe_right;
  79. }
  80. [[nodiscard]] const T* Right() const {
  81. return rbe_right;
  82. }
  83. void SetRight(T* right) {
  84. rbe_right = right;
  85. }
  86. [[nodiscard]] T* Parent() {
  87. return rbe_parent;
  88. }
  89. [[nodiscard]] const T* Parent() const {
  90. return rbe_parent;
  91. }
  92. void SetParent(T* parent) {
  93. rbe_parent = parent;
  94. }
  95. [[nodiscard]] bool IsBlack() const {
  96. return rbe_color == EntryColor::Black;
  97. }
  98. [[nodiscard]] bool IsRed() const {
  99. return rbe_color == EntryColor::Red;
  100. }
  101. [[nodiscard]] EntryColor Color() const {
  102. return rbe_color;
  103. }
  104. void SetColor(EntryColor color) {
  105. rbe_color = color;
  106. }
  107. private:
  108. T* rbe_left = nullptr;
  109. T* rbe_right = nullptr;
  110. T* rbe_parent = nullptr;
  111. EntryColor rbe_color{};
  112. };
  113. template <typename Node>
  114. [[nodiscard]] RBEntry<Node>& RB_ENTRY(Node* node) {
  115. return node->GetEntry();
  116. }
  117. template <typename Node>
  118. [[nodiscard]] const RBEntry<Node>& RB_ENTRY(const Node* node) {
  119. return node->GetEntry();
  120. }
  121. template <typename Node>
  122. [[nodiscard]] Node* RB_PARENT(Node* node) {
  123. return RB_ENTRY(node).Parent();
  124. }
  125. template <typename Node>
  126. [[nodiscard]] const Node* RB_PARENT(const Node* node) {
  127. return RB_ENTRY(node).Parent();
  128. }
  129. template <typename Node>
  130. void RB_SET_PARENT(Node* node, Node* parent) {
  131. return RB_ENTRY(node).SetParent(parent);
  132. }
  133. template <typename Node>
  134. [[nodiscard]] Node* RB_LEFT(Node* node) {
  135. return RB_ENTRY(node).Left();
  136. }
  137. template <typename Node>
  138. [[nodiscard]] const Node* RB_LEFT(const Node* node) {
  139. return RB_ENTRY(node).Left();
  140. }
  141. template <typename Node>
  142. void RB_SET_LEFT(Node* node, Node* left) {
  143. return RB_ENTRY(node).SetLeft(left);
  144. }
  145. template <typename Node>
  146. [[nodiscard]] Node* RB_RIGHT(Node* node) {
  147. return RB_ENTRY(node).Right();
  148. }
  149. template <typename Node>
  150. [[nodiscard]] const Node* RB_RIGHT(const Node* node) {
  151. return RB_ENTRY(node).Right();
  152. }
  153. template <typename Node>
  154. void RB_SET_RIGHT(Node* node, Node* right) {
  155. return RB_ENTRY(node).SetRight(right);
  156. }
  157. template <typename Node>
  158. [[nodiscard]] bool RB_IS_BLACK(const Node* node) {
  159. return RB_ENTRY(node).IsBlack();
  160. }
  161. template <typename Node>
  162. [[nodiscard]] bool RB_IS_RED(const Node* node) {
  163. return RB_ENTRY(node).IsRed();
  164. }
  165. template <typename Node>
  166. [[nodiscard]] EntryColor RB_COLOR(const Node* node) {
  167. return RB_ENTRY(node).Color();
  168. }
  169. template <typename Node>
  170. void RB_SET_COLOR(Node* node, EntryColor color) {
  171. return RB_ENTRY(node).SetColor(color);
  172. }
  173. template <typename Node>
  174. void RB_SET(Node* node, Node* parent) {
  175. auto& entry = RB_ENTRY(node);
  176. entry.SetParent(parent);
  177. entry.SetLeft(nullptr);
  178. entry.SetRight(nullptr);
  179. entry.SetColor(EntryColor::Red);
  180. }
  181. template <typename Node>
  182. void RB_SET_BLACKRED(Node* black, Node* red) {
  183. RB_SET_COLOR(black, EntryColor::Black);
  184. RB_SET_COLOR(red, EntryColor::Red);
  185. }
  186. template <typename Node>
  187. void RB_ROTATE_LEFT(RBHead<Node>* head, Node* elm, Node*& tmp) {
  188. tmp = RB_RIGHT(elm);
  189. RB_SET_RIGHT(elm, RB_LEFT(tmp));
  190. if (RB_RIGHT(elm) != nullptr) {
  191. RB_SET_PARENT(RB_LEFT(tmp), elm);
  192. }
  193. RB_SET_PARENT(tmp, RB_PARENT(elm));
  194. if (RB_PARENT(tmp) != nullptr) {
  195. if (elm == RB_LEFT(RB_PARENT(elm))) {
  196. RB_SET_LEFT(RB_PARENT(elm), tmp);
  197. } else {
  198. RB_SET_RIGHT(RB_PARENT(elm), tmp);
  199. }
  200. } else {
  201. head->SetRoot(tmp);
  202. }
  203. RB_SET_LEFT(tmp, elm);
  204. RB_SET_PARENT(elm, tmp);
  205. }
  206. template <typename Node>
  207. void RB_ROTATE_RIGHT(RBHead<Node>* head, Node* elm, Node*& tmp) {
  208. tmp = RB_LEFT(elm);
  209. RB_SET_LEFT(elm, RB_RIGHT(tmp));
  210. if (RB_LEFT(elm) != nullptr) {
  211. RB_SET_PARENT(RB_RIGHT(tmp), elm);
  212. }
  213. RB_SET_PARENT(tmp, RB_PARENT(elm));
  214. if (RB_PARENT(tmp) != nullptr) {
  215. if (elm == RB_LEFT(RB_PARENT(elm))) {
  216. RB_SET_LEFT(RB_PARENT(elm), tmp);
  217. } else {
  218. RB_SET_RIGHT(RB_PARENT(elm), tmp);
  219. }
  220. } else {
  221. head->SetRoot(tmp);
  222. }
  223. RB_SET_RIGHT(tmp, elm);
  224. RB_SET_PARENT(elm, tmp);
  225. }
  226. template <typename Node>
  227. void RB_INSERT_COLOR(RBHead<Node>* head, Node* elm) {
  228. Node* parent = nullptr;
  229. Node* tmp = nullptr;
  230. while ((parent = RB_PARENT(elm)) != nullptr && RB_IS_RED(parent)) {
  231. Node* gparent = RB_PARENT(parent);
  232. if (parent == RB_LEFT(gparent)) {
  233. tmp = RB_RIGHT(gparent);
  234. if (tmp && RB_IS_RED(tmp)) {
  235. RB_SET_COLOR(tmp, EntryColor::Black);
  236. RB_SET_BLACKRED(parent, gparent);
  237. elm = gparent;
  238. continue;
  239. }
  240. if (RB_RIGHT(parent) == elm) {
  241. RB_ROTATE_LEFT(head, parent, tmp);
  242. tmp = parent;
  243. parent = elm;
  244. elm = tmp;
  245. }
  246. RB_SET_BLACKRED(parent, gparent);
  247. RB_ROTATE_RIGHT(head, gparent, tmp);
  248. } else {
  249. tmp = RB_LEFT(gparent);
  250. if (tmp && RB_IS_RED(tmp)) {
  251. RB_SET_COLOR(tmp, EntryColor::Black);
  252. RB_SET_BLACKRED(parent, gparent);
  253. elm = gparent;
  254. continue;
  255. }
  256. if (RB_LEFT(parent) == elm) {
  257. RB_ROTATE_RIGHT(head, parent, tmp);
  258. tmp = parent;
  259. parent = elm;
  260. elm = tmp;
  261. }
  262. RB_SET_BLACKRED(parent, gparent);
  263. RB_ROTATE_LEFT(head, gparent, tmp);
  264. }
  265. }
  266. RB_SET_COLOR(head->Root(), EntryColor::Black);
  267. }
  268. template <typename Node>
  269. void RB_REMOVE_COLOR(RBHead<Node>* head, Node* parent, Node* elm) {
  270. Node* tmp;
  271. while ((elm == nullptr || RB_IS_BLACK(elm)) && elm != head->Root()) {
  272. if (RB_LEFT(parent) == elm) {
  273. tmp = RB_RIGHT(parent);
  274. if (RB_IS_RED(tmp)) {
  275. RB_SET_BLACKRED(tmp, parent);
  276. RB_ROTATE_LEFT(head, parent, tmp);
  277. tmp = RB_RIGHT(parent);
  278. }
  279. if ((RB_LEFT(tmp) == nullptr || RB_IS_BLACK(RB_LEFT(tmp))) &&
  280. (RB_RIGHT(tmp) == nullptr || RB_IS_BLACK(RB_RIGHT(tmp)))) {
  281. RB_SET_COLOR(tmp, EntryColor::Red);
  282. elm = parent;
  283. parent = RB_PARENT(elm);
  284. } else {
  285. if (RB_RIGHT(tmp) == nullptr || RB_IS_BLACK(RB_RIGHT(tmp))) {
  286. Node* oleft;
  287. if ((oleft = RB_LEFT(tmp)) != nullptr) {
  288. RB_SET_COLOR(oleft, EntryColor::Black);
  289. }
  290. RB_SET_COLOR(tmp, EntryColor::Red);
  291. RB_ROTATE_RIGHT(head, tmp, oleft);
  292. tmp = RB_RIGHT(parent);
  293. }
  294. RB_SET_COLOR(tmp, RB_COLOR(parent));
  295. RB_SET_COLOR(parent, EntryColor::Black);
  296. if (RB_RIGHT(tmp)) {
  297. RB_SET_COLOR(RB_RIGHT(tmp), EntryColor::Black);
  298. }
  299. RB_ROTATE_LEFT(head, parent, tmp);
  300. elm = head->Root();
  301. break;
  302. }
  303. } else {
  304. tmp = RB_LEFT(parent);
  305. if (RB_IS_RED(tmp)) {
  306. RB_SET_BLACKRED(tmp, parent);
  307. RB_ROTATE_RIGHT(head, parent, tmp);
  308. tmp = RB_LEFT(parent);
  309. }
  310. if ((RB_LEFT(tmp) == nullptr || RB_IS_BLACK(RB_LEFT(tmp))) &&
  311. (RB_RIGHT(tmp) == nullptr || RB_IS_BLACK(RB_RIGHT(tmp)))) {
  312. RB_SET_COLOR(tmp, EntryColor::Red);
  313. elm = parent;
  314. parent = RB_PARENT(elm);
  315. } else {
  316. if (RB_LEFT(tmp) == nullptr || RB_IS_BLACK(RB_LEFT(tmp))) {
  317. Node* oright;
  318. if ((oright = RB_RIGHT(tmp)) != nullptr) {
  319. RB_SET_COLOR(oright, EntryColor::Black);
  320. }
  321. RB_SET_COLOR(tmp, EntryColor::Red);
  322. RB_ROTATE_LEFT(head, tmp, oright);
  323. tmp = RB_LEFT(parent);
  324. }
  325. RB_SET_COLOR(tmp, RB_COLOR(parent));
  326. RB_SET_COLOR(parent, EntryColor::Black);
  327. if (RB_LEFT(tmp)) {
  328. RB_SET_COLOR(RB_LEFT(tmp), EntryColor::Black);
  329. }
  330. RB_ROTATE_RIGHT(head, parent, tmp);
  331. elm = head->Root();
  332. break;
  333. }
  334. }
  335. }
  336. if (elm) {
  337. RB_SET_COLOR(elm, EntryColor::Black);
  338. }
  339. }
  340. template <typename Node>
  341. Node* RB_REMOVE(RBHead<Node>* head, Node* elm) {
  342. Node* child = nullptr;
  343. Node* parent = nullptr;
  344. Node* old = elm;
  345. EntryColor color{};
  346. const auto finalize = [&] {
  347. if (color == EntryColor::Black) {
  348. RB_REMOVE_COLOR(head, parent, child);
  349. }
  350. return old;
  351. };
  352. if (RB_LEFT(elm) == nullptr) {
  353. child = RB_RIGHT(elm);
  354. } else if (RB_RIGHT(elm) == nullptr) {
  355. child = RB_LEFT(elm);
  356. } else {
  357. Node* left;
  358. elm = RB_RIGHT(elm);
  359. while ((left = RB_LEFT(elm)) != nullptr) {
  360. elm = left;
  361. }
  362. child = RB_RIGHT(elm);
  363. parent = RB_PARENT(elm);
  364. color = RB_COLOR(elm);
  365. if (child) {
  366. RB_SET_PARENT(child, parent);
  367. }
  368. if (parent) {
  369. if (RB_LEFT(parent) == elm) {
  370. RB_SET_LEFT(parent, child);
  371. } else {
  372. RB_SET_RIGHT(parent, child);
  373. }
  374. } else {
  375. head->SetRoot(child);
  376. }
  377. if (RB_PARENT(elm) == old) {
  378. parent = elm;
  379. }
  380. elm->SetEntry(old->GetEntry());
  381. if (RB_PARENT(old)) {
  382. if (RB_LEFT(RB_PARENT(old)) == old) {
  383. RB_SET_LEFT(RB_PARENT(old), elm);
  384. } else {
  385. RB_SET_RIGHT(RB_PARENT(old), elm);
  386. }
  387. } else {
  388. head->SetRoot(elm);
  389. }
  390. RB_SET_PARENT(RB_LEFT(old), elm);
  391. if (RB_RIGHT(old)) {
  392. RB_SET_PARENT(RB_RIGHT(old), elm);
  393. }
  394. if (parent) {
  395. left = parent;
  396. }
  397. return finalize();
  398. }
  399. parent = RB_PARENT(elm);
  400. color = RB_COLOR(elm);
  401. if (child) {
  402. RB_SET_PARENT(child, parent);
  403. }
  404. if (parent) {
  405. if (RB_LEFT(parent) == elm) {
  406. RB_SET_LEFT(parent, child);
  407. } else {
  408. RB_SET_RIGHT(parent, child);
  409. }
  410. } else {
  411. head->SetRoot(child);
  412. }
  413. return finalize();
  414. }
  415. // Inserts a node into the RB tree
  416. template <typename Node, typename CompareFunction>
  417. Node* RB_INSERT(RBHead<Node>* head, Node* elm, CompareFunction cmp) {
  418. Node* parent = nullptr;
  419. Node* tmp = head->Root();
  420. int comp = 0;
  421. while (tmp) {
  422. parent = tmp;
  423. comp = cmp(elm, parent);
  424. if (comp < 0) {
  425. tmp = RB_LEFT(tmp);
  426. } else if (comp > 0) {
  427. tmp = RB_RIGHT(tmp);
  428. } else {
  429. return tmp;
  430. }
  431. }
  432. RB_SET(elm, parent);
  433. if (parent != nullptr) {
  434. if (comp < 0) {
  435. RB_SET_LEFT(parent, elm);
  436. } else {
  437. RB_SET_RIGHT(parent, elm);
  438. }
  439. } else {
  440. head->SetRoot(elm);
  441. }
  442. RB_INSERT_COLOR(head, elm);
  443. return nullptr;
  444. }
  445. // Finds the node with the same key as elm
  446. template <typename Node, typename CompareFunction>
  447. Node* RB_FIND(RBHead<Node>* head, Node* elm, CompareFunction cmp) {
  448. Node* tmp = head->Root();
  449. while (tmp) {
  450. const int comp = cmp(elm, tmp);
  451. if (comp < 0) {
  452. tmp = RB_LEFT(tmp);
  453. } else if (comp > 0) {
  454. tmp = RB_RIGHT(tmp);
  455. } else {
  456. return tmp;
  457. }
  458. }
  459. return nullptr;
  460. }
  461. // Finds the first node greater than or equal to the search key
  462. template <typename Node, typename CompareFunction>
  463. Node* RB_NFIND(RBHead<Node>* head, Node* elm, CompareFunction cmp) {
  464. Node* tmp = head->Root();
  465. Node* res = nullptr;
  466. while (tmp) {
  467. const int comp = cmp(elm, tmp);
  468. if (comp < 0) {
  469. res = tmp;
  470. tmp = RB_LEFT(tmp);
  471. } else if (comp > 0) {
  472. tmp = RB_RIGHT(tmp);
  473. } else {
  474. return tmp;
  475. }
  476. }
  477. return res;
  478. }
  479. // Finds the node with the same key as lelm
  480. template <typename Node, typename CompareFunction>
  481. Node* RB_FIND_LIGHT(RBHead<Node>* head, const void* lelm, CompareFunction lcmp) {
  482. Node* tmp = head->Root();
  483. while (tmp) {
  484. const int comp = lcmp(lelm, tmp);
  485. if (comp < 0) {
  486. tmp = RB_LEFT(tmp);
  487. } else if (comp > 0) {
  488. tmp = RB_RIGHT(tmp);
  489. } else {
  490. return tmp;
  491. }
  492. }
  493. return nullptr;
  494. }
  495. // Finds the first node greater than or equal to the search key
  496. template <typename Node, typename CompareFunction>
  497. Node* RB_NFIND_LIGHT(RBHead<Node>* head, const void* lelm, CompareFunction lcmp) {
  498. Node* tmp = head->Root();
  499. Node* res = nullptr;
  500. while (tmp) {
  501. const int comp = lcmp(lelm, tmp);
  502. if (comp < 0) {
  503. res = tmp;
  504. tmp = RB_LEFT(tmp);
  505. } else if (comp > 0) {
  506. tmp = RB_RIGHT(tmp);
  507. } else {
  508. return tmp;
  509. }
  510. }
  511. return res;
  512. }
  513. template <typename Node>
  514. Node* RB_NEXT(Node* elm) {
  515. if (RB_RIGHT(elm)) {
  516. elm = RB_RIGHT(elm);
  517. while (RB_LEFT(elm)) {
  518. elm = RB_LEFT(elm);
  519. }
  520. } else {
  521. if (RB_PARENT(elm) && (elm == RB_LEFT(RB_PARENT(elm)))) {
  522. elm = RB_PARENT(elm);
  523. } else {
  524. while (RB_PARENT(elm) && (elm == RB_RIGHT(RB_PARENT(elm)))) {
  525. elm = RB_PARENT(elm);
  526. }
  527. elm = RB_PARENT(elm);
  528. }
  529. }
  530. return elm;
  531. }
  532. template <typename Node>
  533. Node* RB_PREV(Node* elm) {
  534. if (RB_LEFT(elm)) {
  535. elm = RB_LEFT(elm);
  536. while (RB_RIGHT(elm)) {
  537. elm = RB_RIGHT(elm);
  538. }
  539. } else {
  540. if (RB_PARENT(elm) && (elm == RB_RIGHT(RB_PARENT(elm)))) {
  541. elm = RB_PARENT(elm);
  542. } else {
  543. while (RB_PARENT(elm) && (elm == RB_LEFT(RB_PARENT(elm)))) {
  544. elm = RB_PARENT(elm);
  545. }
  546. elm = RB_PARENT(elm);
  547. }
  548. }
  549. return elm;
  550. }
  551. template <typename Node>
  552. Node* RB_MINMAX(RBHead<Node>* head, bool is_min) {
  553. Node* tmp = head->Root();
  554. Node* parent = nullptr;
  555. while (tmp) {
  556. parent = tmp;
  557. if (is_min) {
  558. tmp = RB_LEFT(tmp);
  559. } else {
  560. tmp = RB_RIGHT(tmp);
  561. }
  562. }
  563. return parent;
  564. }
  565. template <typename Node>
  566. Node* RB_MIN(RBHead<Node>* head) {
  567. return RB_MINMAX(head, true);
  568. }
  569. template <typename Node>
  570. Node* RB_MAX(RBHead<Node>* head) {
  571. return RB_MINMAX(head, false);
  572. }
  573. } // namespace Common