465 typedef TKey key_type;
466 typedef ETL_OR_STD::pair<const TKey, TMapped> value_type;
467 typedef TMapped mapped_type;
468 typedef TKeyCompare key_compare;
469 typedef value_type& reference;
470 typedef const value_type& const_reference;
472 typedef value_type&& rvalue_reference;
474 typedef value_type* pointer;
475 typedef const value_type* const_pointer;
476 typedef size_t size_type;
481 typedef key_type&& rvalue_key_reference;
483 typedef mapped_type& mapped_reference;
484 typedef const mapped_type& const_mapped_reference;
490 bool operator()(const_reference lhs, const_reference rhs)
const
492 return (kcompare(lhs.first, rhs.first));
497 key_compare kcompare;
507 explicit Data_Node(value_type value_)
522 return kcompare(node1.value.first, node2.value.first);
527 return kcompare(node.value.first, key);
532 return kcompare(key, node.value.first);
536 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
539 return kcompare(node.value.first, key);
542 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
545 return kcompare(key, node.value.first);
554 key_compare kcompare;
578 return static_cast<const Data_Node*
>(p_node);
586 return static_cast<const Data_Node&
>(node);
594 class iterator :
public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, value_type>
599 friend class const_iterator;
603 , p_node(ETL_NULLPTR)
609 , p_node(ETL_NULLPTR)
613 iterator(imap&
map,
Node* node)
619 iterator(
const iterator& other)
621 , p_node(other.p_node)
627 iterator& operator++()
629 p_map->next_node(p_node);
633 iterator operator++(
int)
635 iterator temp(*
this);
636 p_map->next_node(p_node);
640 iterator& operator--()
642 p_map->prev_node(p_node);
646 iterator operator--(
int)
648 iterator temp(*
this);
649 p_map->prev_node(p_node);
653 iterator& operator=(
const iterator& other)
656 p_node = other.p_node;
660 reference operator*()
const
662 return imap::data_cast(p_node)->value;
665 pointer operator&()
const
667 return &(imap::data_cast(p_node)->value);
670 pointer operator->()
const
672 return &(imap::data_cast(p_node)->value);
675 friend bool operator==(
const iterator& lhs,
const iterator& rhs)
677 return lhs.p_map == rhs.p_map && lhs.p_node == rhs.p_node;
680 friend bool operator!=(
const iterator& lhs,
const iterator& rhs)
682 return !(lhs == rhs);
699 class const_iterator :
public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, const value_type>
707 , p_node(ETL_NULLPTR)
711 const_iterator(
const imap&
map)
713 , p_node(ETL_NULLPTR)
717 const_iterator(
const imap&
map,
const Node* node)
725 , p_node(other.p_node)
729 const_iterator(
const const_iterator& other)
731 , p_node(other.p_node)
737 const_iterator& operator++()
739 p_map->next_node(p_node);
743 const_iterator operator++(
int)
745 const_iterator temp(*
this);
746 p_map->next_node(p_node);
750 const_iterator& operator--()
752 p_map->prev_node(p_node);
756 const_iterator operator--(
int)
758 const_iterator temp(*
this);
759 p_map->prev_node(p_node);
763 const_iterator& operator=(
const const_iterator& other)
766 p_node = other.p_node;
770 const_reference operator*()
const
772 return imap::data_cast(p_node)->value;
775 const_pointer operator&()
const
777 return imap::data_cast(p_node)->value;
780 const_pointer operator->()
const
782 return &(imap::data_cast(p_node)->value);
785 friend bool operator==(
const const_iterator& lhs,
const const_iterator& rhs)
787 return lhs.p_map == rhs.p_map && lhs.p_node == rhs.p_node;
790 friend bool operator!=(
const const_iterator& lhs,
const const_iterator& rhs)
792 return !(lhs == rhs);
812 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
814 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
815 typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
870 return reverse_iterator(
iterator(*
this));
892 const_reverse_iterator
rend()
const
908 const_reverse_iterator
crend()
const
919 mapped_reference
operator[](rvalue_key_reference key)
923 if (!i_element.p_node)
926 Node* inserted_node = ETL_NULLPTR;
931 Data_Node& node = allocate_data_node_with_key(etl::move(key));
935 inserted_node = insert_node(
root_node, node);
939 i_element =
iterator(*
this, inserted_node);
942 return i_element->second;
955 if (!i_element.p_node)
958 Node* inserted_node = ETL_NULLPTR;
963 Data_Node& node = allocate_data_node_with_key(key);
967 inserted_node = insert_node(
root_node, node);
971 i_element =
iterator(*
this, inserted_node);
974 return i_element->second;
990 return i_element->second;
995 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
996 mapped_reference
at(
const K& key)
1002 return i_element->second;
1019 return i_element->second;
1024 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1025 const_mapped_reference
at(
const K& key)
const
1031 return i_element->second;
1043 template <
typename TIterator>
1065 return find_node(
root_node, key) ? 1 : 0;
1070 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1073 return find_node(
root_node, key) ? 1 : 0;
1083 return ETL_OR_STD::make_pair<iterator, iterator>(
iterator(*
this, find_lower_node(
root_node, key)),
1089 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1090 ETL_OR_STD::pair<iterator, iterator>
equal_range(
const K& key)
1092 return ETL_OR_STD::make_pair<iterator, iterator>(
iterator(*
this, find_lower_node(
root_node, key)),
1103 return ETL_OR_STD::make_pair<const_iterator, const_iterator>(
const_iterator(*
this, find_lower_node(
root_node, key)),
1109 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1110 ETL_OR_STD::pair<const_iterator, const_iterator>
equal_range(
const K& key)
const
1112 return ETL_OR_STD::make_pair<const_iterator, const_iterator>(
const_iterator(*
this, find_lower_node(
root_node, key)),
1123 Node*& reference_node = find_node(
root_node, position.p_node);
1124 iterator next(*
this, reference_node);
1127 remove_node(
root_node, (*position).first);
1138 return remove_node(
root_node, key) ? 1 : 0;
1143 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1147 return remove_node(
root_node, etl::forward<K>(key)) ? 1 : 0;
1156 while (first != last)
1158 first =
erase(first);
1161 return last.to_iterator();
1176 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1195 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1208 ETL_OR_STD::pair<iterator, bool>
insert(const_reference value)
1211 Node* inserted_node = ETL_NULLPTR;
1212 bool inserted =
false;
1217 Data_Node& node = allocate_data_node(value);
1220 inserted_node = insert_node(
root_node, node);
1221 inserted = inserted_node == &node;
1224 return ETL_OR_STD::make_pair(
iterator(*
this, inserted_node), inserted);
1234 ETL_OR_STD::pair<iterator, bool>
insert(rvalue_reference value)
1237 Node* inserted_node = ETL_NULLPTR;
1238 bool inserted =
false;
1243 Data_Node& node = allocate_data_node(etl::move(value));
1246 inserted_node = insert_node(
root_node, node);
1247 inserted = inserted_node == &node;
1250 return ETL_OR_STD::make_pair(
iterator(*
this, inserted_node), inserted);
1264 Node* inserted_node = ETL_NULLPTR;
1269 Data_Node& node = allocate_data_node(value);
1272 inserted_node = insert_node(
root_node, node);
1275 return iterator(*
this, inserted_node);
1289 Node* inserted_node = ETL_NULLPTR;
1294 Data_Node& node = allocate_data_node(etl::move(value));
1297 inserted_node = insert_node(
root_node, node);
1300 return iterator(*
this, inserted_node);
1312 template <
class TIterator>
1315 while (first != last)
1335 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1355 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1375 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1395 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1429 while (from != rhs.end())
1431 this->
insert(etl::move(*from));
1466 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1480 , p_node_pool(&node_pool)
1491 while (item !=
end())
1502 Data_Node& allocate_data_node(const_reference value)
1504 Data_Node* node = allocate_data_node();
1506 ETL_INCREMENT_DEBUG_COUNT;
1515 Data_Node* node = allocate_data_node();
1518 ::new ((
void*)
etl::
addressof(node->value.second)) mapped_type();
1519 ETL_INCREMENT_DEBUG_COUNT;
1527 Data_Node& allocate_data_node(rvalue_reference value)
1529 Data_Node* node = allocate_data_node();
1531 ETL_INCREMENT_DEBUG_COUNT;
1538 Data_Node& allocate_data_node_with_key(rvalue_key_reference key)
1540 Data_Node* node = allocate_data_node();
1543 ::new ((
void*)
etl::
addressof(node->value.second)) mapped_type();
1544 ETL_INCREMENT_DEBUG_COUNT;
1553 Data_Node* allocate_data_node()
1556 return (p_node_pool->*func)();
1562 void destroy_data_node(Data_Node& node)
1564 node.value.~value_type();
1565 p_node_pool->release(&node);
1566 ETL_DECREMENT_DEBUG_COUNT;
1574 Node* found = position;
1578 Data_Node& found_data_node = imap::data_cast(*found);
1584 found = found->children[kLeft];
1586 else if (
node_comp(found_data_node, key))
1589 found = found->children[kRight];
1604 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1605 Node* find_node(
Node* position,
const K& key)
1607 Node* found = position;
1611 Data_Node& found_data_node = imap::data_cast(*found);
1617 found = found->children[kLeft];
1619 else if (
node_comp(found_data_node, key))
1622 found = found->children[kRight];
1641 const Node* found = position;
1645 const Data_Node& found_data_node = imap::data_cast(*found);
1651 found = found->children[kLeft];
1653 else if (
node_comp(found_data_node, key))
1656 found = found->children[kRight];
1671 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1672 const Node* find_node(
const Node* position,
const K& key)
const
1674 const Node* found = position;
1678 const Data_Node& found_data_node = imap::data_cast(*found);
1684 found = found->children[kLeft];
1686 else if (
node_comp(found_data_node, key))
1689 found = found->children[kRight];
1708 Node* found = position;
1711 if (found->children[kLeft] == node)
1713 return found->children[kLeft];
1715 else if (found->children[kRight] == node)
1717 return found->children[kRight];
1723 Data_Node& found_data_node = imap::data_cast(*found);
1724 const Data_Node& data_node = imap::data_cast(*node);
1727 if (
node_comp(data_node, found_data_node))
1730 found = found->children[kLeft];
1732 else if (
node_comp(found_data_node, data_node))
1735 found = found->children[kRight];
1753 Node* find_parent_node(
Node* position,
const Node* node)
1756 Node* found = ETL_NULLPTR;
1760 if (position && node && position != node)
1765 if (position->children[kLeft] != node && position->children[kRight] != node)
1769 const Data_Node& node_data_node = imap::data_cast(*node);
1770 Data_Node& position_data_node = imap::data_cast(*position);
1772 if (
node_comp(node_data_node, position_data_node))
1775 position = position->children[kLeft];
1777 else if (
node_comp(position_data_node, node_data_node))
1780 position = position->children[kRight];
1802 const Node* find_parent_node(
const Node* position,
const Node* node)
const
1805 const Node* found = ETL_NULLPTR;
1809 if (position && node && position != node)
1814 if (position->children[kLeft] != node && position->children[kRight] != node)
1818 const Data_Node& node_data_node = imap::data_cast(*node);
1819 const Data_Node& position_data_node = imap::data_cast(*position);
1821 if (
node_comp(node_data_node, position_data_node))
1824 position = position->children[kLeft];
1826 else if (
node_comp(position_data_node, node_data_node))
1829 position = position->children[kRight];
1853 Node* lower_node = ETL_NULLPTR;
1857 Data_Node& data_node = imap::data_cast(*position);
1861 lower_node = position;
1862 if (position->children[kLeft])
1864 position = position->children[kLeft];
1874 position = position->children[kRight];
1879 lower_node = position;
1880 position = position->children[kLeft];
1890 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1891 Node* find_lower_node(
Node* position,
const K& key)
const
1894 Node* lower_node = ETL_NULLPTR;
1898 Data_Node& data_node = imap::data_cast(*position);
1902 lower_node = position;
1903 if (position->children[kLeft])
1905 position = position->children[kLeft];
1915 position = position->children[kRight];
1920 lower_node = position;
1921 position = position->children[kLeft];
1936 Node* upper_node = ETL_NULLPTR;
1938 Node* node = position;
1942 Data_Node& data_node = imap::data_cast(*node);
1947 node = node->children[kLeft];
1951 node = node->children[kRight];
1953 else if (node->children[kRight])
1970 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1971 Node* find_upper_node(
Node* position,
const K& key)
const
1974 Node* upper_node = ETL_NULLPTR;
1976 Node* node = position;
1980 Data_Node& data_node = imap::data_cast(*node);
1985 node = node->children[kLeft];
1989 node = node->children[kRight];
1991 else if (node->children[kRight])
2013 Node* found = position;
2019 Node* critical_parent_node = ETL_NULLPTR;
2026 if (kNeither != found->weight)
2028 critical_node = found;
2033 Data_Node& found_data_node = imap::data_cast(*found);
2042 else if (
node_comp(found_data_node, node))
2045 found->dir = kRight;
2050 found->dir = kNeither;
2053 critical_node = ETL_NULLPTR;
2056 destroy_data_node(node);
2063 if (found->children[found->dir])
2067 if (kNeither != found->children[found->dir]->weight)
2069 critical_parent_node = found;
2073 found = found->children[found->dir];
2081 found = found->children[found->dir];
2091 if (critical_parent_node == ETL_NULLPTR && critical_node ==
root_node)
2095 else if (critical_parent_node == ETL_NULLPTR && critical_node == position)
2101 if (critical_parent_node != ETL_NULLPTR)
2103 balance_node(critical_parent_node->children[critical_parent_node->dir]);
2124 void next_node(
Node*& position)
2129 if (position->children[kRight])
2138 Node* parent = position;
2143 parent = find_parent_node(
root_node, position);
2145 }
while (parent && parent->children[kRight] == position);
2156 void next_node(
const Node*& position)
const
2161 if (position->children[kRight])
2170 const Node* parent = position;
2175 parent = find_parent_node(
root_node, position);
2177 }
while (parent && parent->children[kRight] == position);
2188 void prev_node(
Node*& position)
2199 if (position->children[kLeft])
2208 Node* parent = position;
2213 parent = find_parent_node(
root_node, position);
2215 }
while (parent && parent->children[kLeft] == position);
2226 void prev_node(
const Node*& position)
const
2237 if (position->children[kLeft])
2246 const Node* parent = position;
2251 parent = find_parent_node(
root_node, position);
2253 }
while (parent && parent->children[kLeft] == position);
2270 Node* found_parent = ETL_NULLPTR;
2271 Node* found = ETL_NULLPTR;
2272 Node* replace_parent = ETL_NULLPTR;
2273 Node* replace = position;
2274 Node* balance_parent = ETL_NULLPTR;
2279 Data_Node& replace_data_node = imap::data_cast(*replace);
2285 replace->dir = kLeft;
2287 else if (
node_comp(replace_data_node, key))
2290 replace->dir = kRight;
2295 replace->dir = replace->children[kLeft] ? kLeft : kRight;
2298 found_parent = replace_parent;
2303 if (replace->children[replace->dir] == ETL_NULLPTR)
2313 if ((replace->weight == kNeither) || (replace->weight == (1 - replace->dir) && replace->children[1 - replace->dir]->weight == kNeither))
2316 balance_parent = replace_parent;
2321 replace_parent = replace;
2322 replace = replace->children[replace->dir];
2331 if (balance->children[balance->dir] == ETL_NULLPTR)
2336 if (balance->weight == kNeither)
2338 balance->weight = 1 - balance->dir;
2340 else if (balance->weight == balance->dir)
2342 balance->weight = kNeither;
2346 int weight = balance->children[1 - balance->dir]->weight;
2348 if (weight == balance->dir)
2351 if (balance_parent == ETL_NULLPTR)
2353 rotate_3node(
root_node, 1 - balance->dir, balance->children[1 - balance->dir]->children[balance->dir]->weight);
2357 rotate_3node(balance_parent->children[balance_parent->dir], 1 - balance->dir,
2358 balance->children[1 - balance->dir]->children[balance->dir]->weight);
2363 else if (weight == kNeither)
2366 if (balance_parent == ETL_NULLPTR)
2373 rotate_2node(balance_parent->children[balance_parent->dir], 1 - balance->dir);
2374 balance_parent->children[balance_parent->dir]->weight = balance->dir;
2378 balance->weight = 1 - balance->dir;
2384 if (balance_parent == ETL_NULLPTR)
2390 rotate_2node(balance_parent->children[balance_parent->dir], 1 - balance->dir);
2396 if (balance == found)
2400 found_parent = balance_parent->children[balance_parent->dir];
2402 found_parent->dir = found_parent->children[kLeft] == found ? kLeft : kRight;
2413 balance_parent = balance;
2414 balance = balance->children[balance->dir];
2421 detach_node(found_parent->children[found_parent->dir], replace_parent->children[replace_parent->dir]);
2439 Data_Node& found_data_node = imap::data_cast(*found);
2445 destroy_data_node(found_data_node);
2457 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
2458 Node* remove_node(
Node*& position,
const K& key)
2463 Node* found_parent = ETL_NULLPTR;
2464 Node* found = ETL_NULLPTR;
2465 Node* replace_parent = ETL_NULLPTR;
2466 Node* replace = position;
2467 Node* balance_parent = ETL_NULLPTR;
2472 Data_Node& replace_data_node = imap::data_cast(*replace);
2478 replace->dir = kLeft;
2480 else if (
node_comp(replace_data_node, key))
2483 replace->dir = kRight;
2488 replace->dir = replace->children[kLeft] ? kLeft : kRight;
2491 found_parent = replace_parent;
2496 if (replace->children[replace->dir] == ETL_NULLPTR)
2506 if ((replace->weight == kNeither) || (replace->weight == (1 - replace->dir) && replace->children[1 - replace->dir]->weight == kNeither))
2509 balance_parent = replace_parent;
2514 replace_parent = replace;
2515 replace = replace->children[replace->dir];
2524 if (balance->children[balance->dir] == ETL_NULLPTR)
2529 if (balance->weight == kNeither)
2531 balance->weight = 1 - balance->dir;
2533 else if (balance->weight == balance->dir)
2535 balance->weight = kNeither;
2539 int weight = balance->children[1 - balance->dir]->weight;
2541 if (weight == balance->dir)
2544 if (balance_parent == ETL_NULLPTR)
2546 rotate_3node(
root_node, 1 - balance->dir, balance->children[1 - balance->dir]->children[balance->dir]->weight);
2550 rotate_3node(balance_parent->children[balance_parent->dir], 1 - balance->dir,
2551 balance->children[1 - balance->dir]->children[balance->dir]->weight);
2556 else if (weight == kNeither)
2559 if (balance_parent == ETL_NULLPTR)
2566 rotate_2node(balance_parent->children[balance_parent->dir], 1 - balance->dir);
2567 balance_parent->children[balance_parent->dir]->weight = balance->dir;
2571 balance->weight = 1 - balance->dir;
2577 if (balance_parent == ETL_NULLPTR)
2583 rotate_2node(balance_parent->children[balance_parent->dir], 1 - balance->dir);
2589 if (balance == found)
2593 found_parent = balance_parent->children[balance_parent->dir];
2595 found_parent->dir = found_parent->children[kLeft] == found ? kLeft : kRight;
2606 balance_parent = balance;
2607 balance = balance->children[balance->dir];
2614 detach_node(found_parent->children[found_parent->dir], replace_parent->children[replace_parent->dir]);
2632 Data_Node& found_data_node = imap::data_cast(*found);
2638 destroy_data_node(found_data_node);
2652#if defined(ETL_POLYMORPHIC_MAP) || defined(ETL_POLYMORPHIC_CONTAINERS)