@@ -1086,15 +1086,89 @@ public:
1086
1086
1087
1087
// FIXME: Make this function const qualified. Unfortunately doing so
1088
1088
// breaks existing code which uses non-const callable comparators.
1089
+
1090
+ // Find place to insert if __v doesn't exist
1091
+ // Set __parent to parent of null leaf
1092
+ // Return reference to null leaf
1093
+ // If __v exists, set parent to node of __v and return reference to node of __v
1089
1094
template <class _Key >
1090
- _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_equal (__end_node_pointer& __parent, const _Key& __v);
1095
+ _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&> __find_equal (const _Key& __v) {
1096
+ using _PairT = pair<__end_node_pointer, __node_base_pointer&>;
1097
+
1098
+ __node_pointer __node = __root ();
1099
+
1100
+ if (__node == nullptr ) {
1101
+ auto __end = __end_node ();
1102
+ return _PairT (__end, __end->__left_ );
1103
+ }
1104
+
1105
+ __node_base_pointer* __node_ptr = __root_ptr ();
1106
+ while (true ) {
1107
+ if (value_comp ()(__v, __node->__value_ )) {
1108
+ if (__node->__left_ == nullptr )
1109
+ return _PairT (static_cast <__end_node_pointer>(__node), __node->__left_ );
1110
+
1111
+ __node_ptr = std::addressof (__node->__left_ );
1112
+ __node = static_cast <__node_pointer>(__node->__left_ );
1113
+ } else if (value_comp ()(__node->__value_ , __v)) {
1114
+ if (__node->__right_ == nullptr )
1115
+ return _PairT (static_cast <__end_node_pointer>(__node), __node->__right_ );
1116
+
1117
+ __node_ptr = std::addressof (__node->__right_ );
1118
+ __node = static_cast <__node_pointer>(__node->__right_ );
1119
+ } else {
1120
+ return _PairT (static_cast <__end_node_pointer>(__node), *__node_ptr);
1121
+ }
1122
+ }
1123
+ }
1124
+
1091
1125
template <class _Key >
1092
- _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_equal (__end_node_pointer& __parent, const _Key& __v) const {
1093
- return const_cast <__tree*>(this )->__find_equal (__parent, __v);
1126
+ _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&> __find_equal (const _Key& __v) const {
1127
+ return const_cast <__tree*>(this )->__find_equal (__v);
1094
1128
}
1129
+
1130
+ // Find place to insert if __v doesn't exist
1131
+ // First check prior to __hint.
1132
+ // Next check after __hint.
1133
+ // Next do O(log N) search.
1134
+ // Set __parent to parent of null leaf
1135
+ // Return reference to null leaf
1136
+ // If __v exists, set parent to node of __v and return reference to node of __v
1095
1137
template <class _Key >
1096
- _LIBCPP_HIDE_FROM_ABI __node_base_pointer&
1097
- __find_equal (const_iterator __hint, __end_node_pointer& __parent, __node_base_pointer& __dummy, const _Key& __v);
1138
+ _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&>
1139
+ __find_equal (const_iterator __hint, __node_base_pointer& __dummy, const _Key& __v) {
1140
+ using _PairT = pair<__end_node_pointer, __node_base_pointer&>;
1141
+
1142
+ if (__hint == end () || value_comp ()(__v, *__hint)) { // check before
1143
+ // __v < *__hint
1144
+ const_iterator __prior = __hint;
1145
+ if (__prior == begin () || value_comp ()(*--__prior, __v)) {
1146
+ // *prev(__hint) < __v < *__hint
1147
+ if (__hint.__ptr_ ->__left_ == nullptr )
1148
+ return _PairT (__hint.__ptr_ , __hint.__ptr_ ->__left_ );
1149
+ return _PairT (__prior.__ptr_ , static_cast <__node_pointer>(__prior.__ptr_ )->__right_ );
1150
+ }
1151
+ // __v <= *prev(__hint)
1152
+ return __find_equal (__v);
1153
+ }
1154
+
1155
+ if (value_comp ()(*__hint, __v)) { // check after
1156
+ // *__hint < __v
1157
+ const_iterator __next = std::next (__hint);
1158
+ if (__next == end () || value_comp ()(__v, *__next)) {
1159
+ // *__hint < __v < *std::next(__hint)
1160
+ if (__hint.__get_np ()->__right_ == nullptr )
1161
+ return _PairT (__hint.__ptr_ , static_cast <__node_pointer>(__hint.__ptr_ )->__right_ );
1162
+ return _PairT (__next.__ptr_ , __next.__ptr_ ->__left_ );
1163
+ }
1164
+ // *next(__hint) <= __v
1165
+ return __find_equal (__v);
1166
+ }
1167
+
1168
+ // else __v == *__hint
1169
+ __dummy = static_cast <__node_base_pointer>(__hint.__ptr_ );
1170
+ return _PairT (__hint.__ptr_ , __dummy);
1171
+ }
1098
1172
1099
1173
_LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc (const __tree& __t ) {
1100
1174
__copy_assign_alloc (__t , integral_constant<bool , __node_traits::propagate_on_container_copy_assignment::value>());
@@ -1647,94 +1721,6 @@ typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Co
1647
1721
return __find_leaf_low (__parent, __v);
1648
1722
}
1649
1723
1650
- // Find place to insert if __v doesn't exist
1651
- // Set __parent to parent of null leaf
1652
- // Return reference to null leaf
1653
- // If __v exists, set parent to node of __v and return reference to node of __v
1654
- template <class _Tp , class _Compare , class _Allocator >
1655
- template <class _Key >
1656
- typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1657
- __tree<_Tp, _Compare, _Allocator>::__find_equal(__end_node_pointer& __parent, const _Key& __v) {
1658
- __node_pointer __nd = __root ();
1659
- __node_base_pointer* __nd_ptr = __root_ptr ();
1660
- if (__nd != nullptr ) {
1661
- while (true ) {
1662
- if (value_comp ()(__v, __nd->__value_ )) {
1663
- if (__nd->__left_ != nullptr ) {
1664
- __nd_ptr = std::addressof (__nd->__left_ );
1665
- __nd = static_cast <__node_pointer>(__nd->__left_ );
1666
- } else {
1667
- __parent = static_cast <__end_node_pointer>(__nd);
1668
- return __parent->__left_ ;
1669
- }
1670
- } else if (value_comp ()(__nd->__value_ , __v)) {
1671
- if (__nd->__right_ != nullptr ) {
1672
- __nd_ptr = std::addressof (__nd->__right_ );
1673
- __nd = static_cast <__node_pointer>(__nd->__right_ );
1674
- } else {
1675
- __parent = static_cast <__end_node_pointer>(__nd);
1676
- return __nd->__right_ ;
1677
- }
1678
- } else {
1679
- __parent = static_cast <__end_node_pointer>(__nd);
1680
- return *__nd_ptr;
1681
- }
1682
- }
1683
- }
1684
- __parent = __end_node ();
1685
- return __parent->__left_ ;
1686
- }
1687
-
1688
- // Find place to insert if __v doesn't exist
1689
- // First check prior to __hint.
1690
- // Next check after __hint.
1691
- // Next do O(log N) search.
1692
- // Set __parent to parent of null leaf
1693
- // Return reference to null leaf
1694
- // If __v exists, set parent to node of __v and return reference to node of __v
1695
- template <class _Tp , class _Compare , class _Allocator >
1696
- template <class _Key >
1697
- typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Compare, _Allocator>::__find_equal(
1698
- const_iterator __hint, __end_node_pointer& __parent, __node_base_pointer& __dummy, const _Key& __v) {
1699
- if (__hint == end () || value_comp ()(__v, *__hint)) // check before
1700
- {
1701
- // __v < *__hint
1702
- const_iterator __prior = __hint;
1703
- if (__prior == begin () || value_comp ()(*--__prior, __v)) {
1704
- // *prev(__hint) < __v < *__hint
1705
- if (__hint.__ptr_ ->__left_ == nullptr ) {
1706
- __parent = __hint.__ptr_ ;
1707
- return __parent->__left_ ;
1708
- } else {
1709
- __parent = __prior.__ptr_ ;
1710
- return static_cast <__node_base_pointer>(__prior.__ptr_ )->__right_ ;
1711
- }
1712
- }
1713
- // __v <= *prev(__hint)
1714
- return __find_equal (__parent, __v);
1715
- } else if (value_comp ()(*__hint, __v)) // check after
1716
- {
1717
- // *__hint < __v
1718
- const_iterator __next = std::next (__hint);
1719
- if (__next == end () || value_comp ()(__v, *__next)) {
1720
- // *__hint < __v < *std::next(__hint)
1721
- if (__hint.__get_np ()->__right_ == nullptr ) {
1722
- __parent = __hint.__ptr_ ;
1723
- return static_cast <__node_base_pointer>(__hint.__ptr_ )->__right_ ;
1724
- } else {
1725
- __parent = __next.__ptr_ ;
1726
- return __parent->__left_ ;
1727
- }
1728
- }
1729
- // *next(__hint) <= __v
1730
- return __find_equal (__parent, __v);
1731
- }
1732
- // else __v == *__hint
1733
- __parent = __hint.__ptr_ ;
1734
- __dummy = static_cast <__node_base_pointer>(__hint.__ptr_ );
1735
- return __dummy;
1736
- }
1737
-
1738
1724
template <class _Tp , class _Compare , class _Allocator >
1739
1725
void __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
1740
1726
__end_node_pointer __parent, __node_base_pointer& __child, __node_base_pointer __new_node) _NOEXCEPT {
@@ -1753,10 +1739,9 @@ template <class _Tp, class _Compare, class _Allocator>
1753
1739
template <class _Key , class ... _Args>
1754
1740
pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool >
1755
1741
__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const & __k, _Args&&... __args) {
1756
- __end_node_pointer __parent;
1757
- __node_base_pointer& __child = __find_equal (__parent, __k);
1758
- __node_pointer __r = static_cast <__node_pointer>(__child);
1759
- bool __inserted = false ;
1742
+ auto [__parent, __child] = __find_equal (__k);
1743
+ __node_pointer __r = static_cast <__node_pointer>(__child);
1744
+ bool __inserted = false ;
1760
1745
if (__child == nullptr ) {
1761
1746
__node_holder __h = __construct_node (std::forward<_Args>(__args)...);
1762
1747
__insert_node_at (__parent, __child, static_cast <__node_base_pointer>(__h.get ()));
@@ -1771,11 +1756,10 @@ template <class _Key, class... _Args>
1771
1756
pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool >
1772
1757
__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
1773
1758
const_iterator __p, _Key const & __k, _Args&&... __args) {
1774
- __end_node_pointer __parent;
1775
1759
__node_base_pointer __dummy;
1776
- __node_base_pointer& __child = __find_equal (__p, __parent , __dummy, __k);
1777
- __node_pointer __r = static_cast <__node_pointer>(__child);
1778
- bool __inserted = false ;
1760
+ auto [__parent, __child] = __find_equal (__p, __dummy, __k);
1761
+ __node_pointer __r = static_cast <__node_pointer>(__child);
1762
+ bool __inserted = false ;
1779
1763
if (__child == nullptr ) {
1780
1764
__node_holder __h = __construct_node (std::forward<_Args>(__args)...);
1781
1765
__insert_node_at (__parent, __child, static_cast <__node_base_pointer>(__h.get ()));
@@ -1800,11 +1784,10 @@ template <class _Tp, class _Compare, class _Allocator>
1800
1784
template <class ... _Args>
1801
1785
pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool >
1802
1786
__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args) {
1803
- __node_holder __h = __construct_node (std::forward<_Args>(__args)...);
1804
- __end_node_pointer __parent;
1805
- __node_base_pointer& __child = __find_equal (__parent, __h->__value_ );
1806
- __node_pointer __r = static_cast <__node_pointer>(__child);
1807
- bool __inserted = false ;
1787
+ __node_holder __h = __construct_node (std::forward<_Args>(__args)...);
1788
+ auto [__parent, __child] = __find_equal (__h->__value_ );
1789
+ __node_pointer __r = static_cast <__node_pointer>(__child);
1790
+ bool __inserted = false ;
1808
1791
if (__child == nullptr ) {
1809
1792
__insert_node_at (__parent, __child, static_cast <__node_base_pointer>(__h.get ()));
1810
1793
__r = __h.release ();
@@ -1818,10 +1801,9 @@ template <class... _Args>
1818
1801
typename __tree<_Tp, _Compare, _Allocator>::iterator
1819
1802
__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args) {
1820
1803
__node_holder __h = __construct_node (std::forward<_Args>(__args)...);
1821
- __end_node_pointer __parent;
1822
1804
__node_base_pointer __dummy;
1823
- __node_base_pointer& __child = __find_equal (__p, __parent , __dummy, __h->__value_ );
1824
- __node_pointer __r = static_cast <__node_pointer>(__child);
1805
+ auto [__parent, __child] = __find_equal (__p, __dummy, __h->__value_ );
1806
+ __node_pointer __r = static_cast <__node_pointer>(__child);
1825
1807
if (__child == nullptr ) {
1826
1808
__insert_node_at (__parent, __child, static_cast <__node_base_pointer>(__h.get ()));
1827
1809
__r = __h.release ();
@@ -1854,10 +1836,9 @@ __tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p, _Arg
1854
1836
template <class _Tp , class _Compare , class _Allocator >
1855
1837
pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool >
1856
1838
__tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const value_type& __v, __node_pointer __nd) {
1857
- __end_node_pointer __parent;
1858
- __node_base_pointer& __child = __find_equal (__parent, __v);
1859
- __node_pointer __r = static_cast <__node_pointer>(__child);
1860
- bool __inserted = false ;
1839
+ auto [__parent, __child] = __find_equal (__v);
1840
+ __node_pointer __r = static_cast <__node_pointer>(__child);
1841
+ bool __inserted = false ;
1861
1842
if (__child == nullptr ) {
1862
1843
__assign_value (__nd->__value_ , __v);
1863
1844
__insert_node_at (__parent, __child, static_cast <__node_base_pointer>(__nd));
@@ -1906,8 +1887,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(_NodeHandle&& __n
1906
1887
return _InsertReturnType{end (), false , _NodeHandle ()};
1907
1888
1908
1889
__node_pointer __ptr = __nh.__ptr_ ;
1909
- __end_node_pointer __parent;
1910
- __node_base_pointer& __child = __find_equal (__parent, __ptr->__value_ );
1890
+ auto [__parent, __child] = __find_equal (__ptr->__value_ );
1911
1891
if (__child != nullptr )
1912
1892
return _InsertReturnType{iterator (static_cast <__node_pointer>(__child)), false , std::move (__nh)};
1913
1893
@@ -1924,10 +1904,9 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(const_iterator __
1924
1904
return end ();
1925
1905
1926
1906
__node_pointer __ptr = __nh.__ptr_ ;
1927
- __end_node_pointer __parent;
1928
1907
__node_base_pointer __dummy;
1929
- __node_base_pointer& __child = __find_equal (__hint, __parent , __dummy, __ptr->__value_ );
1930
- __node_pointer __r = static_cast <__node_pointer>(__child);
1908
+ auto [__parent, __child] = __find_equal (__hint, __dummy, __ptr->__value_ );
1909
+ __node_pointer __r = static_cast <__node_pointer>(__child);
1931
1910
if (__child == nullptr ) {
1932
1911
__insert_node_at (__parent, __child, static_cast <__node_base_pointer>(__ptr));
1933
1912
__r = __ptr;
@@ -1960,8 +1939,7 @@ _LIBCPP_HIDE_FROM_ABI void __tree<_Tp, _Compare, _Allocator>::__node_handle_merg
1960
1939
1961
1940
for (typename _Tree::iterator __i = __source.begin (); __i != __source.end ();) {
1962
1941
__node_pointer __src_ptr = __i.__get_np ();
1963
- __end_node_pointer __parent;
1964
- __node_base_pointer& __child = __find_equal (__parent, __src_ptr->__value_ );
1942
+ auto [__parent, __child] = __find_equal (__src_ptr->__value_ );
1965
1943
++__i;
1966
1944
if (__child != nullptr )
1967
1945
continue ;
0 commit comments