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