@@ -16,7 +16,8 @@ pub use range_compare::{
16
16
// structs //
17
17
///////////////////////////////////////////////////////////////////////////////
18
18
19
- /// A set of elements represented as a sorted list of inclusive ranges.
19
+ /// A set of primitive integers represented as a sorted list of inclusive
20
+ /// ranges.
20
21
///
21
22
/// ```
22
23
/// # #![feature(inclusive_range)]
@@ -39,9 +40,11 @@ pub use range_compare::{
39
40
///
40
41
/// assert_eq!(s.insert_range (3..=12), Some (RangeSet::from (8..=10)));
41
42
/// println!("s: {:?}", s);
42
- /// assert!(! s.spilled());
43
+ /// assert!(s.spilled()); // once spilled, stays spilled
43
44
/// let v : Vec <u32> = s.iter().collect();
44
45
/// assert_eq!(v, vec![0,1,2,3,4,5,6,7,8,9,10,11,12]);
46
+ /// s.shrink_to_fit(); // manually un-spill
47
+ /// assert!(!s.spilled());
45
48
/// # }
46
49
/// ```
47
50
#[ derive( Clone , Debug , Eq , PartialEq ) ]
@@ -134,6 +137,11 @@ pub fn report() {
134
137
// impls //
135
138
///////////////////////////////////////////////////////////////////////////////
136
139
140
+ // the majority of the logic for modifying range sets are the insert_range and
141
+ // remove_range methods
142
+ //
143
+ // there are some helper functions with additional logic such as the
144
+ // binary_search functions
137
145
impl < A , T > RangeSet < A > where
138
146
A : smallvec:: Array < Item =std:: ops:: RangeInclusive < T > >
139
147
+ Eq + std:: fmt:: Debug ,
@@ -147,6 +155,15 @@ impl <A, T> RangeSet <A> where
147
155
}
148
156
}
149
157
158
+ /// New empty range set with the internal smallvec initialized with the given
159
+ /// initial capacity
160
+ #[ inline]
161
+ pub fn with_capacity ( capacity : usize ) -> Self {
162
+ RangeSet {
163
+ ranges : smallvec:: SmallVec :: with_capacity ( capacity)
164
+ }
165
+ }
166
+
150
167
/// Returns a new range set if the given vector of ranges is valid
151
168
/// (`valid_range_vec`)
152
169
#[ inline]
@@ -164,6 +181,78 @@ impl <A, T> RangeSet <A> where
164
181
self . ranges . is_empty ( )
165
182
}
166
183
184
+ /// Clears the range set
185
+ #[ inline]
186
+ pub fn clear ( & mut self ) {
187
+ self . ranges . clear ( )
188
+ }
189
+
190
+ /// Converts into the internal smallvec
191
+ #[ inline]
192
+ pub fn into_smallvec ( self ) -> smallvec:: SmallVec < A > {
193
+ self . ranges
194
+ }
195
+
196
+ /// Insert a single element, returning true if it was successfully inserted
197
+ /// or else false if it was already present
198
+ ///
199
+ /// ```
200
+ /// # #![feature(inclusive_range)]
201
+ /// # #![feature(inclusive_range_syntax)]
202
+ /// # use range_set::RangeSet;
203
+ /// # use std::ops::RangeInclusive;
204
+ /// let mut s = RangeSet::<[RangeInclusive <u32>; 2]>::new();
205
+ /// assert!(s.insert (4));
206
+ /// assert_eq!(s, RangeSet::from (4..=4));
207
+ /// assert!(!s.insert (4));
208
+ /// assert_eq!(s, RangeSet::from (4..=4));
209
+ /// assert!(s.insert (5));
210
+ /// assert_eq!(s, RangeSet::from (4..=5));
211
+ /// assert!(s.insert (3));
212
+ /// assert_eq!(s, RangeSet::from (3..=5));
213
+ /// assert!(s.insert (10));
214
+ /// assert_eq!(s, RangeSet::from_ranges (vec![3..=5, 10..=10].into()).unwrap());
215
+ /// ```
216
+ pub fn insert ( & mut self , element : T ) -> bool {
217
+ if let Some ( _) = self . insert_range ( element..=element) {
218
+ false
219
+ } else {
220
+ true
221
+ }
222
+ }
223
+
224
+ /// Remove a single element, returning true if it was successfully removed
225
+ /// or else false if it was not present
226
+ ///
227
+ /// ```
228
+ /// # #![feature(inclusive_range)]
229
+ /// # #![feature(inclusive_range_syntax)]
230
+ /// # use range_set::RangeSet;
231
+ /// # use std::ops::RangeInclusive;
232
+ /// let mut s = RangeSet::<[RangeInclusive <u32>; 2]>::from (0..=5);
233
+ /// assert!(s.remove (1));
234
+ /// assert_eq!(s, RangeSet::from_ranges (vec![0..=0, 2..=5].into()).unwrap());
235
+ /// assert!(!s.remove (1));
236
+ /// assert_eq!(s, RangeSet::from_ranges (vec![0..=0, 2..=5].into()).unwrap());
237
+ /// assert!(s.remove (4));
238
+ /// assert_eq!(s, RangeSet::from_ranges (vec![0..=0, 2..=3, 5..=5].into()).unwrap());
239
+ /// assert!(s.remove (3));
240
+ /// assert_eq!(s, RangeSet::from_ranges (vec![0..=0, 2..=2, 5..=5].into()).unwrap());
241
+ /// assert!(s.remove (2));
242
+ /// assert_eq!(s, RangeSet::from_ranges (vec![0..=0, 5..=5].into()).unwrap());
243
+ /// assert!(s.remove (0));
244
+ /// assert_eq!(s, RangeSet::from (5..=5));
245
+ /// assert!(s.remove (5));
246
+ /// assert!(s.is_empty());
247
+ /// ```
248
+ pub fn remove ( & mut self , element : T ) -> bool {
249
+ if let Some ( _) = self . remove_range ( element..=element) {
250
+ true
251
+ } else {
252
+ false
253
+ }
254
+ }
255
+
167
256
/// Returns the intersected values if the range is not disjoint
168
257
/// with the curret range set.
169
258
///
@@ -194,13 +283,11 @@ impl <A, T> RangeSet <A> where
194
283
// of the intersection of the given range and the existing range set
195
284
( None , None ) => {
196
285
let isect = self . range_intersection ( & range, 0 ..self . ranges . len ( ) ) ;
197
- self . ranges = {
198
- let mut v = smallvec:: SmallVec :: new ( ) ;
199
- v. push (
200
- std:: cmp:: min ( range. start , self . ranges [ 0 ] . start ) ..=
201
- std:: cmp:: max ( range. end , self . ranges [ self . ranges . len ( ) -1 ] . end ) ) ;
202
- v
203
- } ;
286
+ let new_range =
287
+ std:: cmp:: min ( range. start , self . ranges [ 0 ] . start ) ..=
288
+ std:: cmp:: max ( range. end , self . ranges [ self . ranges . len ( ) -1 ] . end ) ;
289
+ self . ranges . clear ( ) ;
290
+ self . ranges . push ( new_range) ;
204
291
if !isect. is_empty ( ) {
205
292
Some ( isect)
206
293
} else {
@@ -411,6 +498,12 @@ impl <A, T> RangeSet <A> where
411
498
self . ranges . spilled ( )
412
499
}
413
500
501
+ /// Calls `shrink_to_fit` on the underlying smallvec
502
+ #[ inline]
503
+ pub fn shrink_to_fit ( & mut self ) {
504
+ self . ranges . shrink_to_fit ( )
505
+ }
506
+
414
507
/// Insert helper function: search for the last range in self that is
415
508
/// `LessThanAdjacent` or `LessThanProper` when compared with the given range
416
509
fn binary_search_before ( & self , range : & A :: Item ) -> Option < usize > {
0 commit comments