472 typedef TKey key_type;
473 typedef ETL_OR_STD::pair<const TKey, TMapped> value_type;
474 typedef TMapped mapped_type;
475 typedef TKeyCompare key_compare;
476 typedef value_type& reference;
477 typedef const value_type& const_reference;
479 typedef value_type&& rvalue_reference;
481 typedef value_type* pointer;
482 typedef const value_type* const_pointer;
483 typedef size_t size_type;
488 typedef key_type&& rvalue_key_reference;
490 typedef mapped_type& mapped_reference;
491 typedef const mapped_type& const_mapped_reference;
497 bool operator()(const_reference lhs, const_reference rhs)
const
499 return (kcompare(lhs.first, rhs.first));
504 key_compare kcompare;
514 explicit Data_Node(value_type value_)
532 return kcompare(node1.value.first, node2.value.first);
537 return kcompare(node.value.first, key);
542 return kcompare(key, node.value.first);
546 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
549 return kcompare(node.value.first, key);
552 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
555 return kcompare(key, node.value.first);
564 key_compare kcompare;
588 return static_cast<const Data_Node*
>(p_node);
596 return static_cast<const Data_Node&
>(node);
604 class iterator :
public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, value_type>
609 friend class const_iterator;
613 , p_node(ETL_NULLPTR)
619 , p_node(ETL_NULLPTR)
623 iterator(imap&
map,
Node* node)
629 iterator(
const iterator& other)
631 , p_node(other.p_node)
639 iterator& operator ++()
641 p_map->next_node(p_node);
645 iterator operator ++(
int)
647 iterator temp(*
this);
648 p_map->next_node(p_node);
652 iterator& operator --()
654 p_map->prev_node(p_node);
658 iterator operator --(
int)
660 iterator temp(*
this);
661 p_map->prev_node(p_node);
665 iterator& operator =(
const iterator& other)
668 p_node = other.p_node;
672 reference operator *()
const
674 return imap::data_cast(p_node)->value;
677 pointer operator &()
const
679 return &(imap::data_cast(p_node)->value);
682 pointer operator ->()
const
684 return &(imap::data_cast(p_node)->value);
687 friend bool operator == (
const iterator& lhs,
const iterator& rhs)
689 return lhs.p_map == rhs.p_map && lhs.p_node == rhs.p_node;
692 friend bool operator != (
const iterator& lhs,
const iterator& rhs)
694 return !(lhs == rhs);
711 class const_iterator :
public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, const value_type>
719 , p_node(ETL_NULLPTR)
723 const_iterator(
const imap&
map)
725 , p_node(ETL_NULLPTR)
729 const_iterator(
const imap&
map,
const Node* node)
737 , p_node(other.p_node)
741 const_iterator(
const const_iterator& other)
743 , p_node(other.p_node)
751 const_iterator& operator ++()
753 p_map->next_node(p_node);
757 const_iterator operator ++(
int)
759 const_iterator temp(*
this);
760 p_map->next_node(p_node);
764 const_iterator& operator --()
766 p_map->prev_node(p_node);
770 const_iterator operator --(
int)
772 const_iterator temp(*
this);
773 p_map->prev_node(p_node);
777 const_iterator& operator =(
const const_iterator& other)
780 p_node = other.p_node;
784 const_reference operator *()
const
786 return imap::data_cast(p_node)->value;
789 const_pointer operator &()
const
791 return imap::data_cast(p_node)->value;
794 const_pointer operator ->()
const
796 return &(imap::data_cast(p_node)->value);
799 friend bool operator == (
const const_iterator& lhs,
const const_iterator& rhs)
801 return lhs.p_map == rhs.p_map && lhs.p_node == rhs.p_node;
804 friend bool operator != (
const const_iterator& lhs,
const const_iterator& rhs)
806 return !(lhs == rhs);
826 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
828 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
829 typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
884 return reverse_iterator(
iterator(*
this));
906 const_reverse_iterator
rend()
const
922 const_reverse_iterator
crend()
const
933 mapped_reference
operator [](rvalue_key_reference key)
937 if (!i_element.p_node)
940 Node* inserted_node = ETL_NULLPTR;
945 Data_Node& node = allocate_data_node_with_key(etl::move(key));
948 inserted_node = insert_node(
root_node, node);
951 i_element =
iterator(*
this, inserted_node);
954 return i_element->second;
967 if (!i_element.p_node)
970 Node* inserted_node = ETL_NULLPTR;
975 Data_Node& node = allocate_data_node_with_key(key);
978 inserted_node = insert_node(
root_node, node);
981 i_element =
iterator(*
this, inserted_node);
984 return i_element->second;
999 return i_element->second;
1004 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1005 mapped_reference
at(
const K& key)
1011 return i_element->second;
1027 return i_element->second;
1032 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1033 const_mapped_reference
at(
const K& key)
const
1039 return i_element->second;
1050 template <
typename TIterator>
1072 return find_node(
root_node, key) ? 1 : 0;
1077 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1080 return find_node(
root_node, key) ? 1 : 0;
1090 return ETL_OR_STD::make_pair<iterator, iterator>(
iterator(*
this, find_lower_node(
root_node, key)),
1096 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1097 ETL_OR_STD::pair<iterator, iterator>
equal_range(
const K& key)
1099 return ETL_OR_STD::make_pair<iterator, iterator>(
iterator(*
this, find_lower_node(
root_node, key)),
1110 return ETL_OR_STD::make_pair<const_iterator, const_iterator>(
const_iterator(*
this, find_lower_node(
root_node, key)),
1116 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1117 ETL_OR_STD::pair<const_iterator, const_iterator>
equal_range(
const K& key)
const
1119 return ETL_OR_STD::make_pair<const_iterator, const_iterator>(
const_iterator(*
this, find_lower_node(
root_node, key)),
1130 Node*& reference_node = find_node(
root_node, position.p_node);
1131 iterator next(*
this, reference_node);
1134 remove_node(
root_node, (*position).first);
1145 return remove_node(
root_node, key) ? 1 : 0;
1150 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1154 return remove_node(
root_node, etl::forward<K>(key)) ? 1 : 0;
1163 while (first != last)
1165 first =
erase(first);
1168 return last.to_iterator();
1183 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1202 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1214 ETL_OR_STD::pair<iterator, bool>
insert(const_reference value)
1217 Node* inserted_node = ETL_NULLPTR;
1218 bool inserted =
false;
1223 Data_Node& node = allocate_data_node(value);
1226 inserted_node = insert_node(
root_node, node);
1227 inserted = inserted_node == &node;
1230 return ETL_OR_STD::make_pair(
iterator(*
this, inserted_node), inserted);
1239 ETL_OR_STD::pair<iterator, bool>
insert(rvalue_reference value)
1242 Node* inserted_node = ETL_NULLPTR;
1243 bool inserted =
false;
1248 Data_Node& node = allocate_data_node(etl::move(value));
1251 inserted_node = insert_node(
root_node, node);
1252 inserted = inserted_node == &node;
1255 return ETL_OR_STD::make_pair(
iterator(*
this, inserted_node), inserted);
1268 Node* inserted_node = ETL_NULLPTR;
1273 Data_Node& node = allocate_data_node(value);
1276 inserted_node = insert_node(
root_node, node);
1279 return iterator(*
this, inserted_node);
1292 Node* inserted_node = ETL_NULLPTR;
1297 Data_Node& node = allocate_data_node(etl::move(value));
1300 inserted_node = insert_node(
root_node, node);
1303 return iterator(*
this, inserted_node);
1314 template <
class TIterator>
1317 while (first != last)
1337 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1357 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1377 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1397 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1431 while (from != rhs.end())
1433 this->
insert(etl::move(*from));
1468 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1482 , p_node_pool(&node_pool)
1493 while (item !=
end())
1504 Data_Node& allocate_data_node(const_reference value)
1506 Data_Node* node = allocate_data_node();
1508 ETL_INCREMENT_DEBUG_COUNT;
1517 Data_Node* node = allocate_data_node();
1520 ::new ((
void*)
etl::
addressof(node->value.second)) mapped_type();
1521 ETL_INCREMENT_DEBUG_COUNT;
1529 Data_Node& allocate_data_node(rvalue_reference value)
1531 Data_Node* node = allocate_data_node();
1533 ETL_INCREMENT_DEBUG_COUNT;
1540 Data_Node& allocate_data_node_with_key(rvalue_key_reference key)
1542 Data_Node* node = allocate_data_node();
1545 ::new ((
void*)
etl::
addressof(node->value.second)) mapped_type();
1546 ETL_INCREMENT_DEBUG_COUNT;
1555 Data_Node* allocate_data_node()
1558 return (p_node_pool->*func)();
1564 void destroy_data_node(Data_Node& node)
1566 node.value.~value_type();
1567 p_node_pool->release(&node);
1568 ETL_DECREMENT_DEBUG_COUNT;
1576 Node* found = position;
1580 Data_Node& found_data_node = imap::data_cast(*found);
1586 found = found->children[kLeft];
1588 else if (
node_comp(found_data_node, key))
1591 found = found->children[kRight];
1606 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1607 Node* find_node(
Node* position,
const K& key)
1609 Node* found = position;
1613 Data_Node& found_data_node = imap::data_cast(*found);
1619 found = found->children[kLeft];
1621 else if (
node_comp(found_data_node, key))
1624 found = found->children[kRight];
1643 const Node* found = position;
1647 const Data_Node& found_data_node = imap::data_cast(*found);
1653 found = found->children[kLeft];
1655 else if (
node_comp(found_data_node, key))
1658 found = found->children[kRight];
1673 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1674 const Node* find_node(
const Node* position,
const K& key)
const
1676 const Node* found = position;
1680 const Data_Node& found_data_node = imap::data_cast(*found);
1686 found = found->children[kLeft];
1688 else if (
node_comp(found_data_node, key))
1691 found = found->children[kRight];
1710 Node* found = position;
1713 if (found->children[kLeft] == node)
1715 return found->children[kLeft];
1717 else if (found->children[kRight] == node)
1719 return found->children[kRight];
1724 Data_Node& found_data_node = imap::data_cast(*found);
1725 const Data_Node& data_node = imap::data_cast(*node);
1728 if (
node_comp(data_node, found_data_node))
1731 found = found->children[kLeft];
1733 else if (
node_comp(found_data_node, data_node))
1736 found = found->children[kRight];
1754 Node* find_parent_node(
Node* position,
const Node* node)
1757 Node* found = ETL_NULLPTR;
1760 if (position && node && position != node)
1765 if (position->children[kLeft] != node &&
1766 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;
1808 if (position && node && position != node)
1813 if (position->children[kLeft] != node &&
1814 position->children[kRight] != node)
1817 const Data_Node& node_data_node = imap::data_cast(*node);
1818 const Data_Node& position_data_node = imap::data_cast(*position);
1820 if (
node_comp(node_data_node, position_data_node))
1823 position = position->children[kLeft];
1825 else if (
node_comp(position_data_node, node_data_node))
1828 position = position->children[kRight];
1852 Node* lower_node = ETL_NULLPTR;
1856 Data_Node& data_node = imap::data_cast(*position);
1860 lower_node = position;
1861 if (position->children[kLeft])
1863 position = position->children[kLeft];
1873 position = position->children[kRight];
1878 lower_node = position;
1879 position = position->children[kLeft];
1889 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1890 Node* find_lower_node(
Node* position,
const K& key)
const
1893 Node* lower_node = ETL_NULLPTR;
1897 Data_Node& data_node = imap::data_cast(*position);
1901 lower_node = position;
1902 if (position->children[kLeft])
1904 position = position->children[kLeft];
1914 position = position->children[kRight];
1919 lower_node = position;
1920 position = position->children[kLeft];
1935 Node* upper_node = ETL_NULLPTR;
1937 Node* node = position;
1941 Data_Node& data_node = imap::data_cast(*node);
1946 node = node->children[kLeft];
1950 node = node->children[kRight];
1952 else if (node->children[kRight])
1969 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1970 Node* find_upper_node(
Node* position,
const K& key)
const
1973 Node* upper_node = ETL_NULLPTR;
1975 Node* node = position;
1979 Data_Node& data_node = imap::data_cast(*node);
1984 node = node->children[kLeft];
1988 node = node->children[kRight];
1990 else if (node->children[kRight])
2012 Node* found = position;
2018 Node* critical_parent_node = ETL_NULLPTR;
2025 if (kNeither != found->weight)
2027 critical_node = found;
2031 Data_Node& found_data_node = imap::data_cast(*found);
2040 else if (
node_comp(found_data_node, node))
2043 found->dir = kRight;
2048 found->dir = kNeither;
2051 critical_node = ETL_NULLPTR;
2054 destroy_data_node(node);
2061 if (found->children[found->dir])
2065 if (kNeither != found->children[found->dir]->weight)
2067 critical_parent_node = found;
2071 found = found->children[found->dir];
2079 found = found->children[found->dir];
2089 if (critical_parent_node == ETL_NULLPTR && critical_node ==
root_node)
2093 else if (critical_parent_node == ETL_NULLPTR && critical_node == position)
2099 if (critical_parent_node != ETL_NULLPTR)
2101 balance_node(critical_parent_node->children[critical_parent_node->dir]);
2122 void next_node(
Node*&position)
2127 if (position->children[kRight])
2136 Node* parent = position;
2141 parent = find_parent_node(
root_node, position);
2143 }
while (parent && parent->children[kRight] == position);
2154 void next_node(
const Node*& position)
const
2159 if (position->children[kRight])
2168 const Node* parent = position;
2173 parent = find_parent_node(
root_node, position);
2175 }
while (parent && parent->children[kRight] == position);
2186 void prev_node(
Node*&position)
2197 if (position->children[kLeft])
2206 Node* parent = position;
2211 parent = find_parent_node(
root_node, position);
2213 }
while (parent && parent->children[kLeft] == position);
2224 void prev_node(
const Node*& position)
const
2235 if (position->children[kLeft])
2244 const Node* parent = position;
2249 parent = find_parent_node(
root_node, position);
2251 }
while (parent && parent->children[kLeft] == position);
2268 Node* found_parent = ETL_NULLPTR;
2269 Node* found = ETL_NULLPTR;
2270 Node* replace_parent = ETL_NULLPTR;
2271 Node* replace = position;
2272 Node* balance_parent = ETL_NULLPTR;
2277 Data_Node& replace_data_node = imap::data_cast(*replace);
2283 replace->dir = kLeft;
2285 else if (
node_comp(replace_data_node, key))
2288 replace->dir = kRight;
2293 replace->dir = replace->children[kLeft] ? kLeft : kRight;
2296 found_parent = replace_parent;
2301 if (replace->children[replace->dir] == ETL_NULLPTR)
2311 if ((replace->weight == kNeither) ||
2312 (replace->weight == (1 - replace->dir) &&
2313 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)
2354 balance->children[1 - balance->dir]->children[balance->dir]->weight);
2358 rotate_3node(balance_parent->children[balance_parent->dir], 1 - balance->dir,
2359 balance->children[1 - balance->dir]->children[balance->dir]->weight);
2364 else if (weight == kNeither)
2367 if (balance_parent == ETL_NULLPTR)
2374 rotate_2node(balance_parent->children[balance_parent->dir], 1 - balance->dir);
2375 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],
2422 replace_parent->children[replace_parent->dir]);
2440 Data_Node& found_data_node = imap::data_cast(*found);
2446 destroy_data_node(found_data_node);
2458 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
2459 Node* remove_node(
Node*& position,
const K& key)
2464 Node* found_parent = ETL_NULLPTR;
2465 Node* found = ETL_NULLPTR;
2466 Node* replace_parent = ETL_NULLPTR;
2467 Node* replace = position;
2468 Node* balance_parent = ETL_NULLPTR;
2473 Data_Node& replace_data_node = imap::data_cast(*replace);
2479 replace->dir = kLeft;
2481 else if (
node_comp(replace_data_node, key))
2484 replace->dir = kRight;
2489 replace->dir = replace->children[kLeft] ? kLeft : kRight;
2492 found_parent = replace_parent;
2497 if (replace->children[replace->dir] == ETL_NULLPTR)
2507 if ((replace->weight == kNeither) ||
2508 (replace->weight == (1 - replace->dir) &&
2509 replace->children[1 - replace->dir]->weight == kNeither))
2512 balance_parent = replace_parent;
2517 replace_parent = replace;
2518 replace = replace->children[replace->dir];
2527 if (balance->children[balance->dir] == ETL_NULLPTR)
2532 if (balance->weight == kNeither)
2534 balance->weight = 1 - balance->dir;
2536 else if (balance->weight == balance->dir)
2538 balance->weight = kNeither;
2542 int weight = balance->children[1 - balance->dir]->weight;
2544 if (weight == balance->dir)
2547 if (balance_parent == ETL_NULLPTR)
2550 balance->children[1 - balance->dir]->children[balance->dir]->weight);
2554 rotate_3node(balance_parent->children[balance_parent->dir], 1 - balance->dir,
2555 balance->children[1 - balance->dir]->children[balance->dir]->weight);
2560 else if (weight == kNeither)
2563 if (balance_parent == ETL_NULLPTR)
2570 rotate_2node(balance_parent->children[balance_parent->dir], 1 - balance->dir);
2571 balance_parent->children[balance_parent->dir]->weight = balance->dir;
2574 balance->weight = 1 - balance->dir;
2580 if (balance_parent == ETL_NULLPTR)
2586 rotate_2node(balance_parent->children[balance_parent->dir], 1 - balance->dir);
2592 if (balance == found)
2596 found_parent = balance_parent->children[balance_parent->dir];
2598 found_parent->dir = found_parent->children[kLeft] == found ? kLeft : kRight;
2609 balance_parent = balance;
2610 balance = balance->children[balance->dir];
2617 detach_node(found_parent->children[found_parent->dir],
2618 replace_parent->children[replace_parent->dir]);
2636 Data_Node& found_data_node = imap::data_cast(*found);
2642 destroy_data_node(found_data_node);
2656#if defined(ETL_POLYMORPHIC_MAP) || defined(ETL_POLYMORPHIC_CONTAINERS)