| { | ||
| "git": { | ||
| "sha1": "ea591bc2de5202790c600638c96efa392413001c" | ||
| "sha1": "6905bdbb8a873c3e5c965833b56e494b26b1c816" | ||
| } | ||
| } |
+1
-1
@@ -12,2 +12,2 @@ # Compiled files | ||
| /Cargo.lock | ||
| /target/ | ||
| /target |
+6
-1
@@ -16,3 +16,3 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO | ||
| name = "arrayvec" | ||
| version = "0.5.0" | ||
| version = "0.5.1" | ||
| authors = ["bluss"] | ||
@@ -31,3 +31,8 @@ description = "A vector with fixed capacity, backed by an array (it can be stored on the stack too). Implements fixed capacity ArrayVec and ArrayString." | ||
| tag-name = "{{version}}" | ||
| [profile.bench] | ||
| debug = true | ||
| [profile.release] | ||
| debug = true | ||
| [[bench]] | ||
@@ -34,0 +39,0 @@ name = "extend" |
+19
-1
@@ -25,4 +25,22 @@ | ||
| - 0.5.0 (not released yet) | ||
| - 0.5.1 | ||
| - Add ``as_ptr``, ``as_mut_ptr`` accessors directly on the ``ArrayVec`` by @tbu- | ||
| (matches the same addition to ``Vec`` which happened in Rust 1.37). | ||
| - Add method ``ArrayString::len`` (now available directly, not just through deref to str). | ||
| - Use raw pointers instead of ``&mut [u8]`` for encoding chars into ``ArrayString`` | ||
| (uninit best practice fix). | ||
| - Use raw pointers instead of ``get_unchecked_mut`` where the target may be | ||
| uninitialized a everywhere relevant in the ArrayVec implementation | ||
| (uninit best practice fix). | ||
| - Changed inline hints on many methods, mainly removing inline hints | ||
| - ``ArrayVec::dispose`` is now deprecated (it has no purpose anymore) | ||
| - 0.4.12 | ||
| - Use raw pointers instead of ``get_unchecked_mut`` where the target may be | ||
| uninitialized a everywhere relevant in the ArrayVec implementation. | ||
| - 0.5.0 | ||
| - Use ``MaybeUninit`` (now unconditionally) in the implementation of | ||
@@ -29,0 +47,0 @@ ``ArrayVec`` |
+8
-11
@@ -70,2 +70,6 @@ use std::borrow::Borrow; | ||
| /// Return the length of the string. | ||
| #[inline] | ||
| pub fn len(&self) -> usize { self.len.to_usize() } | ||
| /// Create a new `ArrayString` from a `str`. | ||
@@ -117,3 +121,3 @@ /// | ||
| /// ``` | ||
| #[inline] | ||
| #[inline(always)] | ||
| pub fn capacity(&self) -> usize { A::CAPACITY } | ||
@@ -172,3 +176,5 @@ | ||
| unsafe { | ||
| match encode_utf8(c, &mut self.raw_mut_bytes()[len..]) { | ||
| let ptr = self.xs.ptr_mut().add(len); | ||
| let remaining_cap = self.capacity() - len; | ||
| match encode_utf8(c, ptr, remaining_cap) { | ||
| Ok(n) => { | ||
@@ -250,3 +256,2 @@ self.set_len(len + n); | ||
| /// ``` | ||
| #[inline] | ||
| pub fn pop(&mut self) -> Option<char> { | ||
@@ -280,3 +285,2 @@ let ch = match self.chars().rev().next() { | ||
| /// ``` | ||
| #[inline] | ||
| pub fn truncate(&mut self, new_len: usize) { | ||
@@ -312,3 +316,2 @@ if new_len <= self.len() { | ||
| /// ``` | ||
| #[inline] | ||
| pub fn remove(&mut self, idx: usize) -> char { | ||
@@ -345,3 +348,2 @@ let ch = match self[idx..].chars().next() { | ||
| /// and may use other debug assertions. | ||
| #[inline] | ||
| pub unsafe fn set_len(&mut self, length: usize) { | ||
@@ -356,7 +358,2 @@ debug_assert!(length <= self.capacity()); | ||
| } | ||
| /// Return a mutable slice of the whole string’s buffer | ||
| unsafe fn raw_mut_bytes(&mut self) -> &mut [u8] { | ||
| slice::from_raw_parts_mut(self.xs.ptr_mut(), self.capacity()) | ||
| } | ||
| } | ||
@@ -363,0 +360,0 @@ |
+0
-2
@@ -90,6 +90,4 @@ | ||
| #[doc(hidden)] | ||
| #[inline] | ||
| fn as_slice(&self) -> &[Self::Item] { self } | ||
| #[doc(hidden)] | ||
| #[inline] | ||
| fn as_mut_slice(&mut self) -> &mut [Self::Item] { self } | ||
@@ -96,0 +94,0 @@ } |
+59
-15
@@ -13,2 +13,4 @@ // Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT | ||
| use std::ptr; | ||
| // UTF-8 ranges and tags for encoding characters | ||
@@ -26,2 +28,7 @@ const TAG_CONT: u8 = 0b1000_0000; | ||
| #[inline] | ||
| unsafe fn write(ptr: *mut u8, index: usize, byte: u8) { | ||
| ptr::write(ptr.add(index), byte) | ||
| } | ||
| /// Encode a char into buf using UTF-8. | ||
@@ -31,23 +38,25 @@ /// | ||
| /// On error, return `EncodeUtf8Error` if the buffer was too short for the char. | ||
| /// | ||
| /// Safety: `ptr` must be writable for `len` bytes. | ||
| #[inline] | ||
| pub fn encode_utf8(ch: char, buf: &mut [u8]) -> Result<usize, EncodeUtf8Error> | ||
| pub unsafe fn encode_utf8(ch: char, ptr: *mut u8, len: usize) -> Result<usize, EncodeUtf8Error> | ||
| { | ||
| let code = ch as u32; | ||
| if code < MAX_ONE_B && buf.len() >= 1 { | ||
| buf[0] = code as u8; | ||
| if code < MAX_ONE_B && len >= 1 { | ||
| write(ptr, 0, code as u8); | ||
| return Ok(1); | ||
| } else if code < MAX_TWO_B && buf.len() >= 2 { | ||
| buf[0] = (code >> 6 & 0x1F) as u8 | TAG_TWO_B; | ||
| buf[1] = (code & 0x3F) as u8 | TAG_CONT; | ||
| } else if code < MAX_TWO_B && len >= 2 { | ||
| write(ptr, 0, (code >> 6 & 0x1F) as u8 | TAG_TWO_B); | ||
| write(ptr, 1, (code & 0x3F) as u8 | TAG_CONT); | ||
| return Ok(2); | ||
| } else if code < MAX_THREE_B && buf.len() >= 3 { | ||
| buf[0] = (code >> 12 & 0x0F) as u8 | TAG_THREE_B; | ||
| buf[1] = (code >> 6 & 0x3F) as u8 | TAG_CONT; | ||
| buf[2] = (code & 0x3F) as u8 | TAG_CONT; | ||
| } else if code < MAX_THREE_B && len >= 3 { | ||
| write(ptr, 0, (code >> 12 & 0x0F) as u8 | TAG_THREE_B); | ||
| write(ptr, 1, (code >> 6 & 0x3F) as u8 | TAG_CONT); | ||
| write(ptr, 2, (code & 0x3F) as u8 | TAG_CONT); | ||
| return Ok(3); | ||
| } else if buf.len() >= 4 { | ||
| buf[0] = (code >> 18 & 0x07) as u8 | TAG_FOUR_B; | ||
| buf[1] = (code >> 12 & 0x3F) as u8 | TAG_CONT; | ||
| buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT; | ||
| buf[3] = (code & 0x3F) as u8 | TAG_CONT; | ||
| } else if len >= 4 { | ||
| write(ptr, 0, (code >> 18 & 0x07) as u8 | TAG_FOUR_B); | ||
| write(ptr, 1, (code >> 12 & 0x3F) as u8 | TAG_CONT); | ||
| write(ptr, 2, (code >> 6 & 0x3F) as u8 | TAG_CONT); | ||
| write(ptr, 3, (code & 0x3F) as u8 | TAG_CONT); | ||
| return Ok(4); | ||
@@ -58,1 +67,36 @@ }; | ||
| #[test] | ||
| fn test_encode_utf8() { | ||
| // Test that all codepoints are encoded correctly | ||
| let mut data = [0u8; 16]; | ||
| for codepoint in 0..=(std::char::MAX as u32) { | ||
| if let Some(ch) = std::char::from_u32(codepoint) { | ||
| for elt in &mut data { *elt = 0; } | ||
| let ptr = data.as_mut_ptr(); | ||
| let len = data.len(); | ||
| unsafe { | ||
| let res = encode_utf8(ch, ptr, len).ok().unwrap(); | ||
| assert_eq!(res, ch.len_utf8()); | ||
| } | ||
| let string = std::str::from_utf8(&data).unwrap(); | ||
| assert_eq!(string.chars().next(), Some(ch)); | ||
| } | ||
| } | ||
| } | ||
| #[test] | ||
| fn test_encode_utf8_oob() { | ||
| // test that we report oob if the buffer is too short | ||
| let mut data = [0u8; 16]; | ||
| let chars = ['a', 'α', '�', '𐍈']; | ||
| for (len, &ch) in (1..=4).zip(&chars) { | ||
| assert_eq!(len, ch.len_utf8(), "Len of ch={}", ch); | ||
| let ptr = data.as_mut_ptr(); | ||
| unsafe { | ||
| assert!(matches::matches!(encode_utf8(ch, ptr, len - 1), Err(_))); | ||
| assert!(matches::matches!(encode_utf8(ch, ptr, len), Ok(_))); | ||
| } | ||
| } | ||
| } | ||
+24
-20
@@ -137,3 +137,3 @@ //! **arrayvec** provides the types `ArrayVec` and `ArrayString`: | ||
| /// ``` | ||
| #[inline] | ||
| #[inline(always)] | ||
| pub fn capacity(&self) -> usize { A::CAPACITY } | ||
@@ -239,10 +239,14 @@ | ||
| /// ``` | ||
| #[inline] | ||
| pub unsafe fn push_unchecked(&mut self, element: A::Item) { | ||
| let len = self.len(); | ||
| debug_assert!(len < A::CAPACITY); | ||
| ptr::write(self.get_unchecked_mut(len), element); | ||
| ptr::write(self.get_unchecked_ptr(len), element); | ||
| self.set_len(len + 1); | ||
| } | ||
| /// Get pointer to where element at `index` would be | ||
| unsafe fn get_unchecked_ptr(&mut self, index: usize) -> *mut A::Item { | ||
| self.xs.ptr_mut().add(index) | ||
| } | ||
| /// Insert `element` at position `index`. | ||
@@ -305,3 +309,3 @@ /// | ||
| { | ||
| let p: *mut _ = self.get_unchecked_mut(index); | ||
| let p: *mut _ = self.get_unchecked_ptr(index); | ||
| // Shift everything over to make space. (Duplicating the | ||
@@ -340,3 +344,3 @@ // `index`th element into two consecutive places.) | ||
| self.set_len(new_len); | ||
| Some(ptr::read(self.get_unchecked_mut(new_len))) | ||
| Some(ptr::read(self.get_unchecked_ptr(new_len))) | ||
| } | ||
@@ -514,3 +518,2 @@ } | ||
| /// not greater than the capacity. | ||
| #[inline] | ||
| pub unsafe fn set_len(&mut self, length: usize) { | ||
@@ -636,3 +639,4 @@ debug_assert!(length <= self.capacity()); | ||
| /// Dispose of `self` without the overwriting that is needed in Drop. | ||
| /// Dispose of `self` (same as drop) | ||
| #[deprecated="Use std::mem::drop instead, if at all needed."] | ||
| pub fn dispose(mut self) { | ||
@@ -652,2 +656,12 @@ self.clear(); | ||
| } | ||
| /// Return a raw pointer to the vector's buffer. | ||
| pub fn as_ptr(&self) -> *const A::Item { | ||
| self.xs.ptr() | ||
| } | ||
| /// Return a raw mutable pointer to the vector's buffer. | ||
| pub fn as_mut_ptr(&mut self) -> *mut A::Item { | ||
| self.xs.ptr_mut() | ||
| } | ||
| } | ||
@@ -754,3 +768,2 @@ | ||
| #[inline] | ||
| fn next(&mut self) -> Option<A::Item> { | ||
@@ -763,3 +776,3 @@ if self.index == self.v.len { | ||
| self.index = Index::from(index + 1); | ||
| Some(ptr::read(self.v.get_unchecked_mut(index))) | ||
| Some(ptr::read(self.v.get_unchecked_ptr(index))) | ||
| } | ||
@@ -776,3 +789,2 @@ } | ||
| impl<A: Array> DoubleEndedIterator for IntoIter<A> { | ||
| #[inline] | ||
| fn next_back(&mut self) -> Option<A::Item> { | ||
@@ -785,3 +797,3 @@ if self.index == self.v.len { | ||
| self.v.set_len(new_len); | ||
| Some(ptr::read(self.v.get_unchecked_mut(new_len))) | ||
| Some(ptr::read(self.v.get_unchecked_ptr(new_len))) | ||
| } | ||
@@ -802,3 +814,3 @@ } | ||
| let elements = slice::from_raw_parts_mut( | ||
| self.v.get_unchecked_mut(index), | ||
| self.v.get_unchecked_ptr(index), | ||
| len - index); | ||
@@ -856,3 +868,2 @@ ptr::drop_in_place(elements); | ||
| #[inline] | ||
| fn next(&mut self) -> Option<Self::Item> { | ||
@@ -866,3 +877,2 @@ self.iter.next().map(|elt| | ||
| #[inline] | ||
| fn size_hint(&self) -> (usize, Option<usize>) { | ||
@@ -876,3 +886,2 @@ self.iter.size_hint() | ||
| { | ||
| #[inline] | ||
| fn next_back(&mut self) -> Option<Self::Item> { | ||
@@ -1076,3 +1085,2 @@ self.iter.next_back().map(|elt| | ||
| impl<A: Array> PartialOrd for ArrayVec<A> where A::Item: PartialOrd { | ||
| #[inline] | ||
| fn partial_cmp(&self, other: &ArrayVec<A>) -> Option<cmp::Ordering> { | ||
@@ -1082,3 +1090,2 @@ (**self).partial_cmp(other) | ||
| #[inline] | ||
| fn lt(&self, other: &Self) -> bool { | ||
@@ -1088,3 +1095,2 @@ (**self).lt(other) | ||
| #[inline] | ||
| fn le(&self, other: &Self) -> bool { | ||
@@ -1094,3 +1100,2 @@ (**self).le(other) | ||
| #[inline] | ||
| fn ge(&self, other: &Self) -> bool { | ||
@@ -1100,3 +1105,2 @@ (**self).ge(other) | ||
| #[inline] | ||
| fn gt(&self, other: &Self) -> bool { | ||
@@ -1103,0 +1107,0 @@ (**self).gt(other) |
Sorry, the diff of this file is not supported yet