@@ -120,13 +120,8 @@ where
120120 #[ inline]
121121 pub fn from_bitslice ( slice : & BitSlice < T , O > ) -> Self {
122122 let bitspan = slice. as_bitspan ( ) ;
123-
124- let mut vec = bitspan
125- . elements ( )
126- . pipe ( Vec :: with_capacity)
127- . pipe ( ManuallyDrop :: new) ;
128- vec. extend ( slice. domain ( ) ) ;
129-
123+ let vec = slice. domain ( ) . into_iter ( ) . collect :: < Vec < _ > > ( ) ;
124+ let mut vec = ManuallyDrop :: new ( vec) ;
130125 let bitspan = unsafe {
131126 BitSpan :: new_unchecked (
132127 vec. as_mut_ptr ( ) . cast :: < T > ( ) . into_address ( ) ,
@@ -241,11 +236,108 @@ where
241236 /// It is not practical to allocate a vector that will fail this conversion.
242237 #[ inline]
243238 pub fn try_from_vec ( vec : Vec < T > ) -> Result < Self , Vec < T > > {
244- let mut vec = ManuallyDrop :: new ( vec) ;
245- let capacity = vec . capacity ( ) ;
239+ Self :: try_from_partial_vec ( vec, BitIdx :: MIN , None )
240+ }
246241
247- BitPtr :: from_mut_slice ( vec. as_mut_slice ( ) )
248- . span ( vec. len ( ) * bits_of :: < T :: Mem > ( ) )
242+ /// Converts a regular vector in-place into a bit-vector covering parts
243+ /// of the elements.
244+ ///
245+ /// The produced bit-vector spans `length` bits of the original vector
246+ /// starting at `head` bit of the first element. If `length` is `None`,
247+ /// spans bits starting at `head` bit of the first element until the end
248+ /// of the original vector.
249+ ///
250+ /// ## Panics
251+ ///
252+ /// This panics if the source vector is too long to view as a bit-slice,
253+ /// or if specified total length of the vector goes beyond provided
254+ /// bytes.
255+ ///
256+ /// ## Examples
257+ ///
258+ /// ```rust
259+ /// use bitvec::prelude::*;
260+ /// use bitvec::index::BitIdx;
261+ ///
262+ /// let bv = BitVec::<_, Msb0>::from_partial_vec(
263+ /// vec![0u8, 1, 0x80],
264+ /// BitIdx::new(4).unwrap(),
265+ /// Some(18),
266+ /// );
267+ /// assert_eq!(bits![0, 0, 0, 0,
268+ /// 0, 0, 0, 0, 0, 0, 0, 1,
269+ /// 1, 0, 0, 0, 0, 0], bv);
270+ /// ```
271+ #[ inline]
272+ pub fn from_partial_vec (
273+ vec : Vec < T > ,
274+ head : crate :: index:: BitIdx < T :: Mem > ,
275+ length : Option < usize > ,
276+ ) -> Self {
277+ Self :: try_from_partial_vec ( vec, head, length)
278+ . expect ( "vector was too long to be converted into a `BitVec`" )
279+ }
280+
281+ /// Attempts to converts a regular vector in-place into a bit-vector
282+ /// covering parts of the elements.
283+ ///
284+ /// This fairs if the source vector is too long to view as a bit-slice,
285+ /// or if specified total length of the vector goes beyond provided
286+ /// bytes.
287+ ///
288+ /// On success, the produced bit-vector spans `length` bits of the
289+ /// original vector starting at `head` bit of the first element. If
290+ /// `length` is `None`, spans bits starting at `head` bit of the first
291+ /// element until the end of the original vector.
292+ ///
293+ /// ## Examples
294+ ///
295+ /// ```rust
296+ /// use bitvec::prelude::*;
297+ /// use bitvec::index::BitIdx;
298+ ///
299+ /// let bv = BitVec::<_, Msb0>::try_from_partial_vec(
300+ /// vec![0u8, 1, 0x80],
301+ /// BitIdx::new(4).unwrap(),
302+ /// Some(18),
303+ /// ).unwrap();
304+ /// assert_eq!(bits![0, 0, 0, 0,
305+ /// 0, 0, 0, 0, 0, 0, 0, 1,
306+ /// 1, 0, 0, 0, 0, 0], bv);
307+ ///
308+ /// let bv = BitVec::<_, Msb0>::try_from_partial_vec(
309+ /// vec![0u8, 1, 0x80],
310+ /// BitIdx::new(4).unwrap(),
311+ /// Some(24),
312+ /// );
313+ /// assert_eq!(None, bv.ok());
314+ /// ```
315+ #[ inline]
316+ pub fn try_from_partial_vec (
317+ vec : Vec < T > ,
318+ head : crate :: index:: BitIdx < T :: Mem > ,
319+ length : Option < usize > ,
320+ ) -> Result < Self , Vec < T > > {
321+ let start = usize:: from ( head. into_inner ( ) ) ;
322+ let length = if let Some ( len) = length {
323+ len. checked_add ( start)
324+ . map ( crate :: mem:: elts :: < T > )
325+ . filter ( |elts| * elts <= vec. len ( ) )
326+ . map ( |_| len)
327+ } else {
328+ vec. len ( )
329+ . checked_mul ( bits_of :: < T :: Mem > ( ) )
330+ . and_then ( |len| len. checked_sub ( start) )
331+ } ;
332+ let length = match length {
333+ None => return Err ( vec) ,
334+ Some ( length) => length,
335+ } ;
336+
337+ let capacity = vec. capacity ( ) ;
338+ let mut vec = ManuallyDrop :: new ( vec) ;
339+ BitPtr :: from_slice_with_index_mut ( vec. as_mut_slice ( ) , head)
340+ . span ( length)
249341 . map ( |bitspan| Self { bitspan, capacity } )
250342 . map_err ( |_| ManuallyDrop :: into_inner ( vec) )
251343 }
0 commit comments