Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
intrusive_links.h
00001 ///\file 00002 00003 /****************************************************************************** 00004 The MIT License(MIT) 00005 00006 Embedded Template Library. 00007 https://github.com/ETLCPP/etl 00008 http://www.etlcpp.com 00009 00010 Copyright(c) 2016 jwellbelove 00011 00012 Permission is hereby granted, free of charge, to any person obtaining a copy 00013 of this software and associated documentation files(the "Software"), to deal 00014 in the Software without restriction, including without limitation the rights 00015 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 00016 copies of the Software, and to permit persons to whom the Software is 00017 furnished to do so, subject to the following conditions : 00018 00019 The above copyright notice and this permission notice shall be included in all 00020 copies or substantial portions of the Software. 00021 00022 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00023 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00024 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 00025 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00026 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00027 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00028 SOFTWARE. 00029 ******************************************************************************/ 00030 00031 #ifndef __ETL_INTRUSIVE_LINKS__ 00032 #define __ETL_INTRUSIVE_LINKS__ 00033 00034 #include <assert.h> 00035 #include <utility> 00036 00037 #include "platform.h " 00038 #include "nullptr.h " 00039 #include "type_traits.h " 00040 #include "exception.h " 00041 #include "error_handler.h " 00042 00043 #undef ETL_FILE 00044 #define ETL_FILE "22" 00045 00046 //***************************************************************************** 00047 // Note: 00048 // The link functions work slightly differently to the STL 'insert' convention 00049 // in that the second link parameter will be inserted after the first. 00050 // i.e. 00051 // If the list contains '1', '2', '3', '4' and "link_splice '2','5'" is invoked the 00052 // resulting list will contain '1', '2', '5', '3', '4' 00053 // This is to maintain consistency between forward and bidirectional links 00054 // and also is intuitive. 00055 //***************************************************************************** 00056 00057 namespace etl 00058 { 00059 //*************************************************************************** 00060 /// Link exception. 00061 //*************************************************************************** 00062 class link_exception : public etl::exception 00063 { 00064 public: 00065 00066 link_exception(string_type reason_, string_type file_name_, numeric_type line_number_) 00067 : exception(reason_, file_name_, line_number_) 00068 { 00069 } 00070 }; 00071 00072 //*************************************************************************** 00073 /// not unlinked exception. 00074 //*************************************************************************** 00075 class not_unlinked_exception : public etl::link_exception 00076 { 00077 public: 00078 00079 not_unlinked_exception(string_type file_name_, numeric_type line_number_) 00080 : link_exception(ETL_ERROR_TEXT("link:still linked", ETL_FILE"A"), file_name_, line_number_) 00081 { 00082 } 00083 }; 00084 00085 //*************************************************************************** 00086 /// A forward link. 00087 //*************************************************************************** 00088 template <const size_t ID_> 00089 struct forward_link 00090 { 00091 enum 00092 { 00093 ID = ID_, 00094 }; 00095 00096 void clear() 00097 { 00098 etl_next = std::nullptr; 00099 } 00100 00101 bool is_linked() const 00102 { 00103 return etl_next != std::nullptr; 00104 } 00105 00106 forward_link* etl_next; 00107 }; 00108 00109 // Reference, Reference 00110 template <typename TLink> 00111 typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type 00112 link(TLink& lhs, TLink& rhs) 00113 { 00114 lhs.etl_next = &rhs; 00115 } 00116 00117 // Reference, Reference 00118 template <typename TLink> 00119 typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type 00120 link_splice(TLink& lhs, TLink& rhs) 00121 { 00122 rhs.etl_next = lhs.etl_next; 00123 lhs.etl_next = &rhs; 00124 } 00125 00126 // Pointer, Pointer 00127 template <typename TLink> 00128 typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type 00129 link(TLink* lhs, TLink* rhs) 00130 { 00131 if (lhs != std::nullptr) 00132 { 00133 lhs->etl_next = rhs; 00134 } 00135 } 00136 00137 // Pointer, Pointer 00138 template <typename TLink> 00139 typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type 00140 link_splice(TLink* lhs, TLink* rhs) 00141 { 00142 if (lhs != std::nullptr) 00143 { 00144 if (rhs != std::nullptr) 00145 { 00146 rhs->etl_next = lhs->etl_next; 00147 } 00148 00149 lhs->etl_next = rhs; 00150 } 00151 } 00152 00153 // Reference, Pointer 00154 template <typename TLink> 00155 typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type 00156 link(TLink& lhs, TLink* rhs) 00157 { 00158 lhs.etl_next = rhs; 00159 } 00160 00161 // Reference, Pointer 00162 template <typename TLink> 00163 typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type 00164 link_splice(TLink& lhs, TLink* rhs) 00165 { 00166 if (rhs != std::nullptr) 00167 { 00168 rhs->etl_next = lhs.etl_next; 00169 } 00170 00171 lhs.etl_next = rhs; 00172 } 00173 00174 // Pointer, Reference 00175 template <typename TLink> 00176 typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type 00177 link(TLink* lhs, TLink& rhs) 00178 { 00179 if (lhs != std::nullptr) 00180 { 00181 lhs->etl_next = &rhs; 00182 } 00183 } 00184 00185 // Pointer, Reference 00186 template <typename TLink> 00187 typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type 00188 link_splice(TLink* lhs, TLink& rhs) 00189 { 00190 if (lhs != std::nullptr) 00191 { 00192 rhs.etl_next = lhs->etl_next; 00193 lhs->etl_next = &rhs; 00194 } 00195 } 00196 00197 // Reference, Reference, Reference 00198 template <typename TLink> 00199 typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type 00200 link_splice(TLink& lhs, TLink& first, TLink& last) 00201 { 00202 last.etl_next = lhs.etl_next; 00203 lhs.etl_next = &first; 00204 } 00205 00206 // Pointer, Reference, Reference 00207 template <typename TLink> 00208 typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type 00209 link_splice(TLink* lhs, TLink& first, TLink& last) 00210 { 00211 if (lhs != std::nullptr) 00212 { 00213 last.etl_next = lhs->etl_next; 00214 lhs->etl_next = &first; 00215 } 00216 else 00217 { 00218 last.etl_next = std::nullptr; 00219 } 00220 } 00221 00222 // Reference 00223 template <typename TLink> 00224 typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type 00225 unlink_after(TLink& node) 00226 { 00227 if (node.etl_next != std::nullptr) 00228 { 00229 TLink* unlinked_node = node.etl_next; 00230 node.etl_next = unlinked_node->etl_next; 00231 } 00232 } 00233 00234 // Reference, Reference 00235 template <typename TLink> 00236 typename etl::enable_if<etl::is_same<TLink, etl::forward_link<TLink::ID> >::value, void>::type 00237 unlink_after(TLink& before, TLink& last) 00238 { 00239 before.etl_next = last.etl_next; 00240 } 00241 00242 //*************************************************************************** 00243 /// A bidirectional link. 00244 //*************************************************************************** 00245 template <const size_t ID_> 00246 struct bidirectional_link 00247 { 00248 enum 00249 { 00250 ID = ID_, 00251 }; 00252 00253 void clear() 00254 { 00255 etl_previous = std::nullptr; 00256 etl_next = std::nullptr; 00257 } 00258 00259 bool is_linked() const 00260 { 00261 return (etl_previous != std::nullptr) || (etl_next != std::nullptr); 00262 } 00263 00264 void reverse() 00265 { 00266 std::swap(etl_previous, etl_next); 00267 } 00268 00269 bidirectional_link* etl_previous; 00270 bidirectional_link* etl_next; 00271 00272 void unlink() 00273 { 00274 // Connect the previous link with the next. 00275 if (etl_previous != std::nullptr) 00276 { 00277 etl_previous->etl_next = etl_next; 00278 } 00279 00280 // Connect the next link with the previous. 00281 if (etl_next != std::nullptr) 00282 { 00283 etl_next->etl_previous = etl_previous; 00284 } 00285 } 00286 }; 00287 00288 // Reference, Reference 00289 template <typename TLink> 00290 typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID> >::value, void>::type 00291 link(TLink& lhs, TLink& rhs) 00292 { 00293 lhs.etl_next = &rhs; 00294 rhs.etl_previous = &lhs; 00295 } 00296 00297 // Reference, Reference 00298 template <typename TLink> 00299 typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID> >::value, void>::type 00300 link_splice(TLink& lhs, TLink& rhs) 00301 { 00302 rhs.etl_next = lhs.etl_next; 00303 rhs.etl_previous = &lhs; 00304 00305 if (lhs.etl_next != std::nullptr) 00306 { 00307 lhs.etl_next->etl_previous = &rhs; 00308 } 00309 00310 lhs.etl_next = &rhs; 00311 } 00312 00313 // Pointer, Pointer 00314 template <typename TLink> 00315 typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID> >::value, void>::type 00316 link(TLink* lhs, TLink* rhs) 00317 { 00318 if (lhs != std::nullptr) 00319 { 00320 lhs->etl_next = rhs; 00321 } 00322 00323 if (rhs != std::nullptr) 00324 { 00325 rhs->etl_previous = lhs; 00326 } 00327 } 00328 00329 // Pointer, Pointer 00330 template <typename TLink> 00331 typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID> >::value, void>::type 00332 link_splice(TLink* lhs, TLink* rhs) 00333 { 00334 if (rhs != std::nullptr) 00335 { 00336 if (lhs != std::nullptr) 00337 { 00338 rhs->etl_next = lhs->etl_next; 00339 } 00340 00341 rhs->etl_previous = lhs; 00342 } 00343 00344 if (lhs != std::nullptr) 00345 { 00346 if (lhs->etl_next != std::nullptr) 00347 { 00348 lhs->etl_next->etl_previous = rhs; 00349 } 00350 00351 lhs->etl_next = rhs; 00352 } 00353 } 00354 00355 // Reference, Pointer 00356 template <typename TLink> 00357 typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID> >::value, void>::type 00358 link(TLink& lhs, TLink* rhs) 00359 { 00360 lhs.etl_next = rhs; 00361 00362 if (rhs != std::nullptr) 00363 { 00364 rhs->etl_previous = &lhs; 00365 } 00366 } 00367 00368 // Reference, Pointer 00369 template <typename TLink> 00370 typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID> >::value, void>::type 00371 link_splice(TLink& lhs, TLink* rhs) 00372 { 00373 if (rhs != std::nullptr) 00374 { 00375 rhs->etl_next = lhs.etl_next; 00376 rhs->etl_previous = &lhs; 00377 } 00378 00379 if (lhs.etl_next != std::nullptr) 00380 { 00381 lhs.etl_next->etl_previous = rhs; 00382 } 00383 00384 lhs.etl_next = rhs; 00385 } 00386 00387 // Pointer, Reference 00388 template <typename TLink> 00389 typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID> >::value, void>::type 00390 link(TLink* lhs, TLink& rhs) 00391 { 00392 if (lhs != std::nullptr) 00393 { 00394 lhs->etl_next = &rhs; 00395 } 00396 00397 rhs.etl_previous = lhs; 00398 } 00399 00400 // Pointer, Reference 00401 template <typename TLink> 00402 typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID> >::value, void>::type 00403 link_splice(TLink* lhs, TLink& rhs) 00404 { 00405 if (lhs != std::nullptr) 00406 { 00407 rhs.etl_next = lhs->etl_next; 00408 } 00409 00410 rhs.etl_previous = lhs; 00411 00412 if (lhs != std::nullptr) 00413 { 00414 if (lhs->etl_next != std::nullptr) 00415 { 00416 lhs->etl_next->etl_previous = &rhs; 00417 } 00418 00419 lhs->etl_next = &rhs; 00420 } 00421 } 00422 00423 // Reference, Reference, Reference 00424 template <typename TLink> 00425 typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID> >::value, void>::type 00426 link_splice(TLink& lhs, TLink& first, TLink& last) 00427 { 00428 last.etl_next = lhs.etl_next; 00429 first.etl_previous = &lhs; 00430 00431 if (last.etl_next != std::nullptr) 00432 { 00433 last.etl_next->etl_previous = &last; 00434 } 00435 00436 lhs.etl_next = &first; 00437 } 00438 00439 // Pointer, Reference, Reference 00440 template <typename TLink> 00441 typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID> >::value, void>::type 00442 link_splice(TLink* lhs, TLink& first, TLink& last) 00443 { 00444 if (lhs != std::nullptr) 00445 { 00446 last.etl_next = lhs->etl_next; 00447 } 00448 else 00449 { 00450 last.etl_next = std::nullptr; 00451 } 00452 00453 first.etl_previous = lhs; 00454 00455 if (last.etl_next != std::nullptr) 00456 { 00457 last.etl_next->etl_previous = &last; 00458 } 00459 00460 if (lhs != std::nullptr) 00461 { 00462 lhs->etl_next = &first; 00463 } 00464 } 00465 00466 // Reference 00467 template <typename TLink> 00468 typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID> >::value, void>::type 00469 unlink(TLink& node) 00470 { 00471 node.unlink(); 00472 } 00473 00474 // Reference Reference 00475 template <typename TLink> 00476 typename etl::enable_if<etl::is_same<TLink, etl::bidirectional_link<TLink::ID> >::value, void>::type 00477 unlink(TLink& first, TLink& last) 00478 { 00479 if (&first == &last) 00480 { 00481 first.unlink(); 00482 } 00483 else 00484 { 00485 if (last.etl_next != std::nullptr) 00486 { 00487 last.etl_next->etl_previous = first.etl_previous; 00488 } 00489 00490 if (first.etl_previous != std::nullptr) 00491 { 00492 first.etl_previous->etl_next = last.etl_next; 00493 } 00494 } 00495 } 00496 00497 //*************************************************************************** 00498 /// A binary tree link. 00499 //*************************************************************************** 00500 template <const size_t ID_> 00501 struct tree_link 00502 { 00503 enum 00504 { 00505 ID = ID_, 00506 }; 00507 00508 void clear() 00509 { 00510 etl_parent = std::nullptr; 00511 etl_left = std::nullptr; 00512 etl_right = std::nullptr; 00513 } 00514 00515 bool is_linked() const 00516 { 00517 return (etl_parent != std::nullptr) || (etl_left != std::nullptr) || (etl_right != std::nullptr); 00518 } 00519 00520 tree_link* etl_parent; 00521 tree_link* etl_left; 00522 tree_link* etl_right; 00523 }; 00524 00525 // Reference, Reference 00526 template <typename TLink> 00527 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00528 link_left(TLink& parent, TLink& leaf) 00529 { 00530 parent.etl_left = &leaf; 00531 leaf.etl_parent = &parent; 00532 } 00533 00534 template <typename TLink> 00535 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00536 link_right(TLink& parent, TLink& leaf) 00537 { 00538 parent.etl_right = &leaf; 00539 leaf.etl_parent = &parent; 00540 } 00541 00542 // Pointer, Pointer 00543 template <typename TLink> 00544 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00545 link_left(TLink* parent, TLink* leaf) 00546 { 00547 if (parent != std::nullptr) 00548 { 00549 parent->etl_left = leaf; 00550 } 00551 00552 if (leaf != std::nullptr) 00553 { 00554 leaf->etl_parent = parent; 00555 } 00556 } 00557 00558 template <typename TLink> 00559 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00560 link_right(TLink* parent, TLink* leaf) 00561 { 00562 if (parent != std::nullptr) 00563 { 00564 parent->etl_right = leaf; 00565 } 00566 00567 if (leaf != std::nullptr) 00568 { 00569 leaf->etl_parent = parent; 00570 } 00571 } 00572 00573 // Reference, Pointer 00574 template <typename TLink> 00575 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00576 link_left(TLink& parent, TLink* leaf) 00577 { 00578 parent.etl_left = leaf; 00579 00580 if (leaf != std::nullptr) 00581 { 00582 leaf->etl_parent = &parent; 00583 } 00584 } 00585 00586 template <typename TLink> 00587 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00588 link_right(TLink& parent, TLink* leaf) 00589 { 00590 parent.etl_right = leaf; 00591 00592 if (leaf != std::nullptr) 00593 { 00594 leaf->etl_parent = &parent; 00595 } 00596 } 00597 00598 // Pointer, Reference 00599 template <typename TLink> 00600 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00601 link_left(TLink* parent, TLink& leaf) 00602 { 00603 if (parent != std::nullptr) 00604 { 00605 parent->etl_left = &leaf; 00606 } 00607 00608 leaf.etl_parent = parent; 00609 } 00610 00611 template <typename TLink> 00612 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00613 link_right(TLink* parent, TLink& leaf) 00614 { 00615 if (parent != std::nullptr) 00616 { 00617 parent->etl_right = &leaf; 00618 } 00619 00620 leaf.etl_parent = parent; 00621 } 00622 00623 // Reference, Reference 00624 template <typename TLink> 00625 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00626 link_rotate_left(TLink& parent, TLink& leaf) 00627 { 00628 parent.etl_right = leaf.etl_left; 00629 00630 if (parent.etl_right != std::nullptr) 00631 { 00632 parent.etl_right->etl_parent = &parent; 00633 } 00634 00635 leaf.etl_parent = parent.etl_parent; 00636 parent.etl_parent = &leaf; 00637 leaf.etl_left = &parent; 00638 } 00639 00640 template <typename TLink> 00641 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00642 link_rotate_right(TLink& parent, TLink& leaf) 00643 { 00644 parent.etl_left = leaf.etl_right; 00645 00646 if (parent.etl_left != std::nullptr) 00647 { 00648 parent.etl_left->etl_parent = &parent; 00649 } 00650 00651 leaf.etl_parent = parent.etl_parent; 00652 parent.etl_parent = &leaf; 00653 leaf.etl_right = &parent; 00654 } 00655 00656 // Pointer, Pointer 00657 template <typename TLink> 00658 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00659 link_rotate_left(TLink* parent, TLink* leaf) 00660 { 00661 if ((parent != std::nullptr) && (leaf != std::nullptr)) 00662 { 00663 link_rotate_left(*parent, *leaf); 00664 } 00665 } 00666 00667 template <typename TLink> 00668 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00669 link_rotate_right(TLink* parent, TLink* leaf) 00670 { 00671 if ((parent != std::nullptr) && (leaf != std::nullptr)) 00672 { 00673 link_rotate_right(*parent, *leaf); 00674 } 00675 } 00676 00677 // Reference, Pointer 00678 template <typename TLink> 00679 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00680 link_rotate_left(TLink& parent, TLink* leaf) 00681 { 00682 if (leaf != std::nullptr) 00683 { 00684 link_rotate_left(parent, *leaf); 00685 } 00686 } 00687 00688 template <typename TLink> 00689 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00690 link_rotate_right(TLink& parent, TLink* leaf) 00691 { 00692 if (leaf != std::nullptr) 00693 { 00694 link_rotate_right(parent, *leaf); 00695 } 00696 } 00697 00698 // Pointer, Reference 00699 template <typename TLink> 00700 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00701 link_rotate_left(TLink* parent, TLink& leaf) 00702 { 00703 if (parent != std::nullptr) 00704 { 00705 link_rotate_left(*parent, leaf); 00706 } 00707 } 00708 00709 template <typename TLink> 00710 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00711 link_rotate_right(TLink* parent, TLink& leaf) 00712 { 00713 if (parent != std::nullptr) 00714 { 00715 link_rotate_right(*parent, leaf); 00716 } 00717 } 00718 00719 // Reference, Reference 00720 /// Automatically detects whether a left or right rotate is expected. 00721 template <typename TLink> 00722 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00723 link_rotate(TLink& parent, TLink& leaf) 00724 { 00725 if (parent.etl_left == &leaf) 00726 { 00727 etl::link_rotate_right(parent, leaf); 00728 } 00729 else 00730 { 00731 etl::link_rotate_left(parent, leaf); 00732 } 00733 } 00734 00735 // Pointer, Pointer 00736 /// Automatically detects whether a left or right rotate is expected. 00737 template <typename TLink> 00738 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00739 link_rotate(TLink* parent, TLink* leaf) 00740 { 00741 if ((parent != std::nullptr) && (leaf != std::nullptr)) 00742 { 00743 if (parent->etl_left == leaf) 00744 { 00745 etl::link_rotate_right(*parent, *leaf); 00746 } 00747 else 00748 { 00749 etl::link_rotate_left(*parent, *leaf); 00750 } 00751 } 00752 } 00753 00754 // Reference, Pointer 00755 /// Automatically detects whether a left or right rotate is expected. 00756 template <typename TLink> 00757 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00758 link_rotate(TLink& parent, TLink* leaf) 00759 { 00760 if (leaf != std::nullptr) 00761 { 00762 if (parent.etl_left == leaf) 00763 { 00764 etl::link_rotate_right(parent, *leaf); 00765 } 00766 else 00767 { 00768 etl::link_rotate_left(parent, *leaf); 00769 } 00770 } 00771 } 00772 00773 // Pointer, Reference 00774 /// Automatically detects whether a left or right rotate is expected. 00775 template <typename TLink> 00776 typename etl::enable_if<etl::is_same<TLink, etl::tree_link<TLink::ID> >::value, void>::type 00777 link_rotate(TLink* parent, TLink& leaf) 00778 { 00779 if (parent != std::nullptr) 00780 { 00781 if (parent->etl_left == &leaf) 00782 { 00783 etl::link_rotate_right(*parent, leaf); 00784 } 00785 else 00786 { 00787 etl::link_rotate_left(*parent, leaf); 00788 } 00789 } 00790 } 00791 } 00792 00793 #undef ETL_FILE 00794 #endif 00795
Generated on Tue Jul 12 2022 14:05:41 by
