Repository: sharksforarms/deku
Pull request #281 (2022-10-08 01:29:00)

Draft: Upgrade to bitvec 1.0.0
Re-based #246 ontop of master, see previous conversation about decrease in performance for bitvec v1.0.0.

Perf:
```
deku_read_byte          time:   [11.305 ns 11.324 ns 11.345 ns]
                        change: [+94.803% +96.463% +97.712%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 13 outliers among 100 measurements (13.00%)
  8 (8.00%) low severe
  1 (1.00%) low mild
  3 (3.00%) high mild
  1 (1.00%) high severe

deku_write_byte         time:   [49.903 ns 49.993 ns 50.090 ns]
                        change: [+3.0667% +4.5991% +5.6636%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 15 outliers among 100 measurements (15.00%)
  8 (8.00%) low severe
  5 (5.00%) low mild
  1 (1.00%) high mild
  1 (1.00%) high severe

deku_read_bits          time:   [503.43 ns 507.66 ns 512.69 ns]
                        change: [+47.073% +48.526% +50.216%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 25 outliers among 100 measurements (25.00%)
  10 (10.00%) low mild
  6 (6.00%) high mild
  9 (9.00%) high severe

deku_write_bits         time:   [90.864 ns 91.240 ns 91.599 ns]
                        change: [+23.361% +24.209% +25.044%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 2 outliers among 100 measurements (2.00%)
  2 (2.00%) high mild

deku_read_enum          time:   [17.811 ns 17.857 ns 17.925 ns]
                        change: [+70.445% +71.741% +72.950%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 13 outliers among 100 measurements (13.00%)
  5 (5.00%) low severe
  6 (6.00%) low mild
  2 (2.00%) high severe

deku_write_enum         time:   [82.910 ns 83.161 ns 83.523 ns]
                        change: [+4.7235% +10.857% +18.023%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 10 outliers among 100 measurements (10.00%)
  1 (1.00%) low severe
  4 (4.00%) low mild
  5 (5.00%) high severe

deku_read_vec           time:   [770.09 ns 771.19 ns 772.52 ns]
                        change: [+48.267% +48.711% +49.148%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 16 outliers among 100 measurements (16.00%)
  10 (10.00%) low severe
  2 (2.00%) low mild
  2 (2.00%) high mild
  2 (2.00%) high severe

deku_write_vec          time:   [3.6065 µs 3.6152 µs 3.6257 µs]
                        change: [+4.4250% +4.7500% +5.1047%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 8 outliers among 100 measurements (8.00%)
  3 (3.00%) low severe
  2 (2.00%) low mild
  3 (3.00%) high severe

deku_read_vec_perf      time:   [786.85 ns 789.84 ns 793.66 ns]
                        change: [+61.063% +63.122% +64.875%] (p = 0.00 < 0.05)
                        Performance has regressed.
Found 12 outliers among 100 measurements (12.00%)
  4 (4.00%) low severe
  3 (3.00%) low mild
  1 (1.00%) high mild
  4 (4.00%) high severe

deku_write_vec_perf     time:   [3.7249 µs 3.7338 µs 3.7437 µs]
                        change: [-1.0642% -0.7533% -0.4036%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 8 outliers among 100 measurements (8.00%)
  3 (3.00%) low severe
  1 (1.00%) low mild
  2 (2.00%) high mild
  2 (2.00%) high severe
```

duskmoon314: Does the performance issue block this?

I'm trying to use Deku in my experimental crate but suffering from the problem mentioned in #296. How can we help to push forward this PR?
sharksforarms: Looks like it's time to push towards bitvec 1.0.0, if we release this change as a major release version, clients will need to opt-in to the performance difference (although they may need to opt-in just tot be able to build again, unless they use an older deku).
wcampbell0x2a: Agreed, hopefully we can figure out the performance later.

Patch:
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 8e06af5..bf2e805 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -7,7 +7,7 @@ jobs:
     name: Build
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - uses: actions-rs/toolchain@v1
         with:
           profile: minimal
@@ -22,7 +22,7 @@ jobs:
     name: Test Suite
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - uses: actions-rs/toolchain@v1
         with:
           profile: minimal
@@ -37,7 +37,7 @@ jobs:
     name: Miri Test
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - uses: actions-rs/toolchain@v1
         with:
           toolchain: nightly
@@ -49,7 +49,7 @@ jobs:
     name: Miri Test Big Endian
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - uses: actions-rs/toolchain@v1
         with:
           toolchain: nightly
@@ -62,7 +62,7 @@ jobs:
     name: Examples
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - uses: actions-rs/toolchain@v1
         with:
           profile: minimal
@@ -74,7 +74,7 @@ jobs:
     name: Rustfmt
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - uses: actions-rs/toolchain@v1
         with:
           profile: minimal
@@ -90,7 +90,7 @@ jobs:
     name: Clippy
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - uses: actions-rs/toolchain@v1
         with:
           profile: minimal
@@ -106,7 +106,7 @@ jobs:
     name: Ensure no_std
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - uses: actions-rs/toolchain@v1
         with:
           toolchain: nightly
@@ -117,7 +117,7 @@ jobs:
     name: Ensure wasm
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v2
+      - uses: actions/checkout@v3
       - uses: actions-rs/toolchain@v1
         with:
           toolchain: nightly
@@ -135,7 +135,7 @@ jobs:
       options: --security-opt seccomp=unconfined
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v2
+        uses: actions/checkout@v3
 
       - name: Generate code coverage
         run: |
diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml
index 50bfe03..76f07e0 100644
--- a/.github/workflows/pull_request.yml
+++ b/.github/workflows/pull_request.yml
@@ -5,7 +5,7 @@ jobs:
     name: Benchmark
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@master
+      - uses: actions/checkout@v3
         with:
           fetch-depth: 0
       - uses: actions-rs/toolchain@v1
@@ -13,6 +13,7 @@ jobs:
           profile: minimal
           toolchain: stable
           override: true
-      - uses: jasonwilliams/criterion-compare-action@move_to_actions
+      - uses: boa-dev/criterion-compare-action@v3
         with:
-          token: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
+          branchName: ${{ github.base_ref }}
+          token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/Cargo.toml b/Cargo.toml
index 4a1ce6e..c993e54 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,17 +27,17 @@ const_generics = []
 
 [dependencies]
 deku_derive = { version = "^0.14.0", path = "deku-derive", default-features = false}
-bitvec = { version = "0.22.1", default-features = false }
+bitvec = { version = "1.0.1", default-features = false }
 log = { version = "0.4.17", optional = true }
 
 [dev-dependencies]
-rstest = "0.13.0"
-hexlit = "0.5.3"
-criterion = "0.3.5"
+rstest = "0.15.0"
+hexlit = "0.5.5"
+criterion = "0.4.0"
 alloc_counter = "0.0.4"
-trybuild = "1.0.54"
+trybuild = "1.0.71"
 rustc-hash = "1.1.0"
-env_logger = "0.9.1"
+env_logger = "0.9.3"
 
 [[bench]]
 name = "deku"
diff --git a/deku-derive/src/macros/deku_read.rs b/deku-derive/src/macros/deku_read.rs
index fc8d4bd..0e6d4d8 100644
--- a/deku-derive/src/macros/deku_read.rs
+++ b/deku-derive/src/macros/deku_read.rs
@@ -77,7 +77,7 @@ fn emit_struct(input: &DekuData) -> Result<TokenStream, syn::Error> {
                 let __deku_pad = 8 * ((__deku_rest.len() + 7) / 8) - __deku_rest.len();
                 let __deku_read_idx = __deku_input_bits.len() - (__deku_rest.len() + __deku_pad);
 
-                Ok(((__deku_input_bits[__deku_read_idx..].as_raw_slice(), __deku_pad), __deku_value))
+                Ok(((__deku_input_bits[__deku_read_idx..].domain().region().unwrap().1, __deku_pad), __deku_value))
             },
             &input.ctx,
             &input.ctx_default,
