Changeset f9823e2 in mainline
- Timestamp:
- 2018-07-05T21:41:22Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1fafb3e
- Parents:
- 23dcc14
- git-author:
- Dzejrou <dzejrou@…> (2018-04-27 22:16:07)
- git-committer:
- Dzejrou <dzejrou@…> (2018-07-05 21:41:22)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/cpp/include/impl/algorithm.hpp
r23dcc14 rf9823e2 35 35 namespace std 36 36 { 37 template<class T> 38 struct less; 39 37 40 /** 38 41 * 25.2, non-modyfing sequence operations: … … 806 809 */ 807 810 811 namespace aux 812 { 813 template<class T> 814 T heap_parent(T idx) 815 { 816 return (idx - 1) / 2; 817 } 818 819 template<class T> 820 T heap_left_child(T idx) 821 { 822 return 2 * idx + 1; 823 } 824 825 template<class T> 826 T heap_right_child(T idx) 827 { 828 return 2 * idx + 2; 829 } 830 831 template<class RandomAccessIterator, class Size, class Compare> 832 void correct_children(RandomAccessIterator first, 833 Size idx, Size count, Compare comp) 834 { 835 using aux::heap_left_child; 836 using aux::heap_right_child; 837 838 auto left = heap_left_child(idx); 839 auto right = heap_right_child(idx); 840 841 bool left_incorrect{comp(first[idx], first[left])}; 842 bool right_incorrect{comp(first[idx], first[right])}; 843 while ((left < count && left_incorrect) || 844 (right < count && right_incorrect)) 845 { 846 if (right >= count || (left_incorrect && comp(first[right], first[left]))) 847 { 848 swap(first[idx], first[left]); 849 850 idx = left; 851 } 852 else if (right < count && right_incorrect) 853 { 854 swap(first[idx], first[right]); 855 856 idx = right; 857 } // Else should not happen because of the while condition. 858 859 left = heap_left_child(idx); 860 right = heap_right_child(idx); 861 862 left_incorrect = comp(first[idx], first[left]); 863 right_incorrect = comp(first[idx], first[right]); 864 } 865 } 866 } 867 808 868 /** 809 869 * 25.4.6.1, push_heap: 810 870 */ 811 871 812 // TODO: implement 872 template<class RandomAccessIterator> 873 void push_heap(RandomAccessIterator first, 874 RandomAccessIterator last) 875 { 876 using value_type = typename iterator_traits<RandomAccessIterator>::value_type; 877 878 push_heap(first, last, less<value_type>{}); 879 } 880 881 template<class RandomAccessIterator, class Compare> 882 void push_heap(RandomAccessIterator first, 883 RandomAccessIterator last, 884 Compare comp) 885 { 886 using aux::heap_parent; 887 888 auto count = distance(first, last); 889 if (count <= 1) 890 return; 891 892 auto idx = count - 1; 893 auto parent = heap_parent(idx); 894 while (idx > 0 && comp(first[parent], first[idx])) 895 { 896 swap(first[idx], first[parent]); 897 898 idx = parent; 899 parent = heap_parent(idx); 900 } 901 } 813 902 814 903 /** … … 816 905 */ 817 906 818 // TODO: implement 907 template<class RandomAccessIterator> 908 void pop_heap(RandomAccessIterator first, 909 RandomAccessIterator last) 910 { 911 using value_type = typename iterator_traits<RandomAccessIterator>::value_type; 912 913 pop_heap(first, last, less<value_type>{}); 914 } 915 916 template<class RandomAccessIterator, class Compare> 917 void pop_heap(RandomAccessIterator first, 918 RandomAccessIterator last, 919 Compare comp) 920 { 921 auto count = distance(first, last); 922 if (count <= 1) 923 return; 924 925 swap(first[0], first[count - 1]); 926 aux::correct_children(first, decltype(count){}, count - 2, comp); 927 } 819 928 820 929 /** … … 822 931 */ 823 932 824 // TODO: implement 933 template<class RandomAccessIterator> 934 void make_heap(RandomAccessIterator first, 935 RandomAccessIterator last) 936 { 937 using value_type = typename iterator_traits<RandomAccessIterator>::value_type; 938 939 make_heap(first, last, less<value_type>{}); 940 } 941 942 template<class RandomAccessIterator, class Compare> 943 void make_heap(RandomAccessIterator first, 944 RandomAccessIterator last, 945 Compare comp) 946 { 947 auto count = distance(first, last); 948 if (count <= 1) 949 return; 950 951 for (auto i = count; i > 0; --i) 952 { 953 auto idx = i - 1; 954 955 aux::correct_children(first, idx, count, comp); 956 } 957 } 825 958 826 959 /** … … 828 961 */ 829 962 830 // TODO: implement 963 template<class RandomAccessIterator> 964 void sort_heap(RandomAccessIterator first, 965 RandomAccessIterator last) 966 { 967 using value_type = typename iterator_traits<RandomAccessIterator>::value_type; 968 969 sort_heap(first, last, less<value_type>{}); 970 } 971 972 template<class RandomAccessIterator, class Compare> 973 void sort_heap(RandomAccessIterator first, 974 RandomAccessIterator last, 975 Compare comp) 976 { 977 while (first != last) 978 pop_heap(first, last--, comp); 979 } 831 980 832 981 /** … … 834 983 */ 835 984 836 // TODO: implement 985 template<class RandomAccessIterator> 986 auto is_heap_until(RandomAccessIterator first, RandomAccessIterator last) 987 { 988 using value_type = typename iterator_traits<RandomAccessIterator>::value_type; 989 990 return is_heap_until(first, last, less<value_type>{}); 991 } 992 993 template<class RandomAccessIterator, class Compare> 994 auto is_heap_until(RandomAccessIterator first, RandomAccessIterator last, 995 Compare comp) 996 { 997 using aux::heap_left_child; 998 using aux::heap_right_child; 999 1000 auto count = distance(first, last); 1001 if (count < 2) 1002 return last; 1003 1004 auto res = first; 1005 for (decltype(count) idx = 0; idx < count; ++idx) 1006 { 1007 auto left = heap_left_child(idx); 1008 auto right = heap_right_child(idx); 1009 1010 if (left < count && comp(first[idx], first[left])) 1011 return res; 1012 if (right < count && comp(first[idx], first[right])) 1013 return res; 1014 1015 ++res; 1016 } 1017 1018 return res; 1019 } 1020 1021 template<class RandomAccessIterator> 1022 bool is_heap(RandomAccessIterator first, RandomAccessIterator last) 1023 { 1024 return is_heap_until(first, last) == last; 1025 } 1026 1027 template<class RandomAccessIterator, class Compare> 1028 bool is_heap(RandomAccessIterator first, RandomAccessIterator last, 1029 Compare comp) 1030 { 1031 return is_heap_until(first, last, comp) == last; 1032 } 837 1033 838 1034 /**
Note:
See TracChangeset
for help on using the changeset viewer.