Skip to content

Commit

Permalink
refactor: Rename array
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmah309 committed Mar 5, 2024
1 parent 0e0ca53 commit 853c6e0
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 29 deletions.
8 changes: 4 additions & 4 deletions lib/src/array/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Array

Array is a zero cost extension type of List, where the list is treated as non-growable. This is useful for correctly handling lists where growable is false and const lists, as these types of lists are treated the same in the regular Dart type system, which may lead to errors.
`Arr` (Array) is a zero cost extension type of List, where the list is treated as non-growable. This is useful for correctly handling lists where growable is false and const lists - as these types of lists are treated the same in the regular Dart type system, which may lead to errors.
```dart
var array = Array(null, 10);
array = Array.constant(const [1,2,3,4,5]);
var array = Arr(null, 10);
array = Arr.constant(const [1,2,3,4,5]);
for(final entry in array){
// do something
}
var (slice1, slice2) = array.splitSlice(3);
```
`Array` is not a typical array compared to most other languages - a non-const array will still be on the heap, but the allocation will be more efficient since it does not reserve additional capacity. Which is important since allocations account for most of the cost of using the heap compared to the stack.
`Arr`'s allocation will be more efficient than compare to a List since it does not reserve additional capacity and allocates the full amount eagerly. Which is important since allocations account for most of the cost of the runtime costs of a List.
21 changes: 11 additions & 10 deletions lib/src/array/array.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,23 @@
import 'package:rust_core/result.dart';
import 'package:rust_core/slice.dart';

