634 typedef ETL_OR_STD::pair<const TKey, TMapped> value_type;
635 typedef const TKey key_type;
636 typedef TMapped mapped_type;
637 typedef TKeyCompare key_compare;
638 typedef value_type& reference;
639 typedef const value_type& const_reference;
641 typedef value_type&& rvalue_reference;
643 typedef value_type* pointer;
644 typedef const value_type* const_pointer;
645 typedef size_t size_type;
647 typedef const key_type& const_key_reference;
649 typedef key_type&& rvalue_key_reference;
656 bool operator()(const_reference lhs, const_reference rhs)
const
658 return (kcompare(lhs.first, rhs.first));
663 key_compare kcompare;
673 explicit Data_Node(value_type value_)
686 return kcompare(node1.value.first, node2.value.first);
689 bool node_comp(
const Data_Node& node, const_key_reference key)
const
691 return kcompare(node.value.first, key);
694 bool node_comp(const_key_reference key,
const Data_Node& node)
const
696 return kcompare(key, node.value.first);
700 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
703 return kcompare(node.value.first, key);
706 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
709 return kcompare(key, node.value.first);
718 key_compare kcompare;
742 return static_cast<const Data_Node*
>(p_node);
750 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)
792 iterator& operator ++()
794 p_multimap->next_node(p_node);
798 iterator operator ++(
int)
800 iterator temp(*
this);
801 p_multimap->next_node(p_node);
805 iterator& operator --()
807 p_multimap->prev_node(p_node);
811 iterator operator --(
int)
813 iterator temp(*
this);
814 p_multimap->prev_node(p_node);
818 iterator& operator =(
const iterator& other)
820 p_multimap = other.p_multimap;
821 p_node = other.p_node;
825 reference operator *()
const
827 return imultimap::data_cast(p_node)->value;
830 pointer operator &()
const
832 return &(imultimap::data_cast(p_node)->value);
835 pointer operator ->()
const
837 return &(imultimap::data_cast(p_node)->value);
840 friend bool operator == (
const iterator& lhs,
const iterator& rhs)
842 return lhs.p_multimap == rhs.p_multimap && lhs.p_node == rhs.p_node;
845 friend bool operator != (
const iterator& lhs,
const iterator& rhs)
847 return !(lhs == rhs);
853 imultimap* p_multimap;
863 class const_iterator :
public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, const value_type>
867 friend class imultimap;
870 : p_multimap(ETL_NULLPTR)
871 , p_node(ETL_NULLPTR)
875 const_iterator(
const imultimap&
multimap)
877 , p_node(ETL_NULLPTR)
881 const_iterator(
const imultimap&
multimap,
const Node* node)
888 : p_multimap(other.p_multimap)
889 , p_node(other.p_node)
893 const_iterator(
const const_iterator& other)
894 : p_multimap(other.p_multimap)
895 , p_node(other.p_node)
903 const_iterator& operator ++()
905 p_multimap->next_node(p_node);
909 const_iterator operator ++(
int)
911 const_iterator temp(*
this);
912 p_multimap->next_node(p_node);
916 const_iterator& operator --()
918 p_multimap->prev_node(p_node);
922 const_iterator operator --(
int)
924 const_iterator temp(*
this);
925 p_multimap->prev_node(p_node);
929 const_iterator& operator =(
const const_iterator& other)
931 p_multimap = other.p_multimap;
932 p_node = other.p_node;
936 const_reference operator *()
const
938 return imultimap::data_cast(p_node)->value;
941 const_pointer operator &()
const
943 return imultimap::data_cast(p_node)->value;
946 const_pointer operator ->()
const
948 return &(imultimap::data_cast(p_node)->value);
951 friend bool operator == (
const const_iterator& lhs,
const const_iterator& rhs)
953 return lhs.p_multimap == rhs.p_multimap && lhs.p_node == rhs.p_node;
956 friend bool operator != (
const const_iterator& lhs,
const const_iterator& rhs)
958 return !(lhs == rhs);
970 const imultimap* p_multimap;
977 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
979 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
980 typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
1035 return reverse_iterator(
iterator(*
this));
1057 const_reverse_iterator
rend()
const
1085 template <
typename TIterator>
1105 size_type
count(const_key_reference key)
const
1107 return count_nodes(key);
1112 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1115 return count_nodes(key);
1123 ETL_OR_STD::pair<iterator, iterator>
equal_range(const_key_reference key)
1125 return ETL_OR_STD::make_pair<iterator, iterator>(
iterator(*
this, find_lower_node(
root_node, key)),
1131 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1132 ETL_OR_STD::pair<iterator, iterator>
equal_range(
const K& key)
1134 return ETL_OR_STD::make_pair<iterator, iterator>(
iterator(*
this, find_lower_node(
root_node, key)),
1143 ETL_OR_STD::pair<const_iterator, const_iterator>
equal_range(const_key_reference key)
const
1145 return ETL_OR_STD::make_pair<const_iterator, const_iterator>(
const_iterator(*
this, find_lower_node(
root_node, key)),
1151 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1152 ETL_OR_STD::pair<const_iterator, const_iterator>
equal_range(
const K& key)
const
1154 return ETL_OR_STD::make_pair<const_iterator, const_iterator>(
const_iterator(*
this, find_lower_node(
root_node, key)),
1176 Node* node =
const_cast<Node*
>(position.p_node);
1195 while (lower != upper)
1200 lower =
erase(lower);
1209 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1210 size_type
erase(K&& key)
1216 while (lower != upper)
1221 lower =
erase(lower);
1234 while (first != last)
1236 first =
erase(first);
1239 return last.to_iterator();
1254 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1273 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1288 Node* inserted_node = ETL_NULLPTR;
1293 Data_Node& node = allocate_data_node(value);
1296 inserted_node = insert_node(
root_node, node);
1299 return iterator(*
this, inserted_node);
1311 Node* inserted_node = ETL_NULLPTR;
1316 Data_Node& node = allocate_data_node(etl::move(value));
1319 inserted_node = insert_node(
root_node, node);
1322 return iterator(*
this, inserted_node);
1348 return insert(etl::move(value));
1359 template <
class TIterator>
1362 while (first != last)
1382 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1402 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1422 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1442 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1476 while (from != rhs.end())
1478 this->
insert(etl::move(*from));
1513 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1527 , p_node_pool(&node_pool)
1538 while (item !=
end())
1549 Data_Node& allocate_data_node(const_reference value)
1551 Data_Node* node = allocate_data_node();
1552 ::new (&node->value) const
value_type(value);
1553 ETL_INCREMENT_DEBUG_COUNT;
1561 Data_Node& allocate_data_node(rvalue_reference value)
1563 Data_Node* node = allocate_data_node();
1565 ETL_INCREMENT_DEBUG_COUNT;
1573 Data_Node* allocate_data_node()
1576 return (p_node_pool->*func)();
1582 void destroy_data_node(Data_Node& node)
1584 node.value.~value_type();
1585 p_node_pool->release(&node);
1586 ETL_DECREMENT_DEBUG_COUNT;
1592 size_type count_nodes(const_key_reference key)
const
1595 size_type result = 0;
1602 while (lower != upper)
1605 const Data_Node& data_node = imultimap::data_cast(*lower);
1623 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1624 size_type count_nodes(
const K& key)
const
1627 size_type result = 0;
1634 while (lower != upper)
1637 const Data_Node& data_node = imultimap::data_cast(*lower);
1657 Node* find_node(
Node* position, const_key_reference key)
1659 Node* found = ETL_NULLPTR;
1663 Data_Node& data_node = imultimap::data_cast(*position);
1668 position = position->children[(uint_least8_t) kLeft];
1673 position = position->children[(uint_least8_t) kRight];
1679 position = position->children[(uint_least8_t) kLeft];
1689 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1690 Node* find_node(
Node* position,
const K& key)
1692 Node* found = ETL_NULLPTR;
1696 Data_Node& data_node = imultimap::data_cast(*position);
1701 position = position->children[(uint_least8_t)kLeft];
1706 position = position->children[(uint_least8_t)kRight];
1712 position = position->children[(uint_least8_t)kLeft];
1724 const Node* find_node(
const Node* position, const_key_reference key)
const
1726 const Node* found = ETL_NULLPTR;
1730 const Data_Node& data_node = imultimap::data_cast(*position);
1735 position = position->children[(uint_least8_t) kLeft];
1740 position = position->children[(uint_least8_t) kRight];
1746 position = position->children[(uint_least8_t) kLeft];
1758 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1759 const Node* find_node(
const Node* position,
const K& key)
const
1761 const Node* found = ETL_NULLPTR;
1765 const Data_Node& data_node = imultimap::data_cast(*position);
1770 position = position->children[(uint_least8_t)kLeft];
1775 position = position->children[(uint_least8_t)kRight];
1781 position = position->children[(uint_least8_t)kLeft];
1793 Node* find_lower_node(
Node* position, const_key_reference key)
const
1796 Node* lower_node = ETL_NULLPTR;
1800 Data_Node& data_node = imultimap::data_cast(*position);
1804 lower_node = position;
1805 if (position->children[(uint_least8_t) kLeft])
1807 position = position->children[(uint_least8_t) kLeft];
1817 position = position->children[(uint_least8_t) kRight];
1822 lower_node = position;
1823 position = position->children[(uint_least8_t) kLeft];
1833 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1834 Node* find_lower_node(
Node* position,
const K& key)
const
1837 Node* lower_node = ETL_NULLPTR;
1841 Data_Node& data_node = imultimap::data_cast(*position);
1845 lower_node = position;
1846 if (position->children[(uint_least8_t)kLeft])
1848 position = position->children[(uint_least8_t)kLeft];
1858 position = position->children[(uint_least8_t)kRight];
1863 lower_node = position;
1864 position = position->children[(uint_least8_t)kLeft];
1876 Node* find_upper_node(
Node* position, const_key_reference key)
const
1879 Node* upper_node = ETL_NULLPTR;
1885 Data_Node& data_node = imultimap::data_cast(*position);
1889 position = position->children[(uint_least8_t) kRight];
1893 upper_node = position;
1895 if (!found && position->children[(uint_least8_t) kLeft])
1897 position = position->children[(uint_least8_t) kLeft];
1918 template <typename K, typename KC = TKeyCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1919 Node* find_upper_node(
Node* position,
const K& key)
const
1922 Node* upper_node = ETL_NULLPTR;
1928 Data_Node& data_node = imultimap::data_cast(*position);
1932 position = position->children[(uint_least8_t)kRight];
1936 upper_node = position;
1938 if (!found && position->children[(uint_least8_t)kLeft])
1940 position = position->children[(uint_least8_t)kLeft];
1966 Node* found = position;
1972 Node* critical_parent_node = ETL_NULLPTR;
1979 if ((uint_least8_t) kNeither != found->weight)
1981 critical_node = found;
1985 Data_Node& found_data_node = imultimap::data_cast(*found);
1991 found->dir = (uint_least8_t) kLeft;
1994 else if (
node_comp(found_data_node, node))
1997 found->dir = (uint_least8_t) kRight;
2003 found->dir = (uint_least8_t) kRight;
2007 if (found->children[found->dir])
2011 if ((uint_least8_t) kNeither != found->children[found->dir]->weight)
2013 critical_parent_node = found;
2017 found = found->children[found->dir];
2022 attach_node(found, found->children[found->dir], node);
2025 found = found->children[found->dir];
2035 if (critical_parent_node == ETL_NULLPTR && critical_node ==
root_node)
2039 else if (critical_parent_node == ETL_NULLPTR && critical_node == position)
2045 if (critical_parent_node != ETL_NULLPTR)
2047 balance_node(critical_parent_node->children[critical_parent_node->dir]);
2069 void remove_node(
Node* node)
2075 Data_Node& data_node = imultimap::data_cast(*node);
2090 node->parent->children[(uint_least8_t) kLeft] == node ? (uint_least8_t) kLeft : (uint_least8_t) kRight;
2093 node = node->parent;
2112 node->dir = node->children[(uint_least8_t) kLeft] ? (uint_least8_t) kLeft : (uint_least8_t) kRight;
2123 if ((node->weight == (uint_least8_t) kNeither) ||
2124 (node->weight == (1 - node->dir) &&
2125 node->children[1 - node->dir]->weight == (uint_least8_t) kNeither))
2132 node = node->children[node->dir];
2146 if (node->children[node->dir] == ETL_NULLPTR)
2156 if ((node->weight == (uint_least8_t) kNeither) ||
2157 (node->weight == (1 - node->dir) &&
2158 node->children[1 - node->dir]->weight == (uint_least8_t) kNeither))
2165 node = node->children[node->dir];
2168 Data_Node& replace_data_node = imultimap::data_cast(*node);
2171 if (
node_comp(data_node, replace_data_node))
2174 node->dir = (uint_least8_t) kLeft;
2176 else if (
node_comp(replace_data_node, data_node))
2179 node->dir = (uint_least8_t) kRight;
2184 node->dir = node->children[(uint_least8_t) kLeft] ? (uint_least8_t) kLeft : (uint_least8_t) kRight;
2193 if (balance->children[balance->dir] == ETL_NULLPTR)
2200 if (balance->weight == (uint_least8_t) kNeither)
2202 balance->weight = 1 - balance->dir;
2206 else if (balance->weight == balance->dir)
2208 balance->weight = (uint_least8_t) kNeither;
2213 int weight = balance->children[1 - balance->dir]->weight;
2215 if (weight == balance->dir)
2218 if (balance->parent == ETL_NULLPTR)
2221 balance->children[1 - balance->dir]->children[balance->dir]->weight);
2225 rotate_3node(balance->parent->children[balance->parent->dir], 1 - balance->dir,
2226 balance->children[1 - balance->dir]->children[balance->dir]->weight);
2231 else if (weight == (uint_least8_t) kNeither)
2234 if (balance->parent == ETL_NULLPTR)
2244 Node* old_parent = balance->parent;
2245 rotate_2node(balance->parent->children[balance->parent->dir], 1 - balance->dir);
2246 old_parent->children[old_parent->dir]->weight = balance->dir;
2249 balance->weight = 1 - balance->dir;
2255 if (balance->parent == ETL_NULLPTR)
2261 rotate_2node(balance->parent->children[balance->parent->dir], 1 - balance->dir);
2267 balance = balance->children[balance->dir];
2274 detach_node(found->parent->children[found->parent->dir],
2275 node->parent->children[node->parent->dir]);
2296 destroy_data_node(data_node);
2306#if defined(ETL_POLYMORPHIC_MULTIMAP) || defined(ETL_POLYMORPHIC_CONTAINERS)