1use std::any::Any;
8use std::ops::Deref;
9use std::sync::Arc;
10
11use crate::complex::Cx;
12use crate::dtype::DType;
13use crate::exact::{Ext, Rat};
14
15pub type Owner = Arc<dyn Any + Send + Sync>;
18
19pub struct Buf<T> {
30 repr: Repr<T>,
31}
32
33enum Repr<T> {
34 Owned(Arc<Vec<T>>),
36 Slice { buf: Arc<Vec<T>>, off: usize, len: usize },
41 Foreign { ptr: *const T, len: usize, owner: Owner },
42}
43
44unsafe impl<T: Send + Sync> Send for Buf<T> {}
54unsafe impl<T: Send + Sync> Sync for Buf<T> {}
56
57impl<T> Buf<T> {
58 pub fn new() -> Buf<T> {
59 Buf { repr: Repr::Owned(Arc::new(Vec::new())) }
60 }
61
62 pub fn from_vec(v: Vec<T>) -> Buf<T> {
63 Buf { repr: Repr::Owned(Arc::new(v)) }
64 }
65
66 pub unsafe fn foreign(ptr: *const T, len: usize, owner: Owner) -> Buf<T> {
74 Buf { repr: Repr::Foreign { ptr, len, owner } }
75 }
76
77 pub fn is_foreign(&self) -> bool {
79 matches!(self.repr, Repr::Foreign { .. })
80 }
81
82 pub fn owner(&self) -> Option<&Owner> {
90 match &self.repr {
91 Repr::Owned(_) | Repr::Slice { .. } => None,
92 Repr::Foreign { owner, .. } => Some(owner),
93 }
94 }
95
96 pub fn as_slice(&self) -> &[T] {
97 match &self.repr {
98 Repr::Owned(v) => v,
99 Repr::Slice { buf, off, len } => &buf[*off..*off + *len],
100 Repr::Foreign { ptr, len, .. } => {
101 if *len == 0 {
102 &[]
103 } else {
104 unsafe { std::slice::from_raw_parts(*ptr, *len) }
108 }
109 }
110 }
111 }
112}
113
114impl<T: Clone> Buf<T> {
115 pub fn to_mut(&mut self) -> &mut Vec<T> {
119 if !matches!(self.repr, Repr::Owned(_)) {
123 self.repr = Repr::Owned(Arc::new(self.as_slice().to_vec()));
124 }
125 match &mut self.repr {
126 Repr::Owned(v) => Arc::make_mut(v),
127 _ => unreachable!("just converted to a whole owned buffer"),
128 }
129 }
130
131 pub fn into_vec(self) -> Vec<T> {
134 match self.repr {
135 Repr::Owned(v) => Arc::try_unwrap(v).unwrap_or_else(|v| v.as_slice().to_vec()),
136 Repr::Slice { ref buf, off, len } => buf[off..off + len].to_vec(),
137 Repr::Foreign { .. } => self.as_slice().to_vec(),
138 }
139 }
140
141 pub fn push(&mut self, value: T) {
142 self.to_mut().push(value);
143 }
144
145 pub fn extend_from_slice(&mut self, other: &[T]) {
146 self.to_mut().extend_from_slice(other);
147 }
148
149 pub fn slice(&self, start: usize, end: usize) -> Buf<T> {
154 match &self.repr {
155 Repr::Owned(v) => {
156 assert!(start <= end && end <= v.len(), "slice out of range");
157 if start == 0 && end == v.len() {
158 return Buf { repr: Repr::Owned(Arc::clone(v)) };
159 }
160 Buf { repr: Repr::Slice { buf: Arc::clone(v), off: start, len: end - start } }
161 }
162 Repr::Slice { buf, off, len } => {
163 assert!(start <= end && end <= *len, "slice out of range");
164 let repr =
165 Repr::Slice { buf: Arc::clone(buf), off: off + start, len: end - start };
166 Buf { repr }
167 }
168 Repr::Foreign { ptr, len, owner } => {
169 assert!(start <= end && end <= *len, "slice out of range");
170 unsafe { Buf::foreign(ptr.add(start), end - start, owner.clone()) }
173 }
174 }
175 }
176}
177
178impl<T> Deref for Buf<T> {
179 type Target = [T];
180
181 fn deref(&self) -> &[T] {
182 self.as_slice()
183 }
184}
185
186impl<T: Clone> Clone for Buf<T> {
190 fn clone(&self) -> Buf<T> {
191 match &self.repr {
192 Repr::Owned(v) => Buf { repr: Repr::Owned(Arc::clone(v)) },
193 Repr::Slice { buf, off, len } => {
194 Buf { repr: Repr::Slice { buf: Arc::clone(buf), off: *off, len: *len } }
195 }
196 Repr::Foreign { ptr, len, owner } => {
197 unsafe { Buf::foreign(*ptr, *len, owner.clone()) }
199 }
200 }
201 }
202}
203
204impl<T> Default for Buf<T> {
205 fn default() -> Buf<T> {
206 Buf::new()
207 }
208}
209
210impl<T: std::fmt::Debug> std::fmt::Debug for Buf<T> {
211 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
212 std::fmt::Debug::fmt(self.as_slice(), f)
213 }
214}
215
216impl<T: PartialEq> PartialEq for Buf<T> {
217 fn eq(&self, other: &Buf<T>) -> bool {
218 self.as_slice() == other.as_slice()
219 }
220}
221
222impl<T> From<Vec<T>> for Buf<T> {
223 fn from(v: Vec<T>) -> Buf<T> {
224 Buf::from_vec(v)
225 }
226}
227
228impl<'a, T> IntoIterator for &'a Buf<T> {
229 type Item = &'a T;
230 type IntoIter = std::slice::Iter<'a, T>;
231
232 fn into_iter(self) -> std::slice::Iter<'a, T> {
233 self.as_slice().iter()
234 }
235}
236
237impl<T> FromIterator<T> for Buf<T> {
238 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Buf<T> {
239 Buf::from_vec(Vec::from_iter(iter))
240 }
241}
242
243#[derive(Clone, Debug, PartialEq)]
244pub enum Data {
245 Bool(Buf<u8>),
246 I64(Buf<i64>),
247 Ext(Buf<Ext>),
251 Rat(Buf<Rat>),
253 F64(Buf<f64>),
254 Complex(Buf<Cx>),
257 Char(Buf<char>),
258 Box(Buf<Array>),
262}
263
264impl Data {
265 pub fn dtype(&self) -> DType {
266 match self {
267 Data::Bool(_) => DType::Bool,
268 Data::I64(_) => DType::I64,
269 Data::Ext(_) => DType::Ext,
270 Data::Rat(_) => DType::Rat,
271 Data::F64(_) => DType::F64,
272 Data::Complex(_) => DType::Complex,
273 Data::Char(_) => DType::Char,
274 Data::Box(_) => DType::Box,
275 }
276 }
277
278 pub fn len(&self) -> usize {
279 match self {
280 Data::Bool(v) => v.len(),
281 Data::I64(v) => v.len(),
282 Data::Ext(v) => v.len(),
283 Data::Rat(v) => v.len(),
284 Data::F64(v) => v.len(),
285 Data::Complex(v) => v.len(),
286 Data::Char(v) => v.len(),
287 Data::Box(v) => v.len(),
288 }
289 }
290
291 pub fn is_empty(&self) -> bool {
292 self.len() == 0
293 }
294
295 pub fn is_foreign(&self) -> bool {
297 match self {
298 Data::Bool(v) => v.is_foreign(),
299 Data::I64(v) => v.is_foreign(),
300 Data::Ext(v) => v.is_foreign(),
301 Data::Rat(v) => v.is_foreign(),
302 Data::F64(v) => v.is_foreign(),
303 Data::Complex(v) => v.is_foreign(),
304 Data::Char(v) => v.is_foreign(),
305 Data::Box(v) => v.is_foreign(),
306 }
307 }
308
309 pub fn owner(&self) -> Option<&Owner> {
312 match self {
313 Data::Bool(v) => v.owner(),
314 Data::I64(v) => v.owner(),
315 Data::Ext(v) => v.owner(),
316 Data::Rat(v) => v.owner(),
317 Data::F64(v) => v.owner(),
318 Data::Complex(v) => v.owner(),
319 Data::Char(v) => v.owner(),
320 Data::Box(v) => v.owner(),
321 }
322 }
323
324 pub fn slice(&self, start: usize, end: usize) -> Data {
325 match self {
326 Data::Bool(v) => Data::Bool(v.slice(start, end)),
327 Data::I64(v) => Data::I64(v.slice(start, end)),
328 Data::Ext(v) => Data::Ext(v.slice(start, end)),
329 Data::Rat(v) => Data::Rat(v.slice(start, end)),
330 Data::F64(v) => Data::F64(v.slice(start, end)),
331 Data::Complex(v) => Data::Complex(v.slice(start, end)),
332 Data::Char(v) => Data::Char(v.slice(start, end)),
333 Data::Box(v) => Data::Box(v.slice(start, end)),
334 }
335 }
336
337 pub fn empty(dtype: DType) -> Data {
338 match dtype {
339 DType::Bool => Data::Bool(Buf::new()),
340 DType::I64 => Data::I64(Buf::new()),
341 DType::Ext => Data::Ext(Buf::new()),
342 DType::Rat => Data::Rat(Buf::new()),
343 DType::F64 => Data::F64(Buf::new()),
344 DType::Complex => Data::Complex(Buf::new()),
345 DType::Char => Data::Char(Buf::new()),
346 DType::Box => Data::Box(Buf::new()),
347 }
348 }
349
350 pub fn push_fill(&mut self) {
353 match self {
354 Data::Bool(v) => v.push(0),
355 Data::I64(v) => v.push(0),
356 Data::Ext(v) => v.push(Ext::default()),
357 Data::Rat(v) => v.push(Rat::zero()),
358 Data::F64(v) => v.push(0.0),
359 Data::Complex(v) => v.push(crate::complex::ZERO),
360 Data::Char(v) => v.push(' '),
361 Data::Box(v) => v.push(Array::box_fill()),
362 }
363 }
364
365 pub fn extend_from(&mut self, other: &Data) -> bool {
366 match (self, other) {
367 (Data::Bool(a), Data::Bool(b)) => a.extend_from_slice(b),
368 (Data::I64(a), Data::I64(b)) => a.extend_from_slice(b),
369 (Data::Ext(a), Data::Ext(b)) => a.extend_from_slice(b),
370 (Data::Rat(a), Data::Rat(b)) => a.extend_from_slice(b),
371 (Data::F64(a), Data::F64(b)) => a.extend_from_slice(b),
372 (Data::Complex(a), Data::Complex(b)) => a.extend_from_slice(b),
373 (Data::Char(a), Data::Char(b)) => a.extend_from_slice(b),
374 (Data::Box(a), Data::Box(b)) => a.extend_from_slice(b),
375 _ => return false,
376 }
377 true
378 }
379
380 pub fn interleave(columns: &[Data], rows: usize) -> Option<Data> {
392 let cols = columns.len();
393 let first = columns.first()?;
394 if columns.iter().any(|c| c.dtype() != first.dtype() || c.len() < rows) {
395 return None;
396 }
397
398 fn weave<T: Copy + Default + Send + Sync>(columns: &[&[T]], rows: usize) -> Vec<T> {
402 let cols = columns.len();
403 let (out, _) = crate::par::fill(rows * cols, |start, part: &mut [T]| {
404 let mut rest = &mut part[..];
405 let mut at = start;
406 let lead = ((cols - at % cols) % cols).min(rest.len());
408 if lead > 0 {
409 let (head, tail) = rest.split_at_mut(lead);
410 let r = at / cols;
411 for (k, slot) in head.iter_mut().enumerate() {
412 *slot = columns[at % cols + k][r];
413 }
414 at += lead;
415 rest = tail;
416 }
417 let whole = rest.len() / cols;
418 let (body, tail) = rest.split_at_mut(whole * cols);
419 let r0 = at / cols;
420 for (k, row) in body.chunks_exact_mut(cols).enumerate() {
421 for (slot, col) in row.iter_mut().zip(columns) {
422 *slot = col[r0 + k];
423 }
424 }
425 let r = r0 + whole;
427 for (c, slot) in tail.iter_mut().enumerate() {
428 *slot = columns[c][r];
429 }
430 true
431 });
432 out
433 }
434
435 fn weave_cloned<T: Clone>(columns: &[&[T]], rows: usize) -> Vec<T> {
439 let mut out = Vec::with_capacity(rows * columns.len());
440 for r in 0..rows {
441 for c in columns {
442 out.push(c[r].clone());
443 }
444 }
445 out
446 }
447
448 macro_rules! by {
449 ($variant:ident, $weave:ident) => {{
450 let mut s = Vec::with_capacity(cols);
451 for c in columns {
452 let Data::$variant(v) = c else { return None };
453 s.push(v.as_slice());
454 }
455 Some(Data::$variant($weave(&s, rows).into()))
456 }};
457 }
458 match first.dtype() {
459 DType::Bool => by!(Bool, weave),
460 DType::I64 => by!(I64, weave),
461 DType::F64 => by!(F64, weave),
462 DType::Complex => by!(Complex, weave),
463 DType::Char => by!(Char, weave),
464 DType::Ext => by!(Ext, weave_cloned),
465 DType::Rat => by!(Rat, weave_cloned),
466 DType::Box => by!(Box, weave_cloned),
467 }
468 }
469
470 pub fn cast(&self, to: DType) -> Option<Data> {
472 if self.dtype() == to {
473 return Some(self.clone());
474 }
475 match (self, to) {
476 (Data::Bool(v), DType::I64) => Some(Data::I64(v.iter().map(|&x| x as i64).collect())),
477 (Data::Bool(v), DType::F64) => Some(Data::F64(v.iter().map(|&x| x as f64).collect())),
478 (Data::I64(v), DType::F64) => Some(Data::F64(v.iter().map(|&x| x as f64).collect())),
479 (Data::Bool(v), DType::Ext) => Some(Data::Ext(v.iter().map(|&x| Ext::from(x)).collect())),
480 (Data::I64(v), DType::Ext) => Some(Data::Ext(v.iter().map(|&x| Ext::from(x)).collect())),
481 (Data::Bool(v), DType::Rat) => {
482 Some(Data::Rat(v.iter().map(|&x| Rat::from_int(Ext::from(x))).collect()))
483 }
484 (Data::I64(v), DType::Rat) => {
485 Some(Data::Rat(v.iter().map(|&x| Rat::from_int(Ext::from(x))).collect()))
486 }
487 (Data::Ext(v), DType::Rat) => {
488 Some(Data::Rat(v.iter().map(|x| Rat::from_int(x.clone())).collect()))
489 }
490 (Data::Ext(v), DType::F64) => {
491 Some(Data::F64(v.iter().map(crate::exact::ext_to_f64).collect()))
492 }
493 (Data::Rat(v), DType::F64) => Some(Data::F64(v.iter().map(Rat::to_f64).collect())),
494 (Data::Bool(v), DType::Complex) => {
495 Some(Data::Complex(v.iter().map(|&x| [x as f64, 0.0]).collect()))
496 }
497 (Data::I64(v), DType::Complex) => {
498 Some(Data::Complex(v.iter().map(|&x| [x as f64, 0.0]).collect()))
499 }
500 (Data::Ext(v), DType::Complex) => {
501 Some(Data::Complex(v.iter().map(|x| [crate::exact::ext_to_f64(x), 0.0]).collect()))
502 }
503 (Data::Rat(v), DType::Complex) => {
504 Some(Data::Complex(v.iter().map(|x| [x.to_f64(), 0.0]).collect()))
505 }
506 (Data::F64(v), DType::Complex) => {
507 Some(Data::Complex(v.iter().map(|&x| [x, 0.0]).collect()))
508 }
509 _ => None,
510 }
511 }
512}
513
514#[derive(Clone, Debug, PartialEq)]
515pub struct Array {
516 pub shape: Vec<usize>,
517 pub data: Data,
518}
519
520impl Array {
521 pub fn new(shape: Vec<usize>, data: Data) -> Array {
522 debug_assert_eq!(shape.iter().product::<usize>(), data.len());
523 Array { shape, data }
524 }
525
526 pub fn scalar_i64(v: i64) -> Array {
527 Array { shape: vec![], data: Data::I64(vec![v].into()) }
528 }
529
530 pub fn scalar_f64(v: f64) -> Array {
531 Array { shape: vec![], data: Data::F64(vec![v].into()) }
532 }
533
534 pub fn scalar_bool(v: bool) -> Array {
535 Array { shape: vec![], data: Data::Bool(vec![v as u8].into()) }
536 }
537
538 pub fn from_i64(values: Vec<i64>) -> Array {
539 Array { shape: vec![values.len()], data: Data::I64(values.into()) }
540 }
541
542 pub fn from_f64(values: Vec<f64>) -> Array {
543 Array { shape: vec![values.len()], data: Data::F64(values.into()) }
544 }
545
546 pub fn from_chars(values: Vec<char>) -> Array {
547 Array { shape: vec![values.len()], data: Data::Char(values.into()) }
548 }
549
550 pub fn empty(dtype: DType) -> Array {
551 Array { shape: vec![0], data: Data::empty(dtype) }
552 }
553
554 pub fn boxed(value: Array) -> Array {
556 Array { shape: vec![], data: Data::Box(vec![value].into()) }
557 }
558
559 pub fn box_fill() -> Array {
562 Array::empty(DType::I64)
563 }
564
565 pub fn dtype(&self) -> DType {
566 self.data.dtype()
567 }
568
569 pub fn rank(&self) -> usize {
570 self.shape.len()
571 }
572
573 pub fn count(&self) -> usize {
575 self.shape.iter().product()
576 }
577
578 pub fn items(&self) -> usize {
580 self.shape.first().copied().unwrap_or(1)
581 }
582
583 pub fn item_size(&self) -> usize {
585 self.shape.iter().skip(1).product()
586 }
587
588 pub fn cast(&self, to: DType) -> Option<Array> {
589 Some(Array { shape: self.shape.clone(), data: self.data.cast(to)? })
590 }
591
592 pub fn cells(&self, frame_rank: usize) -> Vec<Array> {
595 debug_assert!(frame_rank <= self.rank());
596 let cell_shape: Vec<usize> = self.shape[frame_rank..].to_vec();
597 let cell_size: usize = cell_shape.iter().product();
598 let n: usize = self.shape[..frame_rank].iter().product();
599 (0..n)
600 .map(|i| Array {
601 shape: cell_shape.clone(),
602 data: self.data.slice(i * cell_size, (i + 1) * cell_size),
603 })
604 .collect()
605 }
606
607 pub fn cell_at(&self, frame_rank: usize, index: usize) -> Array {
609 let cell_shape: Vec<usize> = self.shape[frame_rank..].to_vec();
610 let cell_size: usize = cell_shape.iter().product();
611 Array {
612 shape: cell_shape,
613 data: self.data.slice(index * cell_size, (index + 1) * cell_size),
614 }
615 }
616
617 pub fn item(&self, i: usize) -> Array {
619 debug_assert!(self.rank() >= 1);
620 self.cell_at(1, i)
621 }
622
623 pub fn as_i64_slice(&self) -> Option<&[i64]> {
624 match &self.data {
625 Data::I64(v) => Some(v),
626 _ => None,
627 }
628 }
629
630 pub fn as_boxes(&self) -> Option<&[Array]> {
632 match &self.data {
633 Data::Box(v) => Some(v),
634 _ => None,
635 }
636 }
637
638 pub fn as_f64_slice(&self) -> Option<&[f64]> {
639 match &self.data {
640 Data::F64(v) => Some(v),
641 _ => None,
642 }
643 }
644
645 pub fn as_ext_slice(&self) -> Option<&[Ext]> {
647 match &self.data {
648 Data::Ext(v) => Some(v),
649 _ => None,
650 }
651 }
652
653 pub fn as_rat_slice(&self) -> Option<&[Rat]> {
655 match &self.data {
656 Data::Rat(v) => Some(v),
657 _ => None,
658 }
659 }
660
661 pub fn as_complex_slice(&self) -> Option<&[Cx]> {
662 match &self.data {
663 Data::Complex(v) => Some(v),
664 _ => None,
665 }
666 }
667
668 pub fn to_complex_vec(&self) -> Option<Vec<Cx>> {
670 match &self.data {
671 Data::Bool(v) => Some(v.iter().map(|&x| [x as f64, 0.0]).collect()),
672 Data::I64(v) => Some(v.iter().map(|&x| [x as f64, 0.0]).collect()),
673 Data::Ext(v) => Some(v.iter().map(|x| [crate::exact::ext_to_f64(x), 0.0]).collect()),
674 Data::Rat(v) => Some(v.iter().map(|x| [x.to_f64(), 0.0]).collect()),
675 Data::F64(v) => Some(v.iter().map(|&x| [x, 0.0]).collect()),
676 Data::Complex(v) => Some(v.to_vec()),
677 Data::Char(_) | Data::Box(_) => None,
678 }
679 }
680
681 pub fn to_f64_vec(&self) -> Option<Vec<f64>> {
683 match &self.data {
684 Data::Bool(v) => Some(v.iter().map(|&x| x as f64).collect()),
685 Data::I64(v) => Some(v.iter().map(|&x| x as f64).collect()),
686 Data::Ext(v) => Some(v.iter().map(crate::exact::ext_to_f64).collect()),
687 Data::Rat(v) => Some(v.iter().map(Rat::to_f64).collect()),
688 Data::F64(v) => Some(v.to_vec()),
689 Data::Complex(_) | Data::Char(_) | Data::Box(_) => None,
692 }
693 }
694
695 pub fn to_i64_vec(&self) -> Option<Vec<i64>> {
697 match &self.data {
698 Data::Bool(v) => Some(v.iter().map(|&x| x as i64).collect()),
699 Data::I64(v) => Some(v.to_vec()),
700 Data::Ext(v) => v.iter().map(crate::exact::ext_to_i64).collect(),
703 Data::Rat(v) => {
704 v.iter().map(|x| x.to_int().as_ref().and_then(crate::exact::ext_to_i64)).collect()
705 }
706 Data::F64(v) => {
707 let mut out = Vec::with_capacity(v.len());
708 for &x in v.iter() {
709 if x.fract() != 0.0 || x.abs() >= i64::MAX as f64 {
710 return None;
711 }
712 out.push(x as i64);
713 }
714 Some(out)
715 }
716 Data::Complex(_) | Data::Char(_) | Data::Box(_) => None,
717 }
718 }
719}
720
721#[cfg(test)]
722mod tests {
723 use super::*;
724 use std::sync::atomic::{AtomicBool, Ordering};
725
726 struct Guard {
729 values: Vec<i64>,
730 dropped: Arc<AtomicBool>,
731 }
732
733 impl Drop for Guard {
734 fn drop(&mut self) {
735 self.dropped.store(true, Ordering::SeqCst);
736 }
737 }
738
739 fn foreign_buf(values: Vec<i64>, dropped: Arc<AtomicBool>) -> Buf<i64> {
740 let guard = Arc::new(Guard { values, dropped });
741 let ptr = guard.values.as_ptr();
742 let len = guard.values.len();
743 unsafe { Buf::foreign(ptr, len, guard) }
746 }
747
748 #[test]
749 fn owned_buf_derefs_to_its_slice() {
750 let b: Buf<i64> = vec![1, 2, 3].into();
751 assert!(!b.is_foreign());
752 assert_eq!(&b[..], &[1, 2, 3]);
753 assert_eq!(b.len(), 3);
754 assert_eq!(b.iter().sum::<i64>(), 6);
755 }
756
757 #[test]
758 fn empty_buf_is_a_valid_empty_slice() {
759 let b: Buf<f64> = Buf::new();
760 assert_eq!(&b[..], &[] as &[f64]);
761 let f = unsafe { Buf::<f64>::foreign(std::ptr::null(), 0, Arc::new(())) };
763 assert_eq!(&f[..], &[] as &[f64]);
764 }
765
766 #[test]
767 fn cloning_an_owned_buf_shares_the_same_memory() {
768 let b: Buf<i64> = vec![1, 2, 3].into();
769 let c = b.clone();
770 assert_eq!(b.as_ptr(), c.as_ptr(), "owned clone copied the elements");
771 assert_eq!(&c[..], &[1, 2, 3]);
772 }
773
774 #[test]
775 fn writing_to_a_shared_owned_buf_copies_first() {
776 let b: Buf<i64> = vec![1, 2, 3].into();
777 let mut c = b.clone();
778 c.to_mut()[0] = 99;
779 assert_eq!(&b[..], &[1, 2, 3], "the other holder saw the write");
780 assert_eq!(&c[..], &[99, 2, 3]);
781 assert_ne!(b.as_ptr(), c.as_ptr());
782 let ptr = c.as_ptr();
784 c.to_mut()[1] = 98;
785 assert_eq!(c.as_ptr(), ptr, "unshared write copied");
786 }
787
788 #[test]
789 fn into_vec_moves_when_sole_holder_and_copies_when_shared() {
790 let b: Buf<i64> = vec![1, 2, 3].into();
791 let ptr = b.as_ptr();
792 let v = b.into_vec();
793 assert_eq!(v.as_ptr(), ptr, "sole holder copied instead of moving");
794
795 let b: Buf<i64> = vec![1, 2, 3].into();
796 let c = b.clone();
797 let v = b.into_vec();
798 assert_eq!(v, vec![1, 2, 3]);
799 assert_eq!(&c[..], &[1, 2, 3]);
800 }
801
802 #[test]
803 fn foreign_buf_reads_borrowed_memory_and_keeps_the_owner_alive() {
804 let dropped = Arc::new(AtomicBool::new(false));
805 let b = foreign_buf(vec![10, 20, 30], dropped.clone());
806 assert!(b.is_foreign());
807 assert_eq!(&b[..], &[10, 20, 30]);
808 assert!(!dropped.load(Ordering::SeqCst), "owner dropped while borrowed");
809 drop(b);
810 assert!(dropped.load(Ordering::SeqCst), "owner leaked after the buffer died");
811 }
812
813 #[test]
814 fn cloning_a_foreign_buf_shares_the_same_memory() {
815 let dropped = Arc::new(AtomicBool::new(false));
816 let b = foreign_buf(vec![1, 2, 3], dropped.clone());
817 let c = b.clone();
818 assert!(c.is_foreign());
819 assert_eq!(b.as_ptr(), c.as_ptr());
820 drop(b);
821 assert!(!dropped.load(Ordering::SeqCst), "owner dropped while a clone lives");
822 assert_eq!(&c[..], &[1, 2, 3]);
823 }
824
825 #[test]
826 fn slicing_a_foreign_buf_keeps_borrowing() {
827 let dropped = Arc::new(AtomicBool::new(false));
828 let b = foreign_buf(vec![1, 2, 3, 4], dropped.clone());
829 let s = b.slice(1, 3);
830 assert!(s.is_foreign());
831 assert_eq!(&s[..], &[2, 3]);
832 drop(b);
833 assert_eq!(&s[..], &[2, 3]);
834 assert!(!dropped.load(Ordering::SeqCst));
835 }
836
837 #[test]
838 fn mutating_a_foreign_buf_copies_first() {
839 let dropped = Arc::new(AtomicBool::new(false));
840 let mut b = foreign_buf(vec![1, 2, 3], dropped.clone());
841 b.push(4);
842 assert!(!b.is_foreign());
843 assert_eq!(&b[..], &[1, 2, 3, 4]);
844 drop(b);
846 assert!(dropped.load(Ordering::SeqCst));
847 }
848
849 #[test]
850 fn copy_on_write_leaves_other_holders_alone() {
851 let dropped = Arc::new(AtomicBool::new(false));
852 let b = foreign_buf(vec![1, 2, 3], dropped.clone());
853 let mut c = b.clone();
854 c.to_mut()[0] = 99;
855 assert_eq!(&b[..], &[1, 2, 3]);
856 assert_eq!(&c[..], &[99, 2, 3]);
857 }
858
859 #[test]
860 fn foreign_data_slices_without_copying() {
861 let dropped = Arc::new(AtomicBool::new(false));
862 let a = Array::new(vec![2, 2], Data::I64(foreign_buf(vec![1, 2, 3, 4], dropped)));
863 assert!(a.data.is_foreign());
864 let row = a.item(1);
865 assert!(row.data.is_foreign());
866 assert_eq!(row.as_i64_slice(), Some(&[3, 4][..]));
867 }
868
869 #[test]
870 fn foreign_data_extends_by_copying() {
871 let dropped = Arc::new(AtomicBool::new(false));
872 let mut d = Data::I64(foreign_buf(vec![1, 2], dropped));
873 assert!(d.is_foreign());
874 assert!(d.extend_from(&Data::I64(vec![3].into())));
875 assert!(!d.is_foreign());
876 assert_eq!(d, Data::I64(vec![1, 2, 3].into()));
877 }
878}