fat_core 2.0.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,194 +1,198 @@
1
- class Range
2
- # Return a range that concatenates this range with other; return nil
3
- # if the ranges are not contiguous.
4
- def join(other)
5
- if left_contiguous?(other)
6
- Range.new(min, other.max)
7
- elsif right_contiguous?(other)
8
- Range.new(other.min, max)
1
+ module FatCore
2
+ module Range
3
+ # Return a range that concatenates this range with other; return nil
4
+ # if the ranges are not contiguous.
5
+ def join(other)
6
+ if left_contiguous?(other)
7
+ ::Range.new(min, other.max)
8
+ elsif right_contiguous?(other)
9
+ ::Range.new(other.min, max)
10
+ end
9
11
  end
10
- end
11
12
 
12
- # Is self on the left of and contiguous to other?
13
- def left_contiguous?(other)
14
- if max.respond_to?(:succ)
15
- max.succ == other.min
16
- else
17
- max == other.min
13
+ # Is self on the left of and contiguous to other?
14
+ def left_contiguous?(other)
15
+ if max.respond_to?(:succ)
16
+ max.succ == other.min
17
+ else
18
+ max == other.min
19
+ end
18
20
  end
19
- end
20
21
 
21
- # Is self on the right of and contiguous to other?
22
- def right_contiguous?(other)
23
- if other.max.respond_to?(:succ)
24
- other.max.succ == min
25
- else
26
- other.max == min
22
+ # Is self on the right of and contiguous to other?
23
+ def right_contiguous?(other)
24
+ if other.max.respond_to?(:succ)
25
+ other.max.succ == min
26
+ else
27
+ other.max == min
28
+ end
27
29
  end
28
- end
29
30
 
30
- def contiguous?(other)
31
- left_contiguous?(other) || right_contiguous?(other)
32
- end
31
+ def contiguous?(other)
32
+ left_contiguous?(other) || right_contiguous?(other)
33
+ end
33
34
 
34
- def subset_of?(other)
35
- min >= other.min && max <= other.max
36
- end
35
+ def subset_of?(other)
36
+ min >= other.min && max <= other.max
37
+ end
37
38
 
38
- def proper_subset_of?(other)
39
- min > other.min && max < other.max
40
- end
39
+ def proper_subset_of?(other)
40
+ min > other.min && max < other.max
41
+ end
41
42
 
42
- def superset_of?(other)
43
- min <= other.min && max >= other.max
44
- end
43
+ def superset_of?(other)
44
+ min <= other.min && max >= other.max
45
+ end
45
46
 
46
- def proper_superset_of?(other)
47
- min < other.min && max > other.max
48
- end
47
+ def proper_superset_of?(other)
48
+ min < other.min && max > other.max
49
+ end
49
50
 
50
- def overlaps?(other)
51
- (cover?(other.min) || cover?(other.max) ||
52
- other.cover?(min) || other.cover?(max))
53
- end
51
+ def overlaps?(other)
52
+ (cover?(other.min) || cover?(other.max) ||
53
+ other.cover?(min) || other.cover?(max))
54
+ end
54
55
 
55
- def intersection(other)
56
- return nil unless overlaps?(other)
57
- ([min, other.min].max..[max, other.max].min)
58
- end
59
- alias & intersection
56
+ def intersection(other)
57
+ return nil unless overlaps?(other)
58
+ ([min, other.min].max..[max, other.max].min)
59
+ end
60
+ alias & intersection
60
61
 
