@@ -1169,15 +1169,89 @@ public:
1169
1169
1170
1170
// FIXME: Make this function const qualified. Unfortunately doing so
1171
1171
// breaks existing code which uses non-const callable comparators.
1172
+
1173
+ // Find place to insert if __v doesn't exist
1174
+ // Set __parent to parent of null leaf
1175
+ // Return reference to null leaf
1176
+ // If __v exists, set parent to node of __v and return reference to node of __v
1172
1177
template <class _Key >
1173
- _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_equal (__end_node_pointer& __parent, const _Key& __v);
1178
+ _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&> __find_equal (const _Key& __v) {
1179
+ using _PairT = pair<__end_node_pointer, __node_base_pointer&>;
1180
+
1181
+ __node_pointer __node = __root ();
1182
+
1183
+ if (__node == nullptr ) {
1184
+ auto __end = __end_node ();
1185
+ return _PairT (__end, __end->__left_ );
1186
+ }
1187
+
1188
+ __node_base_pointer* __node_ptr = __root_ptr ();
1189
+ while (true ) {
1190
+ if (value_comp ()(__v, __node->__value_ )) {
1191
+ if (__node->__left_ == nullptr )
1192
+ return _PairT (static_cast <__end_node_pointer>(__node), __node->__left_ );
1193
+
1194
+ __node_ptr = std::addressof (__node->__left_ );
1195
+ __node = static_cast <__node_pointer>(__node->__left_ );
1196
+ } else if (value_comp ()(__node->__value_ , __v)) {
1197
+ if (__node->__right_ == nullptr )
1198
+ return _PairT (__node, __node->__right_ );
1199
+
1200
+ __node_ptr = std::addressof (__node->__right_ );
1201
+ __node = static_cast <__node_pointer>(__node->__right_ );
1202
+ } else {
1203
+ return _PairT (static_cast <__end_node_pointer>(__node), *__node_ptr);
1204
+ }
1205
+ }
1206
+ }
1207
+
1174
1208
template <class _Key >
1175
- _LIBCPP_HIDE_FROM_ABI __node_base_pointer& __find_equal (__end_node_pointer& __parent, const _Key& __v) const {
1176
- return const_cast <__tree*>(this )->__find_equal (__parent, __v);
1209
+ _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&> __find_equal (const _Key& __v) const {
1210
+ return const_cast <__tree*>(this )->__find_equal (__v);
1177
1211
}
1212
+
1213
+ // Find place to insert if __v doesn't exist
1214
+ // First check prior to __hint.
1215
+ // Next check after __hint.
1216
+ // Next do O(log N) search.
1217
+ // Set __parent to parent of null leaf
1218
+ // Return reference to null leaf
1219
+ // If __v exists, set parent to node of __v and return reference to node of __v
1178
1220
template <class _Key >
1179
- _LIBCPP_HIDE_FROM_ABI __node_base_pointer&
1180
- __find_equal (const_iterator __hint, __end_node_pointer& __parent, __node_base_pointer& __dummy, const _Key& __v);
1221
+ _LIBCPP_HIDE_FROM_ABI pair<__end_node_pointer, __node_base_pointer&>
1222
+ __find_equal (const_iterator __hint, __node_base_pointer& __dummy, const _Key& __v) {
1223
+ using _PairT = pair<__end_node_pointer, __node_base_pointer&>;
1224
+
1225
+ if (__hint == end () || value_comp ()(__v, *__hint)) { // check before
1226
+ // __v < *__hint
1227
+ const_iterator __prior = __hint;
1228
+ if (__prior == begin () || value_comp ()(*--__prior, __v)) {
1229
+ // *prev(__hint) < __v < *__hint
1230
+ if (__hint.__ptr_ ->__left_ == nullptr )
1231
+ return _PairT (__hint.__ptr_ , __hint.__ptr_ ->__left_ );
1232
+ return _PairT (__prior.__ptr_ , static_cast <__node_pointer>(__prior.__ptr_ )->__right_ );
1233
+ }
1234
+ // __v <= *prev(__hint)
1235
+ return __find_equal (__v);
1236
+ }
1237
+
1238
+ if (value_comp ()(*__hint, __v)) { // check after
1239
+ // *__hint < __v
1240
+ const_iterator __next = std::next (__hint);
1241
+ if (__next == end () || value_comp ()(__v, *__next)) {
1242
+ // *__hint < __v < *std::next(__hint)
1243
+ if (__hint.__get_np ()->__right_ == nullptr )
1244
+ return _PairT (__hint.__ptr_ , static_cast <__node_pointer>(__hint.__ptr_ )->__right_ );
1245
+ return _PairT (__next.__ptr_ , __next.__ptr_ ->__left_ );
1246
+ }
1247
+ // *next(__hint) <= __v
1248
+ return __find_equal (__v);
1249
+ }
1250
+
1251
+ // else __v == *__hint
1252
+ __dummy = static_cast <__node_base_pointer>(__hint.__ptr_ );
1253
+ return _PairT (__hint.__ptr_ , __dummy);
1254
+ }
1181
1255
1182
1256
_LIBCPP_HIDE_FROM_ABI void __copy_assign_alloc (const __tree& __t ) {
1183
1257
__copy_assign_alloc (__t , integral_constant<bool , __node_traits::propagate_on_container_copy_assignment::value>());
@@ -1620,94 +1694,6 @@ typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Co
1620
1694
return __find_leaf_low (__parent, __v);
1621
1695
}
1622
1696
1623
- // Find place to insert if __v doesn't exist
1624
- // Set __parent to parent of null leaf
1625
- // Return reference to null leaf
1626
- // If __v exists, set parent to node of __v and return reference to node of __v
1627
- template <class _Tp , class _Compare , class _Allocator >
1628
- template <class _Key >
1629
- typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer&
1630
- __tree<_Tp, _Compare, _Allocator>::__find_equal(__end_node_pointer& __parent, const _Key& __v) {
1631
- __node_pointer __nd = __root ();
1632
- __node_base_pointer* __nd_ptr = __root_ptr ();
1633
- if (__nd != nullptr ) {
1634
- while (true ) {
1635
- if (value_comp ()(__v, __nd->__value_ )) {
1636
- if (__nd->__left_ != nullptr ) {
1637
- __nd_ptr = std::addressof (__nd->__left_ );
1638
- __nd = static_cast <__node_pointer>(__nd->__left_ );
1639
- } else {
1640
- __parent = static_cast <__end_node_pointer>(__nd);
1641
- return __parent->__left_ ;
1642
- }
1643
- } else if (value_comp ()(__nd->__value_ , __v)) {
1644
- if (__nd->__right_ != nullptr ) {
1645
- __nd_ptr = std::addressof (__nd->__right_ );
1646
- __nd = static_cast <__node_pointer>(__nd->__right_ );
1647
- } else {
1648
- __parent = static_cast <__end_node_pointer>(__nd);
1649
- return __nd->__right_ ;
1650
- }
1651
- } else {
1652
- __parent = static_cast <__end_node_pointer>(__nd);
1653
- return *__nd_ptr;
1654
- }
1655
- }
1656
- }
1657
- __parent = __end_node ();
1658
- return __parent->__left_ ;
1659
- }
1660
-
1661
- // Find place to insert if __v doesn't exist
1662
- // First check prior to __hint.
1663
- // Next check after __hint.
1664
- // Next do O(log N) search.
1665
- // Set __parent to parent of null leaf
1666
- // Return reference to null leaf
1667
- // If __v exists, set parent to node of __v and return reference to node of __v
1668
- template <class _Tp , class _Compare , class _Allocator >
1669
- template <class _Key >
1670
- typename __tree<_Tp, _Compare, _Allocator>::__node_base_pointer& __tree<_Tp, _Compare, _Allocator>::__find_equal(
1671
- const_iterator __hint, __end_node_pointer& __parent, __node_base_pointer& __dummy, const _Key& __v) {
1672
- if (__hint == end () || value_comp ()(__v, *__hint)) // check before
1673
- {
1674
- // __v < *__hint
1675
- const_iterator __prior = __hint;
1676
- if (__prior == begin () || value_comp ()(*--__prior, __v)) {
1677
- // *prev(__hint) < __v < *__hint
1678
- if (__hint.__ptr_ ->__left_ == nullptr ) {
1679
- __parent = __hint.__ptr_ ;
1680
- return __parent->__left_ ;
1681
- } else {
1682
- __parent = __prior.__ptr_ ;
1683
- return static_cast <__node_base_pointer>(__prior.__ptr_ )->__right_ ;
1684
- }
1685
- }
1686
- // __v <= *prev(__hint)
1687
- return __find_equal (__parent, __v);
1688
- } else if (value_comp ()(*__hint, __v)) // check after
1689
- {
1690
- // *__hint < __v
1691
- const_iterator __next = std::next (__hint);
1692
- if (__next == end () || value_comp ()(__v, *__next)) {
1693
- // *__hint < __v < *std::next(__hint)
1694
- if (__hint.__get_np ()->__right_ == nullptr ) {
1695
- __parent = __hint.__ptr_ ;
1696
- return static_cast <__node_base_pointer>(__hint.__ptr_ )->__right_ ;
1697
- } else {
1698
- __parent = __next.__ptr_ ;
1699
- return __parent->__left_ ;
1700
- }
1701
- }
1702
- // *next(__hint) <= __v
1703
- return __find_equal (__parent, __v);
1704
- }
1705
- // else __v == *__hint
1706
- __parent = __hint.__ptr_ ;
1707
- __dummy = static_cast <__node_base_pointer>(__hint.__ptr_ );
1708
- return __dummy;
1709
- }
1710
-
1711
1697
template <class _Tp , class _Compare , class _Allocator >
1712
1698
void __tree<_Tp, _Compare, _Allocator>::__insert_node_at(
1713
1699
__end_node_pointer __parent, __node_base_pointer& __child, __node_base_pointer __new_node) _NOEXCEPT {
@@ -1726,10 +1712,9 @@ template <class _Tp, class _Compare, class _Allocator>
1726
1712
template <class _Key , class ... _Args>
1727
1713
pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool >
1728
1714
__tree<_Tp, _Compare, _Allocator>::__emplace_unique_key_args(_Key const & __k, _Args&&... __args) {
1729
- __end_node_pointer __parent;
1730
- __node_base_pointer& __child = __find_equal (__parent, __k);
1731
- __node_pointer __r = static_cast <__node_pointer>(__child);
1732
- bool __inserted = false ;
1715
+ auto [__parent, __child] = __find_equal (__k);
1716
+ __node_pointer __r = static_cast <__node_pointer>(__child);
1717
+ bool __inserted = false ;
1733
1718
if (__child == nullptr ) {
1734
1719
__node_holder __h = __construct_node (std::forward<_Args>(__args)...);
1735
1720
__insert_node_at (__parent, __child, static_cast <__node_base_pointer>(__h.get ()));
@@ -1744,11 +1729,10 @@ template <class _Key, class... _Args>
1744
1729
pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool >
1745
1730
__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_key_args(
1746
1731
const_iterator __p, _Key const & __k, _Args&&... __args) {
1747
- __end_node_pointer __parent;
1748
1732
__node_base_pointer __dummy;
1749
- __node_base_pointer& __child = __find_equal (__p, __parent , __dummy, __k);
1750
- __node_pointer __r = static_cast <__node_pointer>(__child);
1751
- bool __inserted = false ;
1733
+ auto [__parent, __child] = __find_equal (__p, __dummy, __k);
1734
+ __node_pointer __r = static_cast <__node_pointer>(__child);
1735
+ bool __inserted = false ;
1752
1736
if (__child == nullptr ) {
1753
1737
__node_holder __h = __construct_node (std::forward<_Args>(__args)...);
1754
1738
__insert_node_at (__parent, __child, static_cast <__node_base_pointer>(__h.get ()));
@@ -1774,8 +1758,7 @@ template <class... _Args>
1774
1758
pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool >
1775
1759
__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args) {
1776
1760
__node_holder __h = __construct_node (std::forward<_Args>(__args)...);
1777
- __end_node_pointer __parent;
1778
- __node_base_pointer& __child = __find_equal (__parent, __h->__value_ );
1761
+ auto [__parent, __child] = __find_equal (__h->__value_ );
1779
1762
__node_pointer __r = static_cast <__node_pointer>(__child);
1780
1763
bool __inserted = false ;
1781
1764
if (__child == nullptr ) {
@@ -1791,10 +1774,9 @@ template <class... _Args>
1791
1774
typename __tree<_Tp, _Compare, _Allocator>::iterator
1792
1775
__tree<_Tp, _Compare, _Allocator>::__emplace_hint_unique_impl(const_iterator __p, _Args&&... __args) {
1793
1776
__node_holder __h = __construct_node (std::forward<_Args>(__args)...);
1794
- __end_node_pointer __parent;
1795
1777
__node_base_pointer __dummy;
1796
- __node_base_pointer& __child = __find_equal (__p, __parent , __dummy, __h->__value_ );
1797
- __node_pointer __r = static_cast <__node_pointer>(__child);
1778
+ auto [__parent, __child] = __find_equal (__p, __dummy, __h->__value_ );
1779
+ __node_pointer __r = static_cast <__node_pointer>(__child);
1798
1780
if (__child == nullptr ) {
1799
1781
__insert_node_at (__parent, __child, static_cast <__node_base_pointer>(__h.get ()));
1800
1782
__r = __h.release ();
@@ -1827,8 +1809,7 @@ __tree<_Tp, _Compare, _Allocator>::__emplace_hint_multi(const_iterator __p, _Arg
1827
1809
template <class _Tp , class _Compare , class _Allocator >
1828
1810
pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool >
1829
1811
__tree<_Tp, _Compare, _Allocator>::__node_assign_unique(const value_type& __v, __node_pointer __nd) {
1830
- __end_node_pointer __parent;
1831
- __node_base_pointer& __child = __find_equal (__parent, __v);
1812
+ auto [__parent, __child] = __find_equal (__v);
1832
1813
__node_pointer __r = static_cast <__node_pointer>(__child);
1833
1814
bool __inserted = false ;
1834
1815
if (__child == nullptr ) {
@@ -1879,8 +1860,7 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(_NodeHandle&& __n
1879
1860
return _InsertReturnType{end (), false , _NodeHandle ()};
1880
1861
1881
1862
__node_pointer __ptr = __nh.__ptr_ ;
1882
- __end_node_pointer __parent;
1883
- __node_base_pointer& __child = __find_equal (__parent, __ptr->__value_ );
1863
+ auto [__parent, __child] = __find_equal (__ptr->__value_ );
1884
1864
if (__child != nullptr )
1885
1865
return _InsertReturnType{iterator (static_cast <__node_pointer>(__child)), false , std::move (__nh)};
1886
1866
@@ -1897,10 +1877,9 @@ __tree<_Tp, _Compare, _Allocator>::__node_handle_insert_unique(const_iterator __
1897
1877
return end ();
1898
1878
1899
1879
__node_pointer __ptr = __nh.__ptr_ ;
1900
- __end_node_pointer __parent;
1901
1880
__node_base_pointer __dummy;
1902
- __node_base_pointer& __child = __find_equal (__hint, __parent , __dummy, __ptr->__value_ );
1903
- __node_pointer __r = static_cast <__node_pointer>(__child);
1881
+ auto [__parent, __child] = __find_equal (__hint, __dummy, __ptr->__value_ );
1882
+ __node_pointer __r = static_cast <__node_pointer>(__child);
1904
1883
if (__child == nullptr ) {
1905
1884
__insert_node_at (__parent, __child, static_cast <__node_base_pointer>(__ptr));
1906
1885
__r = __ptr;
@@ -1932,9 +1911,8 @@ _LIBCPP_HIDE_FROM_ABI void __tree<_Tp, _Compare, _Allocator>::__node_handle_merg
1932
1911
static_assert (is_same<typename _Tree::__node_pointer, __node_pointer>::value, " " );
1933
1912
1934
1913
for (typename _Tree::iterator __i = __source.begin (); __i != __source.end ();) {
1935
- __node_pointer __src_ptr = __i.__get_np ();
1936
- __end_node_pointer __parent;
1937
- __node_base_pointer& __child = __find_equal (__parent, __src_ptr->__value_ );
1914
+ __node_pointer __src_ptr = __i.__get_np ();
1915
+ auto [__parent, __child] = __find_equal (__src_ptr->__value_ );
1938
1916
++__i;
1939
1917
if (__child != nullptr )
1940
1918
continue ;
0 commit comments