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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
use std::fmt::{self, Debug, Formatter};
use std::iter::FromIterator;
use std::ops::{Add, AddAssign};
use std::rc::Rc;
use super::Value;
/// Create a new [`Array`] from values.
#[macro_export]
macro_rules! array {
($value:expr; $count:expr) => {
$crate::eval::Array::from_vec(vec![$crate::eval::Value::from($value); $count])
};
($($value:expr),* $(,)?) => {
$crate::eval::Array::from_vec(vec![$($crate::eval::Value::from($value)),*])
};
}
/// A variably-typed array with clone-on-write value semantics.
#[derive(Clone, PartialEq)]
pub struct Array {
vec: Rc<Vec<Value>>,
}
impl Array {
/// Create a new, empty array.
pub fn new() -> Self {
Self { vec: Rc::new(vec![]) }
}
/// Create a new array from a vector of values.
pub fn from_vec(vec: Vec<Value>) -> Self {
Self { vec: Rc::new(vec) }
}
/// Create a new, empty array with the given `capacity`.
pub fn with_capacity(capacity: usize) -> Self {
Self {
vec: Rc::new(Vec::with_capacity(capacity)),
}
}
/// Whether the array is empty.
pub fn is_empty(&self) -> bool {
self.len() == 0
}
/// The length of the array.
pub fn len(&self) -> usize {
self.vec.len()
}
/// Borrow the value at the given index.
pub fn get(&self, index: usize) -> Option<&Value> {
self.vec.get(index)
}
/// Mutably borrow the value at the given index.
pub fn get_mut(&mut self, index: usize) -> Option<&mut Value> {
Rc::make_mut(&mut self.vec).get_mut(index)
}
/// Set the value at the given index.
///
/// This panics the `index` is out of range.
pub fn set(&mut self, index: usize, value: Value) {
Rc::make_mut(&mut self.vec)[index] = value;
}
/// Push a value to the end of the array.
pub fn push(&mut self, value: Value) {
Rc::make_mut(&mut self.vec).push(value);
}
/// Extend the array with the values from another array.
pub fn extend(&mut self, other: &Array) {
Rc::make_mut(&mut self.vec).extend(other.into_iter())
}
/// Clear the array.
pub fn clear(&mut self) {
if Rc::strong_count(&mut self.vec) == 1 {
Rc::make_mut(&mut self.vec).clear();
} else {
*self = Self::new();
}
}
/// Repeat this array `n` times.
pub fn repeat(&self, n: usize) -> Self {
let len = self.len().checked_mul(n).expect("capacity overflow");
self.into_iter().cycle().take(len).collect()
}
/// Iterate over references to the contained values.
pub fn iter(&self) -> std::slice::Iter<Value> {
self.vec.iter()
}
/// Iterate over the contained values.
pub fn into_iter(&self) -> impl Iterator<Item = Value> + Clone + '_ {
// TODO: Actually consume the vector if the ref-count is 1?
self.iter().cloned()
}
}
impl Default for Array {
fn default() -> Self {
Self::new()
}
}
impl Debug for Array {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.debug_list().entries(self.vec.iter()).finish()
}
}
impl FromIterator<Value> for Array {
fn from_iter<T: IntoIterator<Item = Value>>(iter: T) -> Self {
Array { vec: Rc::new(iter.into_iter().collect()) }
}
}
impl<'a> IntoIterator for &'a Array {
type Item = &'a Value;
type IntoIter = std::slice::Iter<'a, Value>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl Add<&Array> for Array {
type Output = Self;
fn add(mut self, rhs: &Array) -> Self::Output {
self.extend(rhs);
self
}
}
impl AddAssign<&Array> for Array {
fn add_assign(&mut self, rhs: &Array) {
self.extend(rhs);
}
}
|