Merge pull request #6 from Lokathor/v1.0.1-updates

V1.0.1 updates
This commit is contained in:
Lokathor 2019-11-26 14:34:44 -07:00 committed by GitHub
commit 0628dab084
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 181 additions and 129 deletions

View File

@ -4,7 +4,7 @@ git:
quiet: true
rust:
- 1.38.0
- 1.34.0
- stable
- beta
- nightly
@ -30,23 +30,23 @@ matrix:
# If we wanted to flag on --release mode we'd add a line like this
#- { os: linux, rust: 1.38.0, env: FLAGS=--release }
- { os: linux, rust: 1.38.0, env: TARGET=wasm32-unknown-unknown }
- { os: linux, rust: 1.38.0, env: TARGET=wasm32-wasi }
- { os: linux, rust: 1.34.0, env: TARGET=wasm32-unknown-unknown }
#- { os: linux, rust: 1.34.0, env: TARGET=wasm32-wasi }
- { os: linux, rust: 1.38.0, env: TARGET=aarch64-linux-android }
- { os: linux, rust: 1.38.0, env: TARGET=armv7-linux-androideabi }
- { os: linux, rust: 1.38.0, env: TARGET=i686-linux-android }
- { os: linux, rust: 1.38.0, env: TARGET=x86_64-linux-android }
- { os: linux, rust: 1.34.0, env: TARGET=aarch64-linux-android }
- { os: linux, rust: 1.34.0, env: TARGET=armv7-linux-androideabi }
- { os: linux, rust: 1.34.0, env: TARGET=i686-linux-android }
- { os: linux, rust: 1.34.0, env: TARGET=x86_64-linux-android }
- { os: linux, rust: 1.38.0, env: TARGET=arm-unknown-linux-gnueabihf }
- { os: linux, rust: 1.38.0, env: TARGET=armv7-unknown-linux-gnueabihf }
- { os: linux, rust: 1.38.0, env: TARGET=thumbv7neon-unknown-linux-gnueabihf }
- { os: linux, rust: 1.34.0, env: TARGET=arm-unknown-linux-gnueabihf }
- { os: linux, rust: 1.34.0, env: TARGET=armv7-unknown-linux-gnueabihf }
- { os: linux, rust: 1.34.0, env: TARGET=thumbv7neon-unknown-linux-gnueabihf }
- { os: osx, rust: 1.38.0, env: TARGET=aarch64-apple-ios }
- { os: osx, rust: 1.38.0, env: TARGET=armv7-apple-ios }
- { os: osx, rust: 1.38.0, env: TARGET=armv7s-apple-ios }
- { os: osx, rust: 1.38.0, env: TARGET=i386-apple-ios }
- { os: osx, rust: 1.38.0, env: TARGET=x86_64-apple-ios }
- { os: osx, rust: 1.34.0, env: TARGET=aarch64-apple-ios }
- { os: osx, rust: 1.34.0, env: TARGET=armv7-apple-ios }
- { os: osx, rust: 1.34.0, env: TARGET=armv7s-apple-ios }
- { os: osx, rust: 1.34.0, env: TARGET=i386-apple-ios }
- { os: osx, rust: 1.34.0, env: TARGET=x86_64-apple-ios }
script:
- pushd scripts

View File

@ -8,7 +8,7 @@ readme = "README.md"
keywords = ["transmute", "bytes", "casting"]
categories = ["encoding", "no-std"]
edition = "2018"
license = "BlueOak-1.0.0"
license = "Zlib"
[package.metadata.docs.rs]
all-features = true

View File