61
- def union(other)
62
- return nil unless overlaps?(other) || contiguous?(other)
63
- ([min, other.min].min..[max, other.max].max)
64
- end
65
- alias + union
66
-
67
- # The difference method, -, removes the overlapping part of the other
68
- # argument from self. Because in the case where self is a superset of the
69
- # other range, this will result in the difference being two non-contiguous
70
- # ranges, this returns an array of ranges. If there is no overlap or if
71
- # self is a subset of the other range, return an array of self
72
- def difference(other)
73
- unless max.respond_to?(:succ) && min.respond_to?(:pred) &&
74
- other.max.respond_to?(:succ) && other.min.respond_to?(:pred)
75
- raise 'Range difference requires objects have pred and succ methods'
76
- end
77
- if subset_of?(other)
78
- # (4..7) - (0..10)
79
- []
80
- elsif proper_superset_of?(other)
81
- # (4..7) - (5..5) -> [(4..4), (6..7)]
82
- [(min..other.min.pred), (other.max.succ..max)]
83
- elsif overlaps?(other) && other.min <= min
84
- # (4..7) - (2..5) -> (6..7)
85
- [(other.max.succ..max)]
86
- elsif overlaps?(other) && other.max >= max
87
- # (4..7) - (6..10) -> (4..5)
88
- [(min..other.min.pred)]
89
- else
90
- [self]
62
+ def union(other)
63
+ return nil unless overlaps?(other) || contiguous?(other)
64
+ ([min, other.min].min..[max, other.max].max)
91
65
  end
92
- end
93
- alias - difference
94
-
95
- # Return whether any of the ranges that are within self overlap one
96
- # another
97
- def has_overlaps_within?(ranges)
98
- result = false
99
- unless ranges.empty?
100
- ranges.each do |r1|
101
- next unless overlaps?(r1)
102
- result =
103
- ranges.any? do |r2|
66
+ alias + union
67
+
68
+ # The difference method, -, removes the overlapping part of the other
69
+ # argument from self. Because in the case where self is a superset of the
70
+ # other range, this will result in the difference being two non-contiguous
71
+ # ranges, this returns an array of ranges. If there is no overlap or if
72
+ # self is a subset of the other range, return an array of self
73
+ def difference(other)
74
+ unless max.respond_to?(:succ) && min.respond_to?(:pred) &&
75
+ other.max.respond_to?(:succ) && other.min.respond_to?(:pred)
76
+ raise 'Range difference requires objects have pred and succ methods'
77
+ end
78
+ if subset_of?(other)
79
+ # (4..7) - (0..10)
80
+ []
81
+ elsif proper_superset_of?(other)
82
+ # (4..7) - (5..5) -> [(4..4), (6..7)]
83
+ [(min..other.min.pred), (other.max.succ..max)]
84
+ elsif overlaps?(other) && other.min <= min
85
+ # (4..7) - (2..5) -> (6..7)
86
+ [(other.max.succ..max)]
87
+ elsif overlaps?(other) && other.max >= max
88
+ # (4..7) - (6..10) -> (4..5)
89
+ [(min..other.min.pred)]
90
+ else
91
+ [self]
92
+ end
93
+ end
94
+ alias - difference
95
+
96
+ # Return whether any of the ranges that are within self overlap one
97
+ # another
98
+ def has_overlaps_within?(ranges)
99
+ result = false
100
+ unless ranges.empty?
101
+ ranges.each do |r1|
102
+ next unless overlaps?(r1)
103
+ result =
104
+ ranges.any? do |r2|
104
105
  r1.object_id != r2.object_id && overlaps?(r2) &&
105
106
  r1.overlaps?(r2)
106
107
  end
107
- return true if result
108
+ return true if result
109
+ end
108
110
  end
111
+ result
109
112
  end
110
- result
111
- end
112
113
 
113
- # Return true if the given ranges collectively cover this range
114
- # without overlaps.
115
- def spanned_by?(ranges)
116
- joined_range = nil
117
- ranges.sort_by(&:min).each do |r|
118
- unless joined_range
119
- joined_range = r
120
- next
114
+ # Return true if the given ranges collectively cover this range
115
+ # without overlaps.
116
+ def spanned_by?(ranges)
117
+ joined_range = nil
118
+ ranges.sort_by(&:min).each do |r|
119
+ unless joined_range
120
+ joined_range = r
121
+ next
122
+ end
123
+ joined_range = joined_range.join(r)
124
+ break if joined_range.nil?
125
+ end
126
+ if !joined_range.nil?
127
+ joined_range.min <= min && joined_range.max >= max
128
+ else
129
+ false
121
130
  end
122
- joined_range = joined_range.join(r)
123
- break if joined_range.nil?
124
- end
125
- if !joined_range.nil?
126
- joined_range.min <= min && joined_range.max >= max
127
- else
128
- false
129
131
  end
