LLVM: include/llvm/ADT/SetOperations.h Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15#ifndef LLVM_ADT_SETOPERATIONS_H

16#define LLVM_ADT_SETOPERATIONS_H

17

19

20namespace llvm {

21

23template <typename Set, typename Fn>

25 decltype(std::declval().remove_if(std::declval()));

26

27template <typename Set, typename Fn>

30

31template

33 decltype(std::declval().erase(std::declval().begin()));

34

35template

38

39}

40

41

42

43template <class S1Ty, class S2Ty> bool set_union(S1Ty &S1, const S2Ty &S2) {

44 bool Changed = false;

45

46 for (const auto &E : S2)

47 if (S1.insert(E).second)

48 Changed = true;

49

50 return Changed;

51}

52

53

54

55

56

57

58template <class S1Ty, class S2Ty> void set_intersect(S1Ty &S1, const S2Ty &S2) {

59 auto Pred = [&S2](const auto &E) { return !S2.count(E); };

61 S1.remove_if(Pred);

62 } else {

63 typename S1Ty::iterator Next;

64 for (typename S1Ty::iterator I = S1.begin(); I != S1.end(); I = Next) {

65 Next = std::next(I);

66 if (!S2.count(*I))

67 S1.erase(I);

68 }

69 }

70}

71

72template <class S1Ty, class S2Ty>

74 S1Ty Result;

75 for (const auto &E : S1)

76 if (S2.count(E))

77 Result.insert(E);

78 return Result;

79}

80

81

82template <class S1Ty, class S2Ty>

84 if (S1.size() < S2.size())

86 else

88}

89

90

91

92template <class S1Ty, class S2Ty>

94 S1Ty Result;

95 for (const auto &E : S1)

96 if (!S2.count(E))

97 Result.insert(E);

98 return Result;

99}

100

101

102

103

104

105

106template <class S1Ty, class S2Ty> void set_subtract(S1Ty &S1, const S2Ty &S2) {

107

108

109

110 using ElemTy = decltype(*S1.begin());

111 if constexpr (detail::HasMemberContains<S2Ty, ElemTy>) {

112 auto Pred = [&S2](const auto &E) { return S2.contains(E); };

114 if (S1.size() < S2.size()) {

115 S1.remove_if(Pred);

116 return;

117 }

118 } else if constexpr (detail::HasMemberEraseIter) {

119 if (S1.size() < S2.size()) {

120 typename S1Ty::iterator Next;

121 for (typename S1Ty::iterator SI = S1.begin(), SE = S1.end(); SI != SE;

122 SI = Next) {

123 Next = std::next(SI);

124 if (S2.contains(*SI))

125 S1.erase(SI);

126 }

127 return;

128 }

129 }

130 }

131

132 for (const auto &E : S2)

133 S1.erase(E);

134}

135

136

137

138

139template <class S1Ty, class S2Ty>

140void set_subtract(S1Ty &S1, const S2Ty &S2, S1Ty &Removed, S1Ty &Remaining) {

141 for (const auto &E : S2)

142 if (S1.erase(E))

143 Removed.insert(E);

144 else

145 Remaining.insert(E);

146}

147

148

149

150template <class S1Ty, class S2Ty>

152 if (S1.size() > S2.size())

153 return false;

154 for (const auto It : S1)

155 if (!S2.count(It))

156 return false;

157 return true;

158}

159

160}

161

162#endif

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

decltype(std::declval< Set >().remove_if(std::declval< Fn >())) check_has_member_remove_if_t

decltype(std::declval< Set >().erase(std::declval< Set >().begin())) check_has_member_erase_iter_t

static constexpr bool HasMemberRemoveIf

static constexpr bool HasMemberEraseIter

This is an optimization pass for GlobalISel generic memory operations.

void set_intersect(S1Ty &S1, const S2Ty &S2)

set_intersect(A, B) - Compute A := A ^ B Identical to set_intersection, except that it works on set<>...

bool set_is_subset(const S1Ty &S1, const S2Ty &S2)

set_is_subset(A, B) - Return true iff A in B

void set_subtract(S1Ty &S1, const S2Ty &S2)

set_subtract(A, B) - Compute A := A - B

typename detail::detector< void, Op, Args... >::value_t is_detected

Detects if a given trait holds for some set of arguments 'Args'.

bool set_union(S1Ty &S1, const S2Ty &S2)

set_union(A, B) - Compute A := A u B, return whether A changed.

S1Ty set_intersection(const S1Ty &S1, const S2Ty &S2)

set_intersection(A, B) - Return A ^ B

S1Ty set_difference(const S1Ty &S1, const S2Ty &S2)

set_difference(A, B) - Return A - B

S1Ty set_intersection_impl(const S1Ty &S1, const S2Ty &S2)