633 typedef ETL_OR_STD::pair<const TKey, TMapped> value_type;
634 typedef const TKey key_type;
635 typedef TMapped mapped_type;
636 typedef TKeyCompare key_compare;
637 typedef value_type& reference;
638 typedef const value_type& const_reference;
640 typedef value_type&& rvalue_reference;
642 typedef value_type* pointer;
643 typedef const value_type* const_pointer;
644 typedef size_t size_type;
646 typedef const key_type& const_key_reference;
648 typedef key_type&& rvalue_key_reference;
655 bool operator()(const_reference lhs, const_reference rhs)
const
657 return (kcompare(lhs.first, rhs.first));
662 key_compare kcompare;
672 explicit Data_Node(value_type value_)
685 return kcompare(node1.value.first, node2.value.first);
688 bool node_comp(
const Data_Node& node, const_key_reference key)
const
690 return kcompare(node.value.first, key);
693 bool node_comp(const_key_reference key,
const Data_Node& node)
const
695 return kcompare(key, node.value.first);
699 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
702 return kcompare(node.value.first, key);
705 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
708 return kcompare(key, node.value.first);
717 key_compare kcompare;
741 return static_cast<const Data_Node*
>(p_node);
749 return static_cast<const Data_Node&
>(node);
757 class iterator :
public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, value_type>
761 friend class imultimap;
762 friend class const_iterator;
765 : p_multimap(ETL_NULLPTR)
766 , p_node(ETL_NULLPTR)
772 , p_node(ETL_NULLPTR)
782 iterator(
const iterator& other)
783 : p_multimap(other.p_multimap)
784 , p_node(other.p_node)
790 iterator& operator++()
792 p_multimap->next_node(p_node);
796 iterator operator++(
int)
798 iterator temp(*
this);
799 p_multimap->next_node(p_node);
803 iterator& operator--()
805 p_multimap->prev_node(p_node);
809 iterator operator--(
int)
811 iterator temp(*
this);
812 p_multimap->prev_node(p_node);
816 iterator& operator=(
const iterator& other)
818 p_multimap = other.p_multimap;
819 p_node = other.p_node;
823 reference operator*()
const
825 return imultimap::data_cast(p_node)->value;
828 pointer operator&()
const
830 return &(imultimap::data_cast(p_node)->value);
833 pointer operator->()
const
835 return &(imultimap::data_cast(p_node)->value);
838 friend bool operator==(
const iterator& lhs,
const iterator& rhs)
840 return lhs.p_multimap == rhs.p_multimap && lhs.p_node == rhs.p_node;
843 friend bool operator!=(
const iterator& lhs,
const iterator& rhs)
845 return !(lhs == rhs);
851 imultimap* p_multimap;
861 class const_iterator :
public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, const value_type>
865 friend class imultimap;
868 : p_multimap(ETL_NULLPTR)
869 , p_node(ETL_NULLPTR)
873 const_iterator(
const imultimap&
multimap)
875 , p_node(ETL_NULLPTR)
879 const_iterator(
const imultimap&
multimap,
const Node* node)
886 : p_multimap(other.p_multimap)
887 , p_node(other.p_node)
891 const_iterator(
const const_iterator& other)
892 : p_multimap(other.p_multimap)
893 , p_node(other.p_node)
899 const_iterator& operator++()
901 p_multimap->next_node(p_node);
905 const_iterator operator++(
int)
907 const_iterator temp(*
this);
908 p_multimap->next_node(p_node);
912 const_iterator& operator--()
914 p_multimap->prev_node(p_node);
918 const_iterator operator--(
int)
920 const_iterator temp(*
this);
921 p_multimap->prev_node(p_node);
925 const_iterator& operator=(
const const_iterator& other)
927 p_multimap = other.p_multimap;
928 p_node = other.p_node;
932 const_reference operator*()
const
934 return imultimap::data_cast(p_node)->value;
937 const_pointer operator&()
const
939 return imultimap::data_cast(p_node)->value;
942 const_pointer operator->()
const
944 return &(imultimap::data_cast(p_node)->value);
947 friend bool operator==(
const const_iterator& lhs,
const const_iterator& rhs)
949 return lhs.p_multimap == rhs.p_multimap && lhs.p_node == rhs.p_node;
952 friend bool operator!=(
const const_iterator& lhs,
const const_iterator& rhs)
954 return !(lhs == rhs);
966 const imultimap* p_multimap;
973 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
975 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
976 typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
1031 return reverse_iterator(
iterator(*
this));
1053 const_reverse_iterator
rend()
const
1082 template <
typename TIterator>
1102 size_type
count(const_key_reference key)
const
1104 return count_nodes(key);
1109 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1112 return count_nodes(key);
1120 ETL_OR_STD::pair<iterator, iterator>
equal_range(const_key_reference key)
1122 return ETL_OR_STD::make_pair<iterator, iterator>(
iterator(*
this, find_lower_node(
root_node, key)),
1128 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1129 ETL_OR_STD::pair<iterator, iterator>
equal_range(
const K& key)
1131 return ETL_OR_STD::make_pair<iterator, iterator>(
iterator(*
this, find_lower_node(
root_node, key)),
1140 ETL_OR_STD::pair<const_iterator, const_iterator>
equal_range(const_key_reference key)
const
1142 return ETL_OR_STD::make_pair<const_iterator, const_iterator>(
const_iterator(*
this, find_lower_node(
root_node, key)),
1148 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1149 ETL_OR_STD::pair<const_iterator, const_iterator>
equal_range(
const K& key)
const
1151 return ETL_OR_STD::make_pair<const_iterator, const_iterator>(
const_iterator(*
this, find_lower_node(
root_node, key)),
1173 Node* node =
const_cast<Node*
>(position.p_node);
1192 while (lower != upper)
1197 lower =
erase(lower);
1206 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1207 size_type
erase(K&& key)
1213 while (lower != upper)
1218 lower =
erase(lower);
1231 while (first != last)
1233 first =
erase(first);
1236 return last.to_iterator();
1251 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1270 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1286 Node* inserted_node = ETL_NULLPTR;
1291 Data_Node& node = allocate_data_node(value);
1294 inserted_node = insert_node(
root_node, node);
1297 return iterator(*
this, inserted_node);
1310 Node* inserted_node = ETL_NULLPTR;
1315 Data_Node& node = allocate_data_node(etl::move(value));
1318 inserted_node = insert_node(
root_node, node);
1321 return iterator(*
this, inserted_node);
1349 return insert(etl::move(value));
1361 template <
class TIterator>
1364 while (first != last)
1384 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1404 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1424 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1444 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1478 while (from != rhs.end())
1480 this->
insert(etl::move(*from));
1515 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1529 , p_node_pool(&node_pool)
1540 while (item !=
end())
1551 Data_Node& allocate_data_node(const_reference value)
1553 Data_Node* node = allocate_data_node();
1554 ::new (&node->value) const
value_type(value);
1555 ETL_INCREMENT_DEBUG_COUNT;
1563 Data_Node& allocate_data_node(rvalue_reference value)
1565 Data_Node* node = allocate_data_node();
1567 ETL_INCREMENT_DEBUG_COUNT;
1575 Data_Node* allocate_data_node()
1578 return (p_node_pool->*func)();
1584 void destroy_data_node(Data_Node& node)
1586 node.value.~value_type();
1587 p_node_pool->release(&node);
1588 ETL_DECREMENT_DEBUG_COUNT;
1594 size_type count_nodes(const_key_reference key)
const
1597 size_type result = 0;
1604 while (lower != upper)
1607 const Data_Node& data_node = imultimap::data_cast(*lower);
1625 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1626 size_type count_nodes(
const K& key)
const
1629 size_type result = 0;
1636 while (lower != upper)
1639 const Data_Node& data_node = imultimap::data_cast(*lower);
1659 Node* find_node(
Node* position, const_key_reference key)
1661 Node* found = ETL_NULLPTR;
1665 Data_Node& data_node = imultimap::data_cast(*position);
1670 position = position->children[(uint_least8_t)kLeft];
1675 position = position->children[(uint_least8_t)kRight];
1681 position = position->children[(uint_least8_t)kLeft];
1691 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1692 Node* find_node(
Node* position,
const K& key)
1694 Node* found = ETL_NULLPTR;
1698 Data_Node& data_node = imultimap::data_cast(*position);
1703 position = position->children[(uint_least8_t)kLeft];
1708 position = position->children[(uint_least8_t)kRight];
1714 position = position->children[(uint_least8_t)kLeft];
1726 const Node* find_node(
const Node* position, const_key_reference key)
const
1728 const Node* found = ETL_NULLPTR;
1732 const Data_Node& data_node = imultimap::data_cast(*position);
1737 position = position->children[(uint_least8_t)kLeft];
1742 position = position->children[(uint_least8_t)kRight];
1748 position = position->children[(uint_least8_t)kLeft];
1760 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1761 const Node* find_node(
const Node* position,
const K& key)
const
1763 const Node* found = ETL_NULLPTR;
1767 const Data_Node& data_node = imultimap::data_cast(*position);
1772 position = position->children[(uint_least8_t)kLeft];
1777 position = position->children[(uint_least8_t)kRight];
1783 position = position->children[(uint_least8_t)kLeft];
1795 Node* find_lower_node(
Node* position, const_key_reference key)
const
1798 Node* lower_node = ETL_NULLPTR;
1802 Data_Node& data_node = imultimap::data_cast(*position);
1806 lower_node = position;
1807 if (position->children[(uint_least8_t)kLeft])
1809 position = position->children[(uint_least8_t)kLeft];
1819 position = position->children[(uint_least8_t)kRight];
1824 lower_node = position;
1825 position = position->children[(uint_least8_t)kLeft];
1835 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1836 Node* find_lower_node(
Node* position,
const K& key)
const
1839 Node* lower_node = ETL_NULLPTR;
1843 Data_Node& data_node = imultimap::data_cast(*position);
1847 lower_node = position;
1848 if (position->children[(uint_least8_t)kLeft])
1850 position = position->children[(uint_least8_t)kLeft];
1860 position = position->children[(uint_least8_t)kRight];
1865 lower_node = position;
1866 position = position->children[(uint_least8_t)kLeft];
1878 Node* find_upper_node(
Node* position, const_key_reference key)
const
1881 Node* upper_node = ETL_NULLPTR;
1887 Data_Node& data_node = imultimap::data_cast(*position);
1891 position = position->children[(uint_least8_t)kRight];
1895 upper_node = position;
1897 if (!found && position->children[(uint_least8_t)kLeft])
1899 position = position->children[(uint_least8_t)kLeft];
1920 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1921 Node* find_upper_node(
Node* position,
const K& key)
const
1924 Node* upper_node = ETL_NULLPTR;
1930 Data_Node& data_node = imultimap::data_cast(*position);
1934 position = position->children[(uint_least8_t)kRight];
1938 upper_node = position;
1940 if (!found && position->children[(uint_least8_t)kLeft])
1942 position = position->children[(uint_least8_t)kLeft];
1968 Node* found = position;
1974 Node* critical_parent_node = ETL_NULLPTR;
1981 if ((uint_least8_t)kNeither != found->weight)
1983 critical_node = found;
1988 Data_Node& found_data_node = imultimap::data_cast(*found);
1994 found->dir = (uint_least8_t)kLeft;
1997 else if (
node_comp(found_data_node, node))
2000 found->dir = (uint_least8_t)kRight;
2006 found->dir = (uint_least8_t)kRight;
2010 if (found->children[found->dir])
2014 if ((uint_least8_t)kNeither != found->children[found->dir]->weight)
2016 critical_parent_node = found;
2020 found = found->children[found->dir];
2025 attach_node(found, found->children[found->dir], node);
2028 found = found->children[found->dir];
2038 if (critical_parent_node == ETL_NULLPTR && critical_node ==
root_node)
2042 else if (critical_parent_node == ETL_NULLPTR && critical_node == position)
2048 if (critical_parent_node != ETL_NULLPTR)
2050 balance_node(critical_parent_node->children[critical_parent_node->dir]);
2072 void remove_node(
Node* node)
2078 Data_Node& data_node = imultimap::data_cast(*node);
2092 node->parent->dir = node->parent->children[(uint_least8_t)kLeft] == node ? (uint_least8_t)kLeft : (uint_least8_t)kRight;
2095 node = node->parent;
2114 node->dir = node->children[(uint_least8_t)kLeft] ? (uint_least8_t)kLeft : (uint_least8_t)kRight;
2125 if ((node->weight == (uint_least8_t)kNeither)
2126 || (node->weight == (1 - node->dir) && node->children[1 - node->dir]->weight == (uint_least8_t)kNeither))
2133 node = node->children[node->dir];
2147 if (node->children[node->dir] == ETL_NULLPTR)
2157 if ((node->weight == (uint_least8_t)kNeither)
2158 || (node->weight == (1 - node->dir) && node->children[1 - node->dir]->weight == (uint_least8_t)kNeither))
2166 node = node->children[node->dir];
2169 Data_Node& replace_data_node = imultimap::data_cast(*node);
2172 if (
node_comp(data_node, replace_data_node))
2175 node->dir = (uint_least8_t)kLeft;
2177 else if (
node_comp(replace_data_node, data_node))
2180 node->dir = (uint_least8_t)kRight;
2185 node->dir = 1 - found->dir;
2194 if (balance->children[balance->dir] == ETL_NULLPTR)
2202 if (balance->weight == (uint_least8_t)kNeither)
2204 balance->weight = 1 - balance->dir;
2208 else if (balance->weight == balance->dir)
2210 balance->weight = (uint_least8_t)kNeither;
2215 int weight = balance->children[1 - balance->dir]->weight;
2217 if (weight == balance->dir)
2220 if (balance->parent == ETL_NULLPTR)
2222 rotate_3node(
root_node, 1 - balance->dir, balance->children[1 - balance->dir]->children[balance->dir]->weight);
2226 rotate_3node(balance->parent->children[balance->parent->dir], 1 - balance->dir,
2227 balance->children[1 - balance->dir]->children[balance->dir]->weight);
2232 else if (weight == (uint_least8_t)kNeither)
2235 if (balance->parent == ETL_NULLPTR)
2245 Node* old_parent = balance->parent;
2246 rotate_2node(balance->parent->children[balance->parent->dir], 1 - balance->dir);
2247 old_parent->children[old_parent->dir]->weight = balance->dir;
2251 balance->weight = 1 - balance->dir;
2257 if (balance->parent == ETL_NULLPTR)
2263 rotate_2node(balance->parent->children[balance->parent->dir], 1 - balance->dir);
2269 balance = balance->children[balance->dir];
2276 detach_node(found->parent->children[found->parent->dir], node->parent->children[node->parent->dir]);
2297 destroy_data_node(data_node);
2307#if defined(ETL_POLYMORPHIC_MULTIMAP) || defined(ETL_POLYMORPHIC_CONTAINERS)