Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add resize() to Vec and Bytes #6864

Merged
merged 5 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions sway-lib-std/src/bytes.sw
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,61 @@ impl Bytes {

spliced
}

/// Resizes the `Bytes` in-place so that `len` is equal to `new_len`.
///
/// # Additional Information
///
/// If `new_len` is greater than `len`, the `Bytes` is extended by the difference, with each additional slot filled with value. If `new_len` is less than `len`, the `Bytes` is simply truncated.
bitzoic marked this conversation as resolved.
Show resolved Hide resolved
///
/// # Arguments
///
/// * `new_len`: [u64] - The new length of the `Bytes`.
/// * `value`: [u8] - The value to fill the new length.
///
/// # Examples
///
/// ```sway
/// fn foo() {
/// let bytes = Bytes::new();
/// bytes.resize(1, 7u8);
/// assert(bytes.len() == 1);
/// assert(bytes.get(0).unwrap() == 7u8);
///
/// bytes.resize(2, 9u8);
/// assert(bytes.len() == 2);
/// assert(bytes.get(0).unwrap() == 7u8);
/// assert(bytes.get(1).unwrap() == 9u8);
///
/// bytes.resize(1, 0);
/// assert(bytes.len() == 1);
/// assert(bytes.get(0).unwrap() == 7u8);
/// assert(bytes.get(1) == None);
/// }
/// ```
pub fn resize(ref mut self, new_len: u64, value: u8) {
// If the length is the less, just truncate
bitzoic marked this conversation as resolved.
Show resolved Hide resolved
if self.len >= new_len {
self.len = new_len;
return;
}

// If we don't have enough capacity, alloc more
if self.buf.cap < new_len {
self.buf.ptr = realloc_bytes(self.buf.ptr, self.buf.cap, new_len);
self.buf.cap = new_len;
}

// Fill the new length with value
bitzoic marked this conversation as resolved.
Show resolved Hide resolved
let mut i = 0;
let start_ptr = self.buf.ptr.add_uint_offset(self.len);
while i + self.len < new_len {
start_ptr.add_uint_offset(i).write_byte(value);
i += 1;
}

self.len = new_len;
}
}

