llvm.org GIT mirror llvm / 12061ae
[MISC]Fix wrong usage of std::equal() Differential Revision: https://reviews.llvm.org/D49958 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340000 91177308-0d34-0410-b5e6-96231b3b80d8 Chen Zheng 2 years ago
4 changed file(s) with 158 addition(s) and 138 deletion(s). Raw diff Collapse all Expand all
10041004 C.clear();
10051005 }
10061006
1007 /// Provide wrappers to std::for_each which take ranges instead of having to
1008 /// pass begin/end explicitly.
1009 template
1010 UnaryPredicate for_each(R &&Range, UnaryPredicate P) {
1011 return std::for_each(adl_begin(Range), adl_end(Range), P);
1012 }
1013
1014 /// Provide wrappers to std::all_of which take ranges instead of having to pass
1015 /// begin/end explicitly.
1016 template
1017 bool all_of(R &&Range, UnaryPredicate P) {
1018 return std::all_of(adl_begin(Range), adl_end(Range), P);
1019 }
1020
1021 /// Provide wrappers to std::any_of which take ranges instead of having to pass
1022 /// begin/end explicitly.
1023 template
1024 bool any_of(R &&Range, UnaryPredicate P) {
1025 return std::any_of(adl_begin(Range), adl_end(Range), P);
1026 }
1027
1028 /// Provide wrappers to std::none_of which take ranges instead of having to pass
1029 /// begin/end explicitly.
1030 template
1031 bool none_of(R &&Range, UnaryPredicate P) {
1032 return std::none_of(adl_begin(Range), adl_end(Range), P);
1033 }
1034
1035 /// Provide wrappers to std::find which take ranges instead of having to pass
1036 /// begin/end explicitly.
1037 template
1038 auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range)) {
1039 return std::find(adl_begin(Range), adl_end(Range), Val);
1040 }
1041
1042 /// Provide wrappers to std::find_if which take ranges instead of having to pass
1043 /// begin/end explicitly.
1044 template
1045 auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
1046 return std::find_if(adl_begin(Range), adl_end(Range), P);
1047 }
1048
1049 template
1050 auto find_if_not(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
1051 return std::find_if_not(adl_begin(Range), adl_end(Range), P);
1052 }
1053
1054 /// Provide wrappers to std::remove_if which take ranges instead of having to
1055 /// pass begin/end explicitly.
1056 template
1057 auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
1058 return std::remove_if(adl_begin(Range), adl_end(Range), P);
1059 }
1060
1061 /// Provide wrappers to std::copy_if which take ranges instead of having to
1062 /// pass begin/end explicitly.
1063 template
1064 OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P) {
1065 return std::copy_if(adl_begin(Range), adl_end(Range), Out, P);
1066 }
1067
1068 template
1069 OutputIt copy(R &&Range, OutputIt Out) {
1070 return std::copy(adl_begin(Range), adl_end(Range), Out);
1071 }
1072
1073 /// Wrapper function around std::find to detect if an element exists
1074 /// in a container.
1075 template
1076 bool is_contained(R &&Range, const E &Element) {
1077 return std::find(adl_begin(Range), adl_end(Range), Element) != adl_end(Range);
1078 }
1079
1080 /// Wrapper function around std::count to count the number of times an element
1081 /// \p Element occurs in the given range \p Range.
1082 template
1083 auto count(R &&Range, const E &Element) ->
1084 typename std::iterator_traits::difference_type {
1085 return std::count(adl_begin(Range), adl_end(Range), Element);
1086 }
1087
1088 /// Wrapper function around std::count_if to count the number of times an
1089 /// element satisfying a given predicate occurs in a range.
1090 template
1091 auto count_if(R &&Range, UnaryPredicate P) ->
1092 typename std::iterator_traits::difference_type {
1093 return std::count_if(adl_begin(Range), adl_end(Range), P);
1094 }
1095
1096 /// Wrapper function around std::transform to apply a function to a range and
1097 /// store the result elsewhere.
1098 template
1099 OutputIt transform(R &&Range, OutputIt d_first, UnaryPredicate P) {
1100 return std::transform(adl_begin(Range), adl_end(Range), d_first, P);
1101 }
1102
1103 /// Provide wrappers to std::partition which take ranges instead of having to
1104 /// pass begin/end explicitly.
1105 template
1106 auto partition(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
1107 return std::partition(adl_begin(Range), adl_end(Range), P);
1108 }
1109
1110 /// Provide wrappers to std::lower_bound which take ranges instead of having to
1111 /// pass begin/end explicitly.
1112 template
1113 auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) {
1114 return std::lower_bound(adl_begin(Range), adl_end(Range), I);
1115 }
1116
1117 /// Given a range of type R, iterate the entire range and return a
1118 /// SmallVector with elements of the vector. This is useful, for example,
1119 /// when you want to iterate a range and then sort the results.
1120 template
1121 SmallVector>::type, Size>
1122 to_vector(R &&Range) {
1123 return {adl_begin(Range), adl_end(Range)};
1124 }
1125
1126 /// Provide a container algorithm similar to C++ Library Fundamentals v2's
1127 /// `erase_if` which is equivalent to:
1128 ///
1129 /// C.erase(remove_if(C, pred), C.end());
1130 ///
1131 /// This version works for any container with an erase method call accepting
1132 /// two iterators.
1133 template
1134 void erase_if(Container &C, UnaryPredicate P) {
1135 C.erase(remove_if(C, P), C.end());
1136 }
1137
11381007 /// Get the size of a range. This is a wrapper function around std::distance
11391008 /// which is only enabled when the operation is O(1).
11401009 template
11471016 return std::distance(Range.begin(), Range.end());
11481017 }
11491018
1019 /// Provide wrappers to std::for_each which take ranges instead of having to
1020 /// pass begin/end explicitly.
1021 template
1022 UnaryPredicate for_each(R &&Range, UnaryPredicate P) {
1023 return std::for_each(adl_begin(Range), adl_end(Range), P);
1024 }
1025
1026 /// Provide wrappers to std::all_of which take ranges instead of having to pass
1027 /// begin/end explicitly.
1028 template
1029 bool all_of(R &&Range, UnaryPredicate P) {
1030 return std::all_of(adl_begin(Range), adl_end(Range), P);
1031 }
1032
1033 /// Provide wrappers to std::any_of which take ranges instead of having to pass
1034 /// begin/end explicitly.
1035 template
1036 bool any_of(R &&Range, UnaryPredicate P) {
1037 return std::any_of(adl_begin(Range), adl_end(Range), P);
1038 }
1039
1040 /// Provide wrappers to std::none_of which take ranges instead of having to pass
1041 /// begin/end explicitly.
1042 template
1043 bool none_of(R &&Range, UnaryPredicate P) {
1044 return std::none_of(adl_begin(Range), adl_end(Range), P);
1045 }
1046
1047 /// Provide wrappers to std::find which take ranges instead of having to pass
1048 /// begin/end explicitly.
1049 template
1050 auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range)) {
1051 return std::find(adl_begin(Range), adl_end(Range), Val);
1052 }
1053
1054 /// Provide wrappers to std::find_if which take ranges instead of having to pass
1055 /// begin/end explicitly.
1056 template
1057 auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
1058 return std::find_if(adl_begin(Range), adl_end(Range), P);
1059 }
1060
1061 template
1062 auto find_if_not(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
1063 return std::find_if_not(adl_begin(Range), adl_end(Range), P);
1064 }
1065
1066 /// Provide wrappers to std::remove_if which take ranges instead of having to
1067 /// pass begin/end explicitly.
1068 template
1069 auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
1070 return std::remove_if(adl_begin(Range), adl_end(Range), P);
1071 }
1072
1073 /// Provide wrappers to std::copy_if which take ranges instead of having to
1074 /// pass begin/end explicitly.
1075 template
1076 OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P) {
1077 return std::copy_if(adl_begin(Range), adl_end(Range), Out, P);
1078 }
1079
1080 template
1081 OutputIt copy(R &&Range, OutputIt Out) {
1082 return std::copy(adl_begin(Range), adl_end(Range), Out);
1083 }
1084
1085 /// Wrapper function around std::find to detect if an element exists
1086 /// in a container.
1087 template
1088 bool is_contained(R &&Range, const E &Element) {
1089 return std::find(adl_begin(Range), adl_end(Range), Element) != adl_end(Range);
1090 }
1091
1092 /// Wrapper function around std::count to count the number of times an element
1093 /// \p Element occurs in the given range \p Range.
1094 template
1095 auto count(R &&Range, const E &Element) ->
1096 typename std::iterator_traits::difference_type {
1097 return std::count(adl_begin(Range), adl_end(Range), Element);
1098 }
1099
1100 /// Wrapper function around std::count_if to count the number of times an
1101 /// element satisfying a given predicate occurs in a range.
1102 template
1103 auto count_if(R &&Range, UnaryPredicate P) ->
1104 typename std::iterator_traits::difference_type {
1105 return std::count_if(adl_begin(Range), adl_end(Range), P);
1106 }
1107
1108 /// Wrapper function around std::transform to apply a function to a range and
1109 /// store the result elsewhere.
1110 template
1111 OutputIt transform(R &&Range, OutputIt d_first, UnaryPredicate P) {
1112 return std::transform(adl_begin(Range), adl_end(Range), d_first, P);
1113 }
1114
1115 /// Provide wrappers to std::partition which take ranges instead of having to
1116 /// pass begin/end explicitly.
1117 template
1118 auto partition(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
1119 return std::partition(adl_begin(Range), adl_end(Range), P);
1120 }
1121
1122 /// Provide wrappers to std::lower_bound which take ranges instead of having to
1123 /// pass begin/end explicitly.
1124 template
1125 auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) {
1126 return std::lower_bound(adl_begin(Range), adl_end(Range), I);
1127 }
1128
1129 /// Wrapper function around std::equal to detect if all elements
1130 /// in a container are same.
1131 template
1132 bool is_splat(R &&Range) {
1133 size_t range_size = size(Range);
1134 return range_size != 0 && (range_size == 1 ||
1135 std::equal(adl_begin(Range) + 1, adl_end(Range), adl_begin(Range)));
1136 }
1137
1138 /// Given a range of type R, iterate the entire range and return a
1139 /// SmallVector with elements of the vector. This is useful, for example,
1140 /// when you want to iterate a range and then sort the results.
1141 template
1142 SmallVector>::type, Size>
1143 to_vector(R &&Range) {
1144 return {adl_begin(Range), adl_end(Range)};
1145 }
1146
1147 /// Provide a container algorithm similar to C++ Library Fundamentals v2's
1148 /// `erase_if` which is equivalent to:
1149 ///
1150 /// C.erase(remove_if(C, pred), C.end());
1151 ///
1152 /// This version works for any container with an erase method call accepting
1153 /// two iterators.
1154 template
1155 void erase_if(Container &C, UnaryPredicate P) {
1156 C.erase(remove_if(C, P), C.end());
1157 }
1158
11501159 //===----------------------------------------------------------------------===//
11511160 // Extra additions to
11521161 //===----------------------------------------------------------------------===//
29302930 ISD::VSELECT : ISD::SELECT;
29312931
29322932 // Min/max matching is only viable if all output VTs are the same.
2933 if (std::equal(ValueVTs.begin(), ValueVTs.end(), ValueVTs.begin())) {
2933 if (is_splat(ValueVTs)) {
29342934 EVT VT = ValueVTs[0];
29352935 LLVMContext &Ctx = *DAG.getContext();
29362936 auto &TLI = DAG.getTargetLoweringInfo();
31733173 SmallVector OperandList;
31743174 std::copy(FilteredPhiArgs.begin(), FilteredPhiArgs.end(),
31753175 std::back_inserter(OperandList));
3176 bool Okay = OperandList.size() == 1;
3177 if (!Okay)
3178 Okay =
3179 std::equal(OperandList.begin(), OperandList.end(), OperandList.begin());
3176 bool Okay = is_splat(OperandList);
31803177 if (Okay)
31813178 return singleReachablePHIPath(Visited, cast(OperandList[0]),
31823179 Second);
32713268 const MemoryDef *MD = cast(U);
32723269 return ValueToClass.lookup(MD->getMemoryInst());
32733270 });
3274 assert(std::equal(PhiOpClasses.begin(), PhiOpClasses.end(),
3275 PhiOpClasses.begin()) &&
3271 assert(is_splat(PhiOpClasses) &&
32763272 "All MemoryPhi arguments should be in the same class");
32773273 }
32783274 }
414414 EXPECT_EQ(EIR.end(), I);
415415 }
416416
417 TEST(STLExtrasTest, splat) {
418 std::vector V;
419 EXPECT_FALSE(is_splat(V));
420
421 V.push_back(1);
422 EXPECT_TRUE(is_splat(V));
423
424 V.push_back(1);
425 V.push_back(1);
426 EXPECT_TRUE(is_splat(V));
427
428 V.push_back(2);
429 EXPECT_FALSE(is_splat(V));
430 }
431
417432 } // namespace