generic-array-0.12.0/.gitignore 0000644 0000000 0000000 00000000223 13247141140 0014472 0 ustar 00 0000000 0000000 # Compiled files
*.o
*.so
*.rlib
*.dll
.vscode
# Executables
*.exe
# Generated by Cargo
/target/
# We don't pin yet
Cargo.lock
generic-array-0.12.0/.travis.yml 0000644 0000000 0000000 00000002342 13143623722 0014625 0 ustar 00 0000000 0000000 language: rust
script:
- cd $TRAVIS_BUILD_DIR
- cargo build
- cargo test
- cargo build --features serde
- cargo test --features serde
after_success: |-
[ $TRAVIS_BRANCH = master ] &&
[ $TRAVIS_PULL_REQUEST = false ] &&
cargo doc &&
echo "" > target/doc/index.html &&
sudo pip install ghp-import &&
ghp-import -n target/doc &&
git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
env:
global:
secure: te+DVowxg7YWHJHKRE2eEKEg5lK8IwK4aeKZ6rsDMaTcQFzP+jzSYJiodVuDMXy45sfDMCnkWmVmpfXFI5tCLBSqTDXXOZ0UpE2f4fI0d3inH6McEoXNM43HNZqvEWj6Uc4PzTSzkywcAhg39I08PRbp5zzdj+UhB0Ty++Twwjpipr2KQMNmu9RZEwPtbyjqE69yXkDWy1oM3o51uPnpK0RUH+ZE+B0StTG6CMzVY3gW+kQX96Ow+LYkhgn/YjfubVvKO7QHz8Nd1hOxg78tn1ZTHIazN7p3bJejpsZoU92cNCcx1xM0vV/rXNN1pLxzJOBxNC9tU9FNJAaLsg5kAVGZi8Xvu62nUmkpzki71/nilHBAUxJHGIyv0H52p4DyITEN8NzR5WkqN4qBv814Dpvna1Ua3TPqiYWP/LBb+xM27DuPHKuOifePNWehE84qhQMPgArQyiNCgfKaKbaiFO+J4jiUfEV/1aztuEFyHftLoRYstmHfMkhwYHfSf683QGjlqqoL3SFClp1sKAp8WO5b5ZasT9fOGaqPWi8g28/ZGIu67wocT/hJvXxwozAycsXV36JVHs1ab/ujRYMUbcnObx8E5taKLKhWn2jYWsrJ99bUag7F6wTz1erG0eboScTD8QgVY7Zfvz0Eh1MfePOhEJGZfETR80BypC9fZhY=
generic-array-0.12.0/Cargo.toml.orig 0000644 0000000 0000000 00000001476 13337663063 0015421 0 ustar 00 0000000 0000000 [package]
name = "generic-array"
version = "0.12.0"
authors = [ "Bartłomiej Kamiński ", "Aaron Trent " ]
description = "Generic types implementing functionality of arrays"
readme = "README.md"
license = "MIT"
documentation = "http://fizyk20.github.io/generic-array/generic_array/"
repository = "https://github.com/fizyk20/generic-array.git"
keywords = ["generic", "array"]
categories = ["data-structures", "no-std"]
[badges]
travis-ci = { repository = "fizyk20/generic-array" }
[lib]
name = "generic_array"
[dependencies]
typenum = "1.10"
serde = { version = "1.0", optional = true, default-features = false }
[dev_dependencies]
# this can't yet be made optional, see https://github.com/rust-lang/cargo/issues/1596
serde_json = "1.0"
bincode = "1.0" generic-array-0.12.0/Cargo.toml 0000644 00000002373 00000000000 0011706 0 ustar 00 # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "generic-array"
version = "0.12.0"
authors = ["Bartłomiej Kamiński ", "Aaron Trent "]
description = "Generic types implementing functionality of arrays"
documentation = "http://fizyk20.github.io/generic-array/generic_array/"
readme = "README.md"
keywords = ["generic", "array"]
categories = ["data-structures", "no-std"]
license = "MIT"
repository = "https://github.com/fizyk20/generic-array.git"
[lib]
name = "generic_array"
[dependencies.serde]
version = "1.0"
optional = true
default-features = false
[dependencies.typenum]
version = "1.10"
[dev-dependencies.bincode]
version = "1.0"
[dev-dependencies.serde_json]
version = "1.0"
[badges.travis-ci]
repository = "fizyk20/generic-array"
generic-array-0.12.0/CHANGELOG.md 0000644 0000000 0000000 00000004241 13337662765 0014344 0 ustar 00 0000000 0000000 * **`0.12.0`**
* Allow trailing commas in `arr!` macro.
* **BREAKING**: Serialize `GenericArray` using `serde` tuples, instead of variable-length sequences. This may not be compatible with old serialized data.
* **`0.11.0`**
* **BREAKING** Redesign `GenericSequence` with an emphasis on use in generic type parameters.
* Add `MappedGenericSequence` and `FunctionalSequence`
* Implements optimized `map`, `zip` and `fold` for `GenericArray`, `&GenericArray` and `&mut GenericArray`
* **BREAKING** Remove `map_ref`, `zip_ref` and `map_slice`
* `map_slice` is now equivalent to `GenericArray::from_iter(slice.iter().map(...))`
* **`0.10.0`**
* Add `GenericSequence`, `Lengthen`, `Shorten`, `Split` and `Concat` traits.
* Redefine `transmute` to avert errors.
* **`0.9.0`**
* Rewrite construction methods to be well-defined in panic situations, correctly dropping elements.
* `NoDrop` crate replaced by `ManuallyDrop` as it became stable in Rust core.
* Add optimized `map`/`map_ref` and `zip`/`zip_ref` methods to `GenericArray`
* **`0.8.0`**
* Implement `AsRef`, `AsMut`, `Borrow`, `BorrowMut`, `Hash` for `GenericArray`
* Update `serde` to `1.0`
* Update `typenum`
* Make macro `arr!` non-cloning
* Implement `From<[T; N]>` up to `N=32`
* Fix #45
* **`0.7.0`**
* Upgrade `serde` to `0.9`
* Make `serde` with `no_std`
* Implement `PartialOrd`/`Ord` for `GenericArray`
* **`0.6.0`**
* Fixed #30
* Implement `Default` for `GenericArray`
* Implement `LowerHex` and `UpperHex` for `GenericArray`
* Use `precision` formatting field in hex representation
* Add `as_slice`, `as_mut_slice`
* Remove `GenericArray::new` in favor of `Default` trait
* Add `from_slice` and `from_mut_slice`
* `no_std` and `core` for crate.
* **`0.5.0`**
* Update `serde`
* remove `no_std` feature, fixed #19
* **`0.4.0`**
* Re-export `typenum`
* **`0.3.0`**
* Implement `IntoIter` for `GenericArray`
* Add `map` method
* Add optional `serde` (de)serialization support feature.
* **`< 0.3.0`**
* Initial implementation in late 2015
generic-array-0.12.0/LICENSE 0000644 0000000 0000000 00000002123 13143623722 0013516 0 ustar 00 0000000 0000000 The MIT License (MIT)
Copyright (c) 2015 Bartłomiej Kamiński
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. generic-array-0.12.0/README.md 0000644 0000000 0000000 00000002275 13161227172 0013777 0 ustar 00 0000000 0000000 [](https://crates.io/crates/generic-array)
[](https://travis-ci.org/fizyk20/generic-array)
# generic-array
This crate implements generic array types for Rust.
[Documentation](http://fizyk20.github.io/generic-array/generic_array/)
## Usage
The Rust arrays `[T; N]` are problematic in that they can't be used generically with respect to `N`, so for example this won't work:
```rust
struct Foo {
data: [i32; N]
}
```
**generic-array** defines a new trait `ArrayLength` and a struct `GenericArray>`, which let the above be implemented as:
```rust
struct Foo> {
data: GenericArray
}
```
To actually define a type implementing `ArrayLength`, you can use unsigned integer types defined in [typenum](https://github.com/paholg/typenum) crate - for example, `GenericArray` would work almost like `[T; 5]` :)
In version 0.1.1 an `arr!` macro was introduced, allowing for creation of arrays as shown below:
```rust
let array = arr![u32; 1, 2, 3];
assert_eq!(array[2], 3);
```
generic-array-0.12.0/rustfmt.toml 0000644 0000000 0000000 00000000121 13310755421 0015104 0 ustar 00 0000000 0000000 reorder_imports = true
reorder_imported_names = true
use_try_shorthand = true
generic-array-0.12.0/src/arr.rs 0000644 0000000 0000000 00000003427 13337662001 0014440 0 ustar 00 0000000 0000000 //! Implementation for `arr!` macro.
use super::ArrayLength;
use core::ops::Add;
use typenum::U1;
/// Helper trait for `arr!` macro
pub trait AddLength>: ArrayLength {
/// Resulting length
type Output: ArrayLength;
}
impl AddLength for N1
where
N1: ArrayLength + Add,
N2: ArrayLength,
>::Output: ArrayLength,
{
type Output = >::Output;
}
/// Helper type for `arr!` macro
pub type Inc = >::Output;
#[doc(hidden)]
#[macro_export]
macro_rules! arr_impl {
($T:ty; $N:ty, [$($x:expr),*], []) => ({
unsafe { $crate::transmute::<_, $crate::GenericArray<$T, $N>>([$($x),*]) }
});
($T:ty; $N:ty, [], [$x1:expr]) => (
arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1 as $T], [])
);
($T:ty; $N:ty, [], [$x1:expr, $($x:expr),+]) => (
arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1 as $T], [$($x),+])
);
($T:ty; $N:ty, [$($y:expr),+], [$x1:expr]) => (
arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),+, $x1 as $T], [])
);
($T:ty; $N:ty, [$($y:expr),+], [$x1:expr, $($x:expr),+]) => (
arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),+, $x1 as $T], [$($x),+])
);
}
/// Macro allowing for easy generation of Generic Arrays.
/// Example: `let test = arr![u32; 1, 2, 3];`
#[macro_export]
macro_rules! arr {
($T:ty; $(,)*) => ({
unsafe { $crate::transmute::<[$T; 0], $crate::GenericArray<$T, $crate::typenum::U0>>([]) }
});
($T:ty; $($x:expr),* $(,)*) => (
arr_impl!($T; $crate::typenum::U0, [], [$($x),*])
);
($($x:expr,)+) => (arr![$($x),*]);
() => ("""Macro requires a type, e.g. `let array = arr![u32; 1, 2, 3];`")
}
generic-array-0.12.0/src/functional.rs 0000644 0000000 0000000 00000006557 13260762455 0016036 0 ustar 00 0000000 0000000 //! Functional programming with generic sequences
//!
//! Please see `tests/generics.rs` for examples of how to best use these in your generic functions.
use super::ArrayLength;
use core::iter::FromIterator;
use sequence::*;
/// Defines the relationship between one generic sequence and another,
/// for operations such as `map` and `zip`.
pub unsafe trait MappedGenericSequence: GenericSequence
where
Self::Length: ArrayLength,
{
/// Mapped sequence type
type Mapped: GenericSequence;
}
unsafe impl<'a, T, U, S: MappedGenericSequence> MappedGenericSequence for &'a S
where
&'a S: GenericSequence,
S: GenericSequence>::Length>,
>::Length: ArrayLength,
{
type Mapped = >::Mapped;
}
unsafe impl<'a, T, U, S: MappedGenericSequence> MappedGenericSequence for &'a mut S
where
&'a mut S: GenericSequence,
S: GenericSequence>::Length>,
>::Length: ArrayLength,
{
type Mapped = >::Mapped;
}
/// Accessor type for a mapped generic sequence
pub type MappedSequence =
<>::Mapped as GenericSequence>::Sequence;
/// Defines functional programming methods for generic sequences
pub unsafe trait FunctionalSequence: GenericSequence {
/// Maps a `GenericSequence` to another `GenericSequence`.
///
/// If the mapping function panics, any already initialized elements in the new sequence
/// will be dropped, AND any unused elements in the source sequence will also be dropped.
fn map(self, f: F) -> MappedSequence
where
Self: MappedGenericSequence,
Self::Length: ArrayLength,
F: FnMut(Self::Item) -> U,
{
FromIterator::from_iter(self.into_iter().map(f))
}
/// Combines two `GenericSequence` instances and iterates through both of them,
/// initializing a new `GenericSequence` with the result of the zipped mapping function.
///
/// If the mapping function panics, any already initialized elements in the new sequence
/// will be dropped, AND any unused elements in the source sequences will also be dropped.
#[inline]
fn zip(self, rhs: Rhs, f: F) -> MappedSequence
where
Self: MappedGenericSequence,
Rhs: MappedGenericSequence>,
Self::Length: ArrayLength + ArrayLength,
Rhs: GenericSequence,
F: FnMut(Self::Item, Rhs::Item) -> U,
{
rhs.inverted_zip2(self, f)
}
/// Folds (or reduces) a sequence of data into a single value.
///
/// If the fold function panics, any unused elements will be dropped.
fn fold(self, init: U, f: F) -> U
where
F: FnMut(U, Self::Item) -> U,
{
self.into_iter().fold(init, f)
}
}
unsafe impl<'a, T, S: GenericSequence> FunctionalSequence for &'a S
where
&'a S: GenericSequence,
{
}
unsafe impl<'a, T, S: GenericSequence> FunctionalSequence for &'a mut S
where
&'a mut S: GenericSequence,
{
}
generic-array-0.12.0/src/hex.rs 0000644 0000000 0000000 00000007247 13260762455 0014455 0 ustar 00 0000000 0000000 //! Generic array are commonly used as a return value for hash digests, so
//! it's a good idea to allow to hexlify them easily. This module implements
//! `std::fmt::LowerHex` and `std::fmt::UpperHex` traits.
//!
//! Example:
//!
//! ```rust
//! # #[macro_use]
//! # extern crate generic_array;
//! # extern crate typenum;
//! # fn main() {
//! let array = arr![u8; 10, 20, 30];
//! assert_eq!(format!("{:x}", array), "0a141e");
//! # }
//! ```
//!
use {ArrayLength, GenericArray};
use core::cmp::min;
use core::fmt;
use core::ops::Add;
use core::str;
use typenum::*;
static LOWER_CHARS: &'static [u8] = b"0123456789abcdef";
static UPPER_CHARS: &'static [u8] = b"0123456789ABCDEF";
impl> fmt::LowerHex for GenericArray
where
T: Add,
>::Output: ArrayLength,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let max_digits = f.precision().unwrap_or_else(|| self.len() * 2);
let max_hex = (max_digits >> 1) + (max_digits & 1);
if T::to_usize() < 1024 {
// For small arrays use a stack allocated
// buffer of 2x number of bytes
let mut res = GenericArray::>::default();
for (i, c) in self.iter().take(max_hex).enumerate() {
res[i * 2] = LOWER_CHARS[(c >> 4) as usize];
res[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize];
}
f.write_str(unsafe { str::from_utf8_unchecked(&res[..max_digits]) })?;
} else {
// For large array use chunks of up to 1024 bytes (2048 hex chars)
let mut buf = [0u8; 2048];
let mut digits_left = max_digits;
for chunk in self[..max_hex].chunks(1024) {
for (i, c) in chunk.iter().enumerate() {
buf[i * 2] = LOWER_CHARS[(c >> 4) as usize];
buf[i * 2 + 1] = LOWER_CHARS[(c & 0xF) as usize];
}
let n = min(chunk.len() * 2, digits_left);
f.write_str(unsafe { str::from_utf8_unchecked(&buf[..n]) })?;
digits_left -= n;
}
}
Ok(())
}
}
impl> fmt::UpperHex for GenericArray
where
T: Add,
>::Output: ArrayLength,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let max_digits = f.precision().unwrap_or_else(|| self.len() * 2);
let max_hex = (max_digits >> 1) + (max_digits & 1);
if T::to_usize() < 1024 {
// For small arrays use a stack allocated
// buffer of 2x number of bytes
let mut res = GenericArray::>::default();
for (i, c) in self.iter().take(max_hex).enumerate() {
res[i * 2] = UPPER_CHARS[(c >> 4) as usize];
res[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize];
}
f.write_str(unsafe { str::from_utf8_unchecked(&res[..max_digits]) })?;
} else {
// For large array use chunks of up to 1024 bytes (2048 hex chars)
let mut buf = [0u8; 2048];
let mut digits_left = max_digits;
for chunk in self[..max_hex].chunks(1024) {
for (i, c) in chunk.iter().enumerate() {
buf[i * 2] = UPPER_CHARS[(c >> 4) as usize];
buf[i * 2 + 1] = UPPER_CHARS[(c & 0xF) as usize];
}
let n = min(chunk.len() * 2, digits_left);
f.write_str(unsafe { str::from_utf8_unchecked(&buf[..n]) })?;
digits_left -= n;
}
}
Ok(())
}
}
generic-array-0.12.0/src/impl_serde.rs 0000644 0000000 0000000 00000005451 13337662001 0015776 0 ustar 00 0000000 0000000 //! Serde serialization/deserialization implementation
use core::fmt;
use core::marker::PhantomData;
use serde::de::{self, SeqAccess, Visitor};
use serde::{ser::SerializeTuple, Deserialize, Deserializer, Serialize, Serializer};
use {ArrayLength, GenericArray};
impl Serialize for GenericArray
where
T: Serialize,
N: ArrayLength,
{
#[inline]
fn serialize(&self, serializer: S) -> Result
where
S: Serializer,
{
let mut tup = serializer.serialize_tuple(N::to_usize())?;
for el in self {
tup.serialize_element(el)?;
}
tup.end()
}
}
struct GAVisitor {
_t: PhantomData,
_n: PhantomData,
}
impl<'de, T, N> Visitor<'de> for GAVisitor
where
T: Deserialize<'de> + Default,
N: ArrayLength,
{
type Value = GenericArray;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("struct GenericArray")
}
fn visit_seq(self, mut seq: A) -> Result, A::Error>
where
A: SeqAccess<'de>,
{
let mut result = GenericArray::default();
for i in 0..N::to_usize() {
result[i] = seq
.next_element()?
.ok_or_else(|| de::Error::invalid_length(i, &self))?;
}
Ok(result)
}
}
impl<'de, T, N> Deserialize<'de> for GenericArray
where
T: Deserialize<'de> + Default,
N: ArrayLength,
{
fn deserialize(deserializer: D) -> Result, D::Error>
where
D: Deserializer<'de>,
{
let visitor = GAVisitor {
_t: PhantomData,
_n: PhantomData,
};
deserializer.deserialize_tuple(N::to_usize(), visitor)
}
}
#[cfg(test)]
mod tests {
use super::*;
use bincode;
use typenum;
#[test]
fn test_serialize() {
let array = GenericArray::::default();
let serialized = bincode::serialize(&array);
assert!(serialized.is_ok());
}
#[test]
fn test_deserialize() {
let mut array = GenericArray::::default();
array[0] = 1;
array[1] = 2;
let serialized = bincode::serialize(&array).unwrap();
let deserialized = bincode::deserialize::>(&array);
assert!(deserialized.is_ok());
let array = deserialized.unwrap();
assert_eq!(array[0], 1);
assert_eq!(array[1], 2);
}
#[test]
fn test_serialized_size() {
let array = GenericArray::::default();
let size = bincode::serialized_size(&array).unwrap();
assert_eq!(size, 1);
}
}
generic-array-0.12.0/src/impls.rs 0000644 0000000 0000000 00000007127 13260762455 0015012 0 ustar 00 0000000 0000000 use super::{ArrayLength, GenericArray};
use core::borrow::{Borrow, BorrowMut};
use core::cmp::Ordering;
use core::fmt::{self, Debug};
use core::hash::{Hash, Hasher};
use functional::*;
use sequence::*;
impl Default for GenericArray
where
N: ArrayLength,
{
#[inline]
fn default() -> Self {
Self::generate(|_| T::default())
}
}
impl Clone for GenericArray
where
N: ArrayLength,
{
fn clone(&self) -> GenericArray {
self.map(|x| x.clone())
}
}
impl Copy for GenericArray
where
N: ArrayLength,
N::ArrayType: Copy,
{
}
impl PartialEq for GenericArray
where
N: ArrayLength,
{
fn eq(&self, other: &Self) -> bool {
**self == **other
}
}
impl Eq for GenericArray
where
N: ArrayLength,
{
}
impl PartialOrd for GenericArray
where
N: ArrayLength,
{
fn partial_cmp(&self, other: &GenericArray) -> Option {
PartialOrd::partial_cmp(self.as_slice(), other.as_slice())
}
}
impl Ord for GenericArray
where
N: ArrayLength,
{
fn cmp(&self, other: &GenericArray) -> Ordering {
Ord::cmp(self.as_slice(), other.as_slice())
}
}
impl Debug for GenericArray
where
N: ArrayLength,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
self[..].fmt(fmt)
}
}
impl Borrow<[T]> for GenericArray
where
N: ArrayLength,
{
fn borrow(&self) -> &[T] {
&self[..]
}
}
impl BorrowMut<[T]> for GenericArray
where
N: ArrayLength,
{
fn borrow_mut(&mut self) -> &mut [T] {
&mut self[..]
}
}
impl AsRef<[T]> for GenericArray
where
N: ArrayLength,
{
fn as_ref(&self) -> &[T] {
&self[..]
}
}
impl AsMut<[T]> for GenericArray
where
N: ArrayLength,
{
fn as_mut(&mut self) -> &mut [T] {
&mut self[..]
}
}
impl Hash for GenericArray
where
N: ArrayLength,
{
fn hash(&self, state: &mut H)
where
H: Hasher,
{
Hash::hash(&self[..], state)
}
}
macro_rules! impl_from {
($($n: expr => $ty: ty),*) => {
$(
impl From<[T; $n]> for GenericArray {
fn from(arr: [T; $n]) -> Self {
use core::mem::{forget, transmute_copy};
let x = unsafe { transmute_copy(&arr) };
forget(arr);
x
}
}
)*
}
}
impl_from! {
1 => ::typenum::U1,
2 => ::typenum::U2,
3 => ::typenum::U3,
4 => ::typenum::U4,
5 => ::typenum::U5,
6 => ::typenum::U6,
7 => ::typenum::U7,
8 => ::typenum::U8,
9 => ::typenum::U9,
10 => ::typenum::U10,
11 => ::typenum::U11,
12 => ::typenum::U12,
13 => ::typenum::U13,
14 => ::typenum::U14,
15 => ::typenum::U15,
16 => ::typenum::U16,
17 => ::typenum::U17,
18 => ::typenum::U18,
19 => ::typenum::U19,
20 => ::typenum::U20,
21 => ::typenum::U21,
22 => ::typenum::U22,
23 => ::typenum::U23,
24 => ::typenum::U24,
25 => ::typenum::U25,
26 => ::typenum::U26,
27 => ::typenum::U27,
28 => ::typenum::U28,
29 => ::typenum::U29,
30 => ::typenum::U30,
31 => ::typenum::U31,
32 => ::typenum::U32
}
generic-array-0.12.0/src/iter.rs 0000644 0000000 0000000 00000011045 13260762455 0014623 0 ustar 00 0000000 0000000 //! `GenericArray` iterator implementation.
use super::{ArrayLength, GenericArray};
use core::{cmp, ptr, fmt, mem};
use core::mem::ManuallyDrop;
/// An iterator that moves out of a `GenericArray`
pub struct GenericArrayIter> {
// Invariants: index <= index_back <= N
// Only values in array[index..index_back] are alive at any given time.
// Values from array[..index] and array[index_back..] are already moved/dropped.
array: ManuallyDrop>,
index: usize,
index_back: usize,
}
#[cfg(test)]
mod test {
use super::*;
fn send(_iter: I) {}
#[test]
fn test_send_iter() {
send(GenericArray::from([1, 2, 3, 4]).into_iter());
}
}
impl GenericArrayIter
where
N: ArrayLength,
{
/// Returns the remaining items of this iterator as a slice
#[inline]
pub fn as_slice(&self) -> &[T] {
&self.array.as_slice()[self.index..self.index_back]
}
/// Returns the remaining items of this iterator as a mutable slice
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [T] {
&mut self.array.as_mut_slice()[self.index..self.index_back]
}
}
impl IntoIterator for GenericArray
where
N: ArrayLength,
{
type Item = T;
type IntoIter = GenericArrayIter;
fn into_iter(self) -> Self::IntoIter {
GenericArrayIter {
array: ManuallyDrop::new(self),
index: 0,
index_back: N::to_usize(),
}
}
}
// Based on work in rust-lang/rust#49000
impl fmt::Debug for GenericArrayIter
where
N: ArrayLength,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("GenericArrayIter")
.field(&self.as_slice())
.finish()
}
}
impl Drop for GenericArrayIter
where
N: ArrayLength,
{
#[inline]
fn drop(&mut self) {
// Drop values that are still alive.
for p in self.as_mut_slice() {
unsafe {
ptr::drop_in_place(p);
}
}
}
}
// Based on work in rust-lang/rust#49000
impl Clone for GenericArrayIter
where
N: ArrayLength,
{
fn clone(&self) -> Self {
// This places all cloned elements at the start of the new array iterator,
// not at their original indices.
unsafe {
let mut iter = GenericArrayIter {
array: ManuallyDrop::new(mem::uninitialized()),
index: 0,
index_back: 0,
};
for (dst, src) in iter.array.iter_mut().zip(self.as_slice()) {
ptr::write(dst, src.clone());
iter.index_back += 1;
}
iter
}
}
}
impl Iterator for GenericArrayIter
where
N: ArrayLength,
{
type Item = T;
#[inline]
fn next(&mut self) -> Option {
if self.index < self.index_back {
let p = unsafe { Some(ptr::read(self.array.get_unchecked(self.index))) };
self.index += 1;
p
} else {
None
}
}
#[inline]
fn size_hint(&self) -> (usize, Option) {
let len = self.len();
(len, Some(len))
}
#[inline]
fn count(self) -> usize {
self.len()
}
fn nth(&mut self, n: usize) -> Option {
// First consume values prior to the nth.
let ndrop = cmp::min(n, self.len());
for p in &mut self.array[self.index..self.index + ndrop] {
self.index += 1;
unsafe {
ptr::drop_in_place(p);
}
}
self.next()
}
fn last(mut self) -> Option {
// Note, everything else will correctly drop first as `self` leaves scope.
self.next_back()
}
}
impl DoubleEndedIterator for GenericArrayIter
where
N: ArrayLength,
{
fn next_back(&mut self) -> Option {
if self.index < self.index_back {
self.index_back -= 1;
unsafe { Some(ptr::read(self.array.get_unchecked(self.index_back))) }
} else {
None
}
}
}
impl ExactSizeIterator for GenericArrayIter
where
N: ArrayLength,
{
fn len(&self) -> usize {
self.index_back - self.index
}
}
// TODO: Implement `FusedIterator` and `TrustedLen` when stabilized generic-array-0.12.0/src/lib.rs 0000644 0000000 0000000 00000042070 13337662001 0014417 0 ustar 00 0000000 0000000 //! This crate implements a structure that can be used as a generic array type.use
//! Core Rust array types `[T; N]` can't be used generically with
//! respect to `N`, so for example this:
//!
//! ```{should_fail}
//! struct Foo {
//! data: [T; N]
//! }
//! ```
//!
//! won't work.
//!
//! **generic-array** exports a `GenericArray` type, which lets
//! the above be implemented as:
//!
//! ```
//! # use generic_array::{ArrayLength, GenericArray};
//! struct Foo> {
//! data: GenericArray
//! }
//! ```
//!
//! The `ArrayLength` trait is implemented by default for
//! [unsigned integer types](../typenum/uint/index.html) from
//! [typenum](../typenum/index.html).
//!
//! For ease of use, an `arr!` macro is provided - example below:
//!
//! ```
//! # #[macro_use]
//! # extern crate generic_array;
//! # extern crate typenum;
//! # fn main() {
//! let array = arr![u32; 1, 2, 3];
//! assert_eq!(array[2], 3);
//! # }
//! ```
#![deny(missing_docs)]
#![no_std]
#[cfg(feature = "serde")]
extern crate serde;
#[cfg(test)]
extern crate bincode;
pub extern crate typenum;
mod hex;
mod impls;
#[cfg(feature = "serde")]
pub mod impl_serde;
use core::iter::FromIterator;
use core::marker::PhantomData;
use core::mem::ManuallyDrop;
use core::ops::{Deref, DerefMut};
use core::{mem, ptr, slice};
use typenum::bit::{B0, B1};
use typenum::uint::{UInt, UTerm, Unsigned};
#[cfg_attr(test, macro_use)]
pub mod arr;
pub mod functional;
pub mod iter;
pub mod sequence;
use functional::*;
pub use iter::GenericArrayIter;
use sequence::*;
/// Trait making `GenericArray` work, marking types to be used as length of an array
pub unsafe trait ArrayLength: Unsigned {
/// Associated type representing the array type for the number
type ArrayType;
}
unsafe impl ArrayLength for UTerm {
#[doc(hidden)]
type ArrayType = ();
}
/// Internal type used to generate a struct of appropriate size
#[allow(dead_code)]
#[repr(C)]
#[doc(hidden)]
pub struct GenericArrayImplEven {
parent1: U,
parent2: U,
_marker: PhantomData,
}
impl Clone for GenericArrayImplEven {
fn clone(&self) -> GenericArrayImplEven {
GenericArrayImplEven {
parent1: self.parent1.clone(),
parent2: self.parent2.clone(),
_marker: PhantomData,
}
}
}
impl Copy for GenericArrayImplEven {}
/// Internal type used to generate a struct of appropriate size
#[allow(dead_code)]
#[repr(C)]
#[doc(hidden)]
pub struct GenericArrayImplOdd {
parent1: U,
parent2: U,
data: T,
}
impl Clone for GenericArrayImplOdd {
fn clone(&self) -> GenericArrayImplOdd {
GenericArrayImplOdd {
parent1: self.parent1.clone(),
parent2: self.parent2.clone(),
data: self.data.clone(),
}
}
}
impl Copy for GenericArrayImplOdd {}
unsafe impl> ArrayLength for UInt {
#[doc(hidden)]
type ArrayType = GenericArrayImplEven;
}
unsafe impl> ArrayLength for UInt {
#[doc(hidden)]
type ArrayType = GenericArrayImplOdd;
}
/// Struct representing a generic array - `GenericArray` works like [T; N]
#[allow(dead_code)]
pub struct GenericArray> {
data: U::ArrayType,
}
unsafe impl> Send for GenericArray {}
unsafe impl> Sync for GenericArray {}
impl Deref for GenericArray
where
N: ArrayLength,
{
type Target = [T];
fn deref(&self) -> &[T] {
unsafe { slice::from_raw_parts(self as *const Self as *const T, N::to_usize()) }
}
}
impl DerefMut for GenericArray
where
N: ArrayLength,
{
fn deref_mut(&mut self) -> &mut [T] {
unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut T, N::to_usize()) }
}
}
/// Creates an array one element at a time using a mutable iterator
/// you can write to with `ptr::write`.
///
/// Incremenent the position while iterating to mark off created elements,
/// which will be dropped if `into_inner` is not called.
#[doc(hidden)]
pub struct ArrayBuilder> {
array: ManuallyDrop>,
position: usize,
}
impl> ArrayBuilder {
#[doc(hidden)]
#[inline]
pub unsafe fn new() -> ArrayBuilder {
ArrayBuilder {
array: ManuallyDrop::new(mem::uninitialized()),
position: 0,
}
}
/// Creates a mutable iterator for writing to the array using `ptr::write`.
///
/// Increment the position value given as a mutable reference as you iterate
/// to mark how many elements have been created.
#[doc(hidden)]
#[inline]
pub unsafe fn iter_position(&mut self) -> (slice::IterMut, &mut usize) {
(self.array.iter_mut(), &mut self.position)
}
/// When done writing (assuming all elements have been written to),
/// get the inner array.
#[doc(hidden)]
#[inline]
pub unsafe fn into_inner(self) -> GenericArray {
let array = ptr::read(&self.array);
mem::forget(self);
ManuallyDrop::into_inner(array)
}
}
impl> Drop for ArrayBuilder {
fn drop(&mut self) {
for value in &mut self.array[..self.position] {
unsafe {
ptr::drop_in_place(value);
}
}
}
}
/// Consumes an array.
///
/// Increment the position while iterating and any leftover elements
/// will be dropped if position does not go to N
#[doc(hidden)]
pub struct ArrayConsumer> {
array: ManuallyDrop>,
position: usize,
}
impl> ArrayConsumer {
#[doc(hidden)]
#[inline]
pub unsafe fn new(array: GenericArray) -> ArrayConsumer {
ArrayConsumer {
array: ManuallyDrop::new(array),
position: 0,
}
}
/// Creates an iterator and mutable reference to the internal position
/// to keep track of consumed elements.
///
/// Increment the position as you iterate to mark off consumed elements
#[doc(hidden)]
#[inline]
pub unsafe fn iter_position(&mut self) -> (slice::Iter, &mut usize) {
(self.array.iter(), &mut self.position)
}
}
impl> Drop for ArrayConsumer {
fn drop(&mut self) {
for value in &mut self.array[self.position..N::to_usize()] {
unsafe {
ptr::drop_in_place(value);
}
}
}
}
impl<'a, T: 'a, N> IntoIterator for &'a GenericArray
where
N: ArrayLength,
{
type IntoIter = slice::Iter<'a, T>;
type Item = &'a T;
fn into_iter(self: &'a GenericArray) -> Self::IntoIter {
self.as_slice().iter()
}
}
impl<'a, T: 'a, N> IntoIterator for &'a mut GenericArray
where
N: ArrayLength,
{
type IntoIter = slice::IterMut<'a, T>;
type Item = &'a mut T;
fn into_iter(self: &'a mut GenericArray) -> Self::IntoIter {
self.as_mut_slice().iter_mut()
}
}
impl FromIterator for GenericArray
where
N: ArrayLength,
{
fn from_iter(iter: I) -> GenericArray
where
I: IntoIterator- ,
{
unsafe {
let mut destination = ArrayBuilder::new();
{
let (destination_iter, position) = destination.iter_position();
for (src, dst) in iter.into_iter().zip(destination_iter) {
ptr::write(dst, src);
*position += 1;
}
}
if destination.position < N::to_usize() {
from_iter_length_fail(destination.position, N::to_usize());
}
destination.into_inner()
}
}
}
#[inline(never)]
#[cold]
fn from_iter_length_fail(length: usize, expected: usize) -> ! {
panic!(
"GenericArray::from_iter received {} elements but expected {}",
length, expected
);
}
unsafe impl GenericSequence for GenericArray
where
N: ArrayLength,
Self: IntoIterator
- ,
{
type Length = N;
type Sequence = Self;
fn generate