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)
1379#if ETL_USING_CPP11 && ETL_NOT_USING_STLPORT
1384 template <
typename... Args>
1390 Data_Node& node = allocate_data_node_from_args(etl::forward<Args>(args)...);
1393 Node* inserted_node = insert_node(
root_node, node);
1396 return iterator(*
this, inserted_node);
1413 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1433 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1453 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1473 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1507 while (from != rhs.end())
1509 this->
insert(etl::move(*from));
1544 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1558 , p_node_pool(&node_pool)
1569 while (item !=
end())
1580 Data_Node& allocate_data_node(const_reference value)
1582 Data_Node* node = allocate_data_node();
1583 ::new (&node->value) const
value_type(value);
1584 ETL_INCREMENT_DEBUG_COUNT;
1592 Data_Node& allocate_data_node(rvalue_reference value)
1594 Data_Node* node = allocate_data_node();
1596 ETL_INCREMENT_DEBUG_COUNT;
1600 #if ETL_NOT_USING_STLPORT
1604 template <
typename... Args>
1605 Data_Node& allocate_data_node_from_args(Args&&... args)
1607 Data_Node* node = allocate_data_node();
1608 ::new (&node->value) const
value_type(
etl::forward<Args>(args)...);
1609 ETL_INCREMENT_DEBUG_COUNT;
1619 Data_Node* allocate_data_node()
1622 return (p_node_pool->*func)();
1628 void destroy_data_node(Data_Node& node)
1630 node.value.~value_type();
1631 p_node_pool->release(&node);
1632 ETL_DECREMENT_DEBUG_COUNT;
1638 size_type count_nodes(const_key_reference key)
const
1641 size_type result = 0;
1648 while (lower != upper)
1651 const Data_Node& data_node = imultimap::data_cast(*lower);
1669 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1670 size_type count_nodes(
const K& key)
const
1673 size_type result = 0;
1680 while (lower != upper)
1683 const Data_Node& data_node = imultimap::data_cast(*lower);
1703 Node* find_node(
Node* position, const_key_reference key)
1705 Node* found = ETL_NULLPTR;
1709 Data_Node& data_node = imultimap::data_cast(*position);
1714 position = position->children[(uint_least8_t)kLeft];
1719 position = position->children[(uint_least8_t)kRight];
1725 position = position->children[(uint_least8_t)kLeft];
1735 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1736 Node* find_node(
Node* position,
const K& key)
1738 Node* found = ETL_NULLPTR;
1742 Data_Node& data_node = imultimap::data_cast(*position);
1747 position = position->children[(uint_least8_t)kLeft];
1752 position = position->children[(uint_least8_t)kRight];
1758 position = position->children[(uint_least8_t)kLeft];
1770 const Node* find_node(
const Node* position, const_key_reference key)
const
1772 const Node* found = ETL_NULLPTR;
1776 const Data_Node& data_node = imultimap::data_cast(*position);
1781 position = position->children[(uint_least8_t)kLeft];
1786 position = position->children[(uint_least8_t)kRight];
1792 position = position->children[(uint_least8_t)kLeft];
1804 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1805 const Node* find_node(
const Node* position,
const K& key)
const
1807 const Node* found = ETL_NULLPTR;
1811 const Data_Node& data_node = imultimap::data_cast(*position);
1816 position = position->children[(uint_least8_t)kLeft];
1821 position = position->children[(uint_least8_t)kRight];
1827 position = position->children[(uint_least8_t)kLeft];
1839 Node* find_lower_node(
Node* position, const_key_reference key)
const
1842 Node* lower_node = ETL_NULLPTR;
1846 Data_Node& data_node = imultimap::data_cast(*position);
1850 lower_node = position;
1851 if (position->children[(uint_least8_t)kLeft])
1853 position = position->children[(uint_least8_t)kLeft];
1863 position = position->children[(uint_least8_t)kRight];
1868 lower_node = position;
1869 position = position->children[(uint_least8_t)kLeft];
1879 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1880 Node* find_lower_node(
Node* position,
const K& key)
const
1883 Node* lower_node = ETL_NULLPTR;
1887 Data_Node& data_node = imultimap::data_cast(*position);
1891 lower_node = position;
1892 if (position->children[(uint_least8_t)kLeft])
1894 position = position->children[(uint_least8_t)kLeft];
1904 position = position->children[(uint_least8_t)kRight];
1909 lower_node = position;
1910 position = position->children[(uint_least8_t)kLeft];
1922 Node* find_upper_node(
Node* position, const_key_reference key)
const
1925 Node* upper_node = ETL_NULLPTR;
1931 Data_Node& data_node = imultimap::data_cast(*position);
1935 position = position->children[(uint_least8_t)kRight];
1939 upper_node = position;
1941 if (!found && position->children[(uint_least8_t)kLeft])
1943 position = position->children[(uint_least8_t)kLeft];
1964 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1965 Node* find_upper_node(
Node* position,
const K& key)
const
1968 Node* upper_node = ETL_NULLPTR;
1974 Data_Node& data_node = imultimap::data_cast(*position);
1978 position = position->children[(uint_least8_t)kRight];
1982 upper_node = position;
1984 if (!found && position->children[(uint_least8_t)kLeft])
1986 position = position->children[(uint_least8_t)kLeft];
2012 Node* found = position;
2018 Node* critical_parent_node = ETL_NULLPTR;
2025 if ((uint_least8_t)kNeither != found->weight)
2027 critical_node = found;
2032 Data_Node& found_data_node = imultimap::data_cast(*found);
2038 found->dir = (uint_least8_t)kLeft;
2041 else if (
node_comp(found_data_node, node))
2044 found->dir = (uint_least8_t)kRight;
2050 found->dir = (uint_least8_t)kRight;
2054 if (found->children[found->dir])
2058 if ((uint_least8_t)kNeither != found->children[found->dir]->weight)
2060 critical_parent_node = found;
2064 found = found->children[found->dir];
2069 attach_node(found, found->children[found->dir], node);
2072 found = found->children[found->dir];
2082 if (critical_parent_node == ETL_NULLPTR && critical_node ==
root_node)
2086 else if (critical_parent_node == ETL_NULLPTR && critical_node == position)
2092 if (critical_parent_node != ETL_NULLPTR)
2094 balance_node(critical_parent_node->children[critical_parent_node->dir]);
2116 void remove_node(
Node* node)
2122 Data_Node& data_node = imultimap::data_cast(*node);
2136 node->parent->dir = node->parent->children[(uint_least8_t)kLeft] == node ? (uint_least8_t)kLeft : (uint_least8_t)kRight;
2139 node = node->parent;
2158 node->dir = node->children[(uint_least8_t)kLeft] ? (uint_least8_t)kLeft : (uint_least8_t)kRight;
2169 if ((node->weight == (uint_least8_t)kNeither)
2170 || (node->weight == (1 - node->dir) && node->children[1 - node->dir]->weight == (uint_least8_t)kNeither))
2177 node = node->children[node->dir];
2191 if (node->children[node->dir] == ETL_NULLPTR)
2201 if ((node->weight == (uint_least8_t)kNeither)
2202 || (node->weight == (1 - node->dir) && node->children[1 - node->dir]->weight == (uint_least8_t)kNeither))
2210 node = node->children[node->dir];
2213 Data_Node& replace_data_node = imultimap::data_cast(*node);
2216 if (
node_comp(data_node, replace_data_node))
2219 node->dir = (uint_least8_t)kLeft;
2221 else if (
node_comp(replace_data_node, data_node))
2224 node->dir = (uint_least8_t)kRight;
2229 node->dir = 1 - found->dir;
2238 if (balance->children[balance->dir] == ETL_NULLPTR)
2246 if (balance->weight == (uint_least8_t)kNeither)
2248 balance->weight = 1 - balance->dir;
2252 else if (balance->weight == balance->dir)
2254 balance->weight = (uint_least8_t)kNeither;
2259 int weight = balance->children[1 - balance->dir]->weight;
2261 if (weight == balance->dir)
2264 if (balance->parent == ETL_NULLPTR)
2266 rotate_3node(
root_node, 1 - balance->dir, balance->children[1 - balance->dir]->children[balance->dir]->weight);
2270 rotate_3node(balance->parent->children[balance->parent->dir], 1 - balance->dir,
2271 balance->children[1 - balance->dir]->children[balance->dir]->weight);
2276 else if (weight == (uint_least8_t)kNeither)
2279 if (balance->parent == ETL_NULLPTR)
2289 Node* old_parent = balance->parent;
2290 rotate_2node(balance->parent->children[balance->parent->dir], 1 - balance->dir);
2291 old_parent->children[old_parent->dir]->weight = balance->dir;
2295 balance->weight = 1 - balance->dir;
2301 if (balance->parent == ETL_NULLPTR)
2307 rotate_2node(balance->parent->children[balance->parent->dir], 1 - balance->dir);
2313 balance = balance->children[balance->dir];
2320 detach_node(found->parent->children[found->parent->dir], node->parent->children[node->parent->dir]);
2341 destroy_data_node(data_node);
2351#if defined(ETL_POLYMORPHIC_MULTIMAP) || defined(ETL_POLYMORPHIC_CONTAINERS)