@ -1,55 +0,0 @@
# Blue Oak Model License
Version 1.0.0
## Purpose
This license gives everyone as much permission to work with
this software as possible, while protecting contributors
from liability.
## Acceptance
In order to receive this license, you must agree to its
rules. The rules of this license are both obligations
under that agreement and conditions to your license.
You must not do anything with this software that triggers
a rule that you cannot or will not follow.
## Copyright
Each contributor licenses you to do everything with this
software that would otherwise infringe that contributor's
copyright in it.
## Notices
You must ensure that everyone who gets a copy of
any part of this software from you, with or without
changes, also gets the text of this license or a link to
<https://blueoakcouncil.org/license/1.0.0>.
## Excuse
If anyone notifies you in writing that you have not
complied with [Notices](#notices), you can keep your
license by taking all practical steps to comply within 30
days after the notice. If you do not do so, your license
ends immediately.
## Patent
Each contributor licenses you to do everything with this
software that would otherwise infringe any patent claims
they can license or become able to license.
## Reliability
No contributor can revoke this license.
## No Liability
***As far as the law allows, this software comes as is,
without any warranty or condition, and no contributor
will be liable to anyone for any damages related to this
software or this license, under any kind of legal claim.***

11
LICENSE-ZLIB.md Normal file
View File

@ -0,0 +1,11 @@
Copyright (c) 2019 Daniel "Lokathor" Gee.
This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

View File

@ -1,5 +1,5 @@
[![License:BlueOak-1.0.0](https://img.shields.io/badge/License-BlueOak_1.0.0-brightgreen.svg)](https://blueoakcouncil.org/license/1.0.0)
![Minimum Rust Version](https://img.shields.io/badge/Min%20Rust-1.38-green.svg)
[![License:Zlib](https://img.shields.io/badge/License-Zlib-brightgreen.svg)](https://opensource.org/licenses/Zlib)
![Minimum Rust Version](https://img.shields.io/badge/Min%20Rust-1.34-green.svg)
[![travis.ci](https://travis-ci.org/Lokathor/bytemuck.svg?branch=master)](https://travis-ci.org/Lokathor/bytemuck)
[![AppVeyor](https://ci.appveyor.com/api/projects/status/hgr4if0snmkmqj88/branch/master?svg=true)](https://ci.appveyor.com/project/Lokathor/bytemuck/branch/master)
[![crates.io](https://img.shields.io/crates/v/bytemuck.svg)](https://crates.io/crates/bytemuck)
@ -7,8 +7,8 @@
# bytemuck
A crate for mucking around with piles of bytes
A crate for mucking around with piles of bytes.
CI coverage:
* Tested on: `x86`, `x86_64`, `wasm`
* Built on: `armv7`, `aarch64`, `thumbv7neon`
## Stability
The goal is to stay at 1.0 until at least the next edition of Rust.

View File

@ -14,13 +14,13 @@ matrix:
environment:
matrix:
# Stable
- channel: 1.38.0
- channel: 1.34.0
target: i686-pc-windows-msvc
- channel: 1.38.0
- channel: 1.34.0
target: i686-pc-windows-gnu
- channel: 1.38.0
- channel: 1.34.0
target: x86_64-pc-windows-msvc
- channel: 1.38.0
- channel: 1.34.0
target: x86_64-pc-windows-gnu
# Beta and Nightly are checked by TravisCI since builds there run in
# parallel.
@ -42,4 +42,4 @@ test_script:
- cargo clippy
- cargo test --no-default-features
- cargo test
- cargo test --all-features
#- cargo test --all-features

7
changelog.md Normal file
View File

@ -0,0 +1,7 @@
# `bytemuck` changelog
## 1.0.1
* Changed to the [zlib](https://opensource.org/licenses/Zlib) license.
* Added much more proper documentation.
* Reduced the minimum Rust version to 1.34

View File

@ -3,5 +3,6 @@ merge_imports = true
reorder_imports = true
use_try_shorthand = true
tab_spaces = 2
max_width = 100
max_width = 80
color = "Never"
use_small_heuristics = "Max"

View File

@ -11,21 +11,21 @@ if [[ "$TARGET" == "wasm32-"* && "$TARGET" != "wasm32-wasi" ]]; then
cargo-web --version || cargo install cargo-web
cargo web test --no-default-features $FLAGS --target=$TARGET
cargo web test $FLAGS --target=$TARGET
cargo web test --all-features $FLAGS --target=$TARGET
#cargo web test --all-features $FLAGS --target=$TARGET
elif [[ "$TARGET" == *"-linux-android"* ]]; then
export PATH=/usr/local/android-sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH
pushd linux-android
cargo build --no-default-features --target=$TARGET $FLAGS
cargo build --target=$TARGET $FLAGS
cargo build --all-features --target=$TARGET $FLAGS
#cargo build --all-features --target=$TARGET $FLAGS
# Don't test, can't run android emulators successfully on travis currently
popd
elif [[ "$TARGET" == *"-apple-ios" || "$TARGET" == "wasm32-wasi" ]]; then
cargo build --no-default-features --target=$TARGET $FLAGS
cargo build --target=$TARGET $FLAGS
cargo build --all-features --target=$TARGET $FLAGS
#cargo build --all-features --target=$TARGET $FLAGS
# Don't test
# iOS simulator setup/teardown is complicated
# cargo-web doesn't support wasm32-wasi yet, nor can wasm-pack test specify a target
@ -36,7 +36,7 @@ elif [[ "$TARGET" == *"-unknown-linux-gnueabihf" ]]; then
pushd generic-cross
cargo build --no-default-features --target=$TARGET $FLAGS
cargo build --target=$TARGET $FLAGS
cargo build --all-features --target=$TARGET $FLAGS
#cargo build --all-features --target=$TARGET $FLAGS
# Don't test
popd
@ -44,12 +44,12 @@ elif [[ "$TARGET" != "" ]]; then
pushd generic-cross
cargo test --no-default-features --target=$TARGET $FLAGS
cargo test --target=$TARGET $FLAGS
cargo test --all-features --target=$TARGET $FLAGS
#cargo test --all-features --target=$TARGET $FLAGS
popd
else
# Push nothing, target host CPU architecture
cargo test --no-default-features $FLAGS
cargo test $FLAGS
cargo test --all-features $FLAGS
#cargo test --all-features $FLAGS
fi

View File

@ -1,7 +1,7 @@
//! Stuff to boost things in the `alloc` crate.
//!
//! You must use the crate with the `extern_crate_alloc` feature for the content
//! in this module to be compiled in!
//! * You must enable the `extern_crate_alloc` feature of `bytemuck` or you will
//! not be able to use this module!
use super::*;
use alloc::{
@ -26,14 +26,16 @@ pub fn cast_box<A: Pod, B: Pod>(input: Box<A>) -> Box<B> {
/// alignment.
/// * The start and end size of the `Box` must have the exact same size.
#[inline]
pub fn try_cast_box<A: Pod, B: Pod>(input: Box<A>) -> Result<Box<B>, (PodCastError, Box<A>)> {
pub fn try_cast_box<A: Pod, B: Pod>(
input: Box<A>,
) -> Result<Box<B>, (PodCastError, Box<A>)> {
if align_of::<A>() != align_of::<B>() {
Err((PodCastError::AlignmentMismatch, input))
} else if size_of::<A>() != size_of::<B>() {
Err((PodCastError::SizeMismatch, input))
} else {
// Note(Lokathor): This is much simpler than with the Vec casting!
let ptr: *mut B = Box::into_raw(input).cast::<B>();
let ptr: *mut B = Box::into_raw(input) as *mut B;
Ok(unsafe { Box::from_raw(ptr) })
}
}
@ -53,13 +55,14 @@ pub fn try_zeroed_box<T: Zeroable>() -> Result<Box<T>, ()> {
if size_of::<T>() == 0 {
return Ok(Box::new(T::zeroed()));
}
let layout = Layout::from_size_align(size_of::<T>(), align_of::<T>()).unwrap();
let layout =
Layout::from_size_align(size_of::<T>(), align_of::<T>()).unwrap();
let ptr = unsafe { alloc_zeroed(layout) };
if ptr.is_null() {
// we don't know what the error is because `alloc_zeroed` is a dumb API
Err(())
} else {
Ok(unsafe { Box::<T>::from_raw(ptr.cast::<T>()) })
Ok(unsafe { Box::<T>::from_raw(ptr as *mut T) })
}
}
@ -88,7 +91,9 @@ pub fn cast_vec<A: Pod, B: Pod>(input: Vec<A>) -> Vec<B> {
/// capacity and length get adjusted during transmutation, but for now it's
/// absolute.
#[inline]
pub fn try_cast_vec<A: Pod, B: Pod>(input: Vec<A>) -> Result<Vec<B>, (PodCastError, Vec<A>)> {
pub fn try_cast_vec<A: Pod, B: Pod>(
input: Vec<A>,
) -> Result<Vec<B>, (PodCastError, Vec<A>)> {
if align_of::<A>() != align_of::<B>() {
Err((PodCastError::AlignmentMismatch, input))
} else if size_of::<A>() != size_of::<B>() {
@ -108,7 +113,7 @@ pub fn try_cast_vec<A: Pod, B: Pod>(input: Vec<A>) -> Result<Vec<B>, (PodCastErr
// "into raw parts" method, which we can switch this too eventually.
let mut manual_drop_vec = ManuallyDrop::new(input);
let vec_ptr: *mut A = manual_drop_vec.as_mut_ptr();
let ptr: *mut B = vec_ptr.cast::<B>();
let ptr: *mut B = vec_ptr as *mut B;
Ok(unsafe { Vec::from_raw_parts(ptr, length, capacity) })
}
}

View File

@ -1,4 +1,41 @@
#![no_std]
#![warn(missing_docs)]
//! This crate gives small utilities for casting between plain data types.
//!
//! ## Basics
//!
//! Data comes in five basic forms in Rust, so we have five basic casting
//! functions:
//!
//! * `T` uses [`cast`]
//! * `&T` uses [`cast_ref`]
//! * `&mut T` uses [`cast_mut`]
//! * `&[T]` uses [`cast_slice`]
//! * `&mut [T]` uses [`cast_slice_mut`]
//!
//! Some casts will never fail (eg: `cast::<u32, f32>` always works), other
//! casts might fail (eg: `cast_ref::<[u8; 4], u32>` will fail if the reference
//! isn't already aligned to 4). Each casting function has a "try" version which
//! will return a `Result`, and the "normal" version which will simply panic on
//! invalid input.
//!
//! ## Using Your Own Types
//!
//! All the functions here are guarded by the [`Pod`] trait, which is a
//! sub-trait of the [`Zeroable`] trait.
//!
//! If you're very sure that your type is eligible, you can implement those
//! traits for your type and then they'll have full casting support. However,
//! these traits are `unsafe`, and you should carefully read the requirements
//! before adding the them to your own types.
//!
//! ## Features
//!
//! * This crate is core only by default, but if you're using Rust 1.36 or later
//! you can enable the `extern_crate_alloc` cargo feature for some additional
//! methods related to `Box` and `Vec`. Note that the `docs.rs` documentation
//! is always built with `extern_crate_alloc` cargo feature enabled.
#[cfg(target_arch = "x86")]
pub(crate) use core::arch::x86;
@ -121,7 +158,9 @@ pub fn pod_align_to<T: Pod, U: Pod>(vals: &[T]) -> (&[T], &[U], &[T]) {
/// As `align_to_mut`, but safe because of the [`Pod`] bound.
#[inline]
pub fn pod_align_to_mut<T: Pod, U: Pod>(vals: &mut [T]) -> (&mut [T], &mut [U], &mut [T]) {
pub fn pod_align_to_mut<T: Pod, U: Pod>(
vals: &mut [T],
) -> (&mut [T], &mut [U], &mut [T]) {
unsafe { vals.align_to_mut::<U>() }
}
@ -136,8 +175,8 @@ pub fn try_cast<A: Pod, B: Pod>(a: A) -> Result<B, PodCastError> {
let mut b = B::zeroed();
// Note(Lokathor): We copy in terms of `u8` because that allows us to bypass
// any potential alignment difficulties.
let ap = (&a as *const A).cast::<u8>();
let bp = (&mut b as *mut B).cast::<u8>();
let ap = &a as *const A as *const u8;
let bp = &mut b as *mut B as *mut u8;
unsafe { ap.copy_to_nonoverlapping(bp, size_of::<A>()) };
Ok(b)
} else {
@ -155,10 +194,12 @@ pub fn try_cast<A: Pod, B: Pod>(a: A) -> Result<B, PodCastError> {
pub fn try_cast_ref<A: Pod, B: Pod>(a: &A) -> Result<&B, PodCastError> {
// Note(Lokathor): everything with `align_of` and `size_of` will optimize away
// after monomorphization.
if align_of::<B>() > align_of::<A>() && (a as *const A as usize) % align_of::<B>() != 0 {
if align_of::<B>() > align_of::<A>()
&& (a as *const A as usize) % align_of::<B>() != 0
{
Err(PodCastError::TargetAlignmentGreaterAndInputNotAligned)
} else if size_of::<B>() == size_of::<A>() {
Ok(unsafe { &*(a as *const A).cast::<B>() })
Ok(unsafe { &*(a as *const A as *const B) })
} else {
Err(PodCastError::SizeMismatch)
}
@ -171,10 +212,12 @@ pub fn try_cast_ref<A: Pod, B: Pod>(a: &A) -> Result<&B, PodCastError> {
pub fn try_cast_mut<A: Pod, B: Pod>(a: &mut A) -> Result<&mut B, PodCastError> {
// Note(Lokathor): everything with `align_of` and `size_of` will optimize away
// after monomorphization.
if align_of::<B>() > align_of::<A>() && (a as *mut A as usize) % align_of::<B>() != 0 {
if align_of::<B>() > align_of::<A>()
&& (a as *mut A as usize) % align_of::<B>() != 0
{
Err(PodCastError::TargetAlignmentGreaterAndInputNotAligned)
} else if size_of::<B>() == size_of::<A>() {
Ok(unsafe { &mut *(a as *mut A).cast::<B>() })
Ok(unsafe { &mut *(a as *mut A as *mut B) })
} else {
Err(PodCastError::SizeMismatch)
}
@ -200,15 +243,17 @@ pub fn try_cast_mut<A: Pod, B: Pod>(a: &mut A) -> Result<&mut B, PodCastError> {
pub fn try_cast_slice<A: Pod, B: Pod>(a: &[A]) -> Result<&[B], PodCastError> {
// Note(Lokathor): everything with `align_of` and `size_of` will optimize away
// after monomorphization.
if align_of::<B>() > align_of::<A>() && (a.as_ptr() as usize) % align_of::<B>() != 0 {
if align_of::<B>() > align_of::<A>()
&& (a.as_ptr() as usize) % align_of::<B>() != 0
{
Err(PodCastError::TargetAlignmentGreaterAndInputNotAligned)
} else if size_of::<B>() == size_of::<A>() {
Ok(unsafe { core::slice::from_raw_parts(a.as_ptr().cast::<B>(), a.len()) })
Ok(unsafe { core::slice::from_raw_parts(a.as_ptr() as *const B, a.len()) })
} else if size_of::<A>() == 0 || size_of::<B>() == 0 {
Err(PodCastError::SizeMismatch)
} else if core::mem::size_of_val(a) % size_of::<B>() == 0 {
let new_len = core::mem::size_of_val(a) / size_of::<B>();
Ok(unsafe { core::slice::from_raw_parts(a.as_ptr().cast::<B>(), new_len) })
Ok(unsafe { core::slice::from_raw_parts(a.as_ptr() as *const B, new_len) })
} else {
Err(PodCastError::OutputSliceWouldHaveSlop)
}
@ -218,18 +263,26 @@ pub fn try_cast_slice<A: Pod, B: Pod>(a: &[A]) -> Result<&[B], PodCastError> {
///
/// As [`try_cast_slice`], but `&mut`.
#[inline]
pub fn try_cast_slice_mut<A: Pod, B: Pod>(a: &mut [A]) -> Result<&mut [B], PodCastError> {
pub fn try_cast_slice_mut<A: Pod, B: Pod>(
a: &mut [A],
) -> Result<&mut [B], PodCastError> {
// Note(Lokathor): everything with `align_of` and `size_of` will optimize away
// after monomorphization.
if align_of::<B>() > align_of::<A>() && (a.as_mut_ptr() as usize) % align_of::<B>() != 0 {
if align_of::<B>() > align_of::<A>()
&& (a.as_mut_ptr() as usize) % align_of::<B>() != 0
{
Err(PodCastError::TargetAlignmentGreaterAndInputNotAligned)
} else if size_of::<B>() == size_of::<A>() {
Ok(unsafe { core::slice::from_raw_parts_mut(a.as_mut_ptr().cast::<B>(), a.len()) })
Ok(unsafe {
core::slice::from_raw_parts_mut(a.as_mut_ptr() as *mut B, a.len())
})
} else if size_of::<A>() == 0 || size_of::<B>() == 0 {
Err(PodCastError::SizeMismatch)
} else if core::mem::size_of_val(a) % size_of::<B>() == 0 {
let new_len = core::mem::size_of_val(a) / size_of::<B>();
Ok(unsafe { core::slice::from_raw_parts_mut(a.as_mut_ptr().cast::<B>(), new_len) })
Ok(unsafe {
core::slice::from_raw_parts_mut(a.as_mut_ptr() as *mut B, new_len)
})
} else {
Err(PodCastError::OutputSliceWouldHaveSlop)
}

View File

@ -16,10 +16,14 @@ use super::*;
///
/// * The type must be inhabited (eg: no
/// [Infallible](core::convert::Infallible)).
/// * The type must allow any bit pattern (eg: no `bool` or `char`).
/// * The type must not contain any padding bytes (eg: no `(u8, u16)`).
/// * A struct needs to have all fields be `Pod` and be `repr(C)`,
/// `repr(transparent)`, or `repr(packed)`.
/// * The type must allow any bit pattern (eg: no `bool` or `char`, which have
/// illegal bit patterns).
/// * The type must not contain any padding bytes, either in the middle or on
/// the end (eg: no `#[repr(C)] struct Foo(u8, u16)`, which has padding in the
/// middle, and also no `#[repr(C)] struct Foo(u16, u8)`, which has padding on
/// the end).
/// * The type needs to have all fields also be `Pod`.
/// * The type needs to be `repr(C)`, `repr(transparent)`, or `repr(packed)`.
pub unsafe trait Pod: Zeroable + Copy + 'static {}
unsafe impl Pod for () {}
@ -58,9 +62,12 @@ unsafe impl<T: 'static> Pod for Option<NonNull<T>> {}
unsafe impl<T: Pod> Pod for PhantomData<T> {}
unsafe impl<T: Pod> Pod for ManuallyDrop<T> {}
// Note(Lokathor): MaybeUninit can NEVER be Pod.
impl_unsafe_marker_for_array!(
Pod, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 48, 64, 96, 128, 256, 512, 1024, 2048, 4096
Pod, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 48, 64, 96, 128, 256,
512, 1024, 2048, 4096
);
#[cfg(target_arch = "x86")]

View File

@ -1,10 +1,14 @@
use super::*;
/// Trait for types that can be safely created with [`zeroed`](core::mem::zeroed).
/// Trait for types that can be safely created with
/// [`zeroed`](core::mem::zeroed).
///
/// An all-zeroes value may or may not be the same value as the
/// [Default](core::default::Default) value of the type.
///
/// ## Safety
///
/// * Your type must be _inhabited_ (eg: no
/// * Your type must be inhabited (eg: no
/// [Infallible](core::convert::Infallible)).
/// * Your type must be allowed to be an "all zeroes" bit pattern (eg: no
/// [`NonNull<T>`](core::ptr::NonNull)).
@ -56,22 +60,40 @@ unsafe impl<T> Zeroable for *const T {}
unsafe impl<T> Zeroable for Option<NonNull<T>> {}
unsafe impl<T: Zeroable> Zeroable for PhantomData<T> {}
unsafe impl<T: Zeroable> Zeroable for ManuallyDrop<T> {}
unsafe impl<T> Zeroable for MaybeUninit<T> {}
// 2.0: add MaybeUninit
//unsafe impl<T> Zeroable for MaybeUninit<T> {}
unsafe impl<A: Zeroable> Zeroable for (A,) {}
unsafe impl<A: Zeroable, B: Zeroable> Zeroable for (A, B) {}
unsafe impl<A: Zeroable, B: Zeroable, C: Zeroable> Zeroable for (A, B, C) {}
unsafe impl<A: Zeroable, B: Zeroable, C: Zeroable, D: Zeroable> Zeroable for (A, B, C, D) {}
unsafe impl<A: Zeroable, B: Zeroable, C: Zeroable, D: Zeroable, E: Zeroable> Zeroable
for (A, B, C, D, E)
unsafe impl<A: Zeroable, B: Zeroable, C: Zeroable, D: Zeroable> Zeroable
for (A, B, C, D)
{
}
unsafe impl<A: Zeroable, B: Zeroable, C: Zeroable, D: Zeroable, E: Zeroable, F: Zeroable> Zeroable
for (A, B, C, D, E, F)
unsafe impl<A: Zeroable, B: Zeroable, C: Zeroable, D: Zeroable, E: Zeroable>
Zeroable for (A, B, C, D, E)
{
}
unsafe impl<A: Zeroable, B: Zeroable, C: Zeroable, D: Zeroable, E: Zeroable, F: Zeroable, G: Zeroable>
Zeroable for (A, B, C, D, E, F, G)
unsafe impl<
A: Zeroable,
B: Zeroable,
C: Zeroable,
D: Zeroable,
E: Zeroable,
F: Zeroable,
> Zeroable for (A, B, C, D, E, F)
{
}
unsafe impl<
A: Zeroable,
B: Zeroable,
C: Zeroable,
D: Zeroable,
E: Zeroable,
F: Zeroable,
G: Zeroable,
> Zeroable for (A, B, C, D, E, F, G)
{
}
unsafe impl<
@ -88,8 +110,9 @@ unsafe impl<
}
impl_unsafe_marker_for_array!(
Zeroable, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31, 32, 48, 64, 96, 128, 256, 512, 1024, 2048, 4096
Zeroable, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 48, 64, 96, 128, 256,
512, 1024, 2048, 4096
);
#[cfg(target_arch = "x86")]