1 /*! A dynamically-allocated buffer containing a `BitSlice<O, T>` region. 2 3 You can read the standard library’s [`alloc::vec` module documentation][std] 4 here. 5 6 This module defines the [`BitVec`] buffer, and all of its associated support 7 code. 8 9 `BitVec` is equivalent to `Vec<bool>`, in its operation and in its relationship 10 to the `BitSlice` type. Most of the interesting work to be done on a 11 bit-sequence is implemented in `BitSlice`, to which `BitVec` dereferences, and 12 the vector container itself only exists to maintain ownership, implement dynamic 13 resizing, and provide some specializations that cannot safely be done on 14 `BitSlice` alone. 15 16 [`BitVec`]: struct.BitVec.html 17 [std]: https://doc.rust-lang.org/alloc/vec 18 !*/ 19 20 #![cfg(feature = "alloc")] 21 22 use crate::{ 23 boxed::BitBox, 24 index::BitIdx, 25 mem::BitMemory, 26 order::{ 27 BitOrder, 28 Lsb0, 29 }, 30 pointer::BitPtr, 31 slice::BitSlice, 32 store::BitStore, 33 }; 34 35 use alloc::vec::Vec; 36 37 use core::{ 38 mem::ManuallyDrop, 39 ptr::NonNull, 40 slice, 41 }; 42 43 use funty::IsInteger; 44 45 use tap::{ 46 pipe::Pipe, 47 tap::Tap, 48 }; 49 50 /** A vector of individual bits, allocated on the heap. 51 52 This is a managed, heap-allocated, buffer that contains a `BitSlice` region. It 53 is analagous to `Vec<bool>`, and is written to be as close as possible to 54 drop-in replacabale for it. This type contains little interesting behavior in 55 its own right, dereferencing instead to [`BitSlice`] for manipulation of the 56 buffer contents, and serves primarily as an interface to the allocator. If you 57 require statically-allocated, fixed-size, owned buffers, you should use the 58 [`BitArray`] type. 59 60 Because `BitVec` directly owns its memory, and can guarantee that no other 61 object in a program has access to its buffers, `BitVec` is able to override some 62 behavior from `BitSlice` in more efficient manners. 63 64 # Documentation 65 66 All APIs that mirror something in the standard library will have an `Original` 67 section linking to the corresponding item. All APIs that have a different 68 signature or behavior than the original will have an `API Differences` section 69 explaining what has changed, and how to adapt your existing code to the change. 70 71 These sections look like this: 72 73 # Original 74 75 [`Vec<T>`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html) 76 77 # API Differences 78 79 The buffer type `Vec<bool>` has no type parameters. `BitVec<O, T>` has the same 80 two type parameters as `BitSlice<O, T>`. Otherwise, `BitVec` is able to 81 implement the full API surface of `Vec<bool>`. 82 83 # Behavior 84 85 Because `BitVec` is a fully-owned buffer, it is able to operate on its memory 86 without concern for any other views that may alias. This enables it to 87 specialize some `BitSlice` behavior to be faster or more efficient. 88 89 # Type Parameters 90 91 This takes the same two type parameters, `O: BitOrder` and `T: BitStore`, as 92 `BitSlice`. 93 94 # Safety 95 96 Like `BitSlice`, `BitVec` is exactly equal in size to `Vec`, and is also 97 absolutely representation-incompatible with it. You must never attempt to 98 type-cast between `Vec<T>` and `BitVec` in any way, nor attempt to modify the 99 memory value of a `BitVec` handle. Doing so will cause allocator and memory 100 errors in your program, likely inducing a panic. 101 102 Everything in the `BitVec` public API, even the `unsafe` parts, are guaranteed 103 to have no more unsafety than their equivalent items in the standard library. 104 All `unsafe` APIs will have documentation explicitly detailing what the API 105 requires you to uphold in order for it to function safely and correctly. All 106 safe APIs will do so themselves. 107 108 # Performance 109 110 The choice of `T: BitStore` type parameter can impact your vector’s performance, 111 as the allocator operates in units of `T` rather than in bits. This means that 112 larger register types will increase the amount of memory reserved in each call 113 to the allocator, meaning fewer calls to `.push()` will actually cause a 114 reällocation. In addition, iteration over the vector is governed by the 115 `BitSlice` characteristics on the type parameter. You are generally better off 116 using larger types when your vector is a data collection rather than a specific 117 I/O protocol buffer. 118 119 # Macro Construction 120 121 Heap allocation can only occur at runtime, but the [`bitvec!`] macro will 122 construct an appropriate `BitSlice` buffer at compile-time, and at run-time, 123 only copy the buffer into a heap allocation. 124 125 [`BitArray`]: ../array/struct.BitArray.html 126 [`BitSlice`]: ../slice/struct.BitSlice.html 127 [`bitvec!`]: ../macro.bitvec.html 128 **/ 129 #[repr(C)] 130 pub struct BitVec<O = Lsb0, T = usize> 131 where 132 O: BitOrder, 133 T: BitStore, 134 { 135 /// Region pointer describing the live portion of the owned buffer. 136 pointer: NonNull<BitSlice<O, T>>, 137 /// Allocated capacity, in elements `T`, of the owned buffer. 138 capacity: usize, 139 } 140 141 /// Methods specific to `BitVec<_, T>`, and not present on `Vec<T>`. 142 impl<O, T> BitVec<O, T> 143 where 144 O: BitOrder, 145 T: BitStore, 146 { 147 /// Constructs a `BitVec` from a value repeated many times. 148 /// 149 /// This function is equivalent to the `bitvec![O, T; bit; len]` macro call, 150 /// and is in fact the implementation of that macro syntax. 151 /// 152 /// # Parameters 153 /// 154 /// - `bit`: The bit value to which all `len` allocated bits will be set. 155 /// - `len`: The number of live bits in the constructed `BitVec`. 156 /// 157 /// # Returns 158 /// 159 /// A `BitVec` with `len` live bits, all set to `bit`. 160 /// 161 /// # Examples 162 /// 163 /// ```rust 164 /// use bitvec::prelude::*; 165 /// 166 /// let bv = BitVec::<Msb0, u8>::repeat(true, 20); 167 /// assert_eq!(bv, bits![1; 20]); 168 /// ``` 169 #[inline] repeat(bit: bool, len: usize) -> Self170 pub fn repeat(bit: bool, len: usize) -> Self { 171 let mut out = Self::with_capacity(len); 172 unsafe { 173 out.set_len(len); 174 } 175 out.set_elements(if bit { T::Mem::ALL } else { T::Mem::ZERO }); 176 out 177 } 178 179 /// Clones a `&BitSlice` into a `BitVec`. 180 /// 181 /// # Original 182 /// 183 /// [`<Vec<T: Clone> as Clone>::clone`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html#impl-Clone) 184 /// 185 /// # Effects 186 /// 187 /// This performs a direct element-wise copy from the source slice to the 188 /// newly-allocated buffer, then sets the vector to have the same starting 189 /// bit as the slice did. This allows for faster behavior. If you require 190 /// that the vector start at the leading edge of the first element, use 191 /// [`force_align`] to guarantee this. 192 /// 193 /// # Examples 194 /// 195 /// ```rust 196 /// use bitvec::prelude::*; 197 /// 198 /// let bits = bits![0, 1, 0, 1, 1, 0, 1, 1]; 199 /// let bv = BitVec::from_bitslice(&bits[2 ..]); 200 /// assert_eq!(bv, bits[2 ..]); 201 /// ``` 202 /// 203 /// [`force_align`]: #method.force_align 204 #[inline] from_bitslice(slice: &BitSlice<O, T>) -> Self205 pub fn from_bitslice(slice: &BitSlice<O, T>) -> Self { 206 let mut bitptr = slice.bitptr(); 207 let (base, elts) = (bitptr.pointer().to_const(), bitptr.elements()); 208 let source = unsafe { slice::from_raw_parts(base, elts) }; 209 210 let vec = elts 211 .pipe(Vec::with_capacity) 212 .pipe(ManuallyDrop::new) 213 .tap_mut(|v| v.extend(source.iter().map(BitStore::load_value))); 214 215 unsafe { 216 bitptr.set_pointer(vec.as_ptr() as *const T); 217 } 218 219 let capacity = vec.capacity(); 220 Self { 221 pointer: bitptr.to_nonnull(), 222 capacity, 223 } 224 } 225 226 /// Converts a `Vec<T>` into a `BitVec<O, T>` without copying its buffer. 227 /// 228 /// # Parameters 229 /// 230 /// - `vec`: A vector to view as bits. 231 /// 232 /// # Returns 233 /// 234 /// A `BitVec` over the `vec` buffer. 235 /// 236 /// # Panics 237 /// 238 /// This panics if `vec` is too long to convert into a `BitVec`. See 239 /// [`BitSlice::MAX_ELTS`]. 240 /// 241 /// # Examples 242 /// 243 /// ```rust 244 /// use bitvec::prelude::*; 245 /// 246 /// let vec = vec![0u8; 4]; 247 /// let bv = BitVec::<LocalBits, _>::from_vec(vec); 248 /// assert_eq!(bv, bits![0; 32]); 249 /// ``` 250 /// 251 /// [`BitSlice::MAX_ELTS`]: 252 /// ../slice/struct.BitSlice.html#associatedconstant.MAX_ELTS 253 #[inline] from_vec(vec: Vec<T>) -> Self254 pub fn from_vec(vec: Vec<T>) -> Self { 255 Self::try_from_vec(vec) 256 .expect("Vector was too long to be converted into a `BitVec`") 257 } 258 259 /// Converts a `Vec<T>` into a `BitVec<O, T>` without copying its buffer. 260 /// 261 /// This method takes ownership of a memory buffer and enables it to be used 262 /// as a bit-vector. Because `Vec` can be longer than `BitVec`s, this is a 263 /// fallible method, and the original vector will be returned if it cannot 264 /// be converted. 265 /// 266 /// # Parameters 267 /// 268 /// - `vec`: Some vector of memory, to be viewed as bits. 269 /// 270 /// # Returns 271 /// 272 /// If `vec` is short enough to be viewed as a `BitVec`, then this returns 273 /// a `BitVec` over the `vec` buffer. If `vec` is too long, then this 274 /// returns `vec` unmodified. 275 /// 276 /// # Examples 277 /// 278 /// ```rust 279 /// use bitvec::prelude::*; 280 /// 281 /// let vec = vec![0u8; 4]; 282 /// let bv = BitVec::<LocalBits, _>::try_from_vec(vec).unwrap(); 283 /// assert_eq!(bv, bits![0; 32]); 284 /// ``` 285 /// 286 /// An example showing this function failing would require an allocation 287 /// exceeding `!0usize >> 3` bytes in size, which is infeasible to produce. 288 #[inline] try_from_vec(vec: Vec<T>) -> Result<Self, Vec<T>>289 pub fn try_from_vec(vec: Vec<T>) -> Result<Self, Vec<T>> { 290 let len = vec.len(); 291 if len > BitSlice::<O, T>::MAX_ELTS { 292 return Err(vec); 293 } 294 295 let vec = ManuallyDrop::new(vec); 296 let (base, capacity) = (vec.as_ptr(), vec.capacity()); 297 Ok(Self { 298 pointer: unsafe { 299 BitPtr::new_unchecked( 300 base, 301 BitIdx::ZERO, 302 len * T::Mem::BITS as usize, 303 ) 304 } 305 .to_nonnull(), 306 capacity, 307 }) 308 } 309 310 /// Copies all bits in a `BitSlice` into the `BitVec`. 311 /// 312 /// This is provided for API completeness; it has no performance benefits 313 /// compared to use of the [`Extend`] implementation. 314 /// 315 /// # Parameters 316 /// 317 /// - `&mut self` 318 /// - `other`: A `BitSlice` reference of the same type parameters as `self`. 319 /// 320 /// # Behavior 321 /// 322 /// `self` is extended by the length of `other`, and then the contents of 323 /// `other` are copied into the newly-allocated end of `self`. 324 /// 325 /// ```rust 326 /// use bitvec::prelude::*; 327 /// 328 /// let mut bv = bitvec![0, 1]; 329 /// bv.extend_from_bitslice(bits![1, 1, 0, 1]); 330 /// 331 /// assert_eq!(bv, bits![0, 1, 1, 1, 0, 1]); 332 /// ``` 333 /// 334 /// [`Extend`]: #impl-Extend<%26'a bool> 335 /// [`.as_bitslice()`]: #method.as_bitslice() 336 #[inline] extend_from_bitslice(&mut self, other: &BitSlice<O, T>)337 pub fn extend_from_bitslice(&mut self, other: &BitSlice<O, T>) { 338 let len = self.len(); 339 let olen = other.len(); 340 self.resize(len + olen, false); 341 unsafe { self.get_unchecked_mut(len ..) }.clone_from_bitslice(other); 342 } 343 344 /// Converts the vector into [`BitBox<O, T>`]. 345 /// 346 /// Note that this will drop any excess capacity. 347 /// 348 /// # Original 349 /// 350 /// [`Vec::into_boxed_slice`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html#method.into_boxed_slice) 351 /// 352 /// # Examples 353 /// 354 /// ```rust 355 /// use bitvec::prelude::*; 356 /// 357 /// let mut bv = bitvec![1; 50]; 358 /// let bb: BitBox = bv.into_boxed_bitslice(); 359 /// assert_eq!(bb, bits![1; 50]); 360 /// ``` 361 /// 362 /// [`BitBox<O, T>`]: ../boxed/struct.BitBox.html 363 #[inline] into_boxed_bitslice(self) -> BitBox<O, T>364 pub fn into_boxed_bitslice(self) -> BitBox<O, T> { 365 let mut bitptr = self.bitptr(); 366 let boxed = self.into_boxed_slice().pipe(ManuallyDrop::new); 367 unsafe { 368 bitptr.set_pointer(boxed.as_ptr()); 369 } 370 unsafe { BitBox::from_raw(bitptr.to_bitslice_ptr_mut::<O>()) } 371 } 372 373 /// Converts the vector back into an ordinary vector of memory elements. 374 /// 375 /// This does not affect the vector’s buffer, only the handle used to 376 /// control it. 377 /// 378 /// # Parameters 379 /// 380 /// - `self` 381 /// 382 /// # Returns 383 /// 384 /// An ordinary vector containing all of the bit-vector’s memory buffer. 385 /// 386 /// # Examples 387 /// 388 /// ```rust 389 /// use bitvec::prelude::*; 390 /// 391 /// let bv = bitvec![0; 5]; 392 /// let vec = bv.into_vec(); 393 /// assert_eq!(vec, [0]); 394 /// ``` 395 #[inline] into_vec(self) -> Vec<T>396 pub fn into_vec(self) -> Vec<T> { 397 let mut this = ManuallyDrop::new(self); 398 let buf = this.as_mut_slice(); 399 unsafe { 400 Vec::from_raw_parts( 401 buf.as_mut_ptr() as *mut T, 402 buf.len(), 403 this.capacity, 404 ) 405 } 406 } 407 408 /// Gets the number of elements `T` that contain live bits of the vector. 409 /// 410 /// # Examples 411 /// 412 /// ```rust 413 /// use bitvec::prelude::*; 414 /// 415 /// let bv = bitvec![LocalBits, u16; 1; 50]; 416 /// assert_eq!(bv.elements(), 4); 417 /// ``` 418 #[inline] elements(&self) -> usize419 pub fn elements(&self) -> usize { 420 self.bitptr().elements() 421 } 422 423 /// Sets the uninitialized bits of the vector to a fixed value. 424 /// 425 /// This method modifies all bits in the allocated buffer that are outside 426 /// the `self.as_bitslice()` view so that they have a consistent value. This 427 /// can be used to zero the uninitialized memory so that when viewed as a 428 /// raw memory slice, bits outside the live region have a predictable value. 429 /// 430 /// # Examples 431 /// 432 /// ```rust 433 /// use bitvec::prelude::*; 434 /// 435 /// let mut bv = 220u8.view_bits::<Lsb0>().to_bitvec(); 436 /// assert_eq!(bv.as_slice(), &[220u8]); 437 /// bv.truncate(4); 438 /// assert_eq!(bv.count_ones(), 2); 439 /// assert_eq!(bv.as_slice(), &[220u8]); 440 /// 441 /// bv.set_uninitialized(false); 442 /// assert_eq!(bv.as_slice(), &[12u8]); 443 /// 444 /// bv.set_uninitialized(true); 445 /// assert_eq!(bv.as_slice(), &[!3u8]); 446 /// ``` 447 #[inline] set_uninitialized(&mut self, value: bool)448 pub fn set_uninitialized(&mut self, value: bool) { 449 let head = self.bitptr().head().value() as usize; 450 let tail = head + self.len(); 451 let capa = self.capacity(); 452 let mut bp = self.bitptr(); 453 unsafe { 454 bp.set_head(BitIdx::ZERO); 455 bp.set_len(capa); 456 let bits = bp.to_bitslice_mut::<O>(); 457 bits.get_unchecked_mut(.. head).set_all(value); 458 bits.get_unchecked_mut(tail ..).set_all(value); 459 } 460 } 461 462 /// Ensures that the live region of the vector’s contents begins at the 463 /// leading edge of the buffer. 464 /// 465 /// # Examples 466 /// 467 /// ```rust 468 /// use bitvec::prelude::*; 469 /// 470 /// let data = 0x3Cu8; 471 /// let bits = data.view_bits::<Msb0>(); 472 /// 473 /// let mut bv = bits[2 .. 6].to_bitvec(); 474 /// assert_eq!(bv, bits[2 .. 6]); 475 /// assert_eq!(bv.as_slice()[0], data); 476 /// 477 /// bv.force_align(); 478 /// assert_eq!(bv, bits[2 .. 6]); 479 /// // It is not specified what happens to bits that are no longer used. 480 /// assert_eq!(bv.as_slice()[0] & 0xF0, 0xF0); 481 /// ``` 482 #[inline] force_align(&mut self)483 pub fn force_align(&mut self) { 484 let bitptr = self.bitptr(); 485 let head = bitptr.head().value() as usize; 486 if head == 0 { 487 return; 488 } 489 let last = bitptr.len() + head; 490 unsafe { 491 self.pointer = 492 bitptr.tap_mut(|bp| bp.set_head(BitIdx::ZERO)).to_nonnull(); 493 self.copy_within_unchecked(head .. last, 0); 494 } 495 } 496 497 /// Writes a value into every element that the vector considers live. 498 /// 499 /// This unconditionally writes `element` into each live location in the 500 /// backing buffer, without altering the `BitVec`’s length or capacity. 501 /// 502 /// It is unspecified what effects this has on the allocated but dead 503 /// elements in the buffer. 504 /// 505 /// # Parameters 506 /// 507 /// - `&mut self` 508 /// - `element`: The value which will be written to each live location in 509 /// the vector’s buffer. 510 /// 511 /// # Examples 512 /// 513 /// ```rust 514 /// use bitvec::prelude::*; 515 /// 516 /// let mut bv = bitvec![LocalBits, u8; 0; 10]; 517 /// assert_eq!(bv.as_slice(), [0, 0]); 518 /// bv.set_elements(0xA5); 519 /// assert_eq!(bv.as_slice(), [0xA5, 0xA5]); 520 /// ``` 521 #[inline] set_elements(&mut self, element: T::Mem)522 pub fn set_elements(&mut self, element: T::Mem) { 523 self.as_mut_slice() 524 .iter_mut() 525 .for_each(|elt| *elt = element.into()); 526 } 527 528 /// Views the buffer’s contents as a `BitSlice`. 529 /// 530 /// This is equivalent to `&bv[..]`. 531 /// 532 /// # Original 533 /// 534 /// [`Vec::as_slice`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html#method.as_slice) 535 /// 536 /// # Examples 537 /// 538 /// ```rust 539 /// use bitvec::prelude::*; 540 /// 541 /// let bv = bitvec![0, 1, 1, 0]; 542 /// let bits = bv.as_bitslice(); 543 /// ``` 544 #[inline] 545 #[cfg(not(tarpaulin_include))] as_bitslice(&self) -> &BitSlice<O, T>546 pub fn as_bitslice(&self) -> &BitSlice<O, T> { 547 unsafe { &*self.pointer.as_ptr() } 548 } 549 550 /// Extracts a mutable bit-slice of the entire vector. 551 /// 552 /// Equivalent to `&mut bv[..]`. 553 /// 554 /// # Original 555 /// 556 /// [`Vec::as_mut_slice`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html#method.as_mut_slice) 557 /// 558 /// # Examples 559 /// 560 /// ```rust 561 /// use bitvec::prelude::*; 562 /// 563 /// let mut bv = bitvec![0, 1, 0, 1]; 564 /// let bits = bv.as_mut_bitslice(); 565 /// bits.set(0, true); 566 /// ``` 567 #[inline] 568 #[cfg(not(tarpaulin_include))] as_mut_bitslice(&mut self) -> &mut BitSlice<O, T>569 pub fn as_mut_bitslice(&mut self) -> &mut BitSlice<O, T> { 570 unsafe { &mut *self.pointer.as_ptr() } 571 } 572 573 /// Returns a raw pointer to the vector’s region. 574 /// 575 /// The caller must ensure that the vector outlives the pointer this 576 /// function returns, or else it will end up pointing to garbage. Modifying 577 /// the vector may cause its buffer to be reallocated, which would also make 578 /// any pointers to it invalid. 579 /// 580 /// The caller must also ensure that the memory the pointer 581 /// (non-transitively) points to is never written to (except inside an 582 /// `UnsafeCell`) using this pointer or any pointer derived from it. If you 583 /// need to mutate the contents of the region, use [`as_mut_bitptr`]. 584 /// 585 /// This pointer is an opaque crate-internal type. Its in-memory 586 /// representation is unsafe to modify in any way. The only safe action to 587 /// take with this pointer is to pass it, unchanged, back into a `bitvec` 588 /// API. 589 /// 590 /// # Examples 591 /// 592 /// ```rust 593 /// use bitvec::prelude::*; 594 /// 595 /// let bv = bitvec![0; 20]; 596 /// let ptr = bv.as_bitptr(); 597 /// 598 /// let bits = unsafe { &*ptr }; 599 /// assert_eq!(bv, bits); 600 /// ``` 601 /// 602 /// [`as_mut_bitptr`]: #method.as_mut_bitptr 603 #[inline] 604 #[cfg(not(tarpaulin_include))] as_bitptr(&self) -> *const BitSlice<O, T>605 pub fn as_bitptr(&self) -> *const BitSlice<O, T> { 606 self.pointer.as_ptr() as *const BitSlice<O, T> 607 } 608 609 /// Returns an unsafe mutable pointer to the vector’s region. 610 /// 611 /// The caller must ensure that the vector outlives the pointer this 612 /// function returns, or else it will end up pointing to garbage. Modifying 613 /// the vector may cause its buffer to be reallocated, which would also make 614 /// any pointers to it invalid. 615 /// 616 /// This pointer is an opaque crate-internal type. Its in-memory 617 /// representation is unsafe to modify in any way. The only safe action to 618 /// take with this pointer is to pass it, unchanged, back into a `bitvec` 619 /// API. 620 /// 621 /// # Examples 622 /// 623 /// ```rust 624 /// use bitvec::prelude::*; 625 /// 626 /// let mut bv = bitvec![0; 20]; 627 /// let ptr = bv.as_mut_bitptr(); 628 /// 629 /// let bits = unsafe { &mut *ptr }; 630 /// assert_eq!(bv, bits); 631 /// ``` 632 #[inline] 633 #[cfg(not(tarpaulin_include))] as_mut_bitptr(&mut self) -> *mut BitSlice<O, T>634 pub fn as_mut_bitptr(&mut self) -> *mut BitSlice<O, T> { 635 self.pointer.as_ptr() 636 } 637 638 #[inline] 639 #[cfg(not(tarpaulin_include))] bitptr(&self) -> BitPtr<T>640 pub(crate) fn bitptr(&self) -> BitPtr<T> { 641 self.pointer.as_ptr().pipe(BitPtr::from_bitslice_ptr_mut) 642 } 643 644 /// Permits a function to modify the `Vec<T>` backing storage of a 645 /// `BitVec<_, T>`. 646 /// 647 /// This produces a temporary `Vec<T::Mem>` structure governing the 648 /// `BitVec`’s buffer and allows a function to view it mutably. After the 649 /// callback returns, the `Vec` is written back into `self` and forgotten. 650 /// 651 /// # Type Parameters 652 /// 653 /// - `F`: A function which operates on a mutable borrow of a `Vec<T::Mem>` 654 /// buffer controller. 655 /// - `R`: The return type of the `F` function. 656 /// 657 /// # Parameters 658 /// 659 /// - `&mut self` 660 /// - `func`: A function which receives a mutable borrow of a `Vec<T::Mem>` 661 /// controlling `self`’s buffer. 662 /// 663 /// # Returns 664 /// 665 /// The return value of `func`. `func` is forbidden from borrowing any part 666 /// of the `Vec<T::Mem>` temporary view. with_vec<F, R>(&mut self, func: F) -> R where F: FnOnce(&mut ManuallyDrop<Vec<T::Mem>>) -> R667 fn with_vec<F, R>(&mut self, func: F) -> R 668 where F: FnOnce(&mut ManuallyDrop<Vec<T::Mem>>) -> R { 669 let cap = self.capacity; 670 let mut bitptr = self.bitptr(); 671 let (base, elts) = 672 (bitptr.pointer().to_mut() as *mut T::Mem, bitptr.elements()); 673 674 let mut vec = unsafe { Vec::from_raw_parts(base, elts, cap) } 675 .pipe(ManuallyDrop::new); 676 let out = func(&mut vec); 677 678 unsafe { 679 bitptr.set_pointer(vec.as_ptr() as *mut T); 680 } 681 self.pointer = bitptr.to_nonnull(); 682 self.capacity = vec.capacity(); 683 out 684 } 685 } 686 687 mod api; 688 mod iter; 689 mod ops; 690 mod traits; 691 692 pub use iter::{ 693 Drain, 694 IntoIter, 695 Splice, 696 }; 697 698 #[cfg(test)] 699 mod tests; 700