@@ -110,7 +110,7 @@ fn emit_struct(input: &DekuData) -> Result<TokenStream, syn::Error> {
 
     tokens.extend(quote! {
         impl #imp ::#crate_::DekuRead<#lifetime, #ctx_types> for #ident #wher {
-            fn read(__deku_input_bits: &#lifetime ::#crate_::bitvec::BitSlice<::#crate_::bitvec::Msb0, u8>, #ctx_arg) -> Result<(&#lifetime ::#crate_::bitvec::BitSlice<::#crate_::bitvec::Msb0, u8>, Self), ::#crate_::DekuError> {
+            fn read(__deku_input_bits: &#lifetime ::#crate_::bitvec::BitSlice<u8, ::#crate_::bitvec::Msb0>, #ctx_arg) -> Result<(&#lifetime ::#crate_::bitvec::BitSlice<u8, ::#crate_::bitvec::Msb0>, Self), ::#crate_::DekuError> {
                 #read_body
             }
         }
@@ -121,7 +121,7 @@ fn emit_struct(input: &DekuData) -> Result<TokenStream, syn::Error> {
 
         tokens.extend(quote! {
             impl #imp ::#crate_::DekuRead<#lifetime> for #ident #wher {
-                fn read(__deku_input_bits: &#lifetime ::#crate_::bitvec::BitSlice<::#crate_::bitvec::Msb0, u8>, _: ()) -> Result<(&#lifetime ::#crate_::bitvec::BitSlice<::#crate_::bitvec::Msb0, u8>, Self), ::#crate_::DekuError> {
+                fn read(__deku_input_bits: &#lifetime ::#crate_::bitvec::BitSlice<u8, ::#crate_::bitvec::Msb0>, _: ()) -> Result<(&#lifetime ::#crate_::bitvec::BitSlice<u8, ::#crate_::bitvec::Msb0>, Self), ::#crate_::DekuError> {
                     #read_body
                 }
             }
@@ -308,7 +308,7 @@ fn emit_enum(input: &DekuData) -> Result<TokenStream, syn::Error> {
                 let __deku_pad = 8 * ((__deku_rest.len() + 7) / 8) - __deku_rest.len();
                 let __deku_read_idx = __deku_input_bits.len() - (__deku_rest.len() + __deku_pad);
 
-                Ok(((__deku_input_bits[__deku_read_idx..].as_raw_slice(), __deku_pad), __deku_value))
+                Ok(((__deku_input_bits[__deku_read_idx..].domain().region().unwrap().1, __deku_pad), __deku_value))
             },
             &input.ctx,
             &input.ctx_default,
@@ -340,7 +340,7 @@ fn emit_enum(input: &DekuData) -> Result<TokenStream, syn::Error> {
     tokens.extend(quote! {
         #[allow(non_snake_case)]
         impl #imp ::#crate_::DekuRead<#lifetime, #ctx_types> for #ident #wher {
-            fn read(__deku_input_bits: &#lifetime ::#crate_::bitvec::BitSlice<::#crate_::bitvec::Msb0, u8>, #ctx_arg) -> Result<(&#lifetime ::#crate_::bitvec::BitSlice<::#crate_::bitvec::Msb0, u8>, Self), ::#crate_::DekuError> {
+            fn read(__deku_input_bits: &#lifetime ::#crate_::bitvec::BitSlice<u8, ::#crate_::bitvec::Msb0>, #ctx_arg) -> Result<(&#lifetime ::#crate_::bitvec::BitSlice<u8, ::#crate_::bitvec::Msb0>, Self), ::#crate_::DekuError> {
                 #read_body
             }
         }
@@ -352,7 +352,7 @@ fn emit_enum(input: &DekuData) -> Result<TokenStream, syn::Error> {
         tokens.extend(quote! {
             #[allow(non_snake_case)]
             impl #imp ::#crate_::DekuRead<#lifetime> for #ident #wher {
-                fn read(__deku_input_bits: &#lifetime ::#crate_::bitvec::BitSlice<::#crate_::bitvec::Msb0, u8>, _: ()) -> Result<(&#lifetime ::#crate_::bitvec::BitSlice<::#crate_::bitvec::Msb0, u8>, Self), ::#crate_::DekuError> {
+                fn read(__deku_input_bits: &#lifetime ::#crate_::bitvec::BitSlice<u8, ::#crate_::bitvec::Msb0>, _: ()) -> Result<(&#lifetime ::#crate_::bitvec::BitSlice<u8, ::#crate_::bitvec::Msb0>, Self), ::#crate_::DekuError> {
                     #read_body
                 }
             }
@@ -453,7 +453,7 @@ fn emit_bit_byte_offsets(
         || byte_offset.is_some()
     {
         Some(quote! {
-            let __deku_bit_offset = usize::try_from(__deku_input_bits.offset_from(__deku_rest))?;
+            let __deku_bit_offset = usize::try_from(unsafe { __deku_rest.as_bitptr().offset_from(__deku_input_bits.as_bitptr()) } )?;
         })
     } else {
         None
diff --git a/deku-derive/src/macros/deku_write.rs b/deku-derive/src/macros/deku_write.rs
index 983c45e..1cd71cb 100644
--- a/deku-derive/src/macros/deku_write.rs
+++ b/deku-derive/src/macros/deku_write.rs
@@ -47,7 +47,7 @@ fn emit_struct(input: &DekuData) -> Result<TokenStream, syn::Error> {
             quote! {
                 match *self {
                     #destructured => {
-                        let mut __deku_acc: ::#crate_::bitvec::BitVec<::#crate_::bitvec::Msb0, u8> = ::#crate_::bitvec::BitVec::new();
+                        let mut __deku_acc: ::#crate_::bitvec::BitVec<u8, ::#crate_::bitvec::Msb0> = ::#crate_::bitvec::BitVec::new();
                         let __deku_output = &mut __deku_acc;
 
                         #magic_write
@@ -62,7 +62,7 @@ fn emit_struct(input: &DekuData) -> Result<TokenStream, syn::Error> {
         );
 
         tokens.extend(quote! {
-            impl #imp core::convert::TryFrom<#ident> for ::#crate_::bitvec::BitVec<::#crate_::bitvec::Msb0, u8> #wher {
+            impl #imp core::convert::TryFrom<#ident> for ::#crate_::bitvec::BitVec<u8, ::#crate_::bitvec::Msb0> #wher {
                 type Error = ::#crate_::DekuError;
 
                 fn try_from(input: #ident) -> Result<Self, Self::Error> {
@@ -80,12 +80,12 @@ fn emit_struct(input: &DekuData) -> Result<TokenStream, syn::Error> {
 
             impl #imp DekuContainerWrite for #ident #wher {
                 fn to_bytes(&self) -> Result<Vec<u8>, ::#crate_::DekuError> {
-                    let mut acc: ::#crate_::bitvec::BitVec<::#crate_::bitvec::Msb0, u8> = self.to_bits()?;
+                    let mut acc: ::#crate_::bitvec::BitVec<u8, ::#crate_::bitvec::Msb0> = self.to_bits()?;
                     Ok(acc.into_vec())
                 }
 
                 #[allow(unused_variables)]
-                fn to_bits(&self) -> Result<::#crate_::bitvec::BitVec<::#crate_::bitvec::Msb0, u8>, ::#crate_::DekuError> {
+                fn to_bits(&self) -> Result<::#crate_::bitvec::BitVec<u8, ::#crate_::bitvec::Msb0>, ::#crate_::DekuError> {
                     #to_bits_body
                 }
             }
@@ -120,7 +120,7 @@ fn emit_struct(input: &DekuData) -> Result<TokenStream, syn::Error> {
 
         impl #imp DekuWrite<#ctx_types> for #ident #wher {
             #[allow(unused_variables)]
-            fn write(&self, __deku_output: &mut ::#crate_::bitvec::BitVec<::#crate_::bitvec::Msb0, u8>, #ctx_arg) -> Result<(), ::#crate_::DekuError> {
+            fn write(&self, __deku_output: &mut ::#crate_::bitvec::BitVec<u8, ::#crate_::bitvec::Msb0>, #ctx_arg) -> Result<(), ::#crate_::DekuError> {
                 #write_body
             }
         }
@@ -132,7 +132,7 @@ fn emit_struct(input: &DekuData) -> Result<TokenStream, syn::Error> {
         tokens.extend(quote! {
             impl #imp DekuWrite for #ident #wher {
                 #[allow(unused_variables)]
-                fn write(&self, __deku_output: &mut ::#crate_::bitvec::BitVec<::#crate_::bitvec::Msb0, u8>, _: ()) -> Result<(), ::#crate_::DekuError> {
+                fn write(&self, __deku_output: &mut ::#crate_::bitvec::BitVec<u8, ::#crate_::bitvec::Msb0>, _: ()) -> Result<(), ::#crate_::DekuError> {
                     #write_body
                 }
             }
@@ -258,7 +258,7 @@ fn emit_enum(input: &DekuData) -> Result<TokenStream, syn::Error> {
     if input.ctx.is_none() || (input.ctx.is_some() && input.ctx_default.is_some()) {
         let to_bits_body = wrap_default_ctx(
             quote! {
-                let mut __deku_acc: ::#crate_::bitvec::BitVec<::#crate_::bitvec::Msb0, u8> = ::#crate_::bitvec::BitVec::new();
+                let mut __deku_acc: ::#crate_::bitvec::BitVec<u8, ::#crate_::bitvec::Msb0> = ::#crate_::bitvec::BitVec::new();
                 let __deku_output = &mut __deku_acc;
 
                 #magic_write
@@ -274,7 +274,7 @@ fn emit_enum(input: &DekuData) -> Result<TokenStream, syn::Error> {
         );
 
         tokens.extend(quote! {
-            impl #imp core::convert::TryFrom<#ident> for ::#crate_::bitvec::BitVec<::#crate_::bitvec::Msb0, u8> #wher {
+            impl #imp core::convert::TryFrom<#ident> for ::#crate_::bitvec::BitVec<u8, ::#crate_::bitvec::Msb0> #wher {
                 type Error = ::#crate_::DekuError;
 
                 fn try_from(input: #ident) -> Result<Self, Self::Error> {
@@ -292,12 +292,12 @@ fn emit_enum(input: &DekuData) -> Result<TokenStream, syn::Error> {
 
             impl #imp DekuContainerWrite for #ident #wher {
                 fn to_bytes(&self) -> Result<Vec<u8>, ::#crate_::DekuError> {
-                    let mut acc: ::#crate_::bitvec::BitVec<::#crate_::bitvec::Msb0, u8> = self.to_bits()?;
+                    let mut acc: ::#crate_::bitvec::BitVec<u8, ::#crate_::bitvec::Msb0> = self.to_bits()?;
                     Ok(acc.into_vec())
                 }
 
                 #[allow(unused_variables)]
-                fn to_bits(&self) -> Result<::#crate_::bitvec::BitVec<::#crate_::bitvec::Msb0, u8>, ::#crate_::DekuError> {
+                fn to_bits(&self) -> Result<::#crate_::bitvec::BitVec<u8, ::#crate_::bitvec::Msb0>, ::#crate_::DekuError> {
                     #to_bits_body
                 }
             }
@@ -334,7 +334,7 @@ fn emit_enum(input: &DekuData) -> Result<TokenStream, syn::Error> {
 
         impl #imp DekuWrite<#ctx_types> for #ident #wher {
             #[allow(unused_variables)]
-            fn write(&self, __deku_output: &mut ::#crate_::bitvec::BitVec<::#crate_::bitvec::Msb0, u8>, #ctx_arg) -> Result<(), ::#crate_::DekuError> {
+            fn write(&self, __deku_output: &mut ::#crate_::bitvec::BitVec<u8, ::#crate_::bitvec::Msb0>, #ctx_arg) -> Result<(), ::#crate_::DekuError> {
                 #write_body
             }
         }
@@ -346,7 +346,7 @@ fn emit_enum(input: &DekuData) -> Result<TokenStream, syn::Error> {
         tokens.extend(quote! {
             impl #imp DekuWrite for #ident #wher {
                 #[allow(unused_variables)]
-                fn write(&self, __deku_output: &mut ::#crate_::bitvec::BitVec<::#crate_::bitvec::Msb0, u8>, _: ()) -> Result<(), ::#crate_::DekuError> {
+                fn write(&self, __deku_output: &mut ::#crate_::bitvec::BitVec<u8, ::#crate_::bitvec::Msb0>, _: ()) -> Result<(), ::#crate_::DekuError> {
                     #write_body
                 }
             }
diff --git a/examples/custom_reader_and_writer.rs b/examples/custom_reader_and_writer.rs
index 9d47adb..29e35e5 100644
--- a/examples/custom_reader_and_writer.rs
+++ b/examples/custom_reader_and_writer.rs
@@ -5,9 +5,9 @@ use std::convert::TryInto;
 
 fn bit_flipper_read(
     field_a: u8,
-    rest: &BitSlice<Msb0, u8>,
+    rest: &BitSlice<u8, Msb0>,
     bit_size: BitSize,
-) -> Result<(&BitSlice<Msb0, u8>, u8), DekuError> {
+) -> Result<(&BitSlice<u8, Msb0>, u8), DekuError> {
     // Access to previously read fields
     println!("field_a = 0x{:X}", field_a);
 
@@ -29,7 +29,7 @@ fn bit_flipper_read(
 fn bit_flipper_write(
     field_a: u8,
     field_b: u8,
-    output: &mut BitVec<Msb0, u8>,
+    output: &mut BitVec<u8, Msb0>,
     bit_size: BitSize,
 ) -> Result<(), DekuError> {
     // Access to previously written fields
diff --git a/src/attributes.rs b/src/attributes.rs
index 2db9a24..22158a2 100644
--- a/src/attributes.rs
+++ b/src/attributes.rs
@@ -776,14 +776,14 @@ struct DekuTest {
 impl DekuTest {
     /// Read and convert to String
     fn read(
-        rest: &BitSlice<Msb0, u8>,
-    ) -> Result<(&BitSlice<Msb0, u8>, String), DekuError> {
+        rest: &BitSlice<u8, Msb0>,
+    ) -> Result<(&BitSlice<u8, Msb0>, String), DekuError> {
         let (rest, value) = u8::read(rest, ())?;
         Ok((rest, value.to_string()))
     }
 
     /// Parse from String to u8 and write
-    fn write(output: &mut BitVec<Msb0, u8>, field_a: &str) -> Result<(), DekuError> {
+    fn write(output: &mut BitVec<u8, Msb0>, field_a: &str) -> Result<(), DekuError> {
         let value = field_a.parse::<u8>().unwrap();
         value.write(output, ())
     }
diff --git a/src/impls/bool.rs b/src/impls/bool.rs
index 52fed53..7b438c2 100644
--- a/src/impls/bool.rs
+++ b/src/impls/bool.rs
@@ -12,9 +12,9 @@ where
     /// wrapper around u8::read with consideration to context, such as bit size
     /// true if the result of the read is `1`, false if `0` and error otherwise
     fn read(
-        input: &'a BitSlice<Msb0, u8>,
+        input: &'a BitSlice<u8, Msb0>,
         inner_ctx: Ctx,
-    ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError> {
+    ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError> {
         let (rest, val) = u8::read(input, inner_ctx)?;
 
         let ret = match val {
@@ -35,7 +35,7 @@ where
     u8: DekuWrite<Ctx>,
 {
     /// wrapper around u8::write with consideration to context, such as bit size
-    fn write(&self, output: &mut BitVec<Msb0, u8>, inner_ctx: Ctx) -> Result<(), DekuError> {
+    fn write(&self, output: &mut BitVec<u8, Msb0>, inner_ctx: Ctx) -> Result<(), DekuError> {
         match self {
             true => (0x01u8).write(output, inner_ctx),
             false => (0x00u8).write(output, inner_ctx),
@@ -62,7 +62,7 @@ mod tests {
         assert_eq!(expected, res_read);
         assert!(rest.is_empty());
 
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         res_read.write(&mut res_write, ()).unwrap();
         assert_eq!(input.to_vec(), res_write.into_vec());
     }
@@ -76,7 +76,7 @@ mod tests {
         assert_eq!(true, res_read);
         assert_eq!(6, rest.len());
 
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         res_read.write(&mut res_write, ()).unwrap();
         assert_eq!(vec![0b01], res_write.into_vec());
     }
diff --git a/src/impls/boxed.rs b/src/impls/boxed.rs
index 35454e1..9ce5465 100644
--- a/src/impls/boxed.rs
+++ b/src/impls/boxed.rs
@@ -9,9 +9,9 @@ where
 {
     /// Read a T from input and store as Box<T>
     fn read(
-        input: &'a BitSlice<Msb0, u8>,
+        input: &'a BitSlice<u8, Msb0>,
         inner_ctx: Ctx,
-    ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError>
+    ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError>
     where
         Self: Sized,
     {
@@ -26,7 +26,7 @@ where
     Ctx: Copy,
 {
     /// Write T from box
-    fn write(&self, output: &mut BitVec<Msb0, u8>, inner_ctx: Ctx) -> Result<(), DekuError> {
+    fn write(&self, output: &mut BitVec<u8, Msb0>, inner_ctx: Ctx) -> Result<(), DekuError> {
         self.as_ref().write(output, inner_ctx)
     }
 }
@@ -39,9 +39,9 @@ where
 {
     /// Read `T`s until the given limit
     fn read(
-        input: &'a BitSlice<Msb0, u8>,
+        input: &'a BitSlice<u8, Msb0>,
         (limit, inner_ctx): (Limit<T, Predicate>, Ctx),
-    ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError>
+    ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError>
     where
         Self: Sized,
     {
@@ -57,7 +57,7 @@ where
     Ctx: Copy,
 {
     /// Write all `T`s to bits
-    fn write(&self, output: &mut BitVec<Msb0, u8>, ctx: Ctx) -> Result<(), DekuError> {
+    fn write(&self, output: &mut BitVec<u8, Msb0>, ctx: Ctx) -> Result<(), DekuError> {
         for v in self.as_ref() {
             v.write(output, ctx)?;
         }
@@ -76,28 +76,28 @@ mod tests {
         case(
             &[0xEF, 0xBE],
             Box::new(native_endian!(0xBEEF_u16)),
-            bits![Msb0, u8;]
+            bits![u8, Msb0;]
         ),
     )]
-    fn test_boxed(input: &[u8], expected: Box<u16>, expected_rest: &BitSlice<Msb0, u8>) {
+    fn test_boxed(input: &[u8], expected: Box<u16>, expected_rest: &BitSlice<u8, Msb0>) {
         let bit_slice = input.view_bits::<Msb0>();
         let (rest, res_read) = <Box<u16>>::read(bit_slice, ()).unwrap();
         assert_eq!(expected, res_read);
         assert_eq!(expected_rest, rest);
 
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         res_read.write(&mut res_write, ()).unwrap();
         assert_eq!(input.to_vec(), res_write.into_vec());
     }
 
     // Note: Copied tests from vec.rs impl
     #[rstest(input, endian, bit_size, limit, expected, expected_rest, expected_write,
-        case::normal_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), 2.into(), vec![0xBBAA, 0xDDCC].into_boxed_slice(), bits![Msb0, u8;], vec![0xAA, 0xBB, 0xCC, 0xDD]),
-        case::normal_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), 2.into(), vec![0xAABB, 0xCCDD].into_boxed_slice(), bits![Msb0, u8;], vec![0xAA, 0xBB, 0xCC, 0xDD]),
-        case::predicate_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), (|v: &u16| *v == 0xBBAA).into(), vec![0xBBAA].into_boxed_slice(), bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
-        case::predicate_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), (|v: &u16| *v == 0xAABB).into(), vec![0xAABB].into_boxed_slice(), bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
-        case::bytes_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), BitSize(16).into(), vec![0xBBAA].into_boxed_slice(), bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
-        case::bytes_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), BitSize(16).into(), vec![0xAABB].into_boxed_slice(), bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
+        case::normal_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), 2.into(), vec![0xBBAA, 0xDDCC].into_boxed_slice(), bits![u8, Msb0;], vec![0xAA, 0xBB, 0xCC, 0xDD]),
+        case::normal_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), 2.into(), vec![0xAABB, 0xCCDD].into_boxed_slice(), bits![u8, Msb0;], vec![0xAA, 0xBB, 0xCC, 0xDD]),
+        case::predicate_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), (|v: &u16| *v == 0xBBAA).into(), vec![0xBBAA].into_boxed_slice(), bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
+        case::predicate_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), (|v: &u16| *v == 0xAABB).into(), vec![0xAABB].into_boxed_slice(), bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
+        case::bytes_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), BitSize(16).into(), vec![0xBBAA].into_boxed_slice(), bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
+        case::bytes_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), BitSize(16).into(), vec![0xAABB].into_boxed_slice(), bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
     )]
     fn test_boxed_slice<Predicate: FnMut(&u16) -> bool>(
         input: &[u8],
@@ -105,7 +105,7 @@ mod tests {
         bit_size: Option<usize>,
         limit: Limit<u16, Predicate>,
         expected: Box<[u16]>,
-        expected_rest: &BitSlice<Msb0, u8>,
+        expected_rest: &BitSlice<u8, Msb0>,
         expected_write: Vec<u8>,
     ) {
         let bit_slice = input.view_bits::<Msb0>();
@@ -118,7 +118,7 @@ mod tests {
         assert_eq!(expected, res_read);
         assert_eq!(expected_rest, rest);
 
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         res_read
             .write(&mut res_write, (endian, BitSize(bit_size)))
             .unwrap();
diff --git a/src/impls/cow.rs b/src/impls/cow.rs
index b50605e..e685aac 100644
--- a/src/impls/cow.rs
+++ b/src/impls/cow.rs
@@ -9,9 +9,9 @@ where
 {
     /// Read a T from input and store as Cow<T>
     fn read(
-        input: &'a BitSlice<Msb0, u8>,
+        input: &'a BitSlice<u8, Msb0>,
         inner_ctx: Ctx,
-    ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError>
+    ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError>
     where
         Self: Sized,
     {
@@ -26,7 +26,7 @@ where
     Ctx: Copy,
 {
     /// Write T from Cow<T>
-    fn write(&self, output: &mut BitVec<Msb0, u8>, inner_ctx: Ctx) -> Result<(), DekuError> {
+    fn write(&self, output: &mut BitVec<u8, Msb0>, inner_ctx: Ctx) -> Result<(), DekuError> {
         (self.borrow() as &T).write(output, inner_ctx)
     }
 }
@@ -41,16 +41,16 @@ mod tests {
         case(
             &[0xEF, 0xBE],
             Cow::Owned(native_endian!(0xBEEF_u16)),
-            bits![Msb0, u8;]
+            bits![u8, Msb0;]
         ),
     )]
-    fn test_cow(input: &[u8], expected: Cow<u16>, expected_rest: &BitSlice<Msb0, u8>) {
+    fn test_cow(input: &[u8], expected: Cow<u16>, expected_rest: &BitSlice<u8, Msb0>) {
         let bit_slice = input.view_bits::<Msb0>();
         let (rest, res_read) = <Cow<u16>>::read(bit_slice, ()).unwrap();
         assert_eq!(expected, res_read);
         assert_eq!(expected_rest, rest);
 
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         res_read.write(&mut res_write, ()).unwrap();
         assert_eq!(input.to_vec(), res_write.into_vec());
     }
diff --git a/src/impls/cstring.rs b/src/impls/cstring.rs
index 5d1ac63..8fac9b4 100644
--- a/src/impls/cstring.rs
+++ b/src/impls/cstring.rs
@@ -6,7 +6,7 @@ impl<Ctx: Copy> DekuWrite<Ctx> for CString
 where
     u8: DekuWrite<Ctx>,
 {
-    fn write(&self, output: &mut BitVec<Msb0, u8>, ctx: Ctx) -> Result<(), DekuError> {
+    fn write(&self, output: &mut BitVec<u8, Msb0>, ctx: Ctx) -> Result<(), DekuError> {
         let bytes = self.as_bytes_with_nul();
         bytes.write(output, ctx)
     }
@@ -17,9 +17,9 @@ where
     u8: DekuRead<'a, Ctx>,
 {
     fn read(
-        input: &'a BitSlice<Msb0, u8>,
+        input: &'a BitSlice<u8, Msb0>,
         ctx: Ctx,
-    ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError>
+    ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError>
     where
         Self: Sized,
     {
@@ -49,7 +49,7 @@ mod tests {
         case(
             &[b't', b'e', b's', b't', b'\0'],
             CString::new("test").unwrap(),
-            bits![Msb0, u8;]
+            bits![u8, Msb0;]
         ),
         case(
             &[b't', b'e', b's', b't', b'\0', b'a'],
@@ -58,15 +58,15 @@ mod tests {
         ),
 
         #[should_panic(expected = "Incomplete(NeedSize { bits: 8 })")]
-        case(&[b't', b'e', b's', b't'], CString::new("test").unwrap(), bits![Msb0, u8;]),
+        case(&[b't', b'e', b's', b't'], CString::new("test").unwrap(), bits![u8, Msb0;]),
     )]
-    fn test_cstring(input: &[u8], expected: CString, expected_rest: &BitSlice<Msb0, u8>) {
+    fn test_cstring(input: &[u8], expected: CString, expected_rest: &BitSlice<u8, Msb0>) {
         let bit_slice = input.view_bits::<Msb0>();
         let (rest, res_read) = CString::read(bit_slice, ()).unwrap();
         assert_eq!(expected, res_read);
         assert_eq!(expected_rest, rest);
 
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         res_read.write(&mut res_write, ()).unwrap();
         assert_eq!(vec![b't', b'e', b's', b't', b'\0'], res_write.into_vec());
     }
diff --git a/src/impls/hashmap.rs b/src/impls/hashmap.rs
index a15d3a7..4a63275 100644
--- a/src/impls/hashmap.rs
+++ b/src/impls/hashmap.rs
@@ -19,11 +19,11 @@ fn read_hashmap_with_predicate<
     Ctx: Copy,
     Predicate: FnMut(usize, &(K, V)) -> bool,
 >(
-    input: &'a BitSlice<Msb0, u8>,
+    input: &'a BitSlice<u8, Msb0>,
     capacity: Option<usize>,
     ctx: Ctx,
     mut predicate: Predicate,
-) -> Result<(&'a BitSlice<Msb0, u8>, HashMap<K, V, S>), DekuError> {
+) -> Result<(&'a BitSlice<u8, Msb0>, HashMap<K, V, S>), DekuError> {
     let mut res = HashMap::with_capacity_and_hasher(capacity.unwrap_or(0), S::default());
 
     let mut rest = input;
@@ -31,7 +31,10 @@ fn read_hashmap_with_predicate<
 
     while !found_predicate {
         let (new_rest, kv) = <(K, V)>::read(rest, ctx)?;
-        found_predicate = predicate(input.offset_from(new_rest) as usize, &kv);
+        found_predicate = predicate(
+            unsafe { new_rest.as_bitptr().offset_from(input.as_bitptr()) } as usize,
+            &kv,
+        );
         res.insert(kv.0, kv.1);
         rest = new_rest;
     }
@@ -65,9 +68,9 @@ impl<
     /// assert_eq!(expected, map)
     /// ```
     fn read(
-        input: &'a BitSlice<Msb0, u8>,
+        input: &'a BitSlice<u8, Msb0>,
         (limit, inner_ctx): (Limit<(K, V), Predicate>, Ctx),
-    ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError>
+    ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError>
     where
         Self: Sized,
     {
@@ -120,9 +123,9 @@ impl<
 {
     /// Read `K, V`s until the given limit from input for types which don't require context.
     fn read(
-        input: &'a BitSlice<Msb0, u8>,
+        input: &'a BitSlice<u8, Msb0>,
         limit: Limit<(K, V), Predicate>,
-    ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError>
+    ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError>
     where
         Self: Sized,
     {
@@ -141,14 +144,14 @@ impl<K: DekuWrite<Ctx>, V: DekuWrite<Ctx>, S, Ctx: Copy> DekuWrite<Ctx> for Hash
     /// # use deku::{ctx::Endian, DekuWrite};
     /// # use deku::bitvec::{Msb0, bitvec};
     /// # use std::collections::HashMap;
-    /// let mut output = bitvec![Msb0, u8;];
+    /// let mut output = bitvec![u8, Msb0;];
     /// let mut map = HashMap::<u8, u32>::default();
     /// map.insert(100, 0x04030201);
     /// map.write(&mut output, Endian::Big).unwrap();
     /// let expected: Vec<u8> = vec![100, 4, 3, 2, 1];
     /// assert_eq!(expected, output.into_vec())
     /// ```
-    fn write(&self, output: &mut BitVec<Msb0, u8>, inner_ctx: Ctx) -> Result<(), DekuError> {
+    fn write(&self, output: &mut BitVec<u8, Msb0>, inner_ctx: Ctx) -> Result<(), DekuError> {
         for kv in self {
             kv.write(output, inner_ctx)?;
         }
@@ -180,24 +183,24 @@ mod tests {
     );
 
     #[rstest(input, endian, bit_size, limit, expected, expected_rest,
-        case::count_0([0xAA].as_ref(), Endian::Little, Some(8), 0.into(), FxHashMap::default(), bits![Msb0, u8; 1, 0, 1, 0, 1, 0, 1, 0]),
-        case::count_1([0x01, 0xAA, 0x02, 0xBB].as_ref(), Endian::Little, Some(8), 1.into(), fxhashmap!{0x01 => 0xAA}, bits![Msb0, u8; 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1]),
-        case::count_2([0x01, 0xAA, 0x02, 0xBB, 0xBB].as_ref(), Endian::Little, Some(8), 2.into(), fxhashmap!{0x01 => 0xAA, 0x02 => 0xBB}, bits![Msb0, u8; 1, 0, 1, 1, 1, 0, 1, 1]),
-        case::until_null([0x01, 0xAA, 0, 0, 0xBB].as_ref(), Endian::Little, None, (|kv: &(u8, u8)| kv.0 == 0u8 && kv.1 == 0u8).into(), fxhashmap!{0x01 => 0xAA, 0 => 0}, bits![Msb0, u8; 1, 0, 1, 1, 1, 0, 1, 1]),
-        case::until_bits([0x01, 0xAA, 0xBB].as_ref(), Endian::Little, None, BitSize(16).into(), fxhashmap!{0x01 => 0xAA}, bits![Msb0, u8; 1, 0, 1, 1, 1, 0, 1, 1]),
-        case::bits_6([0b0000_0100, 0b1111_0000, 0b1000_0000].as_ref(), Endian::Little, Some(6), 2.into(), fxhashmap!{0x01 => 0x0F, 0x02 => 0}, bits![Msb0, u8;]),
+        case::count_0([0xAA].as_ref(), Endian::Little, Some(8), 0.into(), FxHashMap::default(), bits![u8, Msb0; 1, 0, 1, 0, 1, 0, 1, 0]),
+        case::count_1([0x01, 0xAA, 0x02, 0xBB].as_ref(), Endian::Little, Some(8), 1.into(), fxhashmap!{0x01 => 0xAA}, bits![u8, Msb0; 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1]),
+        case::count_2([0x01, 0xAA, 0x02, 0xBB, 0xBB].as_ref(), Endian::Little, Some(8), 2.into(), fxhashmap!{0x01 => 0xAA, 0x02 => 0xBB}, bits![u8, Msb0; 1, 0, 1, 1, 1, 0, 1, 1]),
+        case::until_null([0x01, 0xAA, 0, 0, 0xBB].as_ref(), Endian::Little, None, (|kv: &(u8, u8)| kv.0 == 0u8 && kv.1 == 0u8).into(), fxhashmap!{0x01 => 0xAA, 0 => 0}, bits![u8, Msb0; 1, 0, 1, 1, 1, 0, 1, 1]),
+        case::until_bits([0x01, 0xAA, 0xBB].as_ref(), Endian::Little, None, BitSize(16).into(), fxhashmap!{0x01 => 0xAA}, bits![u8, Msb0; 1, 0, 1, 1, 1, 0, 1, 1]),
+        case::bits_6([0b0000_0100, 0b1111_0000, 0b1000_0000].as_ref(), Endian::Little, Some(6), 2.into(), fxhashmap!{0x01 => 0x0F, 0x02 => 0}, bits![u8, Msb0;]),
         #[should_panic(expected = "Parse(\"too much data: container of 8 bits cannot hold 9 bits\")")]
-        case::not_enough_data([].as_ref(), Endian::Little, Some(9), 1.into(), FxHashMap::default(), bits![Msb0, u8;]),
+        case::not_enough_data([].as_ref(), Endian::Little, Some(9), 1.into(), FxHashMap::default(), bits![u8, Msb0;]),
         #[should_panic(expected = "Parse(\"too much data: container of 8 bits cannot hold 9 bits\")")]
-        case::not_enough_data([0xAA].as_ref(), Endian::Little, Some(9), 1.into(), FxHashMap::default(), bits![Msb0, u8;]),
+        case::not_enough_data([0xAA].as_ref(), Endian::Little, Some(9), 1.into(), FxHashMap::default(), bits![u8, Msb0;]),
         #[should_panic(expected = "Incomplete(NeedSize { bits: 8 })")]
-        case::not_enough_data([0xAA].as_ref(), Endian::Little, Some(8), 2.into(), FxHashMap::default(), bits![Msb0, u8;]),
+        case::not_enough_data([0xAA].as_ref(), Endian::Little, Some(8), 2.into(), FxHashMap::default(), bits![u8, Msb0;]),
         #[should_panic(expected = "Incomplete(NeedSize { bits: 8 })")]
-        case::not_enough_data_until([0xAA].as_ref(), Endian::Little, Some(8), (|_: &(u8, u8)| false).into(), FxHashMap::default(), bits![Msb0, u8;]),
+        case::not_enough_data_until([0xAA].as_ref(), Endian::Little, Some(8), (|_: &(u8, u8)| false).into(), FxHashMap::default(), bits![u8, Msb0;]),
         #[should_panic(expected = "Incomplete(NeedSize { bits: 8 })")]
-        case::not_enough_data_bits([0xAA].as_ref(), Endian::Little, Some(8), (BitSize(16)).into(), FxHashMap::default(), bits![Msb0, u8;]),
+        case::not_enough_data_bits([0xAA].as_ref(), Endian::Little, Some(8), (BitSize(16)).into(), FxHashMap::default(), bits![u8, Msb0;]),
         #[should_panic(expected = "Parse(\"too much data: container of 8 bits cannot hold 9 bits\")")]
-        case::too_much_data([0xAA, 0xBB].as_ref(), Endian::Little, Some(9), 1.into(), FxHashMap::default(), bits![Msb0, u8;]),
+        case::too_much_data([0xAA, 0xBB].as_ref(), Endian::Little, Some(9), 1.into(), FxHashMap::default(), bits![u8, Msb0;]),
     )]
     fn test_hashmap_read<Predicate: FnMut(&(u8, u8)) -> bool>(
         input: &[u8],
@@ -205,7 +208,7 @@ mod tests {
         bit_size: Option<usize>,
         limit: Limit<(u8, u8), Predicate>,
         expected: FxHashMap<u8, u8>,
-        expected_rest: &BitSlice<Msb0, u8>,
+        expected_rest: &BitSlice<u8, Msb0>,
     ) {
         let bit_slice = input.view_bits::<Msb0>();
 
@@ -224,26 +227,26 @@ mod tests {
         case::normal(fxhashmap!{0x11u8 => 0xAABBu16, 0x23u8 => 0xCCDDu16}, Endian::Little, vec![0x11, 0xBB, 0xAA, 0x23, 0xDD, 0xCC]),
     )]
     fn test_hashmap_write(input: FxHashMap<u8, u16>, endian: Endian, expected: Vec<u8>) {
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         input.write(&mut res_write, endian).unwrap();
         assert_eq!(expected, res_write.into_vec());
     }
 
     // Note: These tests also exist in boxed.rs
     #[rstest(input, endian, limit, expected, expected_rest, expected_write,
-        case::normal_le([0xAA, 0xBB, 0, 0xCC, 0xDD, 0].as_ref(), Endian::Little, 2.into(), fxhashmap!{0xBBAA => 0, 0xDDCC => 0}, bits![Msb0, u8;], vec![0xCC, 0xDD, 0, 0xAA, 0xBB, 0]),
-        case::normal_be([0xAA, 0xBB, 0, 0xCC, 0xDD, 0].as_ref(), Endian::Big, 2.into(), fxhashmap!{0xAABB => 0, 0xCCDD => 0}, bits![Msb0, u8;], vec![0xCC, 0xDD, 0, 0xAA, 0xBB, 0]),
-        case::predicate_le([0xAA, 0xBB, 0, 0xCC, 0xDD, 0].as_ref(), Endian::Little, (|kv: &(u16, u8)| kv.0 == 0xBBAA && kv.1 == 0).into(), fxhashmap!{0xBBAA => 0}, bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], vec![0xAA, 0xBB, 0]),
-        case::predicate_be([0xAA, 0xBB, 0, 0xCC, 0xDD, 0].as_ref(), Endian::Big, (|kv: &(u16, u8)| kv.0 == 0xAABB && kv.1 == 0).into(), fxhashmap!{0xAABB => 0}, bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], vec![0xAA, 0xBB, 0]),
-        case::bytes_le([0xAA, 0xBB, 0, 0xCC, 0xDD, 0].as_ref(), Endian::Little, BitSize(24).into(), fxhashmap!{0xBBAA => 0}, bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], vec![0xAA, 0xBB, 0]),
-        case::bytes_be([0xAA, 0xBB, 0, 0xCC, 0xDD, 0].as_ref(), Endian::Big, BitSize(24).into(), fxhashmap!{0xAABB => 0}, bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], vec![0xAA, 0xBB, 0]),
+        case::normal_le([0xAA, 0xBB, 0, 0xCC, 0xDD, 0].as_ref(), Endian::Little, 2.into(), fxhashmap!{0xBBAA => 0, 0xDDCC => 0}, bits![u8, Msb0;], vec![0xCC, 0xDD, 0, 0xAA, 0xBB, 0]),
+        case::normal_be([0xAA, 0xBB, 0, 0xCC, 0xDD, 0].as_ref(), Endian::Big, 2.into(), fxhashmap!{0xAABB => 0, 0xCCDD => 0}, bits![u8, Msb0;], vec![0xCC, 0xDD, 0, 0xAA, 0xBB, 0]),
+        case::predicate_le([0xAA, 0xBB, 0, 0xCC, 0xDD, 0].as_ref(), Endian::Little, (|kv: &(u16, u8)| kv.0 == 0xBBAA && kv.1 == 0).into(), fxhashmap!{0xBBAA => 0}, bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], vec![0xAA, 0xBB, 0]),
+        case::predicate_be([0xAA, 0xBB, 0, 0xCC, 0xDD, 0].as_ref(), Endian::Big, (|kv: &(u16, u8)| kv.0 == 0xAABB && kv.1 == 0).into(), fxhashmap!{0xAABB => 0}, bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], vec![0xAA, 0xBB, 0]),
+        case::bytes_le([0xAA, 0xBB, 0, 0xCC, 0xDD, 0].as_ref(), Endian::Little, BitSize(24).into(), fxhashmap!{0xBBAA => 0}, bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], vec![0xAA, 0xBB, 0]),
+        case::bytes_be([0xAA, 0xBB, 0, 0xCC, 0xDD, 0].as_ref(), Endian::Big, BitSize(24).into(), fxhashmap!{0xAABB => 0}, bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], vec![0xAA, 0xBB, 0]),
     )]
     fn test_hashmap_read_write<Predicate: FnMut(&(u16, u8)) -> bool>(
         input: &[u8],
         endian: Endian,
         limit: Limit<(u16, u8), Predicate>,
         expected: FxHashMap<u16, u8>,
-        expected_rest: &BitSlice<Msb0, u8>,
+        expected_rest: &BitSlice<u8, Msb0>,
         expected_write: Vec<u8>,
     ) {
         let bit_slice = input.view_bits::<Msb0>();
@@ -252,7 +255,7 @@ mod tests {
         assert_eq!(expected, res_read);
         assert_eq!(expected_rest, rest);
 
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         res_read.write(&mut res_write, endian).unwrap();
         assert_eq!(expected_write, res_write.into_vec());
     }
diff --git a/src/impls/hashset.rs b/src/impls/hashset.rs
index 0d76784..eb21532 100644
--- a/src/impls/hashset.rs
+++ b/src/impls/hashset.rs
@@ -18,11 +18,11 @@ fn read_hashset_with_predicate<
     Ctx: Copy,
     Predicate: FnMut(usize, &T) -> bool,
 >(
-    input: &'a BitSlice<Msb0, u8>,
+    input: &'a BitSlice<u8, Msb0>,
     capacity: Option<usize>,
     ctx: Ctx,
     mut predicate: Predicate,
-) -> Result<(&'a BitSlice<Msb0, u8>, HashSet<T, S>), DekuError> {
+) -> Result<(&'a BitSlice<u8, Msb0>, HashSet<T, S>), DekuError> {
     let mut res = HashSet::with_capacity_and_hasher(capacity.unwrap_or(0), S::default());
 
     let mut rest = input;
@@ -30,7 +30,10 @@ fn read_hashset_with_predicate<
 
     while !found_predicate {
         let (new_rest, val) = <T>::read(rest, ctx)?;
-        found_predicate = predicate(input.offset_from(new_rest) as usize, &val);
+        found_predicate = predicate(
+            unsafe { new_rest.as_bitptr().offset_from(input.as_bitptr()) } as usize,
+            &val,
+        );
         res.insert(val);
         rest = new_rest;
     }
@@ -62,9 +65,9 @@ impl<
     /// assert_eq!(expected, set)
     /// ```
     fn read(
-        input: &'a BitSlice<Msb0, u8>,
+        input: &'a BitSlice<u8, Msb0>,
         (limit, inner_ctx): (Limit<T, Predicate>, Ctx),
-    ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError>
+    ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError>
     where
         Self: Sized,
     {
@@ -114,9 +117,9 @@ impl<'a, T: DekuRead<'a> + Eq + Hash, S: BuildHasher + Default, Predicate: FnMut
 {
     /// Read `T`s until the given limit from input for types which don't require context.
     fn read(
-        input: &'a BitSlice<Msb0, u8>,
+        input: &'a BitSlice<u8, Msb0>,
         limit: Limit<T, Predicate>,
-    ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError>
+    ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError>
     where
         Self: Sized,
     {
@@ -136,11 +139,11 @@ impl<T: DekuWrite<Ctx>, S, Ctx: Copy> DekuWrite<Ctx> for HashSet<T, S> {
     /// # use deku::bitvec::{Msb0, bitvec};
     /// # use std::collections::HashSet;
     /// let set: HashSet<u8> = vec![1].into_iter().collect();
-    /// let mut output = bitvec![Msb0, u8;];
+    /// let mut output = bitvec![u8, Msb0;];
     /// set.write(&mut output, Endian::Big).unwrap();
-    /// assert_eq!(output, bitvec![Msb0, u8; 0, 0, 0, 0, 0, 0, 0, 1])
+    /// assert_eq!(output, bitvec![u8, Msb0; 0, 0, 0, 0, 0, 0, 0, 1])
     /// ```
-    fn write(&self, output: &mut BitVec<Msb0, u8>, inner_ctx: Ctx) -> Result<(), DekuError> {
+    fn write(&self, output: &mut BitVec<u8, Msb0>, inner_ctx: Ctx) -> Result<(), DekuError> {
         for v in self {
             v.write(output, inner_ctx)?;
         }
@@ -155,24 +158,24 @@ mod tests {
     use rustc_hash::FxHashSet;
 
     #[rstest(input, endian, bit_size, limit, expected, expected_rest,
-        case::count_0([0xAA].as_ref(), Endian::Little, Some(8), 0.into(), FxHashSet::default(), bits![Msb0, u8; 1, 0, 1, 0, 1, 0, 1, 0]),
-        case::count_1([0xAA, 0xBB].as_ref(), Endian::Little, Some(8), 1.into(), vec![0xAA].into_iter().collect(), bits![Msb0, u8; 1, 0, 1, 1, 1, 0, 1, 1]),
-        case::count_2([0xAA, 0xBB, 0xCC].as_ref(), Endian::Little, Some(8), 2.into(), vec![0xAA, 0xBB].into_iter().collect(), bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0]),
-        case::until_null([0xAA, 0, 0xBB].as_ref(), Endian::Little, None, (|v: &u8| *v == 0u8).into(), vec![0xAA, 0].into_iter().collect(), bits![Msb0, u8; 1, 0, 1, 1, 1, 0, 1, 1]),
-        case::until_bits([0xAA, 0xBB].as_ref(), Endian::Little, None, BitSize(8).into(), vec![0xAA].into_iter().collect(), bits![Msb0, u8; 1, 0, 1, 1, 1, 0, 1, 1]),
-        case::bits_6([0b0110_1001, 0b1110_1001].as_ref(), Endian::Little, Some(6), 2.into(), vec![0b00_011010, 0b00_011110].into_iter().collect(), bits![Msb0, u8; 1, 0, 0, 1]),
+        case::count_0([0xAA].as_ref(), Endian::Little, Some(8), 0.into(), FxHashSet::default(), bits![u8, Msb0; 1, 0, 1, 0, 1, 0, 1, 0]),
+        case::count_1([0xAA, 0xBB].as_ref(), Endian::Little, Some(8), 1.into(), vec![0xAA].into_iter().collect(), bits![u8, Msb0; 1, 0, 1, 1, 1, 0, 1, 1]),
+        case::count_2([0xAA, 0xBB, 0xCC].as_ref(), Endian::Little, Some(8), 2.into(), vec![0xAA, 0xBB].into_iter().collect(), bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0]),
+        case::until_null([0xAA, 0, 0xBB].as_ref(), Endian::Little, None, (|v: &u8| *v == 0u8).into(), vec![0xAA, 0].into_iter().collect(), bits![u8, Msb0; 1, 0, 1, 1, 1, 0, 1, 1]),
+        case::until_bits([0xAA, 0xBB].as_ref(), Endian::Little, None, BitSize(8).into(), vec![0xAA].into_iter().collect(), bits![u8, Msb0; 1, 0, 1, 1, 1, 0, 1, 1]),
+        case::bits_6([0b0110_1001, 0b1110_1001].as_ref(), Endian::Little, Some(6), 2.into(), vec![0b00_011010, 0b00_011110].into_iter().collect(), bits![u8, Msb0; 1, 0, 0, 1]),
         #[should_panic(expected = "Parse(\"too much data: container of 8 bits cannot hold 9 bits\")")]
-        case::not_enough_data([].as_ref(), Endian::Little, Some(9), 1.into(), FxHashSet::default(), bits![Msb0, u8;]),
+        case::not_enough_data([].as_ref(), Endian::Little, Some(9), 1.into(), FxHashSet::default(), bits![u8, Msb0;]),
         #[should_panic(expected = "Parse(\"too much data: container of 8 bits cannot hold 9 bits\")")]
-        case::not_enough_data([0xAA].as_ref(), Endian::Little, Some(9), 1.into(), FxHashSet::default(), bits![Msb0, u8;]),
+        case::not_enough_data([0xAA].as_ref(), Endian::Little, Some(9), 1.into(), FxHashSet::default(), bits![u8, Msb0;]),
         #[should_panic(expected = "Incomplete(NeedSize { bits: 8 })")]
-        case::not_enough_data([0xAA].as_ref(), Endian::Little, Some(8), 2.into(), FxHashSet::default(), bits![Msb0, u8;]),
+        case::not_enough_data([0xAA].as_ref(), Endian::Little, Some(8), 2.into(), FxHashSet::default(), bits![u8, Msb0;]),
         #[should_panic(expected = "Incomplete(NeedSize { bits: 8 })")]
-        case::not_enough_data_until([0xAA].as_ref(), Endian::Little, Some(8), (|_: &u8| false).into(), FxHashSet::default(), bits![Msb0, u8;]),
+        case::not_enough_data_until([0xAA].as_ref(), Endian::Little, Some(8), (|_: &u8| false).into(), FxHashSet::default(), bits![u8, Msb0;]),
         #[should_panic(expected = "Incomplete(NeedSize { bits: 8 })")]
-        case::not_enough_data_bits([0xAA].as_ref(), Endian::Little, Some(8), (BitSize(16)).into(), FxHashSet::default(), bits![Msb0, u8;]),
+        case::not_enough_data_bits([0xAA].as_ref(), Endian::Little, Some(8), (BitSize(16)).into(), FxHashSet::default(), bits![u8, Msb0;]),
         #[should_panic(expected = "Parse(\"too much data: container of 8 bits cannot hold 9 bits\")")]
-        case::too_much_data([0xAA, 0xBB].as_ref(), Endian::Little, Some(9), 1.into(), FxHashSet::default(), bits![Msb0, u8;]),
+        case::too_much_data([0xAA, 0xBB].as_ref(), Endian::Little, Some(9), 1.into(), FxHashSet::default(), bits![u8, Msb0;]),
     )]
     fn test_hashset_read<Predicate: FnMut(&u8) -> bool>(
         input: &[u8],
@@ -180,7 +183,7 @@ mod tests {
         bit_size: Option<usize>,
         limit: Limit<u8, Predicate>,
         expected: FxHashSet<u8>,
-        expected_rest: &BitSlice<Msb0, u8>,
+        expected_rest: &BitSlice<u8, Msb0>,
     ) {
         let bit_slice = input.view_bits::<Msb0>();
 
@@ -199,19 +202,19 @@ mod tests {
         case::normal(vec![0xAABB, 0xCCDD].into_iter().collect(), Endian::Little, vec![0xDD, 0xCC, 0xBB, 0xAA]),
     )]
     fn test_hashset_write(input: FxHashSet<u16>, endian: Endian, expected: Vec<u8>) {
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         input.write(&mut res_write, endian).unwrap();
         assert_eq!(expected, res_write.into_vec());
     }
 
     // Note: These tests also exist in boxed.rs
     #[rstest(input, endian, bit_size, limit, expected, expected_rest, expected_write,
-        case::normal_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), 2.into(), vec![0xBBAA, 0xDDCC].into_iter().collect(), bits![Msb0, u8;], vec![0xCC, 0xDD, 0xAA, 0xBB]),
-        case::normal_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), 2.into(), vec![0xAABB, 0xCCDD].into_iter().collect(), bits![Msb0, u8;], vec![0xCC, 0xDD, 0xAA, 0xBB]),
-        case::predicate_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), (|v: &u16| *v == 0xBBAA).into(), vec![0xBBAA].into_iter().collect(), bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
-        case::predicate_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), (|v: &u16| *v == 0xAABB).into(), vec![0xAABB].into_iter().collect(), bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
-        case::bytes_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), BitSize(16).into(), vec![0xBBAA].into_iter().collect(), bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
-        case::bytes_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), BitSize(16).into(), vec![0xAABB].into_iter().collect(), bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
+        case::normal_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), 2.into(), vec![0xBBAA, 0xDDCC].into_iter().collect(), bits![u8, Msb0;], vec![0xCC, 0xDD, 0xAA, 0xBB]),
+        case::normal_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), 2.into(), vec![0xAABB, 0xCCDD].into_iter().collect(), bits![u8, Msb0;], vec![0xCC, 0xDD, 0xAA, 0xBB]),
+        case::predicate_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), (|v: &u16| *v == 0xBBAA).into(), vec![0xBBAA].into_iter().collect(), bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
+        case::predicate_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), (|v: &u16| *v == 0xAABB).into(), vec![0xAABB].into_iter().collect(), bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
+        case::bytes_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), BitSize(16).into(), vec![0xBBAA].into_iter().collect(), bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
+        case::bytes_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), BitSize(16).into(), vec![0xAABB].into_iter().collect(), bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
     )]
     fn test_hashset_read_write<Predicate: FnMut(&u16) -> bool>(
         input: &[u8],
@@ -219,7 +222,7 @@ mod tests {
         bit_size: Option<usize>,
         limit: Limit<u16, Predicate>,
         expected: FxHashSet<u16>,
-        expected_rest: &BitSlice<Msb0, u8>,
+        expected_rest: &BitSlice<u8, Msb0>,
         expected_write: Vec<u8>,
     ) {
         let bit_slice = input.view_bits::<Msb0>();
@@ -232,7 +235,7 @@ mod tests {
         assert_eq!(expected, res_read);
         assert_eq!(expected_rest, rest);
 
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         res_read
             .write(&mut res_write, (endian, BitSize(bit_size)))
             .unwrap();
diff --git a/src/impls/ipaddr.rs b/src/impls/ipaddr.rs
index 26b9069..304ac8f 100644
--- a/src/impls/ipaddr.rs
+++ b/src/impls/ipaddr.rs
@@ -7,9 +7,9 @@ where
     u32: DekuRead<'a, Ctx>,
 {
     fn read(
-        input: &'a BitSlice<Msb0, u8>,
+        input: &'a BitSlice<u8, Msb0>,
         ctx: Ctx,
-    ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError>
+    ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError>
     where
         Self: Sized,
     {
@@ -22,7 +22,7 @@ impl<Ctx> DekuWrite<Ctx> for Ipv4Addr
 where
     u32: DekuWrite<Ctx>,
 {
-    fn write(&self, output: &mut BitVec<Msb0, u8>, ctx: Ctx) -> Result<(), DekuError> {
+    fn write(&self, output: &mut BitVec<u8, Msb0>, ctx: Ctx) -> Result<(), DekuError> {
         let ip: u32 = (*self).into();
         ip.write(output, ctx)
     }
@@ -33,9 +33,9 @@ where
     u128: DekuRead<'a, Ctx>,
 {
     fn read(
-        input: &'a BitSlice<Msb0, u8>,
+        input: &'a BitSlice<u8, Msb0>,
         ctx: Ctx,
-    ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError>
+    ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError>
     where
         Self: Sized,
     {
@@ -48,7 +48,7 @@ impl<Ctx> DekuWrite<Ctx> for Ipv6Addr
 where
     u128: DekuWrite<Ctx>,
 {
-    fn write(&self, output: &mut BitVec<Msb0, u8>, ctx: Ctx) -> Result<(), DekuError> {
+    fn write(&self, output: &mut BitVec<u8, Msb0>, ctx: Ctx) -> Result<(), DekuError> {
         let ip: u128 = (*self).into();
         ip.write(output, ctx)
     }
@@ -59,7 +59,7 @@ where
     Ipv6Addr: DekuWrite<Ctx>,
     Ipv4Addr: DekuWrite<Ctx>,
 {
-    fn write(&self, output: &mut BitVec<Msb0, u8>, ctx: Ctx) -> Result<(), DekuError> {
+    fn write(&self, output: &mut BitVec<u8, Msb0>, ctx: Ctx) -> Result<(), DekuError> {
         match self {
             IpAddr::V4(ipv4) => ipv4.write(output, ctx),
             IpAddr::V6(ipv6) => ipv6.write(output, ctx),
@@ -74,14 +74,14 @@ mod tests {
     use rstest::rstest;
 
     #[rstest(input, endian, expected, expected_rest,
-        case::normal_le([237, 160, 254, 145].as_ref(), Endian::Little, Ipv4Addr::new(145, 254, 160, 237), bits![Msb0, u8;]),
-        case::normal_be([145, 254, 160, 237].as_ref(), Endian::Big, Ipv4Addr::new(145, 254, 160, 237), bits![Msb0, u8;]),
+        case::normal_le([237, 160, 254, 145].as_ref(), Endian::Little, Ipv4Addr::new(145, 254, 160, 237), bits![u8, Msb0;]),
+        case::normal_be([145, 254, 160, 237].as_ref(), Endian::Big, Ipv4Addr::new(145, 254, 160, 237), bits![u8, Msb0;]),
     )]
     fn test_ipv4(
         input: &[u8],
         endian: Endian,
         expected: Ipv4Addr,
-        expected_rest: &BitSlice<Msb0, u8>,
+        expected_rest: &BitSlice<u8, Msb0>,
     ) {
         let bit_slice = input.view_bits::<Msb0>();
 
@@ -89,20 +89,20 @@ mod tests {
         assert_eq!(expected, res_read);
         assert_eq!(expected_rest, rest);
 
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         res_read.write(&mut res_write, endian).unwrap();
         assert_eq!(input.to_vec(), res_write.into_vec());
     }
 
     #[rstest(input, endian, expected, expected_rest,
-        case::normal_le([0xFF, 0x02, 0x0A, 0xC0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00].as_ref(), Endian::Little, Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x02ff), bits![Msb0, u8;]),
-        case::normal_be([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x0A, 0x02, 0xFF].as_ref(), Endian::Big, Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x02ff), bits![Msb0, u8;]),
+        case::normal_le([0xFF, 0x02, 0x0A, 0xC0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00].as_ref(), Endian::Little, Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x02ff), bits![u8, Msb0;]),
+        case::normal_be([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0x0A, 0x02, 0xFF].as_ref(), Endian::Big, Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x02ff), bits![u8, Msb0;]),
     )]
     fn test_ipv6(
         input: &[u8],
         endian: Endian,
         expected: Ipv6Addr,
-        expected_rest: &BitSlice<Msb0, u8>,
+        expected_rest: &BitSlice<u8, Msb0>,
     ) {
         let bit_slice = input.view_bits::<Msb0>();
 
@@ -110,7 +110,7 @@ mod tests {
         assert_eq!(expected, res_read);
         assert_eq!(expected_rest, rest);
 
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         res_read.write(&mut res_write, endian).unwrap();
         assert_eq!(input.to_vec(), res_write.into_vec());
     }
@@ -118,12 +118,12 @@ mod tests {
     #[test]
     fn test_ip_addr_write() {
         let ip_addr = IpAddr::V4(Ipv4Addr::new(145, 254, 160, 237));
-        let mut ret_write = bitvec![Msb0, u8;];
+        let mut ret_write = bitvec![u8, Msb0;];
         ip_addr.write(&mut ret_write, Endian::Little).unwrap();
         assert_eq!(vec![237, 160, 254, 145], ret_write.into_vec());
 
         let ip_addr = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x02ff));
-        let mut ret_write = bitvec![Msb0, u8;];
+        let mut ret_write = bitvec![u8, Msb0;];
         ip_addr.write(&mut ret_write, Endian::Little).unwrap();
         assert_eq!(
             vec![
diff --git a/src/impls/nonzero.rs b/src/impls/nonzero.rs
index 898b73c..33a5c2b 100644
--- a/src/impls/nonzero.rs
+++ b/src/impls/nonzero.rs
@@ -9,9 +9,9 @@ macro_rules! ImplDekuTraitsCtx {
     ($typ:ty, $readtype:ty, $ctx_arg:tt, $ctx_type:tt) => {
         impl DekuRead<'_, $ctx_type> for $typ {
             fn read(
-                input: &BitSlice<Msb0, u8>,
+                input: &BitSlice<u8, Msb0>,
                 $ctx_arg: $ctx_type,
-            ) -> Result<(&BitSlice<Msb0, u8>, Self), DekuError>
+            ) -> Result<(&BitSlice<u8, Msb0>, Self), DekuError>
             where
                 Self: Sized,
             {
@@ -28,7 +28,7 @@ macro_rules! ImplDekuTraitsCtx {
         impl DekuWrite<$ctx_type> for $typ {
             fn write(
                 &self,
-                output: &mut BitVec<Msb0, u8>,
+                output: &mut BitVec<u8, Msb0>,
                 $ctx_arg: $ctx_type,
             ) -> Result<(), DekuError> {
                 let value = self.get();
@@ -78,7 +78,7 @@ mod tests {
         assert_eq!(expected, res_read);
         assert!(rest.is_empty());
 
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         res_read.write(&mut res_write, ()).unwrap();
         assert_eq!(input.to_vec(), res_write.into_vec());
     }
diff --git a/src/impls/option.rs b/src/impls/option.rs
index b79fcc9..2409607 100644
--- a/src/impls/option.rs
+++ b/src/impls/option.rs
@@ -15,9 +15,9 @@ impl<'a, T: DekuRead<'a, Ctx>, Ctx: Copy> DekuRead<'a, Ctx> for Option<T> {
     /// assert_eq!(v, Some(0x04030201))
     /// ```
     fn read(
-        input: &'a BitSlice<Msb0, u8>,
+        input: &'a BitSlice<u8, Msb0>,
         inner_ctx: Ctx,
-    ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError>
+    ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError>
     where
         Self: Sized,
     {
@@ -34,11 +34,11 @@ impl<T: DekuWrite<Ctx>, Ctx: Copy> DekuWrite<Ctx> for Option<T> {
     /// # use deku::{ctx::Endian, DekuWrite};
     /// # use deku::bitvec::{bitvec, Msb0};
     /// let data = Some(1u8);
-    /// let mut output = bitvec![Msb0, u8;];
+    /// let mut output = bitvec![u8, Msb0;];
     /// data.write(&mut output, Endian::Big).unwrap();
-    /// assert_eq!(output, bitvec![Msb0, u8; 0, 0, 0, 0, 0, 0, 0, 1])
+    /// assert_eq!(output, bitvec![u8, Msb0; 0, 0, 0, 0, 0, 0, 0, 1])
     /// ```
-    fn write(&self, output: &mut BitVec<Msb0, u8>, inner_ctx: Ctx) -> Result<(), DekuError> {
+    fn write(&self, output: &mut BitVec<u8, Msb0>, inner_ctx: Ctx) -> Result<(), DekuError> {
         self.as_ref().map_or(Ok(()), |v| v.write(output, inner_ctx))
     }
 }
diff --git a/src/impls/primitive.rs b/src/impls/primitive.rs
index de539bc..0c819a6 100644
--- a/src/impls/primitive.rs
+++ b/src/impls/primitive.rs
@@ -8,12 +8,14 @@ use alloc::format;
 // specialize u8 for ByteSize
 impl DekuRead<'_, (Endian, ByteSize)> for u8 {
     fn read(
-        input: &BitSlice<Msb0, u8>,
+        input: &BitSlice<u8, Msb0>,
         (_, size): (Endian, ByteSize),
-    ) -> Result<(&BitSlice<Msb0, u8>, Self), DekuError> {
+    ) -> Result<(&BitSlice<u8, Msb0>, Self), DekuError> {
         const MAX_TYPE_BITS: usize = BitSize::of::<u8>().0;
         let bit_size: usize = size.0 * 8;
 
+        // TODO
+        // if they never give [bits] or [bytes] we don't need to check the size
         if bit_size > MAX_TYPE_BITS {
             return Err(DekuError::Parse(format!(
                 "too much data: container of {} bits cannot hold {} bits",
@@ -26,19 +28,16 @@ impl DekuRead<'_, (Endian, ByteSize)> for u8 {
         }
 
         let (bit_slice, rest) = input.split_at(bit_size);
-
         let pad = 8 * ((bit_slice.len() + 7) / 8) - bit_slice.len();
 
         let value = if pad == 0
             && bit_slice.len() == MAX_TYPE_BITS
-            && bit_slice.as_raw_slice().len() * 8 == MAX_TYPE_BITS
+            && bit_slice.domain().region().unwrap().1.len() * 8 == MAX_TYPE_BITS
         {
             // if everything is aligned, just read the value
-            let bytes: &[u8] = bit_slice.as_raw_slice();
-
-            u8::from_le_bytes(bytes.try_into()?)
+            bit_slice.load::<u8>()
         } else {
-            let mut bits: BitVec<Msb0, u8> = BitVec::with_capacity(bit_slice.len() + pad);
+            let mut bits: BitVec<u8, Msb0> = BitVec::with_capacity(bit_slice.len() + pad);
 
             // Copy bits to new BitVec
             bits.extend_from_bitslice(bit_slice);
@@ -67,9 +66,9 @@ macro_rules! ImplDekuReadBits {
     ($typ:ty, $inner:ty) => {
         impl DekuRead<'_, (Endian, BitSize)> for $typ {
             fn read(
-                input: &BitSlice<Msb0, u8>,
+                input: &BitSlice<u8, Msb0>,
                 (endian, size): (Endian, BitSize),
-            ) -> Result<(&BitSlice<Msb0, u8>, Self), DekuError> {
+            ) -> Result<(&BitSlice<u8, Msb0>, Self), DekuError> {
                 const MAX_TYPE_BITS: usize = BitSize::of::<$typ>().0;
                 let bit_size: usize = size.0;
 
@@ -92,10 +91,10 @@ macro_rules! ImplDekuReadBits {
 
                 let value = if pad == 0
                     && bit_slice.len() == MAX_TYPE_BITS
-                    && bit_slice.as_raw_slice().len() * 8 == MAX_TYPE_BITS
+                    && bit_slice.domain().region().unwrap().1.len() * 8 == MAX_TYPE_BITS
                 {
                     // if everything is aligned, just read the value
-                    let bytes: &[u8] = bit_slice.as_raw_slice();
+                    let bytes: &[u8] = bit_slice.domain().region().unwrap().1;
 
                     // Read value
                     if input_is_le {
@@ -106,7 +105,7 @@ macro_rules! ImplDekuReadBits {
                 } else {
                     // Create a new BitVec from the slice and pad un-aligned chunks
                     // i.e. [10010110, 1110] -> [10010110, 00001110]
-                    let bits: BitVec<Msb0, u8> = {
+                    let bits: BitVec<u8, Msb0> = {
                         let mut bits = BitVec::with_capacity(bit_slice.len() + pad);
 
                         // Copy bits to new BitVec
@@ -138,7 +137,7 @@ macro_rules! ImplDekuReadBits {
                         bits
                     };
 
-                    let bytes: &[u8] = bits.as_raw_slice();
+                    let bytes: &[u8] = bits.domain().region().unwrap().1;
 
                     // Read value
                     if input_is_le {
@@ -157,9 +156,9 @@ macro_rules! ImplDekuReadBytes {
     ($typ:ty, $inner:ty) => {
         impl DekuRead<'_, (Endian, ByteSize)> for $typ {
             fn read(
-                input: &BitSlice<Msb0, u8>,
+                input: &BitSlice<u8, Msb0>,
                 (endian, size): (Endian, ByteSize),
-            ) -> Result<(&BitSlice<Msb0, u8>, Self), DekuError> {
+            ) -> Result<(&BitSlice<u8, Msb0>, Self), DekuError> {
                 const MAX_TYPE_BITS: usize = BitSize::of::<$typ>().0;
                 let bit_size: usize = size.0 * 8;
 
@@ -182,10 +181,10 @@ macro_rules! ImplDekuReadBytes {
 
                 let value = if pad == 0
                     && bit_slice.len() == MAX_TYPE_BITS
-                    && bit_slice.as_raw_slice().len() * 8 == MAX_TYPE_BITS
+                    && bit_slice.domain().region().unwrap().1.len() * 8 == MAX_TYPE_BITS
                 {
                     // if everything is aligned, just read the value
-                    let bytes: &[u8] = bit_slice.as_raw_slice();
+                    let bytes: &[u8] = bit_slice.domain().region().unwrap().1;
 
                     // Read value
                     if input_is_le {
@@ -194,7 +193,7 @@ macro_rules! ImplDekuReadBytes {
                         <$typ>::from_be_bytes(bytes.try_into()?)
                     }
                 } else {
-                    let mut bits: BitVec<Msb0, u8> = BitVec::with_capacity(bit_slice.len() + pad);
+                    let mut bits: BitVec<u8, Msb0> = BitVec::with_capacity(bit_slice.len() + pad);
 
                     // Copy bits to new BitVec
                     bits.extend_from_bitslice(bit_slice);
@@ -203,7 +202,7 @@ macro_rules! ImplDekuReadBytes {
                     //i.e. [1110, 10010110] -> [11101001, 0110]
                     bits.force_align();
 
-                    let bytes: &[u8] = bits.as_raw_slice();
+                    let bytes: &[u8] = bit_slice.domain().region().unwrap().1;
 
                     // cannot use from_X_bytes as we don't have enough bytes for $typ
                     // read manually
@@ -233,9 +232,9 @@ macro_rules! ImplDekuReadSignExtend {
     ($typ:ty, $inner:ty) => {
         impl DekuRead<'_, (Endian, ByteSize)> for $typ {
             fn read(
-                input: &BitSlice<Msb0, u8>,
+                input: &BitSlice<u8, Msb0>,
                 (endian, size): (Endian, ByteSize),
-            ) -> Result<(&BitSlice<Msb0, u8>, Self), DekuError> {
+            ) -> Result<(&BitSlice<u8, Msb0>, Self), DekuError> {
                 let (rest, value) =
                     <$inner as DekuRead<'_, (Endian, ByteSize)>>::read(input, (endian, size))?;
 
@@ -248,9 +247,9 @@ macro_rules! ImplDekuReadSignExtend {
         }
         impl DekuRead<'_, (Endian, BitSize)> for $typ {
             fn read(
-                input: &BitSlice<Msb0, u8>,
+                input: &BitSlice<u8, Msb0>,
                 (endian, size): (Endian, BitSize),
-            ) -> Result<(&BitSlice<Msb0, u8>, Self), DekuError> {
+            ) -> Result<(&BitSlice<u8, Msb0>, Self), DekuError> {
                 let (rest, value) =
                     <$inner as DekuRead<'_, (Endian, BitSize)>>::read(input, (endian, size))?;
 
@@ -269,9 +268,9 @@ macro_rules! ForwardDekuRead {
         // Only have `endian`, set `bit_size` to `Size::of::<Type>()`
         impl DekuRead<'_, Endian> for $typ {
             fn read(
-                input: &BitSlice<Msb0, u8>,
+                input: &BitSlice<u8, Msb0>,
                 endian: Endian,
-            ) -> Result<(&BitSlice<Msb0, u8>, Self), DekuError> {
+            ) -> Result<(&BitSlice<u8, Msb0>, Self), DekuError> {
                 let bit_size = BitSize::of::<$typ>();
 
                 // Since we don't have a #[bits] or [bytes], check if we can use bytes for perf
@@ -286,9 +285,9 @@ macro_rules! ForwardDekuRead {
         // Only have `bit_size`, set `endian` to `Endian::default`.
         impl DekuRead<'_, ByteSize> for $typ {
             fn read(
-                input: &BitSlice<Msb0, u8>,
+                input: &BitSlice<u8, Msb0>,
                 byte_size: ByteSize,
-            ) -> Result<(&BitSlice<Msb0, u8>, Self), DekuError> {
+            ) -> Result<(&BitSlice<u8, Msb0>, Self), DekuError> {
                 let endian = Endian::default();
 
                 <$typ>::read(input, (endian, byte_size))
@@ -298,9 +297,9 @@ macro_rules! ForwardDekuRead {
         // Only have `bit_size`, set `endian` to `Endian::default`.
         impl DekuRead<'_, BitSize> for $typ {
             fn read(
-                input: &BitSlice<Msb0, u8>,
+                input: &BitSlice<u8, Msb0>,
                 bit_size: BitSize,
-            ) -> Result<(&BitSlice<Msb0, u8>, Self), DekuError> {
+            ) -> Result<(&BitSlice<u8, Msb0>, Self), DekuError> {
                 let endian = Endian::default();
 
                 // check if we can use ByteSize for performance
@@ -314,9 +313,9 @@ macro_rules! ForwardDekuRead {
 
         impl DekuRead<'_> for $typ {
             fn read(
-                input: &BitSlice<Msb0, u8>,
+                input: &BitSlice<u8, Msb0>,
                 _: (),
-            ) -> Result<(&BitSlice<Msb0, u8>, Self), DekuError> {
+            ) -> Result<(&BitSlice<u8, Msb0>, Self), DekuError> {
                 <$typ>::read(input, Endian::default())
             }
         }
@@ -328,7 +327,7 @@ macro_rules! ImplDekuWrite {
         impl DekuWrite<(Endian, BitSize)> for $typ {
             fn write(
                 &self,
-                output: &mut BitVec<Msb0, u8>,
+                output: &mut BitVec<u8, Msb0>,
                 (endian, size): (Endian, BitSize),
             ) -> Result<(), DekuError> {
                 let input = match endian {
@@ -373,7 +372,7 @@ macro_rules! ImplDekuWrite {
         impl DekuWrite<(Endian, ByteSize)> for $typ {
             fn write(
                 &self,
-                output: &mut BitVec<Msb0, u8>,
+                output: &mut BitVec<u8, Msb0>,
                 (endian, size): (Endian, ByteSize),
             ) -> Result<(), DekuError> {
                 let input = match endian {
@@ -419,7 +418,7 @@ macro_rules! ImplDekuWrite {
         impl DekuWrite<Endian> for $typ {
             fn write(
                 &self,
-                output: &mut BitVec<Msb0, u8>,
+                output: &mut BitVec<u8, Msb0>,
                 endian: Endian,
             ) -> Result<(), DekuError> {
                 let input = match endian {
@@ -439,7 +438,7 @@ macro_rules! ForwardDekuWrite {
         impl DekuWrite<BitSize> for $typ {
             fn write(
                 &self,
-                output: &mut BitVec<Msb0, u8>,
+                output: &mut BitVec<u8, Msb0>,
                 bit_size: BitSize,
             ) -> Result<(), DekuError> {
                 <$typ>::write(self, output, (Endian::default(), bit_size))
@@ -450,7 +449,7 @@ macro_rules! ForwardDekuWrite {
         impl DekuWrite<ByteSize> for $typ {
             fn write(
                 &self,
-                output: &mut BitVec<Msb0, u8>,
+                output: &mut BitVec<u8, Msb0>,
                 bit_size: ByteSize,
             ) -> Result<(), DekuError> {
                 <$typ>::write(self, output, (Endian::default(), bit_size))
@@ -458,7 +457,7 @@ macro_rules! ForwardDekuWrite {
         }
 
         impl DekuWrite for $typ {
-            fn write(&self, output: &mut BitVec<Msb0, u8>, _: ()) -> Result<(), DekuError> {
+            fn write(&self, output: &mut BitVec<u8, Msb0>, _: ()) -> Result<(), DekuError> {
                 <$typ>::write(self, output, Endian::default())
             }
         }
@@ -541,7 +540,7 @@ mod tests {
                 let (_rest, res_read) = <$typ>::read(bit_slice, ENDIAN).unwrap();
                 assert_eq!($expected, res_read);
 
-                let mut res_write = bitvec![Msb0, u8;];
+                let mut res_write = bitvec![u8, Msb0;];
                 res_read.write(&mut res_write, ENDIAN).unwrap();
                 assert_eq!(input, res_write.into_vec());
             }
@@ -633,23 +632,23 @@ mod tests {
     );
 
     #[rstest(input, endian, bit_size, expected, expected_rest,
-        case::normal([0xDD, 0xCC, 0xBB, 0xAA].as_ref(), Endian::Little, Some(32), 0xAABB_CCDD, bits![Msb0, u8;]),
-        case::normal_bits_12_le([0b1001_0110, 0b1110_0000, 0xCC, 0xDD ].as_ref(), Endian::Little, Some(12), 0b1110_1001_0110, bits![Msb0, u8; 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1]),
-        case::normal_bits_12_be([0b1001_0110, 0b1110_0000, 0xCC, 0xDD ].as_ref(), Endian::Big, Some(12), 0b1001_0110_1110, bits![Msb0, u8; 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1]),
-        case::normal_bit_6([0b1001_0110].as_ref(), Endian::Little, Some(6), 0b1001_01, bits![Msb0, u8; 1, 0,]),
+        case::normal([0xDD, 0xCC, 0xBB, 0xAA].as_ref(), Endian::Little, Some(32), 0xAABB_CCDD, bits![u8, Msb0;]),
+        case::normal_bits_12_le([0b1001_0110, 0b1110_0000, 0xCC, 0xDD ].as_ref(), Endian::Little, Some(12), 0b1110_1001_0110, bits![u8, Msb0; 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1]),
+        case::normal_bits_12_be([0b1001_0110, 0b1110_0000, 0xCC, 0xDD ].as_ref(), Endian::Big, Some(12), 0b1001_0110_1110, bits![u8, Msb0; 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1]),
+        case::normal_bit_6([0b1001_0110].as_ref(), Endian::Little, Some(6), 0b1001_01, bits![u8, Msb0; 1, 0,]),
         #[should_panic(expected = "Incomplete(NeedSize { bits: 32 })")]
-        case::not_enough_data([].as_ref(), Endian::Little, Some(32), 0xFF, bits![Msb0, u8;]),
+        case::not_enough_data([].as_ref(), Endian::Little, Some(32), 0xFF, bits![u8, Msb0;]),
         #[should_panic(expected = "Incomplete(NeedSize { bits: 32 })")]
-        case::not_enough_data([0xAA, 0xBB].as_ref(), Endian::Little, Some(32), 0xFF, bits![Msb0, u8;]),
+        case::not_enough_data([0xAA, 0xBB].as_ref(), Endian::Little, Some(32), 0xFF, bits![u8, Msb0;]),
         #[should_panic(expected = "Parse(\"too much data: container of 32 bits cannot hold 64 bits\")")]
-        case::too_much_data([0xAA, 0xBB, 0xCC, 0xDD, 0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(64), 0xFF, bits![Msb0, u8;]),
+        case::too_much_data([0xAA, 0xBB, 0xCC, 0xDD, 0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(64), 0xFF, bits![u8, Msb0;]),
     )]
     fn test_bit_read(
         input: &[u8],
         endian: Endian,
         bit_size: Option<usize>,
         expected: u32,
-        expected_rest: &BitSlice<Msb0, u8>,
+        expected_rest: &BitSlice<u8, Msb0>,
     ) {
         let bit_slice = input.view_bits::<Msb0>();
 
@@ -671,7 +670,7 @@ mod tests {
         case::bit_size_le_bigger(0x03AB, Endian::Little, Some(100), vec![0xAB, 0b11_000000]),
     )]
     fn test_bit_write(input: u32, endian: Endian, bit_size: Option<usize>, expected: Vec<u8>) {
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         match bit_size {
             Some(bit_size) => input
                 .write(&mut res_write, (endian, BitSize(bit_size)))
@@ -682,14 +681,14 @@ mod tests {
     }
 
     #[rstest(input, endian, bit_size, expected, expected_rest, expected_write,
-        case::normal([0xDD, 0xCC, 0xBB, 0xAA].as_ref(), Endian::Little, Some(32), 0xAABB_CCDD, bits![Msb0, u8;], vec![0xDD, 0xCC, 0xBB, 0xAA]),
+        case::normal([0xDD, 0xCC, 0xBB, 0xAA].as_ref(), Endian::Little, Some(32), 0xAABB_CCDD, bits![u8, Msb0;], vec![0xDD, 0xCC, 0xBB, 0xAA]),
     )]
     fn test_bit_read_write(
         input: &[u8],
         endian: Endian,
         bit_size: Option<usize>,
         expected: u32,
-        expected_rest: &BitSlice<Msb0, u8>,
+        expected_rest: &BitSlice<u8, Msb0>,
         expected_write: Vec<u8>,
     ) {
         let bit_slice = input.view_bits::<Msb0>();
@@ -701,7 +700,7 @@ mod tests {
         assert_eq!(expected, res_read);
         assert_eq!(expected_rest, rest);
 
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         match bit_size {
             Some(bit_size) => res_read
                 .write(&mut res_write, (endian, BitSize(bit_size)))
@@ -721,7 +720,7 @@ mod tests {
                 let (rest, res_read) = <$typ>::read(bit_slice, (Endian::Little, BitSize(5))).unwrap();
 
                 assert_eq!(-11, res_read);
-                assert_eq!(bits![Msb0, u8; 0, 0, 0], rest);
+                assert_eq!(bits![u8, Msb0; 0, 0, 0], rest);
             }
         };
     }
diff --git a/src/impls/slice.rs b/src/impls/slice.rs
index e5447e3..c6b8324 100644
--- a/src/impls/slice.rs
+++ b/src/impls/slice.rs
@@ -11,10 +11,10 @@ pub use deku_derive::*;
 /// and a borrow of the latest value to have been read. It should return `true` if reading
 /// should now stop, and `false` otherwise
 fn read_slice_with_predicate<'a, Ctx: Copy, Predicate: FnMut(usize, &u8) -> bool>(
-    input: &'a BitSlice<Msb0, u8>,
+    input: &'a BitSlice<u8, Msb0>,
     ctx: Ctx,
     mut predicate: Predicate,
-) -> Result<(&'a BitSlice<Msb0, u8>, &[u8]), DekuError>
+) -> Result<(&'a BitSlice<u8, Msb0>, &[u8]), DekuError>
 where
     u8: DekuRead<'a, Ctx>,
 {
@@ -25,8 +25,8 @@ where
         let (new_rest, val) = u8::read(rest, ctx)?;
         rest = new_rest;
 
-        let read_idx = input.offset_from(rest) as usize;
-        value = input[..read_idx].as_raw_slice();
+        let read_idx = unsafe { rest.as_bitptr().offset_from(input.as_bitptr()) } as usize;
+        value = input[..read_idx].domain().region().unwrap().1;
 
         if predicate(read_idx, &val) {
             break;
@@ -55,15 +55,15 @@ where
     /// assert_eq!(&[1u8, 2, 3, 4], v)
     /// ```
     fn read(
-        input: &'a BitSlice<Msb0, u8>,
+        input: &'a BitSlice<u8, Msb0>,
         (limit, inner_ctx): (Limit<u8, Predicate>, Ctx),
-    ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError> {
+    ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError> {
         match limit {
             // Read a given count of elements
             Limit::Count(mut count) => {
                 // Handle the trivial case of reading an empty slice
                 if count == 0 {
-                    return Ok((input, &input.as_raw_slice()[..0]));
+                    return Ok((input, &input.domain().region().unwrap().1[..0]));
                 }
 
                 // Otherwise, read until we have read `count` elements
@@ -108,7 +108,7 @@ mod pre_const_generics_impl {
             where
                 $typ: DekuWrite<Ctx>,
             {
-                fn write(&self, output: &mut BitVec<Msb0, u8>, ctx: Ctx) -> Result<(), DekuError> {
+                fn write(&self, output: &mut BitVec<u8, Msb0>, ctx: Ctx) -> Result<(), DekuError> {
                     for v in *self {
                         v.write(output, ctx)?;
                     }
@@ -122,9 +122,9 @@ mod pre_const_generics_impl {
                     $typ: DekuRead<'a, Ctx>,
                 {
                     fn read(
-                        input: &'a BitSlice<Msb0, u8>,
+                        input: &'a BitSlice<u8, Msb0>,
                         ctx: Ctx,
-                    ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError>
+                    ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError>
                     where
                         Self: Sized,
                     {
@@ -144,7 +144,7 @@ mod pre_const_generics_impl {
                 where
                     $typ: DekuWrite<Ctx>,
                 {
-                    fn write(&self, output: &mut BitVec<Msb0, u8>, ctx: Ctx) -> Result<(), DekuError> {
+                    fn write(&self, output: &mut BitVec<u8, Msb0>, ctx: Ctx) -> Result<(), DekuError> {
                         for v in self {
                             v.write(output, ctx)?;
                         }
@@ -182,9 +182,9 @@ mod const_generics_impl {
         T: DekuRead<'a, Ctx>,
     {
         fn read(
-            input: &'a BitSlice<Msb0, u8>,
+            input: &'a BitSlice<u8, Msb0>,
             ctx: Ctx,
-        ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError>
+        ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError>
         where
             Self: Sized,
         {
@@ -210,7 +210,7 @@ mod const_generics_impl {
     where
         T: DekuWrite<Ctx>,
     {
-        fn write(&self, output: &mut BitVec<Msb0, u8>, ctx: Ctx) -> Result<(), DekuError> {
+        fn write(&self, output: &mut BitVec<u8, Msb0>, ctx: Ctx) -> Result<(), DekuError> {
             for v in self {
                 v.write(output, ctx)?;
             }
@@ -222,7 +222,7 @@ mod const_generics_impl {
     where
         T: DekuWrite<Ctx>,
     {
-        fn write(&self, output: &mut BitVec<Msb0, u8>, ctx: Ctx) -> Result<(), DekuError> {
+        fn write(&self, output: &mut BitVec<u8, Msb0>, ctx: Ctx) -> Result<(), DekuError> {
             for v in *self {
                 v.write(output, ctx)?;
             }
@@ -239,14 +239,14 @@ mod tests {
     use rstest::rstest;
 
     #[rstest(input,endian,expected,expected_rest,
-        case::normal_le([0xDD, 0xCC, 0xBB, 0xAA].as_ref(), Endian::Little, [0xCCDD, 0xAABB], bits![Msb0, u8;]),
-        case::normal_be([0xDD, 0xCC, 0xBB, 0xAA].as_ref(), Endian::Big, [0xDDCC, 0xBBAA], bits![Msb0, u8;]),
+        case::normal_le([0xDD, 0xCC, 0xBB, 0xAA].as_ref(), Endian::Little, [0xCCDD, 0xAABB], bits![u8, Msb0;]),
+        case::normal_be([0xDD, 0xCC, 0xBB, 0xAA].as_ref(), Endian::Big, [0xDDCC, 0xBBAA], bits![u8, Msb0;]),
     )]
     fn test_bit_read(
         input: &[u8],
         endian: Endian,
         expected: [u16; 2],
-        expected_rest: &BitSlice<Msb0, u8>,
+        expected_rest: &BitSlice<u8, Msb0>,
     ) {
         let bit_slice = input.view_bits::<Msb0>();
 
@@ -260,13 +260,13 @@ mod tests {
         case::normal_be([0xDDCC, 0xBBAA], Endian::Big, vec![0xDD, 0xCC, 0xBB, 0xAA]),
     )]
     fn test_bit_write(input: [u16; 2], endian: Endian, expected: Vec<u8>) {
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         input.write(&mut res_write, endian).unwrap();
         assert_eq!(expected, res_write.into_vec());
 
         // test &slice
         let input = input.as_ref();
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         input.write(&mut res_write, endian).unwrap();
         assert_eq!(expected, res_write.into_vec());
     }
@@ -277,20 +277,20 @@ mod tests {
             [0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66].as_ref(),
             Endian::Little,
             [[0xCCDD, 0xAABB], [0x8899, 0x6677]],
-            bits![Msb0, u8;],
+            bits![u8, Msb0;],
         ),
         case::normal_le(
             [0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66].as_ref(),
             Endian::Big,
             [[0xDDCC, 0xBBAA], [0x9988, 0x7766]],
-            bits![Msb0, u8;],
+            bits![u8, Msb0;],
         ),
     )]
     fn test_nested_array_bit_read(
         input: &[u8],
         endian: Endian,
         expected: [[u16; 2]; 2],
-        expected_rest: &BitSlice<Msb0, u8>,
+        expected_rest: &BitSlice<u8, Msb0>,
     ) {
         let bit_slice = input.view_bits::<Msb0>();
 
@@ -313,13 +313,13 @@ mod tests {
         ),
     )]
     fn test_nested_array_bit_write(input: [[u16; 2]; 2], endian: Endian, expected: Vec<u8>) {
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         input.write(&mut res_write, endian).unwrap();
         assert_eq!(expected, res_write.into_vec());
 
         // test &slice
         let input = input.as_ref();
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         input.write(&mut res_write, endian).unwrap();
         assert_eq!(expected, res_write.into_vec());
     }
diff --git a/src/impls/tuple.rs b/src/impls/tuple.rs
index 202abd5..9872c77 100644
--- a/src/impls/tuple.rs
+++ b/src/impls/tuple.rs
@@ -37,9 +37,9 @@ macro_rules! ImplDekuTupleTraits {
         impl<'a, Ctx: Copy, $($T:DekuRead<'a, Ctx>+Sized),+> DekuRead<'a, Ctx> for ($($T,)+)
         {
             fn read(
-                input: &'a BitSlice<Msb0, u8>,
+                input: &'a BitSlice<u8, Msb0>,
                 ctx: Ctx,
-            ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError>
+            ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError>
             where
                 Self: Sized,
             {
@@ -57,7 +57,7 @@ macro_rules! ImplDekuTupleTraits {
         impl<Ctx: Copy, $($T:DekuWrite<Ctx>),+> DekuWrite<Ctx> for ($($T,)+)
         {
             #[allow(non_snake_case)]
-            fn write(&self, output: &mut BitVec<Msb0, u8>, ctx: Ctx) -> Result<(), DekuError> {
+            fn write(&self, output: &mut BitVec<u8, Msb0>, ctx: Ctx) -> Result<(), DekuError> {
                 let ($(ref $T,)+) = *self;
                 $(
                     $T.write(output, ctx)?;
@@ -89,12 +89,12 @@ mod tests {
     use rstest::rstest;
 
     #[rstest(input, expected, expected_rest,
-        case::length_1([0xef, 0xbe, 0xad, 0xde].as_ref(), (native_endian!(0xdeadbeef_u32),), bits![Msb0, u8;]),
-        case::length_2([1, 0x24, 0x98, 0x82, 0].as_ref(), (true, native_endian!(0x829824_u32)), bits![Msb0, u8;]),
-        case::length_11([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].as_ref(), (0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8), bits![Msb0, u8;]),
-        case::extra_rest([1, 0x24, 0x98, 0x82, 0, 0].as_ref(), (true, native_endian!(0x829824_u32)), bits![Msb0, u8; 0, 0, 0, 0, 0, 0, 0, 0]),
+        case::length_1([0xef, 0xbe, 0xad, 0xde].as_ref(), (native_endian!(0xdeadbeef_u32),), bits![u8, Msb0;]),
+        case::length_2([1, 0x24, 0x98, 0x82, 0].as_ref(), (true, native_endian!(0x829824_u32)), bits![u8, Msb0;]),
+        case::length_11([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].as_ref(), (0u8, 1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8), bits![u8, Msb0;]),
+        case::extra_rest([1, 0x24, 0x98, 0x82, 0, 0].as_ref(), (true, native_endian!(0x829824_u32)), bits![u8, Msb0; 0, 0, 0, 0, 0, 0, 0, 0]),
     )]
-    fn test_tuple_read<'a, T>(input: &'a [u8], expected: T, expected_rest: &BitSlice<Msb0, u8>)
+    fn test_tuple_read<'a, T>(input: &'a [u8], expected: T, expected_rest: &BitSlice<u8, Msb0>)
     where
         T: DekuRead<'a> + Sized + PartialEq + Debug,
     {
@@ -113,7 +113,7 @@ mod tests {
     where
         T: DekuWrite,
     {
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         input.write(&mut res_write, ()).unwrap();
         assert_eq!(expected, res_write.into_vec());
     }
diff --git a/src/impls/unit.rs b/src/impls/unit.rs
index 0d90002..710f3d7 100644
--- a/src/impls/unit.rs
+++ b/src/impls/unit.rs
@@ -4,9 +4,9 @@ use bitvec::prelude::*;
 impl<Ctx: Copy> DekuRead<'_, Ctx> for () {
     /// NOP on read
     fn read(
-        input: &BitSlice<Msb0, u8>,
+        input: &BitSlice<u8, Msb0>,
         _inner_ctx: Ctx,
-    ) -> Result<(&BitSlice<Msb0, u8>, Self), DekuError>
+    ) -> Result<(&BitSlice<u8, Msb0>, Self), DekuError>
     where
         Self: Sized,
     {
@@ -16,7 +16,7 @@ impl<Ctx: Copy> DekuRead<'_, Ctx> for () {
 
 impl<Ctx: Copy> DekuWrite<Ctx> for () {
     /// NOP on write
-    fn write(&self, _output: &mut BitVec<Msb0, u8>, _inner_ctx: Ctx) -> Result<(), DekuError> {
+    fn write(&self, _output: &mut BitVec<u8, Msb0>, _inner_ctx: Ctx) -> Result<(), DekuError> {
         Ok(())
     }
 }
@@ -37,7 +37,7 @@ mod tests {
         assert_eq!((), res_read);
         assert_eq!(bit_slice, rest);
 
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         res_read.write(&mut res_write, ()).unwrap();
         assert_eq!(0, res_write.len());
     }
diff --git a/src/impls/vec.rs b/src/impls/vec.rs
index 61ad9f3..7f158f4 100644
--- a/src/impls/vec.rs
+++ b/src/impls/vec.rs
@@ -17,11 +17,11 @@ fn read_vec_with_predicate<
     Ctx: Copy,
     Predicate: FnMut(usize, &T) -> bool,
 >(
-    input: &'a BitSlice<Msb0, u8>,
+    input: &'a BitSlice<u8, Msb0>,
     capacity: Option<usize>,
     ctx: Ctx,
     mut predicate: Predicate,
-) -> Result<(&'a BitSlice<Msb0, u8>, Vec<T>), DekuError> {
+) -> Result<(&'a BitSlice<u8, Msb0>, Vec<T>), DekuError> {
     let mut res = capacity.map_or_else(Vec::new, Vec::with_capacity);
 
     let mut rest = input;
@@ -33,7 +33,10 @@ fn read_vec_with_predicate<
 
         // This unwrap is safe as we are pushing to the vec immediately before it,
         // so there will always be a last element
-        if predicate(input.offset_from(rest) as usize, res.last().unwrap()) {
+        if predicate(
+            unsafe { rest.as_bitptr().offset_from(input.as_bitptr()) } as usize,
+            res.last().unwrap(),
+        ) {
             break;
         }
     }
@@ -58,9 +61,9 @@ impl<'a, T: DekuRead<'a, Ctx>, Ctx: Copy, Predicate: FnMut(&T) -> bool>
     /// assert_eq!(vec![0x04030201], v)
     /// ```
     fn read(
-        input: &'a BitSlice<Msb0, u8>,
+        input: &'a BitSlice<u8, Msb0>,
         (limit, inner_ctx): (Limit<T, Predicate>, Ctx),
-    ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError>
+    ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError>
     where
         Self: Sized,
     {
@@ -108,9 +111,9 @@ impl<'a, T: DekuRead<'a>, Predicate: FnMut(&T) -> bool> DekuRead<'a, Limit<T, Pr
 {
     /// Read `T`s until the given limit from input for types which don't require context.
     fn read(
-        input: &'a BitSlice<Msb0, u8>,
+        input: &'a BitSlice<u8, Msb0>,
         limit: Limit<T, Predicate>,
-    ) -> Result<(&'a BitSlice<Msb0, u8>, Self), DekuError>
+    ) -> Result<(&'a BitSlice<u8, Msb0>, Self), DekuError>
     where
         Self: Sized,
     {
@@ -126,11 +129,11 @@ impl<T: DekuWrite<Ctx>, Ctx: Copy> DekuWrite<Ctx> for Vec<T> {
     /// # use deku::{ctx::Endian, DekuWrite};
     /// # use deku::bitvec::{Msb0, bitvec};
     /// let data = vec![1u8];
-    /// let mut output = bitvec![Msb0, u8;];
+    /// let mut output = bitvec![u8, Msb0;];
     /// data.write(&mut output, Endian::Big).unwrap();
-    /// assert_eq!(output, bitvec![Msb0, u8; 0, 0, 0, 0, 0, 0, 0, 1])
+    /// assert_eq!(output, bitvec![u8, Msb0; 0, 0, 0, 0, 0, 0, 0, 1])
     /// ```
-    fn write(&self, output: &mut BitVec<Msb0, u8>, inner_ctx: Ctx) -> Result<(), DekuError> {
+    fn write(&self, output: &mut BitVec<u8, Msb0>, inner_ctx: Ctx) -> Result<(), DekuError> {
         for v in self {
             v.write(output, inner_ctx)?;
         }
@@ -144,24 +147,24 @@ mod tests {
     use rstest::rstest;
 
     #[rstest(input,endian,bit_size,limit,expected,expected_rest,
-        case::count_0([0xAA].as_ref(), Endian::Little, Some(8), 0.into(), vec![], bits![Msb0, u8; 1, 0, 1, 0, 1, 0, 1, 0]),
-        case::count_1([0xAA, 0xBB].as_ref(), Endian::Little, Some(8), 1.into(), vec![0xAA], bits![Msb0, u8; 1, 0, 1, 1, 1, 0, 1, 1]),
-        case::count_2([0xAA, 0xBB, 0xCC].as_ref(), Endian::Little, Some(8), 2.into(), vec![0xAA, 0xBB], bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0]),
-        case::until_null([0xAA, 0, 0xBB].as_ref(), Endian::Little, None, (|v: &u8| *v == 0u8).into(), vec![0xAA, 0], bits![Msb0, u8; 1, 0, 1, 1, 1, 0, 1, 1]),
-        case::until_bits([0xAA, 0xBB].as_ref(), Endian::Little, None, BitSize(8).into(), vec![0xAA], bits![Msb0, u8; 1, 0, 1, 1, 1, 0, 1, 1]),
-        case::bits_6([0b0110_1001, 0b1110_1001].as_ref(), Endian::Little, Some(6), 2.into(), vec![0b00_011010, 0b00_011110], bits![Msb0, u8; 1, 0, 0, 1]),
+        case::count_0([0xAA].as_ref(), Endian::Little, Some(8), 0.into(), vec![], bits![u8, Msb0; 1, 0, 1, 0, 1, 0, 1, 0]),
+        case::count_1([0xAA, 0xBB].as_ref(), Endian::Little, Some(8), 1.into(), vec![0xAA], bits![u8, Msb0; 1, 0, 1, 1, 1, 0, 1, 1]),
+        case::count_2([0xAA, 0xBB, 0xCC].as_ref(), Endian::Little, Some(8), 2.into(), vec![0xAA, 0xBB], bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0]),
+        case::until_null([0xAA, 0, 0xBB].as_ref(), Endian::Little, None, (|v: &u8| *v == 0u8).into(), vec![0xAA, 0], bits![u8, Msb0; 1, 0, 1, 1, 1, 0, 1, 1]),
+        case::until_bits([0xAA, 0xBB].as_ref(), Endian::Little, None, BitSize(8).into(), vec![0xAA], bits![u8, Msb0; 1, 0, 1, 1, 1, 0, 1, 1]),
+        case::bits_6([0b0110_1001, 0b1110_1001].as_ref(), Endian::Little, Some(6), 2.into(), vec![0b00_011010, 0b00_011110], bits![u8, Msb0; 1, 0, 0, 1]),
         #[should_panic(expected = "Parse(\"too much data: container of 8 bits cannot hold 9 bits\")")]
-        case::not_enough_data([].as_ref(), Endian::Little, Some(9), 1.into(), vec![], bits![Msb0, u8;]),
+        case::not_enough_data([].as_ref(), Endian::Little, Some(9), 1.into(), vec![], bits![u8, Msb0;]),
         #[should_panic(expected = "Parse(\"too much data: container of 8 bits cannot hold 9 bits\")")]
-        case::not_enough_data([0xAA].as_ref(), Endian::Little, Some(9), 1.into(), vec![], bits![Msb0, u8;]),
+        case::not_enough_data([0xAA].as_ref(), Endian::Little, Some(9), 1.into(), vec![], bits![u8, Msb0;]),
         #[should_panic(expected = "Incomplete(NeedSize { bits: 8 })")]
-        case::not_enough_data([0xAA].as_ref(), Endian::Little, Some(8), 2.into(), vec![], bits![Msb0, u8;]),
+        case::not_enough_data([0xAA].as_ref(), Endian::Little, Some(8), 2.into(), vec![], bits![u8, Msb0;]),
         #[should_panic(expected = "Incomplete(NeedSize { bits: 8 })")]
-        case::not_enough_data_until([0xAA].as_ref(), Endian::Little, Some(8), (|_: &u8| false).into(), vec![], bits![Msb0, u8;]),
+        case::not_enough_data_until([0xAA].as_ref(), Endian::Little, Some(8), (|_: &u8| false).into(), vec![], bits![u8, Msb0;]),
         #[should_panic(expected = "Incomplete(NeedSize { bits: 8 })")]
-        case::not_enough_data_bits([0xAA].as_ref(), Endian::Little, Some(8), (BitSize(16)).into(), vec![], bits![Msb0, u8;]),
+        case::not_enough_data_bits([0xAA].as_ref(), Endian::Little, Some(8), (BitSize(16)).into(), vec![], bits![u8, Msb0;]),
         #[should_panic(expected = "Parse(\"too much data: container of 8 bits cannot hold 9 bits\")")]
-        case::too_much_data([0xAA, 0xBB].as_ref(), Endian::Little, Some(9), 1.into(), vec![], bits![Msb0, u8;]),
+        case::too_much_data([0xAA, 0xBB].as_ref(), Endian::Little, Some(9), 1.into(), vec![], bits![u8, Msb0;]),
     )]
     fn test_vec_read<Predicate: FnMut(&u8) -> bool>(
         input: &[u8],
@@ -169,7 +172,7 @@ mod tests {
         bit_size: Option<usize>,
         limit: Limit<u8, Predicate>,
         expected: Vec<u8>,
-        expected_rest: &BitSlice<Msb0, u8>,
+        expected_rest: &BitSlice<u8, Msb0>,
     ) {
         let bit_slice = input.view_bits::<Msb0>();
 
@@ -188,19 +191,19 @@ mod tests {
         case::normal(vec![0xAABB, 0xCCDD], Endian::Little, vec![0xBB, 0xAA, 0xDD, 0xCC]),
     )]
     fn test_vec_write(input: Vec<u16>, endian: Endian, expected: Vec<u8>) {
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         input.write(&mut res_write, endian).unwrap();
         assert_eq!(expected, res_write.into_vec());
     }
 
     // Note: These tests also exist in boxed.rs
     #[rstest(input, endian, bit_size, limit, expected, expected_rest, expected_write,
-        case::normal_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), 2.into(), vec![0xBBAA, 0xDDCC], bits![Msb0, u8;], vec![0xAA, 0xBB, 0xCC, 0xDD]),
-        case::normal_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), 2.into(), vec![0xAABB, 0xCCDD], bits![Msb0, u8;], vec![0xAA, 0xBB, 0xCC, 0xDD]),
-        case::predicate_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), (|v: &u16| *v == 0xBBAA).into(), vec![0xBBAA], bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
-        case::predicate_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), (|v: &u16| *v == 0xAABB).into(), vec![0xAABB], bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
-        case::bytes_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), BitSize(16).into(), vec![0xBBAA], bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
-        case::bytes_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), BitSize(16).into(), vec![0xAABB], bits![Msb0, u8; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
+        case::normal_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), 2.into(), vec![0xBBAA, 0xDDCC], bits![u8, Msb0;], vec![0xAA, 0xBB, 0xCC, 0xDD]),
+        case::normal_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), 2.into(), vec![0xAABB, 0xCCDD], bits![u8, Msb0;], vec![0xAA, 0xBB, 0xCC, 0xDD]),
+        case::predicate_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), (|v: &u16| *v == 0xBBAA).into(), vec![0xBBAA], bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
+        case::predicate_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), (|v: &u16| *v == 0xAABB).into(), vec![0xAABB], bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
+        case::bytes_le([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Little, Some(16), BitSize(16).into(), vec![0xBBAA], bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
+        case::bytes_be([0xAA, 0xBB, 0xCC, 0xDD].as_ref(), Endian::Big, Some(16), BitSize(16).into(), vec![0xAABB], bits![u8, Msb0; 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], vec![0xAA, 0xBB]),
     )]
     fn test_vec_read_write<Predicate: FnMut(&u16) -> bool>(
         input: &[u8],
@@ -208,7 +211,7 @@ mod tests {
         bit_size: Option<usize>,
         limit: Limit<u16, Predicate>,
         expected: Vec<u16>,
-        expected_rest: &BitSlice<Msb0, u8>,
+        expected_rest: &BitSlice<u8, Msb0>,
         expected_write: Vec<u8>,
     ) {
         let bit_slice = input.view_bits::<Msb0>();
@@ -221,7 +224,7 @@ mod tests {
         assert_eq!(expected, res_read);
         assert_eq!(expected_rest, rest);
 
-        let mut res_write = bitvec![Msb0, u8;];
+        let mut res_write = bitvec![u8, Msb0;];
         res_read
             .write(&mut res_write, (endian, BitSize(bit_size)))
             .unwrap();
diff --git a/src/lib.rs b/src/lib.rs
index e83c23e..a2210e1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -237,9 +237,9 @@ These are provided as a convenience to the user.
 Always included:
 - `deku::input: (&[u8], usize)` - The initial input byte slice and bit offset
 (available when using [from_bytes](crate::DekuContainerRead::from_bytes))
-- `deku::input_bits: &BitSlice<Msb0, u8>` - The initial input in bits
-- `deku::rest: &BitSlice<Msb0, u8>` - Remaining bits to read
-- `deku::output: &mut BitSlice<Msb0, u8>` - The output bit stream
+- `deku::input_bits: &BitSlice<u8, Msb0>` - The initial input in bits
+- `deku::rest: &BitSlice<u8, Msb0>` - Remaining bits to read
+- `deku::output: &mut BitSlice<u8, Msb0>` - The output bit stream
 
 Conditionally included if referenced:
 - `deku::bit_offset: usize` - Current bit offset from the input
@@ -293,9 +293,9 @@ pub trait DekuRead<'a, Ctx = ()> {
     ///
     /// Returns the remaining bits after parsing in addition to Self.
     fn read(
-        input: &'a bitvec::BitSlice<bitvec::Msb0, u8>,
+        input: &'a bitvec::BitSlice<u8, bitvec::Msb0>,
         ctx: Ctx,
-    ) -> Result<(&'a bitvec::BitSlice<bitvec::Msb0, u8>, Self), DekuError>
+    ) -> Result<(&'a bitvec::BitSlice<u8, bitvec::Msb0>, Self), DekuError>
     where
         Self: Sized;
 }
@@ -320,7 +320,7 @@ pub trait DekuWrite<Ctx = ()> {
     /// needed.
     fn write(
         &self,
-        output: &mut bitvec::BitVec<bitvec::Msb0, u8>,
+        output: &mut bitvec::BitVec<u8, bitvec::Msb0>,
         ctx: Ctx,
     ) -> Result<(), DekuError>;
 }
@@ -332,7 +332,7 @@ pub trait DekuContainerWrite: DekuWrite<()> {
     fn to_bytes(&self) -> Result<Vec<u8>, DekuError>;
 
     /// Write struct/enum to BitVec
-    fn to_bits(&self) -> Result<bitvec::BitVec<bitvec::Msb0, u8>, DekuError>;
+    fn to_bits(&self) -> Result<bitvec::BitVec<u8, bitvec::Msb0>, DekuError>;
 }
 
 /// "Updater" trait: apply mutations to a type
@@ -356,7 +356,7 @@ where
     /// Write value of type to bits
     fn write(
         &self,
-        output: &mut bitvec::BitVec<bitvec::Msb0, u8>,
+        output: &mut bitvec::BitVec<u8, bitvec::Msb0>,
         ctx: Ctx,
     ) -> Result<(), DekuError> {
         <T>::write(self, output, ctx)?;


Test patch:
diff --git a/tests/test_attributes/test_ctx.rs b/tests/test_attributes/test_ctx.rs
index 1d06899..9b2d3ed 100644
--- a/tests/test_attributes/test_ctx.rs
+++ b/tests/test_attributes/test_ctx.rs
@@ -64,7 +64,7 @@ fn test_top_level_ctx_enum() {
     assert!(rest.is_empty());
     assert_eq!(ret_read, TopLevelCtxEnum::VariantA(0x06));
 
-    let mut ret_write = bitvec![Msb0, u8;];
+    let mut ret_write = bitvec![u8, Msb0;];
     ret_read.write(&mut ret_write, (1, 2)).unwrap();
     assert_eq!(ret_write.into_vec(), &test_data[..]);
 }
@@ -97,7 +97,7 @@ fn test_top_level_ctx_enum_default() {
     let (rest, ret_read) = TopLevelCtxEnumDefault::read(test_data.view_bits(), (1, 2)).unwrap();
     assert!(rest.is_empty());
     assert_eq!(ret_read, TopLevelCtxEnumDefault::VariantA(0x06));
-    let mut ret_write = bitvec![Msb0, u8;];
+    let mut ret_write = bitvec![u8, Msb0;];
     ret_read.write(&mut ret_write, (1, 2)).unwrap();
     assert_eq!(test_data.to_vec(), ret_write.into_vec());
 }
@@ -165,7 +165,7 @@ fn test_ctx_default_struct() {
     let (rest, ret_read) = TopLevelCtxStructDefault::read(test_data.view_bits(), (1, 2)).unwrap();
     assert!(rest.is_empty());
     assert_eq!(expected, ret_read);
-    let mut ret_write = bitvec![Msb0, u8;];
+    let mut ret_write = bitvec![u8, Msb0;];
     ret_read.write(&mut ret_write, (1, 2)).unwrap();
     assert_eq!(test_data.to_vec(), ret_write.into_vec());
 }
diff --git a/tests/test_compile/cases/internal_variables.rs b/tests/test_compile/cases/internal_variables.rs
index 1d04e2a..5a78923 100644
--- a/tests/test_compile/cases/internal_variables.rs
+++ b/tests/test_compile/cases/internal_variables.rs
@@ -52,8 +52,8 @@ struct TestMap {
 
 fn dummy_reader(
     offset: usize,
-    rest: &BitSlice<Msb0, u8>,
-) -> Result<(&BitSlice<Msb0, u8>, usize), DekuError> {
+    rest: &BitSlice<u8, Msb0>,
+) -> Result<(&BitSlice<u8, Msb0>, usize), DekuError> {
     Ok((rest, offset))
 }
 #[derive(DekuRead, DekuWrite)]
@@ -76,7 +76,7 @@ struct TestCtx {
 
 fn dummy_writer(
     _offset: usize,
-    _output: &mut BitVec<Msb0, u8>,
+    _output: &mut BitVec<u8, Msb0>,
 ) -> Result<(), DekuError> {
     Ok(())
 }