extension type Array<T>._(List<T> list) implements Iterable<T> {
/// A fixed-size array, denoted as [T; N] in Rust.
extension type Arr<T>._(List<T> list) implements Iterable<T> {

Array(T defaultVal, int size) : list = List.filled(size, defaultVal, growable: false);
Arr(T defaultVal, int size) : list = List.filled(size, defaultVal, growable: false);

const Array.constant(this.list);
const Arr.constant(this.list);

Array.fromList(this.list);
Arr.fromList(this.list);

Array.empty() : list = const [];
Arr.empty() : list = const [];

T operator [](int index) => list[index];
void operator []=(int index, T value) => list[index] = value;

int get length => list.length;

Array<U> cast<U>() => Array._(list.cast<U>());
Arr<U> cast<U>() => Arr._(list.cast<U>());

// as_ascii: Will not be implemented, not possible in Dart
// as_ascii_unchecked_mut: Will not be implemented, not possible in Dart
Expand All @@ -29,8 +30,8 @@ extension type Array<T>._(List<T> list) implements Iterable<T> {
// each_ref: Will not be implemented, not possible in Dart

/// Returns an array of the same size as self, with function f applied to each element in order.
Array<U> map<U>(U Function(T) f) {
return Array._(list.map(f).toList(growable: false));
Arr<U> map<U>(U Function(T) f) {
return Arr._(list.map(f).toList(growable: false));
}

/// Divides array into two [Slice]s at index from end.
Expand All @@ -57,7 +58,7 @@ extension type Array<T>._(List<T> list) implements Iterable<T> {
// transpose: Will not be implemented, not possible in Dart

/// A fallible function f applied to each element on this array in order to return an array the same size as this or the first error encountered.
Result<Array<S>,F> tryMap<S,F extends Object>(Result<S,F> Function(T) f) {
Result<Arr<S>,F> tryMap<S,F extends Object>(Result<S,F> Function(T) f) {
List<S?> result = List.filled(list.length, null, growable: false);
for (int i = 0; i < list.length; i++) {
var res = f(list[i]);
Expand All @@ -66,6 +67,6 @@ extension type Array<T>._(List<T> list) implements Iterable<T> {
}
result[i] = res.unwrap();
}
return Ok(Array._(result.cast<S>()));
return Ok(Arr._(result.cast<S>()));
}
}
4 changes: 2 additions & 2 deletions lib/src/array/array_extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import 'package:rust_core/array.dart';

extension ArrayOnListExtension<T> on List<T> {
/// Transmutes a List into an Array
Array<T> asArr() => Array.fromList(this);
Arr<T> asArr() => Arr.fromList(this);
}
extension ArrayOnIterableExtension<T> on Iterable<T> {
/// Creates an Array from a List
Array<T> toArr() => Array.fromList(toList(growable: false));
Arr<T> toArr() => Arr.fromList(toList(growable: false));
}
12 changes: 6 additions & 6 deletions lib/src/slice/slice.dart
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,12 @@ final class Slice<T> extends Iterable<T> {

/// Returns mutable references to many indices at once.
/// Returns an error if any index is out-of-bounds.
Result<Array<T>, GetManyError> getMany(List<int> indices){
Result<Arr<T>, GetManyError> getMany(List<int> indices){
if(indices.length > _end - _start) return const Err(GetManyError(GetManyErrorType.tooManyIndices));
if (indices.isEmpty) {
return Ok(Array.empty());
return Ok(Arr.empty());
}
var array = Array(this.first, indices.length);
var array = Arr(this.first, indices.length);
for (final (int i, int index) in indices.iter().enumerate()) {
if(index < _start || index >= _end) return const Err(GetManyError(GetManyErrorType.requestedIndexOutOfBounds));
array[i] = this[index];
Expand All @@ -175,14 +175,14 @@ final class Slice<T> extends Iterable<T> {


/// Returns mutable references to many indices at once, without doing any checks.
Array<T> getManyUnchecked(List<int> indices) {
Arr<T> getManyUnchecked(List<int> indices) {
assert(indices.length <= _end - _start,
"The number of indices must be less than or equal to the length of the slice");
if (indices.isEmpty) {
return Array.empty();
return Arr.empty();
}
assert(isNotEmpty, "Requested indices, but this slice is empty.");
var array = Array(this.first, indices.length);
var array = Arr(this.first, indices.length);
for (final (int i, int index) in indices.iter().enumerate()) {
assert(index >= _start && index < _end, "The requiested index out of bounds");
array[i] = this[index];
Expand Down
14 changes: 7 additions & 7 deletions test/array/array_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ import 'package:rust_core/array.dart';

void main() {
test("map", () {
var arr = Array(1, 3);
var arr = Arr(1, 3);
var mapped = arr.map((e) => e + 1);
expect(mapped, [2, 2, 2]);
});

test("map", () {
var arr = Array(1, 3);
var arr = Arr(1, 3);
var mapped = arr.map((e) => e + 1);
expect(mapped, [2, 2, 2]);
});

test("rsplitSlice", () {
var arr = Array(1, 3);
var arr = Arr(1, 3);
var rsplit = arr.rsplitSlice(1);
expect(rsplit.$1, [1, 1]);
expect(rsplit.$2, [1]);
Expand All @@ -32,7 +32,7 @@ void main() {
});

test("splitSlice", () {
var arr = Array(1, 3);
var arr = Arr(1, 3);
var split = arr.splitSlice(1);
expect(split.$1, [1]);
expect(split.$2, [1, 1]);
Expand All @@ -47,13 +47,13 @@ void main() {
});

test("tryMap Ok", () {
var arr = Array(1, 3);
var arr = Arr(1, 3);
var tryMap = arr.tryMap((e) => Ok(e + 1));
expect(tryMap.unwrap(), [2, 2, 2]);
});

test("tryMap Err", () {
var arr = Array(1, 3);
var arr = Arr(1, 3);
var tryMap = arr.tryMap<int, String>((e) {
if (e == 1) {
return Err("Error");
Expand All @@ -66,7 +66,7 @@ void main() {

//************************************************************************//
test("Array and List composability",(){
Array<int> arr = Array(1, 3);
Arr<int> arr = Arr(1, 3);
List<String> list = ["1", "1", "1"];
final other = arr.iter().zip(list);
RIterator<int> other2 = arr.iter();
Expand Down

0 comments on commit 853c6e0

Please sign in to comment.