|
11 | 11 | #define _LIBCPP___TREE |
12 | 12 |
|
13 | 13 | #include <__algorithm/min.h> |
| 14 | +#include <__algorithm/specialized_algorithms.h> |
14 | 15 | #include <__assert> |
15 | 16 | #include <__config> |
16 | 17 | #include <__fwd/pair.h> |
@@ -717,6 +718,59 @@ private: |
717 | 718 | friend class __tree_const_iterator; |
718 | 719 | }; |
719 | 720 |
|
| 721 | +template <class _Reference, class _EndNodePtr, class _NodePtr, class _Func, class _Proj> |
| 722 | +_LIBCPP_HIDE_FROM_ABI bool __tree_iterate_from_root(_EndNodePtr __last, _NodePtr __root, _Func& __func, _Proj& __proj) { |
| 723 | + if (__root->__left_) { |
| 724 | + if (std::__tree_iterate_from_root<_Reference>(__last, static_cast<_NodePtr>(__root->__left_), __func, __proj)) |
| 725 | + return true; |
| 726 | + } |
| 727 | + if (__root == __last) |
| 728 | + return true; |
| 729 | + __func(static_cast<_Reference>(__root->__get_value())); |
| 730 | + if (__root->__right_) |
| 731 | + return std::__tree_iterate_from_root<_Reference>(__last, static_cast<_NodePtr>(__root->__right_), __func, __proj); |
| 732 | + return false; |
| 733 | +} |
| 734 | + |
| 735 | +template <class _Reference, class _NodePtr, class _EndNodePtr, class _Func, class _Proj> |
| 736 | +_LIBCPP_HIDE_FROM_ABI void |
| 737 | +__tree_iterate_from_begin(_EndNodePtr __first, _EndNodePtr __last, _Func& __func, _Proj& __proj) { |
| 738 | + while (true) { |
| 739 | + if (__first == __last) |
| 740 | + return; |
| 741 | + auto __nfirst = static_cast<_NodePtr>(__first); |
| 742 | + __func(static_cast<_Reference>(__nfirst->__get_value())); |
| 743 | + if (__nfirst->__right_) { |
| 744 | + if (std::__tree_iterate_from_root<_Reference>(__last, static_cast<_NodePtr>(__nfirst->__right_), __func, __proj)) |
| 745 | + return; |
| 746 | + } |
| 747 | + if (std::__tree_is_left_child(__nfirst)) { |
| 748 | + __first = __nfirst->__parent_; |
| 749 | + } else { |
| 750 | + do { |
| 751 | + __first = __nfirst->__parent_; |
| 752 | + } while (!std::__tree_is_left_child(__nfirst)); |
| 753 | + } |
| 754 | + } |
| 755 | +} |
| 756 | + |
| 757 | +#ifndef _LIBCPP_CXX03_LANG |
| 758 | +template <class _Tp, class _NodePtr, class _DiffType> |
| 759 | +struct __specialized_algorithm< |
| 760 | + _Algorithm::__for_each, |
| 761 | + __iterator_pair<__tree_iterator<_Tp, _NodePtr, _DiffType>, __tree_iterator<_Tp, _NodePtr, _DiffType>>> { |
| 762 | + static const bool __has_algorithm = true; |
| 763 | + |
| 764 | + using __iterator _LIBCPP_NODEBUG = __tree_iterator<_Tp, _NodePtr, _DiffType>; |
| 765 | + |
| 766 | + template <class _Func, class _Proj> |
| 767 | + _LIBCPP_HIDE_FROM_ABI static void operator()(__iterator __first, __iterator __last, _Func& __func, _Proj& __proj) { |
| 768 | + std::__tree_iterate_from_begin<typename __iterator::reference, _NodePtr>( |
| 769 | + __first.__ptr_, __last.__ptr_, __func, __proj); |
| 770 | + } |
| 771 | +}; |
| 772 | +#endif |
| 773 | + |
720 | 774 | template <class _Tp, class _NodePtr, class _DiffType> |
721 | 775 | class __tree_const_iterator { |
722 | 776 | using _NodeTypes _LIBCPP_NODEBUG = __tree_node_types<_NodePtr>; |
@@ -780,8 +834,28 @@ private: |
780 | 834 |
|
781 | 835 | template <class, class, class> |
782 | 836 | friend class __tree; |
| 837 | + |
| 838 | + friend struct __specialized_algorithm<_Algorithm::__for_each, |
| 839 | + __iterator_pair<__tree_const_iterator, __tree_const_iterator> >; |
783 | 840 | }; |
784 | 841 |
|
| 842 | +#ifndef _LIBCPP_CXX03_LANG |
| 843 | +template <class _Tp, class _NodePtr, class _DiffType> |
| 844 | +struct __specialized_algorithm< |
| 845 | + _Algorithm::__for_each, |
| 846 | + __iterator_pair<__tree_const_iterator<_Tp, _NodePtr, _DiffType>, __tree_const_iterator<_Tp, _NodePtr, _DiffType>>> { |
| 847 | + static const bool __has_algorithm = true; |
| 848 | + |
| 849 | + using __iterator = __tree_const_iterator<_Tp, _NodePtr, _DiffType>; |
| 850 | + |
| 851 | + template <class _Func, class _Proj> |
| 852 | + _LIBCPP_HIDE_FROM_ABI static void operator()(__iterator __first, __iterator __last, _Func& __func, _Proj& __proj) { |
| 853 | + std::__tree_iterate_from_begin<typename __iterator::reference, _NodePtr>( |
| 854 | + __first.__ptr_, __last.__ptr_, __func, __proj); |
| 855 | + } |
| 856 | +}; |
| 857 | +#endif |
| 858 | + |
785 | 859 | template <class _Tp, class _Compare> |
786 | 860 | #ifndef _LIBCPP_CXX03_LANG |
787 | 861 | _LIBCPP_DIAGNOSE_WARNING(!__is_invocable_v<_Compare const&, _Tp const&, _Tp const&>, |
@@ -1466,7 +1540,36 @@ private: |
1466 | 1540 |
|
1467 | 1541 | return __dest; |
1468 | 1542 | } |
| 1543 | + |
| 1544 | + friend struct __specialized_algorithm<_Algorithm::__for_each, __tree>; |
| 1545 | +}; |
| 1546 | + |
| 1547 | +#if _LIBCPP_STD_VER >= 14 |
| 1548 | +template <class _Tp, class _Compare, class _Allocator> |
| 1549 | +struct __specialized_algorithm<_Algorithm::__for_each, __tree<_Tp, _Compare, _Allocator> > { |
| 1550 | + static const bool __has_algorithm = true; |
| 1551 | + |
| 1552 | + using __node_pointer _LIBCPP_NODEBUG = typename __tree<_Tp, _Compare, _Allocator>::__node_pointer; |
| 1553 | + |
| 1554 | + template <class _Func, class _Proj> |
| 1555 | +#ifndef _LIBCPP_COMPILER_GCC |
| 1556 | + _LIBCPP_HIDE_FROM_ABI |
| 1557 | +#endif |
| 1558 | + static void __impl(__node_pointer __root, _Func& __func, _Proj& __proj) { |
| 1559 | + if (__root->__left_) |
| 1560 | + __impl(static_cast<__node_pointer>(__root->__left_), __func, __proj); |
| 1561 | + __func(__root->__get_value()); |
| 1562 | + if (__root->__right_) |
| 1563 | + __impl(static_cast<__node_pointer>(__root->__right_), __func, __proj); |
| 1564 | + } |
| 1565 | + |
| 1566 | + template <class _Tree, class _Func, class _Proj> |
| 1567 | + _LIBCPP_HIDE_FROM_ABI static auto operator()(_Tree&& __range, _Func __func, _Proj __proj) { |
| 1568 | + __impl(__range.__root(), __func, __proj); |
| 1569 | + return std::make_pair(__range.end(), std::move(__func)); |
| 1570 | + } |
1469 | 1571 | }; |
| 1572 | +#endif |
1470 | 1573 |
|
1471 | 1574 | // Precondition: __size_ != 0 |
1472 | 1575 | template <class _Tp, class _Compare, class _Allocator> |
|
0 commit comments