1 /* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_CONTAINER_LIST_H 17 #define FOUNDATION_ACE_FRAMEWORKS_BASE_CONTAINER_LIST_H 18 19 #include <initializer_list> 20 #include <iostream> 21 #include <list> 22 #include <memory> 23 #include <stdexcept> 24 #include <utility> 25 26 #include "base/log/log_wrapper.h" 27 28 #define list_entry(ptr, type, member) reinterpret_cast<type*>(reinterpret_cast<char*>(ptr) - offsetof(type, member)) 29 30 namespace OHOS::Ace { 31 32 template<typename T> 33 class SafeList { 34 public: 35 class iterator; 36 struct list_head { 37 list_head *prev, *next; list_headlist_head38 list_head() : prev(this), next(this) {} list_headlist_head39 list_head(list_head* head) 40 { 41 if (head) { 42 prev = head; 43 next = head->next; 44 head->next->prev = this; 45 head->next = this; 46 } else { 47 prev = next = this; 48 } 49 } ~list_headlist_head50 ~list_head() 51 { 52 prev->next = next; 53 next->prev = prev; 54 prev = next = nullptr; 55 } addlist_head56 void add(list_head* head) 57 { 58 prev->next = next; 59 next->prev = prev; 60 prev = head; 61 next = head->next; 62 head->next->prev = this; 63 head->next = this; 64 } 65 }; 66 67 private: 68 struct TrackedElement { 69 T value; 70 mutable list_head iterator_head; 71 valueTrackedElement72 TrackedElement(const T& val = {}) : value(val) {} TrackedElementTrackedElement73 TrackedElement(T&& val) : value(std::forward<T>(val)) {} TrackedElementTrackedElement74 TrackedElement(const TrackedElement& rhs) : value(rhs.value) {} 75 TrackedElement& operator=(const TrackedElement& rhs) 76 { 77 if (&rhs != this) { 78 this->value = rhs.value; 79 } 80 } 81 ~TrackedElementTrackedElement82 ~TrackedElement() 83 { 84 invalidate_iterators(); 85 } 86 invalidate_iteratorsTrackedElement87 void invalidate_iterators() 88 { 89 list_head *pos, *next; 90 pos = iterator_head.next; 91 while (pos != &iterator_head) { 92 next = pos->next; 93 auto iter = list_entry(pos, iterator, node); 94 iter->container_ = nullptr; 95 pos = next; 96 } 97 } 98 invalidate_iteratorsTrackedElement99 void invalidate_iterators() const 100 { 101 list_head *pos, *next; 102 pos = iterator_head.next; 103 while (pos != &iterator_head) { 104 next = pos->next; 105 auto iter = list_entry(pos, iterator, node); 106 iter->container_ = nullptr; 107 pos = next; 108 } 109 } 110 111 bool operator<(const TrackedElement& other) const 112 { 113 return value < other.value; 114 } 115 116 bool operator>(const TrackedElement& other) const 117 { 118 return value > other.value; 119 } 120 121 bool operator==(const TrackedElement& other) const 122 { 123 return value == other.value; 124 } 125 126 bool operator!=(const TrackedElement& other) const 127 { 128 return value != other.value; 129 } 130 }; 131 132 std::list<TrackedElement> elements; 133 mutable list_head end_iterator_head; 134 invalidate_end_iterators()135 void invalidate_end_iterators() 136 { 137 list_head *pos, *next; 138 pos = end_iterator_head.next; 139 while (pos != &end_iterator_head) { 140 next = pos->next; 141 auto iter = list_entry(pos, iterator, node); 142 iter->container_ = nullptr; 143 pos = next; 144 } 145 } 146 147 public: 148 class iterator { 149 private: 150 using ListIter = typename std::list<TrackedElement>::iterator; 151 list_head node; 152 SafeList* container_ = nullptr; 153 ListIter inner_iter; 154 friend SafeList; get_end()155 ListIter get_end() const 156 { 157 return container_ ? container_->elements.end() : ListIter {}; 158 } 159 160 explicit iterator(SafeList* container, ListIter it = ListIter {}) 161 : node(container ? (it != container->elements.end() ? &it->iterator_head : &container->end_iterator_head) 162 : nullptr), 163 container_(container), inner_iter(it) 164 {} 165 166 public: 167 using difference_type = std::ptrdiff_t; 168 using iterator_category = std::input_iterator_tag; 169 using value_type = T; 170 using pointer = T*; 171 using reference = T&; iterator()172 explicit iterator() : node(), container_(nullptr), inner_iter() {} 173 iterator(const iterator & other)174 iterator(const iterator& other) : container_(other.container_), inner_iter(other.inner_iter) 175 { 176 if (container_) { 177 if (inner_iter != get_end()) { 178 node.add(&inner_iter->iterator_head); 179 } else { 180 node.add(&container_->end_iterator_head); 181 } 182 } 183 } 184 185 T& operator*() const 186 { 187 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && 188 (!container_ || inner_iter == get_end()))) { 189 LOGF_ABORT("Dereferencing invalid iterator"); 190 } 191 return inner_iter->value; 192 } 193 194 T* operator->() const 195 { 196 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && 197 (!container_ || inner_iter == get_end()))) { 198 LOGF_ABORT("Dereferencing invalid iterator"); 199 } 200 return &inner_iter->value; 201 } 202 203 iterator& operator=(const iterator& other) 204 { 205 if (this != &other) { 206 container_ = other.container_; 207 inner_iter = other.inner_iter; 208 209 if (container_) { 210 if (inner_iter != get_end()) { 211 node.add(&inner_iter->iterator_head); 212 } else { 213 node.add(&container_->end_iterator_head); 214 } 215 } 216 } 217 return *this; 218 } 219 220 iterator& operator++() 221 { 222 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) { 223 LOGF_ABORT("Incrementing invalid iterator"); 224 } 225 ++inner_iter; 226 if (inner_iter != get_end()) { 227 node.add(&inner_iter->iterator_head); 228 } else { 229 node.add(&container_->end_iterator_head); 230 } 231 return *this; 232 } 233 234 iterator operator++(int) 235 { 236 auto temp = *this; 237 ++(*this); 238 return temp; 239 } 240 241 iterator& operator--() 242 { 243 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) { 244 LOGF_ABORT("Decrementing invalid iterator"); 245 } 246 --inner_iter; 247 if (inner_iter != get_end()) { 248 node.add(&inner_iter->iterator_head); 249 } else { 250 node.add(&container_->end_iterator_head); 251 } 252 return *this; 253 } 254 255 iterator operator--(int) 256 { 257 auto temp = *this; 258 --(*this); 259 return temp; 260 } 261 262 bool operator==(const iterator& other) const 263 { 264 if (!container_ || !other.container_) { 265 return false; 266 } 267 return inner_iter == other.inner_iter; 268 } 269 270 bool operator!=(const iterator& other) const 271 { 272 return !(*this == other); 273 } 274 }; 275 276 class const_iterator { 277 private: 278 using ListIter = typename std::list<TrackedElement>::const_iterator; 279 list_head node; 280 const SafeList* container_ = nullptr; 281 ListIter inner_iter; 282 friend SafeList; get_cend()283 ListIter get_cend() const 284 { 285 return container_ ? container_->elements.cend() : ListIter {}; 286 } 287 288 explicit const_iterator(const SafeList* container, ListIter it = ListIter {}) 289 : node(container ? (it != container->elements.cend() ? &it->iterator_head : &container->end_iterator_head) 290 : nullptr), 291 container_(container), inner_iter(it) 292 {} 293 294 public: const_iterator()295 explicit const_iterator() : node(), container_(nullptr), inner_iter() {} 296 const_iterator(const iterator & other)297 const_iterator(const iterator& other) : container_(other.container_), inner_iter(other.inner_iter) 298 { 299 if (container_) { 300 if (inner_iter != get_cend()) { 301 node.add(&inner_iter->iterator_head); 302 } else { 303 node.add(&container_->end_iterator_head); 304 } 305 } 306 } 307 const_iterator(const const_iterator & other)308 const_iterator(const const_iterator& other) : container_(other.container_), inner_iter(other.inner_iter) 309 { 310 if (container_) { 311 if (inner_iter != get_cend()) { 312 node.add(&inner_iter->iterator_head); 313 } else { 314 node.add(&container_->end_iterator_head); 315 } 316 } 317 } 318 319 const T& operator*() const 320 { 321 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && 322 (!container_ || inner_iter == get_cend()))) { 323 LOGF_ABORT("Dereferencing invalid const_iterator"); 324 } 325 return inner_iter->value; 326 } 327 328 const T* operator->() const 329 { 330 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && 331 (!container_ || inner_iter == get_cend()))) { 332 LOGF_ABORT("Dereferencing invalid const_iterator"); 333 } 334 return &inner_iter->value; 335 } 336 337 const_iterator& operator=(const const_iterator& other) 338 { 339 if (this != &other) { 340 container_ = other.container_; 341 inner_iter = other.inner_iter; 342 if (container_) { 343 if (inner_iter != get_cend()) { 344 node.add(&inner_iter->iterator_head); 345 } else { 346 node.add(&container_->end_iterator_head); 347 } 348 } 349 } 350 return *this; 351 } 352 353 const_iterator& operator++() 354 { 355 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) { 356 LOGF_ABORT("Incrementing invalid const_iterator"); 357 } 358 ++inner_iter; 359 if (inner_iter != get_cend()) { 360 node.add(&inner_iter->iterator_head); 361 } else { 362 node.add(&container_->end_iterator_head); 363 } 364 return *this; 365 } 366 367 const_iterator operator++(int) 368 { 369 auto temp = *this; 370 ++(*this); 371 return temp; 372 } 373 374 const_iterator& operator--() 375 { 376 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) { 377 LOGF_ABORT("Decrementing invalid const_iterator"); 378 } 379 --inner_iter; 380 if (inner_iter != get_cend()) { 381 node.add(&inner_iter->iterator_head); 382 } else { 383 node.add(&container_->end_iterator_head); 384 } 385 return *this; 386 } 387 388 const_iterator operator--(int) 389 { 390 auto temp = *this; 391 --(*this); 392 return temp; 393 } 394 395 bool operator==(const const_iterator& other) const 396 { 397 if (!container_ || !other.container_) { 398 return false; 399 } 400 return inner_iter == other.inner_iter; 401 } 402 403 bool operator!=(const const_iterator& other) const 404 { 405 return !(*this == other); 406 } 407 }; 408 409 class reverse_iterator { 410 private: 411 using ListIter = typename std::list<TrackedElement>::reverse_iterator; 412 list_head node; 413 SafeList* container_ = nullptr; 414 ListIter inner_iter; 415 friend SafeList; 416 get_rend()417 ListIter get_rend() const 418 { 419 return container_ ? container_->elements.rend() : ListIter {}; 420 } 421 422 explicit reverse_iterator(SafeList* container, ListIter it = ListIter {}) 423 : node(container ? (it != container->elements.rend() ? &it->iterator_head : &container->end_iterator_head) 424 : nullptr), 425 container_(container), inner_iter(it) 426 {} 427 428 public: reverse_iterator()429 explicit reverse_iterator() : node(), container_(nullptr), inner_iter() {} 430 reverse_iterator(const reverse_iterator & other)431 reverse_iterator(const reverse_iterator& other) : container_(other.container_), inner_iter(other.inner_iter) 432 { 433 if (container_) { 434 if (inner_iter != get_rend()) { 435 node.add(&inner_iter->iterator_head); 436 } else { 437 node.add(&container_->end_iterator_head); 438 } 439 } 440 } 441 442 T& operator*() const 443 { 444 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && 445 (!container_ || inner_iter == get_rend()))) { 446 LOGF_ABORT("Dereferencing invalid reverse iterator"); 447 } 448 return inner_iter->value; 449 } 450 451 T* operator->() const 452 { 453 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && 454 (!container_ || inner_iter == get_rend()))) { 455 LOGF_ABORT("Dereferencing invalid reverse iterator"); 456 } 457 return &inner_iter->value; 458 } 459 460 reverse_iterator& operator=(const reverse_iterator& other) 461 { 462 if (this != &other) { 463 container_ = other.container_; 464 inner_iter = other.inner_iter; 465 if (container_) { 466 if (inner_iter != get_rend()) { 467 node.add(&inner_iter->iterator_head); 468 } else { 469 node.add(&container_->end_iterator_head); 470 } 471 } 472 } 473 return *this; 474 } 475 476 reverse_iterator& operator++() 477 { 478 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) { 479 LOGF_ABORT("Incrementing invalid reverse iterator"); 480 } 481 ++inner_iter; 482 if (inner_iter != get_rend()) { 483 node.add(&inner_iter->iterator_head); 484 } else { 485 node.add(&container_->end_iterator_head); 486 } 487 return *this; 488 } 489 490 reverse_iterator operator++(int) 491 { 492 auto tmp = *this; 493 ++(*this); 494 return tmp; 495 } 496 497 reverse_iterator& operator--() 498 { 499 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) { 500 LOGF_ABORT("Decrementing invalid reverse iterator"); 501 } 502 --inner_iter; 503 if (inner_iter != get_rend()) { 504 node.add(&inner_iter->iterator_head); 505 } else { 506 node.add(&container_->end_iterator_head); 507 } 508 return *this; 509 } 510 511 reverse_iterator operator--(int) 512 { 513 auto tmp = *this; 514 --(*this); 515 return tmp; 516 } 517 518 bool operator==(const reverse_iterator& other) const 519 { 520 if (!container_ || !other.container_) { 521 return false; 522 } 523 return inner_iter == other.inner_iter; 524 } 525 526 bool operator!=(const reverse_iterator& other) const 527 { 528 return !(*this == other); 529 } 530 }; 531 532 class const_reverse_iterator { 533 private: 534 using ListIter = typename std::list<TrackedElement>::const_reverse_iterator; 535 list_head node; 536 const SafeList* container_ = nullptr; 537 ListIter inner_iter; 538 friend SafeList; 539 get_crend()540 ListIter get_crend() const 541 { 542 return container_ ? container_->elements.crend() : ListIter {}; 543 } 544 545 explicit const_reverse_iterator(const SafeList* container, ListIter it = ListIter {}) 546 : node(container ? (it != container->elements.crend() ? &it->iterator_head : &container->end_iterator_head) 547 : nullptr), 548 container_(container), inner_iter(it) 549 {} 550 551 public: const_reverse_iterator()552 explicit const_reverse_iterator() : node(), container_(nullptr), inner_iter() {} 553 const_reverse_iterator(const reverse_iterator & other)554 const_reverse_iterator(const reverse_iterator& other) 555 : container_(other.container_), inner_iter(other.inner_iter) 556 { 557 if (container_) { 558 if (inner_iter != get_crend()) { 559 node.add(&inner_iter->iterator_head); 560 } else { 561 node.add(&container_->end_iterator_head); 562 } 563 } 564 } 565 const_reverse_iterator(const const_reverse_iterator & other)566 const_reverse_iterator(const const_reverse_iterator& other) 567 : container_(other.container_), inner_iter(other.inner_iter) 568 { 569 if (container_) { 570 if (inner_iter != get_crend()) { 571 node.add(&inner_iter->iterator_head); 572 } else { 573 node.add(&container_->end_iterator_head); 574 } 575 } 576 } 577 578 const T& operator*() const 579 { 580 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && 581 (!container_ || inner_iter == get_crend()))) { 582 LOGF_ABORT("Dereferencing invalid const_reverse iterator"); 583 } 584 return inner_iter->value; 585 } 586 587 const T* operator->() const 588 { 589 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && 590 (!container_ || inner_iter == get_crend()))) { 591 LOGF_ABORT("Dereferencing invalid const_reverse iterator"); 592 } 593 return &inner_iter->value; 594 } 595 596 const_reverse_iterator& operator=(const const_reverse_iterator& other) 597 { 598 if (this != &other) { 599 container_ = other.container_; 600 inner_iter = other.inner_iter; 601 if (container_) { 602 if (inner_iter != get_crend()) { 603 node.add(&inner_iter->iterator_head); 604 } else { 605 node.add(&container_->end_iterator_head); 606 } 607 } 608 } 609 return *this; 610 } 611 612 const_reverse_iterator& operator++() 613 { 614 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) { 615 LOGF_ABORT("Incrementing invalid const_reverse iterator"); 616 } 617 ++inner_iter; 618 if (inner_iter != get_crend()) { 619 node.add(&inner_iter->iterator_head); 620 } else { 621 node.add(&container_->end_iterator_head); 622 } 623 return *this; 624 } 625 626 const_reverse_iterator operator++(int) 627 { 628 const_reverse_iterator tmp = *this; 629 ++(*this); 630 return tmp; 631 } 632 633 const_reverse_iterator& operator--() 634 { 635 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !container_)) { 636 LOGF_ABORT("Decrementing invalid const_reverse iterator"); 637 } 638 --inner_iter; 639 if (inner_iter != get_crend()) { 640 node.add(&inner_iter->iterator_head); 641 } else { 642 node.add(&container_->end_iterator_head); 643 } 644 return *this; 645 } 646 647 const_reverse_iterator operator--(int) 648 { 649 const_reverse_iterator tmp = *this; 650 --(*this); 651 return tmp; 652 } 653 654 bool operator==(const const_reverse_iterator& other) const 655 { 656 if (!container_ || !other.container_) { 657 return false; 658 } 659 return inner_iter == other.inner_iter; 660 } 661 662 bool operator!=(const const_reverse_iterator& other) const 663 { 664 return !(*this == other); 665 } 666 }; 667 668 SafeList() = default; SafeList(std::initializer_list<T> value)669 SafeList(std::initializer_list<T> value) 670 { 671 for (const auto& val : value) { 672 push_back(val); 673 } 674 } SafeList(const SafeList & other)675 SafeList(const SafeList& other) : elements(other.elements) {} SafeList(SafeList && other)676 SafeList(SafeList&& other) : elements(std::forward<std::list<TrackedElement>>(other.elements)) {} 677 ~SafeList()678 ~SafeList() 679 { 680 invalidate_end_iterators(); 681 } 682 push_back(const T & value)683 void push_back(const T& value) 684 { 685 elements.emplace_back(value); 686 } 687 push_back(T && value)688 void push_back(T&& value) 689 { 690 elements.emplace_back(std::forward<T>(value)); 691 } 692 push_front(const T & value)693 void push_front(const T& value) 694 { 695 elements.emplace_front(value); 696 } 697 push_front(T && value)698 void push_front(T&& value) 699 { 700 elements.emplace_front(std::forward<T>(value)); 701 } 702 pop_front()703 void pop_front() 704 { 705 if (elements.empty()) { 706 LOGF_ABORT("pop_front called on empty container"); 707 } 708 elements.pop_front(); 709 } 710 pop_back()711 void pop_back() 712 { 713 if (elements.empty()) { 714 LOGF_ABORT("pop_back called on empty container"); 715 } 716 elements.pop_back(); 717 } 718 erase(iterator & pos)719 iterator erase(iterator& pos) 720 { 721 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && 722 (!pos.container_ || pos.inner_iter == elements.end()))) { 723 LOGF_ABORT("Erasing with invalid iterator"); 724 } 725 return iterator(this, elements.erase(pos.inner_iter)); 726 } 727 erase(const_iterator & pos)728 iterator erase(const_iterator& pos) 729 { 730 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && 731 (!pos.container_ || pos.inner_iter == elements.end()))) { 732 LOGF_ABORT("Erasing with invalid iterator"); 733 } 734 return iterator(this, elements.erase(pos.inner_iter)); 735 } 736 erase(const_iterator first,const_iterator last)737 iterator erase(const_iterator first, const_iterator last) 738 { 739 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && 740 (!first.container_ || !last.container_ || first.inner_iter == elements.end()))) { 741 LOGF_ABORT("Erasing with invalid iterator"); 742 } 743 return iterator(this, elements.erase(first.inner_iter, last.inner_iter)); 744 } 745 insert(const_iterator pos,const T & value)746 iterator insert(const_iterator pos, const T& value) 747 { 748 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !pos.container_)) { 749 LOGF_ABORT("Inserting with invalid iterator"); 750 } 751 return iterator(this, elements.insert(pos.inner_iter, value)); 752 } insert(const_iterator pos,T && value)753 iterator insert(const_iterator pos, T&& value) 754 { 755 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !pos.container_)) { 756 LOGF_ABORT("Inserting with invalid iterator"); 757 } 758 return iterator(this, elements.insert(pos.inner_iter, std::forward<T>(value))); 759 } insert(const_iterator pos,size_t count,const T & value)760 iterator insert(const_iterator pos, size_t count, const T& value) 761 { 762 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !pos.container_)) { 763 LOGF_ABORT("Inserting with invalid iterator"); 764 } 765 return iterator(this, elements.insert(pos.inner_iter, count, value)); 766 } insert(const_iterator pos,std::initializer_list<T> values)767 iterator insert(const_iterator pos, std::initializer_list<T> values) 768 { 769 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !pos.container_)) { 770 LOGF_ABORT("Inserting with invalid iterator"); 771 } 772 return iterator(this, elements.insert(pos.inner_iter, values.begin(), values.end())); 773 } 774 775 template<typename InputIt, typename std::enable_if<!std::is_same<InputIt, const_iterator>::value, int>::type = 0> insert_impl(const_iterator pos,InputIt first,InputIt last)776 iterator insert_impl(const_iterator pos, InputIt first, InputIt last) 777 { 778 return iterator(this, elements.insert(pos.inner_iter, first, last)); 779 } 780 781 template<typename InputIt, typename std::enable_if<std::is_same<InputIt, const_iterator>::value, int>::type = 0> insert_impl(const_iterator pos,InputIt first,InputIt last)782 iterator insert_impl(const_iterator pos, InputIt first, InputIt last) 783 { 784 return iterator(this, elements.insert(pos.inner_iter, first.inner_iter, last.inner_iter)); 785 } 786 787 template<typename InputIt> insert(const_iterator pos,InputIt first,InputIt last)788 iterator insert(const_iterator pos, InputIt first, InputIt last) 789 { 790 if (ACE_UNLIKELY(OHOS::Ace::SystemProperties::DetectUseInvalidIterator() && !pos.container_)) { 791 LOGF_ABORT("Inserting with invalid iterator"); 792 } 793 return insert_impl(pos, first, last); 794 } 795 get_allocator()796 decltype(auto) get_allocator() const noexcept 797 { 798 return elements.get_allocator(); 799 } 800 assign(size_t count,const T & value)801 void assign(size_t count, const T& value) 802 { 803 clear(); 804 for (int i = 0; i < count; ++i) { 805 emplace_back(value); 806 } 807 } 808 assign(std::initializer_list<T> values)809 void assign(std::initializer_list<T> values) 810 { 811 assign(values.begin(), values.end()); 812 } 813 814 template<typename InputIt> 815 auto assign(InputIt first, InputIt last) -> typename std::enable_if<!std::is_integral<InputIt>::value>::type 816 { 817 clear(); 818 for (; first != last; ++first) { 819 emplace_back(*first); 820 } 821 } 822 823 template<typename... Args> emplace(const_iterator pos,Args &&...args)824 iterator emplace(const_iterator pos, Args&&... args) 825 { 826 auto iter = elements.emplace(pos.inner_iter, T(std::forward<Args>(args)...)); 827 return iterator(this, iter); 828 } 829 830 template<typename... Args> emplace_back(Args &&...args)831 void emplace_back(Args&&... args) 832 { 833 elements.emplace_back(T(std::forward<Args>(args)...)); 834 } 835 836 template<typename... Args> emplace_front(Args &&...args)837 void emplace_front(Args&&... args) 838 { 839 elements.emplace_front(T(std::forward<Args>(args)...)); 840 } 841 front()842 T& front() 843 { 844 if (elements.empty()) { 845 LOGF_ABORT("SafeList: front() called on empty container"); 846 } 847 return elements.front().value; 848 } 849 front()850 const T& front() const 851 { 852 if (elements.empty()) { 853 LOGF_ABORT("SafeList: front() called on empty container"); 854 } 855 return elements.front().value; 856 } 857 back()858 T& back() 859 { 860 if (elements.empty()) { 861 LOGF_ABORT("SafeList: back() called on empty container"); 862 } 863 return elements.back().value; 864 } 865 back()866 const T& back() const 867 { 868 if (elements.empty()) { 869 LOGF_ABORT("SafeList: back() called on empty container"); 870 } 871 return elements.back().value; 872 } 873 clear()874 void clear() 875 { 876 elements.clear(); 877 } 878 empty()879 bool empty() const 880 { 881 return elements.empty(); 882 } 883 size()884 int size() const 885 { 886 return elements.size(); 887 } 888 max_size()889 int max_size() const 890 { 891 return elements.max_size(); 892 } 893 sort()894 void sort() 895 { 896 elements.sort(); 897 } 898 899 template<typename Compare> sort(Compare comp)900 void sort(Compare comp) 901 { 902 auto adapted_comp = [comp](const TrackedElement& a, const TrackedElement& b) { return comp(a.value, b.value); }; 903 elements.sort(adapted_comp); 904 } 905 906 template<typename BinaryPredicate> unique(BinaryPredicate pred)907 void unique(BinaryPredicate pred) 908 { 909 auto adapted_pred = [pred](const TrackedElement& a, const TrackedElement& b) { return pred(a.value, b.value); }; 910 elements.unique(adapted_pred); 911 } 912 unique()913 void unique() 914 { 915 elements.unique(); 916 } 917 reverse()918 void reverse() noexcept 919 { 920 elements.reverse(); 921 } 922 remove(const T & value)923 void remove(const T& value) 924 { 925 elements.remove_if([&](const TrackedElement& elem) { return elem.value == value; }); 926 } 927 928 template<typename UnaryPredicate> remove_if(UnaryPredicate pred)929 void remove_if(UnaryPredicate pred) 930 { 931 elements.remove_if([&](const TrackedElement& elem) { return pred(elem.value); }); 932 } 933 splice(iterator pos,SafeList & other)934 void splice(iterator pos, SafeList& other) 935 { 936 if (other.empty()) { 937 return; 938 } 939 elements.splice(pos.inner_iter, other.elements); 940 } 941 splice(iterator pos,SafeList & other,iterator it)942 void splice(iterator pos, SafeList& other, iterator it) 943 { 944 elements.splice(pos.inner_iter, other.elements, it.inner_iter); 945 } 946 splice(iterator pos,SafeList & other,iterator first,iterator last)947 void splice(iterator pos, SafeList& other, iterator first, iterator last) 948 { 949 elements.splice(pos.inner_iter, other.elements, first.inner_iter, last.inner_iter); 950 } 951 merge(SafeList & other)952 void merge(SafeList& other) 953 { 954 elements.merge(other.elements); 955 } 956 957 template<typename Compare> merge(SafeList & other,Compare comp)958 void merge(SafeList& other, Compare comp) 959 { 960 auto adapted_comp = [comp](const TrackedElement& a, const TrackedElement& b) { return comp(a.value, b.value); }; 961 elements.merge(other.elements, adapted_comp); 962 } 963 swap(SafeList & other)964 void swap(SafeList& other) noexcept 965 { 966 elements.swap(other.elements); 967 } 968 resize(size_t count)969 void resize(size_t count) 970 { 971 elements.resize(count); 972 } 973 resize(size_t count,const T & value)974 void resize(size_t count, const T& value) 975 { 976 elements.resize(count, value); 977 } 978 begin()979 iterator begin() 980 { 981 return iterator(this, elements.begin()); 982 } begin()983 const_iterator begin() const 984 { 985 return const_iterator(this, elements.cbegin()); 986 } end()987 iterator end() 988 { 989 return iterator(this, elements.end()); 990 } end()991 const_iterator end() const 992 { 993 return const_iterator(this, elements.cend()); 994 } cbegin()995 const_iterator cbegin() const 996 { 997 return const_iterator(this, elements.cbegin()); 998 } 999 cend()1000 const_iterator cend() const 1001 { 1002 return const_iterator(this, elements.cend()); 1003 } rbegin()1004 reverse_iterator rbegin() 1005 { 1006 return reverse_iterator(this, elements.rbegin()); 1007 } rend()1008 reverse_iterator rend() 1009 { 1010 return reverse_iterator(this, elements.rend()); 1011 } rbegin()1012 const_reverse_iterator rbegin() const 1013 { 1014 return crbegin(); 1015 } rend()1016 const_reverse_iterator rend() const 1017 { 1018 return crend(); 1019 } crbegin()1020 const_reverse_iterator crbegin() const 1021 { 1022 return const_reverse_iterator(this, elements.crbegin()); 1023 } crend()1024 const_reverse_iterator crend() const 1025 { 1026 return const_reverse_iterator(this, elements.crend()); 1027 } 1028 }; 1029 1030 } // namespace OHOS::Ace 1031 1032 #endif // FOUNDATION_ACE_FRAMEWORKS_BASE_CONTAINER_LIST_H