509 return compare(key, node.value);
513 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
514 bool node_comp(
const Data_Node& node,
const K& key)
const
516 return compare(node.value, key);
519 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
520 bool node_comp(
const K& key,
const Data_Node& node)
const
523 return compare(key, node.value);
537 static Data_Node* data_cast(Node* p_node)
539 return static_cast<Data_Node*
>(p_node);
545 static Data_Node& data_cast(Node& node)
547 return static_cast<Data_Node&
>(node);
553 static const Data_Node* data_cast(
const Node* p_node)
555 return static_cast<const Data_Node*
>(p_node);
561 static const Data_Node& data_cast(
const Node& node)
563 return static_cast<const Data_Node&
>(node);
579 , p_node(ETL_NULLPTR)
585 , p_node(ETL_NULLPTR)
597 , p_node(
other.p_node)
607 p_set->next_node(p_node);
614 p_set->next_node(p_node);
620 p_set->prev_node(p_node);
627 p_set->prev_node(p_node);
634 p_node =
other.p_node;
640 return iset::data_cast(p_node)->value;
645 return &(iset::data_cast(p_node)->value);
650 return &(iset::data_cast(p_node)->value);
655 return lhs.p_set ==
rhs.p_set &&
lhs.p_node ==
rhs.p_node;
684 , p_node(ETL_NULLPTR)
690 , p_node(ETL_NULLPTR)
702 , p_node(
other.p_node)
708 , p_node(
other.p_node)
718 p_set->next_node(p_node);
725 p_set->next_node(p_node);
731 p_set->prev_node(p_node);
738 p_set->prev_node(p_node);
745 p_node =
other.p_node;
751 return iset::data_cast(p_node)->value;
756 return iset::data_cast(p_node)->value;
761 return &(iset::data_cast(p_node)->value);
766 return lhs.p_set ==
rhs.p_set &&
lhs.p_node ==
rhs.p_node;
790 typedef typename etl::iterator_traits<iterator>::difference_type difference_type;
792 typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
793 typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
887 return reverse_iterator(
iterator(*
this));
909 const_reverse_iterator
rend()
const
925 const_reverse_iterator
crend()
const
937 template <
typename TIterator>
959 return find_node(
root_node, key) ? 1 : 0;
965 size_type
count(
const K& key)
const
967 return find_node(
root_node, key) ? 1 : 0;
977 return ETL_OR_STD::make_pair<iterator, iterator>(
iterator(*
this, find_lower_node(
root_node, key)),
984 ETL_OR_STD::pair<iterator, iterator>
equal_range(
const K& key)
986 return ETL_OR_STD::make_pair<iterator, iterator>(
iterator(*
this, find_lower_node(
root_node, key)),
997 return ETL_OR_STD::make_pair<const_iterator, const_iterator>(
const_iterator(*
this, find_lower_node(
root_node, key)),
1004 ETL_OR_STD::pair<const_iterator, const_iterator>
equal_range(
const K& key)
const
1006 return ETL_OR_STD::make_pair<const_iterator, const_iterator>(const_iterator(*
this, find_lower_node(
root_node, key)),
1007 const_iterator(*
this, find_upper_node(
root_node, key)));
1046 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1047 size_type
erase(K&& key_value)
1059 while (first != last)
1061 first =
erase(first);
1064 return last.to_iterator();
1144 Data_Node&
node = allocate_data_node(etl::move(value));
1193 Data_Node&
node = allocate_data_node(etl::move(value));
1210 template <
class TIterator>
1213 while (first != last)
1256 return const_iterator(*
this, find_lower_node(
root_node, key));
1296 return const_iterator(*
this, find_upper_node(
root_node, key));
1340 , p_node_pool(&node_pool)
1362 Data_Node& allocate_data_node(const_reference value)
1364 Data_Node&
node = allocate_data_node();
1365 ::new ((
void*)&
node.value) value_type(value);
1366 ETL_INCREMENT_DEBUG_COUNT
1374 Data_Node& allocate_data_node(rvalue_reference value)
1376 Data_Node& node = allocate_data_node();
1377 ::new ((
void*)&node.value) value_type(etl::move(value));
1378 ETL_INCREMENT_DEBUG_COUNT
1386 Data_Node& allocate_data_node()
1388 Data_Node* (
etl::ipool::*func)() = &etl::ipool::allocate<Data_Node>;
1389 return *(p_node_pool->*func)();
1395 void destroy_data_node(Data_Node& node)
1397 node.value.~value_type();
1399 ETL_DECREMENT_DEBUG_COUNT
1407 Node* found = position;
1411 Data_Node& found_data_node = iset::data_cast(*found);
1417 found = found->children[kLeft];
1419 else if (
node_comp(found_data_node, key))
1422 found = found->children[kRight];
1437 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1438 Node* find_node(Node* position,
const K& key)
1440 Node* found = position;
1444 Data_Node& found_data_node = iset::data_cast(*found);
1450 found = found->children[kLeft];
1452 else if (
node_comp(found_data_node, key))
1455 found = found->children[kRight];
1472 const Node* find_node(
const Node* position,
key_parameter_t key)
const
1474 const Node* found = position;
1478 const Data_Node& found_data_node = iset::data_cast(*found);
1484 found = found->children[kLeft];
1486 else if (
node_comp(found_data_node, key))
1489 found = found->children[kRight];
1504 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1505 const Node* find_node(
const Node* position,
const K& key)
const
1507 const Node* found = position;
1511 const Data_Node& found_data_node = iset::data_cast(*found);
1517 found = found->children[kLeft];
1519 else if (
node_comp(found_data_node, key))
1522 found = found->children[kRight];
1539 Node*& find_node(Node*& position,
const Node* node)
1541 Node* found = position;
1544 if (found->children[kLeft] == node)
1546 return found->children[kLeft];
1548 else if (found->children[kRight] == node)
1550 return found->children[kRight];
1555 Data_Node& found_data_node = iset::data_cast(*found);
1556 const Data_Node& data_node = iset::data_cast(*node);
1559 if (
node_comp(data_node, found_data_node))
1562 found = found->children[kLeft];
1564 else if (
node_comp(found_data_node, data_node))
1567 found = found->children[kRight];
1585 Node* find_parent_node(Node* position,
const Node* node)
1588 Node* found = ETL_NULLPTR;
1591 if (position && node && position != node)
1596 if (position->children[kLeft] != node &&
1597 position->children[kRight] != node)
1600 const Data_Node& node_data_node = iset::data_cast(*node);
1601 Data_Node& position_data_node = iset::data_cast(*position);
1603 if (
node_comp(node_data_node, position_data_node))
1606 position = position->children[kLeft];
1608 else if (
node_comp(position_data_node, node_data_node))
1611 position = position->children[kRight];
1633 const Node* find_parent_node(
const Node* position,
const Node* node)
const
1636 const Node* found = ETL_NULLPTR;
1639 if (position && node && position != node)
1644 if (position->children[kLeft] != node &&
1645 position->children[kRight] != node)
1648 const Data_Node& node_data_node = iset::data_cast(*node);
1649 const Data_Node& position_data_node = iset::data_cast(*position);
1651 if (
node_comp(node_data_node, position_data_node))
1654 position = position->children[kLeft];
1656 else if (
node_comp(position_data_node, node_data_node))
1659 position = position->children[kRight];
1683 Node* lower_node = ETL_NULLPTR;
1687 Data_Node& data_node = iset::data_cast(*position);
1691 lower_node = position;
1692 if (position->children[kLeft])
1694 position = position->children[kLeft];
1704 position = position->children[kRight];
1709 lower_node = position;
1710 position = position->children[kLeft];
1720 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1721 Node* find_lower_node(Node* position,
const K& key)
const
1724 Node* lower_node = ETL_NULLPTR;
1728 Data_Node& data_node = iset::data_cast(*position);
1732 lower_node = position;
1733 if (position->children[kLeft])
1735 position = position->children[kLeft];
1745 position = position->children[kRight];
1750 lower_node = position;
1751 position = position->children[kLeft];
1766 Node* upper_node = ETL_NULLPTR;
1768 Node* node = position;
1772 Data_Node& data_node = iset::data_cast(*node);
1777 node = node->children[kLeft];
1781 node = node->children[kRight];
1783 else if (node->children[kRight])
1800 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
1801 Node* find_upper_node(Node* position,
const K& key)
const
1804 Node* upper_node = ETL_NULLPTR;
1806 Node* node = position;
1810 Data_Node& data_node = iset::data_cast(*node);
1815 node = node->children[kLeft];
1819 node = node->children[kRight];
1821 else if (node->children[kRight])
1840 Node* insert_node(Node*& position, Data_Node& node)
1843 Node* found = position;
1849 Node* critical_parent_node = ETL_NULLPTR;
1856 if (kNeither != found->weight)
1858 critical_node = found;
1862 Data_Node& found_data_node = iset::data_cast(*found);
1871 else if (
node_comp(found_data_node, node))
1874 found->dir = kRight;
1879 found->dir = kNeither;
1882 critical_node = ETL_NULLPTR;
1885 destroy_data_node(node);
1892 if (found->children[found->dir])
1896 if (kNeither != found->children[found->dir]->weight)
1898 critical_parent_node = found;
1902 found = found->children[found->dir];
1910 found = found->children[found->dir];
1920 if (critical_parent_node == ETL_NULLPTR && critical_node ==
root_node)
1924 else if (critical_parent_node == ETL_NULLPTR && critical_node == position)
1930 if (critical_parent_node != ETL_NULLPTR)
1932 balance_node(critical_parent_node->children[critical_parent_node->dir]);
1953 void next_node(Node*&position)
1958 if (position->children[kRight])
1967 Node* parent = position;
1972 parent = find_parent_node(
root_node, position);
1974 }
while (parent && parent->children[kRight] == position);
1985 void next_node(
const Node*& position)
const
1990 if (position->children[kRight])
1999 const Node* parent = position;
2004 parent = find_parent_node(
root_node, position);
2006 }
while (parent && parent->children[kRight] == position);
2017 void prev_node(Node*&position)
2028 if (position->children[kLeft])
2037 Node* parent = position;
2042 parent = find_parent_node(
root_node, position);
2044 }
while (parent && parent->children[kLeft] == position);
2055 void prev_node(
const Node*& position)
const
2066 if (position->children[kLeft])
2075 const Node* parent = position;
2080 parent = find_parent_node(
root_node, position);
2082 }
while (parent && parent->children[kLeft] == position);
2099 Node* found_parent = ETL_NULLPTR;
2100 Node* found = ETL_NULLPTR;
2101 Node* replace_parent = ETL_NULLPTR;
2102 Node* replace = position;
2103 Node* balance_parent = ETL_NULLPTR;
2108 Data_Node& replace_data_node = iset::data_cast(*replace);
2114 replace->dir = kLeft;
2116 else if (
node_comp(replace_data_node, key))
2119 replace->dir = kRight;
2124 replace->dir = replace->children[kLeft] ? kLeft : kRight;
2127 found_parent = replace_parent;
2132 if (replace->children[replace->dir] == ETL_NULLPTR)
2142 if ((replace->weight == kNeither) ||
2143 (replace->weight == (1 - replace->dir) &&
2144 replace->children[1 - replace->dir]->weight == kNeither))
2147 balance_parent = replace_parent;
2152 replace_parent = replace;
2153 replace = replace->children[replace->dir];
2162 if (balance->children[balance->dir] == ETL_NULLPTR)
2167 if (balance->weight == kNeither)
2169 balance->weight = 1 - balance->dir;
2171 else if (balance->weight == balance->dir)
2173 balance->weight = kNeither;
2177 int weight = balance->children[1 - balance->dir]->weight;
2179 if (weight == balance->dir)
2182 if (balance_parent == ETL_NULLPTR)
2185 balance->children[1 - balance->dir]->children[balance->dir]->weight);
2189 rotate_3node(balance_parent->children[balance_parent->dir], 1 - balance->dir,
2190 balance->children[1 - balance->dir]->children[balance->dir]->weight);
2195 else if (weight == kNeither)
2198 if (balance_parent == ETL_NULLPTR)
2205 rotate_2node(balance_parent->children[balance_parent->dir], 1 - balance->dir);
2206 balance_parent->children[balance_parent->dir]->weight = balance->dir;
2209 balance->weight = 1 - balance->dir;
2215 if (balance_parent == ETL_NULLPTR)
2221 rotate_2node(balance_parent->children[balance_parent->dir], 1 - balance->dir);
2227 if (balance == found)
2231 found_parent = balance_parent->children[balance_parent->dir];
2233 found_parent->dir = found_parent->children[kLeft] == found ? kLeft : kRight;
2244 balance_parent = balance;
2245 balance = balance->children[balance->dir];
2252 detach_node(found_parent->children[found_parent->dir],
2253 replace_parent->children[replace_parent->dir]);
2271 Data_Node& found_data_node = iset::data_cast(*found);
2277 destroy_data_node(found_data_node);
2286 template <typename K, typename KC = TCompare, etl::enable_if_t<comparator_is_transparent<KC>::value,
int> = 0>
2287 Node* remove_node(Node*& position,
const K& key)
2292 Node* found_parent = ETL_NULLPTR;
2293 Node* found = ETL_NULLPTR;
2294 Node* replace_parent = ETL_NULLPTR;
2295 Node* replace = position;
2296 Node* balance_parent = ETL_NULLPTR;
2301 Data_Node& replace_data_node = iset::data_cast(*replace);
2307 replace->dir = kLeft;
2309 else if (
node_comp(replace_data_node, key))
2312 replace->dir = kRight;
2317 replace->dir = replace->children[kLeft] ? kLeft : kRight;
2320 found_parent = replace_parent;
2325 if (replace->children[replace->dir] == ETL_NULLPTR)
2335 if ((replace->weight == kNeither) ||
2336 (replace->weight == (1 - replace->dir) &&
2337 replace->children[1 - replace->dir]->weight == kNeither))
2340 balance_parent = replace_parent;
2345 replace_parent = replace;
2346 replace = replace->children[replace->dir];
2355 if (balance->children[balance->dir] == ETL_NULLPTR)
2360 if (balance->weight == kNeither)
2362 balance->weight = 1 - balance->dir;
2364 else if (balance->weight == balance->dir)
2366 balance->weight = kNeither;
2370 int weight = balance->children[1 - balance->dir]->weight;
2372 if (weight == balance->dir)
2375 if (balance_parent == ETL_NULLPTR)
2378 balance->children[1 - balance->dir]->children[balance->dir]->weight);
2382 rotate_3node(balance_parent->children[balance_parent->dir], 1 - balance->dir,
2383 balance->children[1 - balance->dir]->children[balance->dir]->weight);
2388 else if (weight == kNeither)
2391 if (balance_parent == ETL_NULLPTR)
2398 rotate_2node(balance_parent->children[balance_parent->dir], 1 - balance->dir);
2399 balance_parent->children[balance_parent->dir]->weight = balance->dir;
2402 balance->weight = 1 - balance->dir;
2408 if (balance_parent == ETL_NULLPTR)
2414 rotate_2node(balance_parent->children[balance_parent->dir], 1 - balance->dir);
2420 if (balance == found)
2424 found_parent = balance_parent->children[balance_parent->dir];
2426 found_parent->dir = found_parent->children[kLeft] == found ? kLeft : kRight;
2437 balance_parent = balance;
2438 balance = balance->children[balance->dir];
2445 detach_node(found_parent->children[found_parent->dir],
2446 replace_parent->children[replace_parent->dir]);
2464 Data_Node& found_data_node = iset::data_cast(*found);
2470 destroy_data_node(found_data_node);
2484#if defined(ETL_POLYMORPHIC_SET) || defined(ETL_POLYMORPHIC_CONTAINERS)