463 typedef TKey key_type;
464 typedef TKey value_type;
465 typedef TCompare key_compare;
466 typedef TCompare value_compare;
467 typedef value_type& reference;
468 typedef const value_type& const_reference;
470 typedef value_type&& rvalue_reference;
472 typedef value_type* pointer;
473 typedef const value_type* const_pointer;
474 typedef size_t size_type;
483 explicit Data_Node(value_type value_)
499 return compare(node1.value, node2.value);
504 return compare(node.value, key);
510 return compare(key, node.value);
514 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
517 return compare(node.value, key);
520 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
524 return compare(key, node.value);
531 etl::ipool* p_node_pool;
556 return static_cast<const Data_Node*
>(p_node);
564 return static_cast<const Data_Node&
>(node);
572 class iterator :
public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, value_type>
577 friend class const_iterator;
581 , p_node(ETL_NULLPTR)
587 , p_node(ETL_NULLPTR)
591 iterator(iset&
set,
Node* node)
597 iterator(
const iterator& other)
599 , p_node(other.p_node)
605 iterator& operator++()
607 p_set->next_node(p_node);
611 iterator operator++(
int)
613 iterator temp(*
this);
614 p_set->next_node(p_node);
618 iterator& operator--()
620 p_set->prev_node(p_node);
624 iterator operator--(
int)
626 iterator temp(*
this);
627 p_set->prev_node(p_node);
631 iterator& operator=(
const iterator& other)
634 p_node = other.p_node;
638 reference operator*()
const
640 return iset::data_cast(p_node)->value;
643 pointer operator&()
const
645 return &(iset::data_cast(p_node)->value);
648 pointer operator->()
const
650 return &(iset::data_cast(p_node)->value);
653 friend bool operator==(
const iterator& lhs,
const iterator& rhs)
655 return lhs.p_set == rhs.p_set && lhs.p_node == rhs.p_node;
658 friend bool operator!=(
const iterator& lhs,
const iterator& rhs)
660 return !(lhs == rhs);
676 class const_iterator :
public etl::iterator<ETL_OR_STD::bidirectional_iterator_tag, const value_type>
684 , p_node(ETL_NULLPTR)
688 const_iterator(
const iset&
set)
690 , p_node(ETL_NULLPTR)
694 const_iterator(
const iset&
set,
const Node* node)
702 , p_node(other.p_node)
706 const_iterator(
const const_iterator& other)
708 , p_node(other.p_node)
714 const_iterator& operator++()
716 p_set->next_node(p_node);
720 const_iterator operator++(
int)
722 const_iterator temp(*
this);
723 p_set->next_node(p_node);
727 const_iterator& operator--()
729 p_set->prev_node(p_node);
733 const_iterator operator--(
int)
735 const_iterator temp(*
this);
736 p_set->prev_node(p_node);
740 const_iterator& operator=(
const const_iterator& other)
743 p_node = other.p_node;
747 const_reference operator*()
const
749 return iset::data_cast(p_node)->value;
752 const_pointer operator&()
const
754 return iset::data_cast(p_node)->value;
757 const_pointer operator->()
const
759 return &(iset::data_cast(p_node)->value);
762 friend bool operator==(
const const_iterator& lhs,
const const_iterator& rhs)
764 return lhs.p_set == rhs.p_set && lhs.p_node == rhs.p_node;
767 friend bool operator!=(
const const_iterator& lhs,
const const_iterator& rhs)
769 return !(lhs == rhs);
788 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
790 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
791 typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
820 while (from != rhs.end())
825 this->
insert(etl::move(*from));
887 return reverse_iterator(
iterator(*
this));
909 const_reverse_iterator
rend()
const
925 const_reverse_iterator
crend()
const
938 template <
typename TIterator>
939 void assign(TIterator first, TIterator last)
960 return find_node(
root_node, key) ? 1 : 0;
965 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
968 return find_node(
root_node, key) ? 1 : 0;
978 return ETL_OR_STD::make_pair<iterator, iterator>(
iterator(*
this, find_lower_node(
root_node, key)),
984 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
985 ETL_OR_STD::pair<iterator, iterator>
equal_range(
const K& key)
987 return ETL_OR_STD::make_pair<iterator, iterator>(
iterator(*
this, find_lower_node(
root_node, key)),
998 return ETL_OR_STD::make_pair<const_iterator, const_iterator>(
const_iterator(*
this, find_lower_node(
root_node, key)),
1004 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1005 ETL_OR_STD::pair<const_iterator, const_iterator>
equal_range(
const K& key)
const
1007 return ETL_OR_STD::make_pair<const_iterator, const_iterator>(
const_iterator(*
this, find_lower_node(
root_node, key)),
1027 Node*& reference_node = find_node(
root_node, position.p_node);
1028 iterator next(*
this, reference_node);
1042 return remove_node(
root_node, key_value) ? 1 : 0;
1047 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1051 return remove_node(
root_node, etl::forward<K>(key_value)) ? 1 : 0;
1060 while (first != last)
1062 first =
erase(first);
1065 return last.to_iterator();
1080 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1099 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1112 ETL_OR_STD::pair<iterator, bool>
insert(const_reference value)
1115 Node* inserted_node = ETL_NULLPTR;
1116 bool inserted =
false;
1123 ETL_ASSERT_FAIL(ETL_ERROR(
set_full));
1127 return ETL_OR_STD::make_pair(iter,
false);
1132 Data_Node& node = allocate_data_node(value);
1135 inserted_node = insert_node(
root_node, node);
1136 inserted = inserted_node == &node;
1139 return ETL_OR_STD::make_pair(
iterator(*
this, inserted_node), inserted);
1149 ETL_OR_STD::pair<iterator, bool>
insert(rvalue_reference value)
1152 Node* inserted_node = ETL_NULLPTR;
1153 bool inserted =
false;
1160 ETL_ASSERT_FAIL(ETL_ERROR(
set_full));
1164 return ETL_OR_STD::make_pair(iter,
false);
1169 Data_Node& node = allocate_data_node(etl::move(value));
1172 inserted_node = insert_node(
root_node, node);
1173 inserted = inserted_node == &node;
1176 return ETL_OR_STD::make_pair(
iterator(*
this, inserted_node), inserted);
1190 Node* inserted_node = ETL_NULLPTR;
1197 ETL_ASSERT_FAIL(ETL_ERROR(
set_full));
1206 Data_Node& node = allocate_data_node(value);
1209 inserted_node = insert_node(
root_node, node);
1212 return iterator(*
this, inserted_node);
1226 Node* inserted_node = ETL_NULLPTR;
1233 ETL_ASSERT_FAIL(ETL_ERROR(
set_full));
1242 Data_Node& node = allocate_data_node(etl::move(value));
1245 inserted_node = insert_node(
root_node, node);
1248 return iterator(*
this, inserted_node);
1260 template <
class TIterator>
1263 while (first != last)
1283 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1303 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1323 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1343 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1376 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1390 , p_node_pool(&node_pool)
1401 while (item !=
end())
1412 Data_Node& allocate_data_node(const_reference value)
1414 Data_Node* node = allocate_data_node();
1415 ::new ((
void*)&node->value)
value_type(value);
1416 ETL_INCREMENT_DEBUG_COUNT;
1424 Data_Node& allocate_data_node(rvalue_reference value)
1426 Data_Node* node = allocate_data_node();
1427 ::new ((
void*)&node->value) value_type(etl::move(value));
1428 ETL_INCREMENT_DEBUG_COUNT;
1439 return (p_node_pool->*func)();
1447 node.value.~value_type();
1448 p_node_pool->release(&node);
1449 ETL_DECREMENT_DEBUG_COUNT;
1457 Node* found = position;
1461 Data_Node& found_data_node = iset::data_cast(*found);
1467 found = found->children[kLeft];
1469 else if (
node_comp(found_data_node, key))
1472 found = found->children[kRight];
1487 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1488 Node* find_node(
Node* position,
const K& key)
1490 Node* found = position;
1494 Data_Node& found_data_node = iset::data_cast(*found);
1500 found = found->children[kLeft];
1502 else if (
node_comp(found_data_node, key))
1505 found = found->children[kRight];
1524 const Node* found = position;
1528 const Data_Node& found_data_node = iset::data_cast(*found);
1534 found = found->children[kLeft];
1536 else if (
node_comp(found_data_node, key))
1539 found = found->children[kRight];
1554 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1555 const Node* find_node(
const Node* position,
const K& key)
const
1557 const Node* found = position;
1561 const Data_Node& found_data_node = iset::data_cast(*found);
1567 found = found->children[kLeft];
1569 else if (
node_comp(found_data_node, key))
1572 found = found->children[kRight];
1591 Node* found = position;
1594 if (found->children[kLeft] == node)
1596 return found->children[kLeft];
1598 else if (found->children[kRight] == node)
1600 return found->children[kRight];
1606 Data_Node& found_data_node = iset::data_cast(*found);
1607 const Data_Node& data_node = iset::data_cast(*node);
1610 if (
node_comp(data_node, found_data_node))
1613 found = found->children[kLeft];
1615 else if (
node_comp(found_data_node, data_node))
1618 found = found->children[kRight];
1636 Node* find_parent_node(
Node* position,
const Node* node)
1639 Node* found = ETL_NULLPTR;
1643 if (position && node && position != node)
1648 if (position->children[kLeft] != node && position->children[kRight] != node)
1652 const Data_Node& node_data_node = iset::data_cast(*node);
1653 Data_Node& position_data_node = iset::data_cast(*position);
1655 if (
node_comp(node_data_node, position_data_node))
1658 position = position->children[kLeft];
1660 else if (
node_comp(position_data_node, node_data_node))
1663 position = position->children[kRight];
1685 const Node* find_parent_node(
const Node* position,
const Node* node)
const
1688 const Node* found = ETL_NULLPTR;
1692 if (position && node && position != node)
1697 if (position->children[kLeft] != node && position->children[kRight] != node)
1701 const Data_Node& node_data_node = iset::data_cast(*node);
1702 const Data_Node& position_data_node = iset::data_cast(*position);
1704 if (
node_comp(node_data_node, position_data_node))
1707 position = position->children[kLeft];
1709 else if (
node_comp(position_data_node, node_data_node))
1712 position = position->children[kRight];
1736 Node* lower_node = ETL_NULLPTR;
1740 Data_Node& data_node = iset::data_cast(*position);
1744 lower_node = position;
1745 if (position->children[kLeft])
1747 position = position->children[kLeft];
1757 position = position->children[kRight];
1762 lower_node = position;
1763 position = position->children[kLeft];
1773 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1774 Node* find_lower_node(
Node* position,
const K& key)
const
1777 Node* lower_node = ETL_NULLPTR;
1781 Data_Node& data_node = iset::data_cast(*position);
1785 lower_node = position;
1786 if (position->children[kLeft])
1788 position = position->children[kLeft];
1798 position = position->children[kRight];
1803 lower_node = position;
1804 position = position->children[kLeft];
1819 Node* upper_node = ETL_NULLPTR;
1821 Node* node = position;
1825 Data_Node& data_node = iset::data_cast(*node);
1830 node = node->children[kLeft];
1834 node = node->children[kRight];
1836 else if (node->children[kRight])
1853 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1854 Node* find_upper_node(
Node* position,
const K& key)
const
1857 Node* upper_node = ETL_NULLPTR;
1859 Node* node = position;
1863 Data_Node& data_node = iset::data_cast(*node);
1868 node = node->children[kLeft];
1872 node = node->children[kRight];
1874 else if (node->children[kRight])
1896 Node* found = position;
1902 Node* critical_parent_node = ETL_NULLPTR;
1909 if (kNeither != found->weight)
1911 critical_node = found;
1916 Data_Node& found_data_node = iset::data_cast(*found);
1925 else if (
node_comp(found_data_node, node))
1928 found->dir = kRight;
1933 found->dir = kNeither;
1936 critical_node = ETL_NULLPTR;
1939 destroy_data_node(node);
1946 if (found->children[found->dir])
1950 if (kNeither != found->children[found->dir]->weight)
1952 critical_parent_node = found;
1956 found = found->children[found->dir];
1964 found = found->children[found->dir];
1974 if (critical_parent_node == ETL_NULLPTR && critical_node ==
root_node)
1978 else if (critical_parent_node == ETL_NULLPTR && critical_node == position)
1984 if (critical_parent_node != ETL_NULLPTR)
1986 balance_node(critical_parent_node->children[critical_parent_node->dir]);
2007 void next_node(
Node*& position)
2012 if (position->children[kRight])
2021 Node* parent = position;
2026 parent = find_parent_node(
root_node, position);
2028 }
while (parent && parent->children[kRight] == position);
2039 void next_node(
const Node*& position)
const
2044 if (position->children[kRight])
2053 const Node* parent = position;
2058 parent = find_parent_node(
root_node, position);
2060 }
while (parent && parent->children[kRight] == position);
2071 void prev_node(
Node*& position)
2082 if (position->children[kLeft])
2091 Node* parent = position;
2096 parent = find_parent_node(
root_node, position);
2098 }
while (parent && parent->children[kLeft] == position);
2109 void prev_node(
const Node*& position)
const
2120 if (position->children[kLeft])
2129 const Node* parent = position;
2134 parent = find_parent_node(
root_node, position);
2136 }
while (parent && parent->children[kLeft] == position);
2153 Node* found_parent = ETL_NULLPTR;
2154 Node* found = ETL_NULLPTR;
2155 Node* replace_parent = ETL_NULLPTR;
2156 Node* replace = position;
2157 Node* balance_parent = ETL_NULLPTR;
2162 Data_Node& replace_data_node = iset::data_cast(*replace);
2168 replace->dir = kLeft;
2170 else if (
node_comp(replace_data_node, key))
2173 replace->dir = kRight;
2178 replace->dir = replace->children[kLeft] ? kLeft : kRight;
2181 found_parent = replace_parent;
2186 if (replace->children[replace->dir] == ETL_NULLPTR)
2196 if ((replace->weight == kNeither) || (replace->weight == (1 - replace->dir) && replace->children[1 - replace->dir]->weight == kNeither))
2199 balance_parent = replace_parent;
2204 replace_parent = replace;
2205 replace = replace->children[replace->dir];
2214 if (balance->children[balance->dir] == ETL_NULLPTR)
2219 if (balance->weight == kNeither)
2221 balance->weight = 1 - balance->dir;
2223 else if (balance->weight == balance->dir)
2225 balance->weight = kNeither;
2229 int weight = balance->children[1 - balance->dir]->weight;
2231 if (weight == balance->dir)
2234 if (balance_parent == ETL_NULLPTR)
2236 rotate_3node(
root_node, 1 - balance->dir, balance->children[1 - balance->dir]->children[balance->dir]->weight);
2240 rotate_3node(balance_parent->children[balance_parent->dir], 1 - balance->dir,
2241 balance->children[1 - balance->dir]->children[balance->dir]->weight);
2246 else if (weight == kNeither)
2249 if (balance_parent == ETL_NULLPTR)
2256 rotate_2node(balance_parent->children[balance_parent->dir], 1 - balance->dir);
2257 balance_parent->children[balance_parent->dir]->weight = balance->dir;
2261 balance->weight = 1 - balance->dir;
2267 if (balance_parent == ETL_NULLPTR)
2273 rotate_2node(balance_parent->children[balance_parent->dir], 1 - balance->dir);
2279 if (balance == found)
2283 found_parent = balance_parent->children[balance_parent->dir];
2285 found_parent->dir = found_parent->children[kLeft] == found ? kLeft : kRight;
2296 balance_parent = balance;
2297 balance = balance->children[balance->dir];
2304 detach_node(found_parent->children[found_parent->dir], replace_parent->children[replace_parent->dir]);
2322 Data_Node& found_data_node = iset::data_cast(*found);
2328 destroy_data_node(found_data_node);
2337 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
2338 Node* remove_node(
Node*& position,
const K& key)
2343 Node* found_parent = ETL_NULLPTR;
2344 Node* found = ETL_NULLPTR;
2345 Node* replace_parent = ETL_NULLPTR;
2346 Node* replace = position;
2347 Node* balance_parent = ETL_NULLPTR;
2352 Data_Node& replace_data_node = iset::data_cast(*replace);
2358 replace->dir = kLeft;
2360 else if (
node_comp(replace_data_node, key))
2363 replace->dir = kRight;
2368 replace->dir = replace->children[kLeft] ? kLeft : kRight;
2371 found_parent = replace_parent;
2376 if (replace->children[replace->dir] == ETL_NULLPTR)
2386 if ((replace->weight == kNeither) || (replace->weight == (1 - replace->dir) && replace->children[1 - replace->dir]->weight == kNeither))
2389 balance_parent = replace_parent;
2394 replace_parent = replace;
2395 replace = replace->children[replace->dir];
2404 if (balance->children[balance->dir] == ETL_NULLPTR)
2409 if (balance->weight == kNeither)
2411 balance->weight = 1 - balance->dir;
2413 else if (balance->weight == balance->dir)
2415 balance->weight = kNeither;
2419 int weight = balance->children[1 - balance->dir]->weight;
2421 if (weight == balance->dir)
2424 if (balance_parent == ETL_NULLPTR)
2426 rotate_3node(
root_node, 1 - balance->dir, balance->children[1 - balance->dir]->children[balance->dir]->weight);
2430 rotate_3node(balance_parent->children[balance_parent->dir], 1 - balance->dir,
2431 balance->children[1 - balance->dir]->children[balance->dir]->weight);
2436 else if (weight == kNeither)
2439 if (balance_parent == ETL_NULLPTR)
2446 rotate_2node(balance_parent->children[balance_parent->dir], 1 - balance->dir);
2447 balance_parent->children[balance_parent->dir]->weight = balance->dir;
2451 balance->weight = 1 - balance->dir;
2457 if (balance_parent == ETL_NULLPTR)
2463 rotate_2node(balance_parent->children[balance_parent->dir], 1 - balance->dir);
2469 if (balance == found)
2473 found_parent = balance_parent->children[balance_parent->dir];
2475 found_parent->dir = found_parent->children[kLeft] == found ? kLeft : kRight;
2486 balance_parent = balance;
2487 balance = balance->children[balance->dir];
2494 detach_node(found_parent->children[found_parent->dir], replace_parent->children[replace_parent->dir]);
2512 Data_Node& found_data_node = iset::data_cast(*found);
2518 destroy_data_node(found_data_node);
2532#if defined(ETL_POLYMORPHIC_SET) || defined(ETL_POLYMORPHIC_CONTAINERS)