impl core::ops::Eq for Bytes {
Expand Down
55 changes: 55 additions & 0 deletions sway-lib-std/src/vec.sw
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,61 @@ impl<T> Vec<T> {
pub fn ptr(self) -> raw_ptr {
self.buf.ptr()
}

/// Resizes the `Vec` in-place so that `len` is equal to `new_len`.
///
/// # Additional Information
///
/// If `new_len` is greater than `len`, the `Vec` is extended by the difference, with each additional slot filled with value. If `new_len` is less than `len`, the `Vec` is simply truncated.
bitzoic marked this conversation as resolved.
Show resolved Hide resolved
///
/// # Arguments
///
/// * `new_len`: [u64] - The new length of the `Vec`.
/// * `value`: [T] - The value to fill the new length.
///
/// # Examples
///
/// ```sway
/// fn foo() {
/// let vec: Vec<u64> = Vec::new();
/// vec.resize(1, 7);
/// assert(vec.len() == 1);
/// assert(vec.get(0).unwrap() == 7);
///
/// vec.resize(2, 9);
/// assert(vec.len() == 2);
/// assert(vec.get(0).unwrap() == 7);
/// assert(vec.get(1).unwrap() == 9);
///
/// vec.resize(1, 0);
/// assert(vec.len() == 1);
/// assert(vec.get(0).unwrap() == 7);
/// assert(vec.get(1) == None);
/// }
/// ```
pub fn resize(ref mut self, new_len: u64, value: T) {
// If the length is the less, just truncate
bitzoic marked this conversation as resolved.
Show resolved Hide resolved
if self.len >= new_len {
self.len = new_len;
return;
}

// If we don't have enough capacity, alloc more
if self.buf.cap < new_len {
self.buf.ptr = realloc::<T>(self.buf.ptr, self.buf.cap, new_len);
self.buf.cap = new_len;
}

// Fill the new length with value
bitzoic marked this conversation as resolved.
Show resolved Hide resolved
let mut i = 0;
let start_ptr = self.buf.ptr.add::<T>(self.len);
while i + self.len < new_len {
start_ptr.add::<T>(i).write::<T>(value);
i += 1;
}

self.len = new_len;
}
}

impl<T> AsRawSlice for Vec<T> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,10 @@ fn b512_into_bytes() {
iter_2 += 1;
}

let b512_3 = B512::from((b256::zero() , 0x0000000000000000000000000000000000000000000000000000000000000001));
let b512_3 = B512::from((
b256::zero(),
0x0000000000000000000000000000000000000000000000000000000000000001,
));
let bytes_3: Bytes = <B512 as Into<Bytes>>::into(b512_3);
assert(bytes_3.capacity() == 64);
assert(bytes_3.len() == 64);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1078,3 +1078,67 @@ fn bytes_test_u8_limits() {
assert(bytes.get(4).unwrap() == max);
assert(bytes.get(5).unwrap() == min);
}

#[test]
fn bytes_resize() {
let (mut bytes_1, a, b, c) = setup();
assert(bytes_1.len() == 3);
assert(bytes_1.capacity() == 4);

// Resize to same size, no effect
bytes_1.resize(3, 0);
assert(bytes_1.len() == 3);
assert(bytes_1.capacity() == 4);

// Resize to capacity size doesn't impact capacity
bytes_1.resize(4, 1);
assert(bytes_1.len() == 4);
assert(bytes_1.capacity() == 4);
assert(bytes_1.get(0) == Some(5));
assert(bytes_1.get(1) == Some(7));
assert(bytes_1.get(2) == Some(9));
assert(bytes_1.get(3) == Some(1));

// Resize increases size and capacity
bytes_1.resize(10, 2);
assert(bytes_1.len() == 10);
assert(bytes_1.capacity() == 10);
assert(bytes_1.get(0) == Some(5));
assert(bytes_1.get(1) == Some(7));
assert(bytes_1.get(2) == Some(9));
assert(bytes_1.get(3) == Some(1));
assert(bytes_1.get(4) == Some(2));
assert(bytes_1.get(5) == Some(2));
assert(bytes_1.get(6) == Some(2));
assert(bytes_1.get(7) == Some(2));
assert(bytes_1.get(8) == Some(2));
assert(bytes_1.get(9) == Some(2));

// Resize to less doesn't impact capacity or order
bytes_1.resize(1, 0);
assert(bytes_1.len() == 1);
assert(bytes_1.capacity() == 10);
assert(bytes_1.get(0) == Some(5));
assert(bytes_1.get(1) == None);

// Resize to zero doesn't impact capacity and returns None
bytes_1.resize(0, 0);
assert(bytes_1.len() == 0);
assert(bytes_1.capacity() == 10);
assert(bytes_1.get(0) == None);

let mut bytes_2 = Bytes::new();

// Resize to zero on empty vec doesn't impact
bytes_2.resize(0, 0);
assert(bytes_2.len() == 0);
assert(bytes_2.capacity() == 0);

// Resize on empty vec fills and sets capacity
bytes_2.resize(3, 1);
assert(bytes_2.len() == 3);
assert(bytes_2.capacity() == 3);
assert(bytes_2.get(0) == Some(1));
assert(bytes_2.get(1) == Some(1));
assert(bytes_2.get(2) == Some(1));
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
library;

use std::{bytes::Bytes, b512::B512, crypto::{ed25519::*, public_key::*, message::*}, hash::{Hash, sha256}, vm::evm::evm_address::EvmAddress};
use std::{
b512::B512,
bytes::Bytes,
crypto::{
ed25519::*,
message::*,
public_key::*,
},
hash::{
Hash,
sha256,
},
vm::evm::evm_address::EvmAddress,
};

#[test]
fn ed25519_new() {
Expand Down Expand Up @@ -74,7 +87,10 @@ fn ed25519_from_b512() {
iter_1 += 1;
}

let b512_2 = B512::from((b256::zero(), 0x0000000000000000000000000000000000000000000000000000000000000001));
let b512_2 = B512::from((
b256::zero(),
0x0000000000000000000000000000000000000000000000000000000000000001,
));
let ed25519_2 = Ed25519::from(b512_2);
assert(ed25519_2.bits()[63] == 1u8);
let mut iter_2 = 0;
Expand All @@ -101,7 +117,10 @@ fn ed25519_from_b256_tuple() {
iter_1 += 1;
}

let ed25519_2 = Ed25519::from((b256::zero(), 0x0000000000000000000000000000000000000000000000000000000000000001));
let ed25519_2 = Ed25519::from((
b256::zero(),
0x0000000000000000000000000000000000000000000000000000000000000001,
));
assert(ed25519_2.bits()[63] == 1u8);
let mut iter_2 = 0;
while iter_2 < 63 {
Expand All @@ -120,12 +139,12 @@ fn ed25519_from_b256_tuple() {
#[test]
fn ed25519_from_u8_array() {
let array_1 = [
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
];
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8,
];
let ed25519_1 = Ed25519::from(array_1);
let mut iter_1 = 0;
while iter_1 < 64 {
Expand All @@ -134,12 +153,12 @@ fn ed25519_from_u8_array() {
}

let array_2 = [
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8,
];
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
0u8, 0u8, 0u8, 1u8,
];
let ed25519_2 = Ed25519::from(array_2);
assert(ed25519_2.bits()[63] == 1u8);
let mut iter_2 = 0;
Expand All @@ -149,12 +168,13 @@ fn ed25519_from_u8_array() {
}

let array_3 = [
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
];
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8, 255u8,
];
let ed25519_3 = Ed25519::from(array_3);
let mut iter_3 = 0;
while iter_3 < 64 {
Expand All @@ -174,7 +194,10 @@ fn ed25519_try_from_bytes() {
iter_1 += 1;
}

let b256_tuple_2 = (b256::zero(), 0x0000000000000000000000000000000000000000000000000000000000000001);
let b256_tuple_2 = (
b256::zero(),
0x0000000000000000000000000000000000000000000000000000000000000001,
);
let bytes_2 = Bytes::from(raw_slice::from_parts::<u8>(__addr_of(b256_tuple_2), 64));
let ed25519_2 = Ed25519::try_from(bytes_2).unwrap();
assert(ed25519_2.bits()[63] == 1u8);
Expand Down Expand Up @@ -211,7 +234,10 @@ fn ed25519_into_b512() {
let ed25519_1 = Ed25519::from(b512_1);
assert(<Ed25519 as Into<B512>>::into(ed25519_1) == b512_1);

let b512_2 = B512::from((b256::zero(), 0x0000000000000000000000000000000000000000000000000000000000000001));
let b512_2 = B512::from((
b256::zero(),
0x0000000000000000000000000000000000000000000000000000000000000001,
));
let ed25519_2 = Ed25519::from(b512_2);
assert(<Ed25519 as Into<B512>>::into(ed25519_2) == b512_2);

Expand All @@ -223,14 +249,19 @@ fn ed25519_into_b512() {
#[test]
fn ed25519_into_b256() {
let ed25519_1 = Ed25519::from((b256::zero(), b256::zero()));
let (result_1_1, result_2_1) = <Ed25519 as Into<(b256, b256)>>::into(ed25519_1);
let (result_1_1, result_2_1) = <Ed25519 as Into<(b256, b256)>>::into(ed25519_1);
assert(result_1_1 == b256::zero());
assert(result_2_1 == b256::zero());

let ed25519_2 = Ed25519::from((b256::zero(), 0x0000000000000000000000000000000000000000000000000000000000000001));
let ed25519_2 = Ed25519::from((
b256::zero(),
0x0000000000000000000000000000000000000000000000000000000000000001,
));
let (result_1_2, result_2_2): (b256, b256) = <Ed25519 as Into<(b256, b256)>>::into(ed25519_2);
assert(result_1_2 == b256::zero());
assert(result_2_2 == 0x0000000000000000000000000000000000000000000000000000000000000001);
assert(
result_2_2 == 0x0000000000000000000000000000000000000000000000000000000000000001,
);

let ed25519_3 = Ed25519::from((b256::max(), b256::max()));
let (result_1_3, result_2_3): (b256, b256) = <Ed25519 as Into<(b256, b256)>>::into(ed25519_3);
Expand All @@ -248,7 +279,10 @@ fn ed25519_into_bytes() {
iter_1 += 1;
}

let ed25519_2 = Ed25519::from((b256::zero(), 0x0000000000000000000000000000000000000000000000000000000000000001));
let ed25519_2 = Ed25519::from((
b256::zero(),
0x0000000000000000000000000000000000000000000000000000000000000001,
));
let bytes_result_2: Bytes = <Ed25519 as Into<Bytes>>::into(ed25519_2);
assert(bytes_result_2.get(63).unwrap() == 1u8);
let mut iter_2 = 0;
Expand All @@ -270,8 +304,14 @@ fn ed25519_into_bytes() {
fn ed25519_eq() {
let ed25519_1 = Ed25519::from((b256::zero(), b256::zero()));
let ed25519_2 = Ed25519::from((b256::zero(), b256::zero()));
let ed25519_3 = Ed25519::from((b256::zero(), 0x0000000000000000000000000000000000000000000000000000000000000001));
let ed25519_4 = Ed25519::from((b256::zero(), 0x0000000000000000000000000000000000000000000000000000000000000001));
let ed25519_3 = Ed25519::from((
b256::zero(),
0x0000000000000000000000000000000000000000000000000000000000000001,
));
let ed25519_4 = Ed25519::from((
b256::zero(),
0x0000000000000000000000000000000000000000000000000000000000000001,
));
let ed25519_5 = Ed25519::from((b256::max(), b256::max()));
let ed25519_6 = Ed25519::from((b256::max(), b256::max()));

Expand Down
Loading
Loading