130
- end
131
132
 
132
- # If this range is not spanned by the ranges collectively, return an array
133
- # of ranges representing the gaps in coverage. Otherwise return an empty
134
- # array.
135
- def gaps(ranges)
136
- if ranges.empty?
137
- [clone]
138
- elsif spanned_by?(ranges)
139
- []
140
- else
141
- ranges = ranges.sort_by(&:min)
142
- gaps = []
143
- cur_point = min
144
- ranges.each do |rr|
145
- break if rr.min > max
146
- if rr.min > cur_point
147
- start_point = cur_point
148
- end_point = rr.min.pred
149
- gaps << (start_point..end_point)
150
- cur_point = rr.max.succ
151
- elsif rr.max >= cur_point
152
- cur_point = rr.max.succ
133
+ # If this range is not spanned by the ranges collectively, return an array
134
+ # of ranges representing the gaps in coverage. Otherwise return an empty
135
+ # array.
136
+ def gaps(ranges)
137
+ if ranges.empty?
138
+ [clone]
139
+ elsif spanned_by?(ranges)
140
+ []
141
+ else
142
+ ranges = ranges.sort_by(&:min)
143
+ gaps = []
144
+ cur_point = min
145
+ ranges.each do |rr|
146
+ break if rr.min > max
147
+ if rr.min > cur_point
148
+ start_point = cur_point
149
+ end_point = rr.min.pred
150
+ gaps << (start_point..end_point)
151
+ cur_point = rr.max.succ
152
+ elsif rr.max >= cur_point
153
+ cur_point = rr.max.succ
154
+ end
153
155
  end
156
+ gaps << (cur_point..max) if cur_point <= max
157
+ gaps
154
158
  end
155
- gaps << (cur_point..max) if cur_point <= max
156
- gaps
157
159
  end
158
- end
159
160
 
160
- # Similar to gaps, but within this range return the /overlaps/ among the
161
- # given ranges. If there are no overlaps, return an empty array. Don't
162
- # consider overlaps in the ranges that occur outside of self.
163
- def overlaps(ranges)
164
- if ranges.empty? || spanned_by?(ranges)
165
- []
166
- else
167
- ranges = ranges.sort_by(&:min)
168
- overlaps = []
169
- cur_point = nil
170
- ranges.each do |rr|
171
- # Skip ranges outside of self
172
- next if rr.max < min || rr.min > max
173
- # Initialize cur_point to max of first range
174
- if cur_point.nil?
161
+ # Similar to gaps, but within this range return the /overlaps/ among the
162
+ # given ranges. If there are no overlaps, return an empty array. Don't
163
+ # consider overlaps in the ranges that occur outside of self.
164
+ def overlaps(ranges)
165
+ if ranges.empty? || spanned_by?(ranges)
166
+ []
167
+ else
168
+ ranges = ranges.sort_by(&:min)
169
+ overlaps = []
170
+ cur_point = nil
171
+ ranges.each do |rr|
172
+ # Skip ranges outside of self
173
+ next if rr.max < min || rr.min > max
174
+ # Initialize cur_point to max of first range
175
+ if cur_point.nil?
176
+ cur_point = rr.max
177
+ next
178
+ end
179
+ # We are on the second or later range
180
+ if rr.min < cur_point
181
+ start_point = rr.min
182
+ end_point = cur_point
183
+ overlaps << (start_point..end_point)
184
+ end
175
185
  cur_point = rr.max
176
- next
177
- end
178
- # We are on the second or later range
179
- if rr.min < cur_point
180
- start_point = rr.min
181
- end_point = cur_point
182
- overlaps << (start_point..end_point)
183
186
  end
184
- cur_point = rr.max
187
+ overlaps
185
188
  end
186
- overlaps
187
189
  end
188
- end
189
190
 
190
- # Allow erb documents can directly interpolate ranges
191
- def tex_quote
192
- to_s
191
+ # Allow erb documents can directly interpolate ranges
192
+ def tex_quote
193
+ to_s
194
+ end
193
195
  end
194
196
  end
197
+
198
+ Range.include FatCore::Range