Coverage Report

Created: 2026-03-11 07:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/ndarray-0.17.2/src/data_traits.rs
Line
Count
Source
1
// Copyright 2014-2016 bluss and ndarray developers.
2
//
3
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6
// option. This file may not be copied, modified, or distributed
7
// except according to those terms.
8
9
//! The data (inner representation) traits for ndarray
10
11
#[allow(unused_imports)]
12
use rawpointer::PointerExt;
13
14
#[cfg(target_has_atomic = "ptr")]
15
use alloc::sync::Arc;
16
17
#[cfg(not(target_has_atomic = "ptr"))]
18
use portable_atomic_util::Arc;
19
20
#[cfg(not(feature = "std"))]
21
use alloc::vec::Vec;
22
use std::mem::MaybeUninit;
23
use std::mem::{self, size_of};
24
use std::ptr::NonNull;
25
26
use crate::{ArcArray, Array, ArrayBase, ArrayRef, CowRepr, Dimension, OwnedArcRepr, OwnedRepr, RawViewRepr, ViewRepr};
27
28
/// Array representation trait.
29
///
30
/// For an array that meets the invariants of the `ArrayBase` type. This trait
31
/// does not imply any ownership or lifetime; pointers to elements in the array
32
/// may not be safe to dereference.
33
///
34
/// ***Note:*** `RawData` is not an extension interface at this point.
35
/// Traits in Rust can serve many different roles. This trait is public because
36
/// it is used as a bound on public methods.
37
#[allow(clippy::missing_safety_doc)] // not implementable downstream
38
pub unsafe trait RawData: Sized
39
{
40
    /// The array element type.
41
    type Elem;
42
43
    #[doc(hidden)]
44
    fn _is_pointer_inbounds(&self, ptr: *const Self::Elem) -> bool;
45
46
    private_decl! {}
47
}
48
49
/// Array representation trait.
50
///
51
/// For an array with writable elements.
52
///
53
/// ***Internal trait, see `RawData`.***
54
#[allow(clippy::missing_safety_doc)] // not implementable downstream
55
pub unsafe trait RawDataMut: RawData
56
{
57
    /// If possible, ensures that the array has unique access to its data.
58
    ///
59
    /// The implementer must ensure that if the input is contiguous, then the
60
    /// output has the same strides as input.
61
    ///
62
    /// Additionally, if `Self` provides safe mutable access to array elements,
63
    /// then this method **must** panic or ensure that the data is unique.
64
    #[doc(hidden)]
65
    fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
66
    where
67
        Self: Sized,
68
        D: Dimension;
69
70
    /// If possible, returns whether the array has unique access to its data.
71
    ///
72
    /// If `Self` provides safe mutable access to array elements, then it
73
    /// **must** return `Some(_)`.
74
    #[doc(hidden)]
75
    fn try_is_unique(&mut self) -> Option<bool>;
76
}
77
78
/// Array representation trait.
79
///
80
/// An array representation that can be cloned.
81
///
82
/// ***Internal trait, see `RawData`.***
83
#[allow(clippy::missing_safety_doc)] // not implementable downstream
84
pub unsafe trait RawDataClone: RawData
85
{
86
    #[doc(hidden)]
87
    /// Unsafe because, `ptr` must point inside the current storage.
88
    unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>);
89
90
    #[doc(hidden)]
91
0
    unsafe fn clone_from_with_ptr(&mut self, other: &Self, ptr: NonNull<Self::Elem>) -> NonNull<Self::Elem>
92
    {
93
0
        let (data, ptr) = other.clone_with_ptr(ptr);
94
0
        *self = data;
95
0
        ptr
96
0
    }
97
}
98
99
/// Array representation trait.
100
///
101
/// For an array with elements that can be accessed with safe code.
102
///
103
/// ***Internal trait, see `RawData`.***
104
#[allow(clippy::missing_safety_doc)] // not implementable downstream
105
pub unsafe trait Data: RawData
106
{
107
    /// Converts the array to a uniquely owned array, cloning elements if necessary.
108
    #[doc(hidden)]
109
    #[allow(clippy::wrong_self_convention)]
110
    fn into_owned<D>(self_: ArrayBase<Self, D>) -> Array<Self::Elem, D>
111
    where
112
        Self::Elem: Clone,
113
        D: Dimension;
114
115
    /// Converts the array into `Array<A, D>` if this is possible without
116
    /// cloning the array elements. Otherwise, returns `self_` unchanged.
117
    #[doc(hidden)]
118
    fn try_into_owned_nocopy<D>(self_: ArrayBase<Self, D>) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
119
    where D: Dimension;
120
121
    /// Return a shared ownership (copy on write) array based on the existing one,
122
    /// cloning elements if necessary.
123
    #[doc(hidden)]
124
    #[allow(clippy::wrong_self_convention)]
125
0
    fn to_shared<D>(self_: &ArrayBase<Self, D>) -> ArcArray<Self::Elem, D>
126
0
    where
127
0
        Self::Elem: Clone,
128
0
        D: Dimension,
129
    {
130
        // clone to shared
131
0
        self_.to_owned().into_shared()
132
0
    }
133
}
134
135
/// Array representation trait.
136
///
137
/// For an array with writable elements that can be accessed with safe code.
138
///
139
/// ***Internal trait, see `Data`.***
140
//
141
// # For implementers
142
//
143
// If you implement the `DataMut` trait, you are guaranteeing that the
144
// `RawDataMut::try_ensure_unique` implementation always panics or ensures that
145
// the data is unique. You are also guaranteeing that `try_is_unique` always
146
// returns `Some(_)`.
147
#[allow(clippy::missing_safety_doc)] // not implementable downstream
148
pub unsafe trait DataMut: Data + RawDataMut
149
{
150
    /// Ensures that the array has unique access to its data.
151
    #[doc(hidden)]
152
    #[inline]
153
0
    fn ensure_unique<D>(self_: &mut ArrayBase<Self, D>)
154
0
    where
155
0
        Self: Sized,
156
0
        D: Dimension,
157
    {
158
0
        Self::try_ensure_unique(self_)
159
0
    }
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<noisy_float::NoisyFloat<f64, noisy_float::checkers::NumChecker>>> as ndarray::data_traits::DataMut>::ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<noisy_float::NoisyFloat<f32, noisy_float::checkers::NumChecker>>> as ndarray::data_traits::DataMut>::ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<i8>> as ndarray::data_traits::DataMut>::ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<u8>> as ndarray::data_traits::DataMut>::ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<i32>> as ndarray::data_traits::DataMut>::ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<u32>> as ndarray::data_traits::DataMut>::ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<i128>> as ndarray::data_traits::DataMut>::ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<u128>> as ndarray::data_traits::DataMut>::ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<i16>> as ndarray::data_traits::DataMut>::ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<u16>> as ndarray::data_traits::DataMut>::ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<i64>> as ndarray::data_traits::DataMut>::ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<u64>> as ndarray::data_traits::DataMut>::ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut f64> as ndarray::data_traits::DataMut>::ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut f32> as ndarray::data_traits::DataMut>::ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <_ as ndarray::data_traits::DataMut>::ensure_unique::<_>
160
161
    /// Returns whether the array has unique access to its data.
162
    #[doc(hidden)]
163
    #[inline]
164
    #[allow(clippy::wrong_self_convention)] // mut needed for Arc types
165
0
    fn is_unique(&mut self) -> bool
166
    {
167
0
        self.try_is_unique().unwrap()
168
0
    }
169
}
170
171
unsafe impl<A> RawData for RawViewRepr<*const A>
172
{
173
    type Elem = A;
174
175
    #[inline(always)]
176
0
    fn _is_pointer_inbounds(&self, _ptr: *const Self::Elem) -> bool
177
    {
178
0
        true
179
0
    }
180
181
    private_impl! {}
182
}
183
184
unsafe impl<A> RawDataClone for RawViewRepr<*const A>
185
{
186
0
    unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>)
187
    {
188
0
        (*self, ptr)
189
0
    }
190
}
191
192
unsafe impl<A> RawData for RawViewRepr<*mut A>
193
{
194
    type Elem = A;
195
196
    #[inline(always)]
197
0
    fn _is_pointer_inbounds(&self, _ptr: *const Self::Elem) -> bool
198
    {
199
0
        true
200
0
    }
201
202
    private_impl! {}
203
}
204
205
unsafe impl<A> RawDataMut for RawViewRepr<*mut A>
206
{
207
    #[inline]
208
0
    fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
209
0
    where
210
0
        Self: Sized,
211
0
        D: Dimension,
212
    {
213
0
    }
214
215
    #[inline]
216
0
    fn try_is_unique(&mut self) -> Option<bool>
217
    {
218
0
        None
219
0
    }
220
}
221
222
unsafe impl<A> RawDataClone for RawViewRepr<*mut A>
223
{
224
0
    unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>)
225
    {
226
0
        (*self, ptr)
227
0
    }
228
}
229
230
unsafe impl<A> RawData for OwnedArcRepr<A>
231
{
232
    type Elem = A;
233
234
0
    fn _is_pointer_inbounds(&self, self_ptr: *const Self::Elem) -> bool
235
    {
236
0
        self.0._is_pointer_inbounds(self_ptr)
237
0
    }
238
239
    private_impl! {}
240
}
241
242
// NOTE: Copy on write
243
unsafe impl<A> RawDataMut for OwnedArcRepr<A>
244
where A: Clone
245
{
246
0
    fn try_ensure_unique<D>(self_: &mut ArrayBase<Self, D>)
247
0
    where
248
0
        Self: Sized,
249
0
        D: Dimension,
250
    {
251
0
        if Arc::get_mut(&mut self_.data.0).is_some() {
252
0
            return;
253
0
        }
254
0
        if self_.parts.dim.size() <= self_.data.0.len() / 2 {
255
            // Clone only the visible elements if the current view is less than
256
            // half of backing data.
257
0
            *self_ = self_.to_owned().into_shared();
258
0
            return;
259
0
        }
260
0
        let rcvec = &mut self_.data.0;
261
0
        let a_size = mem::size_of::<A>() as isize;
262
0
        let our_off = if a_size != 0 {
263
0
            (self_.parts.ptr.as_ptr() as isize - rcvec.as_ptr() as isize) / a_size
264
        } else {
265
0
            0
266
        };
267
0
        let rvec = Arc::make_mut(rcvec);
268
0
        unsafe {
269
0
            self_.parts.ptr = rvec.as_nonnull_mut().offset(our_off);
270
0
        }
271
0
    }
272
273
0
    fn try_is_unique(&mut self) -> Option<bool>
274
    {
275
0
        Some(Arc::get_mut(&mut self.0).is_some())
276
0
    }
277
}
278
279
unsafe impl<A> Data for OwnedArcRepr<A>
280
{
281
0
    fn into_owned<D>(mut self_: ArrayBase<Self, D>) -> Array<Self::Elem, D>
282
0
    where
283
0
        A: Clone,
284
0
        D: Dimension,
285
    {
286
0
        Self::ensure_unique(&mut self_);
287
0
        let data = Arc::try_unwrap(self_.data.0).ok().unwrap();
288
        // safe because data is equivalent
289
        unsafe {
290
0
            ArrayBase::from_data_ptr(data, self_.parts.ptr).with_strides_dim(self_.parts.strides, self_.parts.dim)
291
        }
292
0
    }
293
294
0
    fn try_into_owned_nocopy<D>(self_: ArrayBase<Self, D>) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
295
0
    where D: Dimension
296
    {
297
0
        match Arc::try_unwrap(self_.data.0) {
298
0
            Ok(owned_data) => unsafe {
299
                // Safe because the data is equivalent.
300
0
                Ok(ArrayBase::from_data_ptr(owned_data, self_.parts.ptr)
301
0
                    .with_strides_dim(self_.parts.strides, self_.parts.dim))
302
            },
303
0
            Err(arc_data) => unsafe {
304
                // Safe because the data is equivalent; we're just
305
                // reconstructing `self_`.
306
0
                Err(ArrayBase::from_data_ptr(OwnedArcRepr(arc_data), self_.parts.ptr)
307
0
                    .with_strides_dim(self_.parts.strides, self_.parts.dim))
308
            },
309
        }
310
0
    }
311
312
    #[allow(clippy::wrong_self_convention)]
313
0
    fn to_shared<D>(self_: &ArrayBase<Self, D>) -> ArcArray<Self::Elem, D>
314
0
    where
315
0
        Self::Elem: Clone,
316
0
        D: Dimension,
317
    {
318
        // to shared using clone of OwnedArcRepr without clone of raw data.
319
0
        self_.clone()
320
0
    }
321
}
322
323
unsafe impl<A> DataMut for OwnedArcRepr<A> where A: Clone {}
324
325
unsafe impl<A> RawDataClone for OwnedArcRepr<A>
326
{
327
0
    unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>)
328
    {
329
        // pointer is preserved
330
0
        (self.clone(), ptr)
331
0
    }
332
}
333
334
unsafe impl<A> RawData for OwnedRepr<A>
335
{
336
    type Elem = A;
337
338
0
    fn _is_pointer_inbounds(&self, self_ptr: *const Self::Elem) -> bool
339
    {
340
0
        let slc = self.as_slice();
341
0
        let ptr = slc.as_ptr() as *mut A;
342
0
        let end = unsafe { ptr.add(slc.len()) };
343
0
        self_ptr >= ptr && self_ptr <= end
344
0
    }
345
346
    private_impl! {}
347
}
348
349
unsafe impl<A> RawDataMut for OwnedRepr<A>
350
{
351
    #[inline]
352
0
    fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
353
0
    where
354
0
        Self: Sized,
355
0
        D: Dimension,
356
    {
357
0
    }
358
359
    #[inline]
360
0
    fn try_is_unique(&mut self) -> Option<bool>
361
    {
362
0
        Some(true)
363
0
    }
364
}
365
366
unsafe impl<A> Data for OwnedRepr<A>
367
{
368
    #[inline]
369
0
    fn into_owned<D>(self_: ArrayBase<Self, D>) -> Array<Self::Elem, D>
370
0
    where
371
0
        A: Clone,
372
0
        D: Dimension,
373
    {
374
0
        self_
375
0
    }
376
377
    #[inline]
378
0
    fn try_into_owned_nocopy<D>(self_: ArrayBase<Self, D>) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
379
0
    where D: Dimension
380
    {
381
0
        Ok(self_)
382
0
    }
383
}
384
385
unsafe impl<A> DataMut for OwnedRepr<A> {}
386
387
unsafe impl<A> RawDataClone for OwnedRepr<A>
388
where A: Clone
389
{
390
0
    unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>)
391
    {
392
0
        let mut u = self.clone();
393
0
        let mut new_ptr = u.as_nonnull_mut();
394
0
        if size_of::<A>() != 0 {
395
0
            let our_off = (ptr.as_ptr() as isize - self.as_ptr() as isize) / mem::size_of::<A>() as isize;
396
0
            new_ptr = new_ptr.offset(our_off);
397
0
        }
398
0
        (u, new_ptr)
399
0
    }
400
401
0
    unsafe fn clone_from_with_ptr(&mut self, other: &Self, ptr: NonNull<Self::Elem>) -> NonNull<Self::Elem>
402
    {
403
0
        let our_off = if size_of::<A>() != 0 {
404
0
            (ptr.as_ptr() as isize - other.as_ptr() as isize) / mem::size_of::<A>() as isize
405
        } else {
406
0
            0
407
        };
408
0
        self.clone_from(other);
409
0
        self.as_nonnull_mut().offset(our_off)
410
0
    }
411
}
412
413
unsafe impl<A> RawData for ViewRepr<&A>
414
{
415
    type Elem = A;
416
417
    #[inline(always)]
418
0
    fn _is_pointer_inbounds(&self, _ptr: *const Self::Elem) -> bool
419
    {
420
0
        true
421
0
    }
422
423
    private_impl! {}
424
}
425
426
unsafe impl<A> Data for ViewRepr<&A>
427
{
428
0
    fn into_owned<D>(self_: ArrayBase<Self, D>) -> Array<Self::Elem, D>
429
0
    where
430
0
        Self::Elem: Clone,
431
0
        D: Dimension,
432
    {
433
0
        self_.to_owned()
434
0
    }
435
436
0
    fn try_into_owned_nocopy<D>(self_: ArrayBase<Self, D>) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
437
0
    where D: Dimension
438
    {
439
0
        Err(self_)
440
0
    }
441
}
442
443
unsafe impl<A> RawDataClone for ViewRepr<&A>
444
{
445
0
    unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>)
446
    {
447
0
        (*self, ptr)
448
0
    }
449
}
450
451
unsafe impl<A> RawData for ViewRepr<&mut A>
452
{
453
    type Elem = A;
454
455
    #[inline(always)]
456
0
    fn _is_pointer_inbounds(&self, _ptr: *const Self::Elem) -> bool
457
    {
458
0
        true
459
0
    }
460
461
    private_impl! {}
462
}
463
464
unsafe impl<A> RawDataMut for ViewRepr<&mut A>
465
{
466
    #[inline]
467
0
    fn try_ensure_unique<D>(_: &mut ArrayBase<Self, D>)
468
0
    where
469
0
        Self: Sized,
470
0
        D: Dimension,
471
    {
472
0
    }
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<noisy_float::NoisyFloat<f64, noisy_float::checkers::NumChecker>>> as ndarray::data_traits::RawDataMut>::try_ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<noisy_float::NoisyFloat<f32, noisy_float::checkers::NumChecker>>> as ndarray::data_traits::RawDataMut>::try_ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<i8>> as ndarray::data_traits::RawDataMut>::try_ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<u8>> as ndarray::data_traits::RawDataMut>::try_ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<i32>> as ndarray::data_traits::RawDataMut>::try_ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<u32>> as ndarray::data_traits::RawDataMut>::try_ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<i128>> as ndarray::data_traits::RawDataMut>::try_ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<u128>> as ndarray::data_traits::RawDataMut>::try_ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<i16>> as ndarray::data_traits::RawDataMut>::try_ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<u16>> as ndarray::data_traits::RawDataMut>::try_ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<i64>> as ndarray::data_traits::RawDataMut>::try_ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut core::option::Option<u64>> as ndarray::data_traits::RawDataMut>::try_ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut f64> as ndarray::data_traits::RawDataMut>::try_ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut f32> as ndarray::data_traits::RawDataMut>::try_ensure_unique::<ndarray::dimension::dim::Dim<[usize; 1]>>
Unexecuted instantiation: <ndarray::ViewRepr<&mut _> as ndarray::data_traits::RawDataMut>::try_ensure_unique::<_>
473
474
    #[inline]
475
0
    fn try_is_unique(&mut self) -> Option<bool>
476
    {
477
0
        Some(true)
478
0
    }
479
}
480
481
unsafe impl<A> Data for ViewRepr<&mut A>
482
{
483
0
    fn into_owned<D>(self_: ArrayBase<Self, D>) -> Array<Self::Elem, D>
484
0
    where
485
0
        Self::Elem: Clone,
486
0
        D: Dimension,
487
    {
488
0
        self_.to_owned()
489
0
    }
490
491
0
    fn try_into_owned_nocopy<D>(self_: ArrayBase<Self, D>) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
492
0
    where D: Dimension
493
    {
494
0
        Err(self_)
495
0
    }
496
}
497
498
unsafe impl<A> DataMut for ViewRepr<&mut A> {}
499
500
/// Array representation trait.
501
///
502
/// A representation which can be the owner of its data.
503
///
504
/// ***Internal trait, see `Data`.***
505
// The owned storage represents the ownership and allocation of the array's elements.
506
// The storage may be unique or shared ownership style; it must be an aliasable owner
507
// (permit aliasing pointers, such as our separate array head pointer).
508
//
509
// The array storage must be initially mutable - copy on write arrays may require copying for
510
// unsharing storage before mutating it. The initially allocated storage must be mutable so
511
// that it can be mutated directly - through .raw_view_mut_unchecked() - for initialization.
512
#[allow(clippy::missing_safety_doc)] // not implementable downstream
513
pub unsafe trait DataOwned: Data
514
{
515
    /// Corresponding owned data with MaybeUninit elements
516
    type MaybeUninit: DataOwned<Elem = MaybeUninit<Self::Elem>> + RawDataSubst<Self::Elem, Output = Self>;
517
    #[doc(hidden)]
518
    fn new(elements: Vec<Self::Elem>) -> Self;
519
520
    /// Converts the data representation to a shared (copy on write)
521
    /// representation, cloning the array elements if necessary.
522
    #[doc(hidden)]
523
    #[allow(clippy::wrong_self_convention)]
524
    fn into_shared<D>(self_: ArrayBase<Self, D>) -> ArcArray<Self::Elem, D>
525
    where
526
        Self::Elem: Clone,
527
        D: Dimension;
528
}
529
530
/// Array representation trait.
531
///
532
/// A representation that is a lightweight view.
533
///
534
/// ***Internal trait, see `Data`.***
535
#[allow(clippy::missing_safety_doc)] // not implementable downstream
536
pub unsafe trait DataShared: Clone + Data + RawDataClone {}
537
538
unsafe impl<A> DataShared for OwnedArcRepr<A> {}
539
unsafe impl<A> DataShared for ViewRepr<&A> {}
540
541
unsafe impl<A> DataOwned for OwnedRepr<A>
542
{
543
    type MaybeUninit = OwnedRepr<MaybeUninit<A>>;
544
545
0
    fn new(elements: Vec<A>) -> Self
546
    {
547
0
        OwnedRepr::from(elements)
548
0
    }
Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<core::mem::maybe_uninit::MaybeUninit<f64>> as ndarray::data_traits::DataOwned>::new
Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<core::mem::maybe_uninit::MaybeUninit<f32>> as ndarray::data_traits::DataOwned>::new
Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<f64> as ndarray::data_traits::DataOwned>::new
Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<f32> as ndarray::data_traits::DataOwned>::new
Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<i32> as ndarray::data_traits::DataOwned>::new
Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<i16> as ndarray::data_traits::DataOwned>::new
Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<i64> as ndarray::data_traits::DataOwned>::new
Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<_> as ndarray::data_traits::DataOwned>::new
549
550
0
    fn into_shared<D>(self_: ArrayBase<Self, D>) -> ArcArray<A, D>
551
0
    where
552
0
        A: Clone,
553
0
        D: Dimension,
554
    {
555
0
        ArcArray::from(self_)
556
0
    }
557
}
558
559
unsafe impl<A> DataOwned for OwnedArcRepr<A>
560
{
561
    type MaybeUninit = OwnedArcRepr<MaybeUninit<A>>;
562
563
0
    fn new(elements: Vec<A>) -> Self
564
    {
565
0
        OwnedArcRepr(Arc::new(OwnedRepr::from(elements)))
566
0
    }
567
568
0
    fn into_shared<D>(self_: ArrayBase<Self, D>) -> ArcArray<A, D>
569
0
    where
570
0
        A: Clone,
571
0
        D: Dimension,
572
    {
573
0
        self_
574
0
    }
575
}
576
577
unsafe impl<A> RawData for CowRepr<'_, A>
578
{
579
    type Elem = A;
580
581
    #[inline]
582
0
    fn _is_pointer_inbounds(&self, ptr: *const Self::Elem) -> bool
583
    {
584
0
        match self {
585
0
            CowRepr::View(view) => view._is_pointer_inbounds(ptr),
586
0
            CowRepr::Owned(data) => data._is_pointer_inbounds(ptr),
587
        }
588
0
    }
589
590
    private_impl! {}
591
}
592
593
unsafe impl<A> RawDataMut for CowRepr<'_, A>
594
where A: Clone
595
{
596
    #[inline]
597
0
    fn try_ensure_unique<D>(array: &mut ArrayBase<Self, D>)
598
0
    where
599
0
        Self: Sized,
600
0
        D: Dimension,
601
    {
602
0
        match array.data {
603
0
            CowRepr::View(_) => {
604
0
                let owned = ArrayRef::to_owned(array);
605
0
                array.data = CowRepr::Owned(owned.data);
606
0
                array.parts.ptr = owned.parts.ptr;
607
0
                array.parts.dim = owned.parts.dim;
608
0
                array.parts.strides = owned.parts.strides;
609
0
            }
610
0
            CowRepr::Owned(_) => {}
611
        }
612
0
    }
613
614
    #[inline]
615
0
    fn try_is_unique(&mut self) -> Option<bool>
616
    {
617
0
        Some(self.is_owned())
618
0
    }
619
}
620
621
unsafe impl<A> RawDataClone for CowRepr<'_, A>
622
where A: Clone
623
{
624
0
    unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>)
625
    {
626
0
        match self {
627
0
            CowRepr::View(view) => {
628
0
                let (new_view, ptr) = view.clone_with_ptr(ptr);
629
0
                (CowRepr::View(new_view), ptr)
630
            }
631
0
            CowRepr::Owned(data) => {
632
0
                let (new_data, ptr) = data.clone_with_ptr(ptr);
633
0
                (CowRepr::Owned(new_data), ptr)
634
            }
635
        }
636
0
    }
637
638
0
    unsafe fn clone_from_with_ptr(&mut self, other: &Self, ptr: NonNull<Self::Elem>) -> NonNull<Self::Elem>
639
    {
640
0
        match (&mut *self, other) {
641
0
            (CowRepr::View(self_), CowRepr::View(other)) => self_.clone_from_with_ptr(other, ptr),
642
0
            (CowRepr::Owned(self_), CowRepr::Owned(other)) => self_.clone_from_with_ptr(other, ptr),
643
0
            (_, CowRepr::Owned(other)) => {
644
0
                let (cloned, ptr) = other.clone_with_ptr(ptr);
645
0
                *self = CowRepr::Owned(cloned);
646
0
                ptr
647
            }
648
0
            (_, CowRepr::View(other)) => {
649
0
                let (cloned, ptr) = other.clone_with_ptr(ptr);
650
0
                *self = CowRepr::View(cloned);
651
0
                ptr
652
            }
653
        }
654
0
    }
655
}
656
657
unsafe impl<'a, A> Data for CowRepr<'a, A>
658
{
659
    #[inline]
660
0
    fn into_owned<D>(self_: ArrayBase<CowRepr<'a, A>, D>) -> Array<Self::Elem, D>
661
0
    where
662
0
        A: Clone,
663
0
        D: Dimension,
664
    {
665
0
        match self_.data {
666
0
            CowRepr::View(_) => self_.to_owned(),
667
0
            CowRepr::Owned(data) => unsafe {
668
                // safe because the data is equivalent so ptr, dims remain valid
669
0
                ArrayBase::from_data_ptr(data, self_.parts.ptr).with_strides_dim(self_.parts.strides, self_.parts.dim)
670
            },
671
        }
672
0
    }
673
674
0
    fn try_into_owned_nocopy<D>(self_: ArrayBase<Self, D>) -> Result<Array<Self::Elem, D>, ArrayBase<Self, D>>
675
0
    where D: Dimension
676
    {
677
0
        match self_.data {
678
0
            CowRepr::View(_) => Err(self_),
679
0
            CowRepr::Owned(data) => unsafe {
680
                // safe because the data is equivalent so ptr, dims remain valid
681
0
                Ok(ArrayBase::from_data_ptr(data, self_.parts.ptr)
682
0
                    .with_strides_dim(self_.parts.strides, self_.parts.dim))
683
            },
684
        }
685
0
    }
686
}
687
688
unsafe impl<A> DataMut for CowRepr<'_, A> where A: Clone {}
689
690
unsafe impl<'a, A> DataOwned for CowRepr<'a, A>
691
{
692
    type MaybeUninit = CowRepr<'a, MaybeUninit<A>>;
693
694
0
    fn new(elements: Vec<A>) -> Self
695
    {
696
0
        CowRepr::Owned(OwnedRepr::new(elements))
697
0
    }
698
699
0
    fn into_shared<D>(self_: ArrayBase<Self, D>) -> ArcArray<A, D>
700
0
    where
701
0
        A: Clone,
702
0
        D: Dimension,
703
    {
704
0
        self_.into_owned().into_shared()
705
0
    }
706
}
707
708
/// Array representation trait.
709
///
710
/// The RawDataSubst trait maps the element type of array storage, while
711
/// keeping the same kind of storage.
712
///
713
/// For example, `RawDataSubst<B>` can map the type `OwnedRepr<A>` to `OwnedRepr<B>`.
714
pub trait RawDataSubst<A>: RawData
715
{
716
    /// The resulting array storage of the same kind but substituted element type
717
    type Output: RawData<Elem = A>;
718
719
    /// Unsafely translate the data representation from one element
720
    /// representation to another.
721
    ///
722
    /// ## Safety
723
    ///
724
    /// Caller must ensure the two types have the same representation.
725
    unsafe fn data_subst(self) -> Self::Output;
726
}
727
728
impl<A, B> RawDataSubst<B> for OwnedRepr<A>
729
{
730
    type Output = OwnedRepr<B>;
731
732
0
    unsafe fn data_subst(self) -> Self::Output
733
    {
734
0
        self.data_subst()
735
0
    }
Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<core::mem::maybe_uninit::MaybeUninit<f64>> as ndarray::data_traits::RawDataSubst<f64>>::data_subst
Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<core::mem::maybe_uninit::MaybeUninit<f32>> as ndarray::data_traits::RawDataSubst<f32>>::data_subst
Unexecuted instantiation: <ndarray::data_repr::OwnedRepr<_> as ndarray::data_traits::RawDataSubst<_>>::data_subst
736
}
737
738
impl<A, B> RawDataSubst<B> for OwnedArcRepr<A>
739
{
740
    type Output = OwnedArcRepr<B>;
741
742
0
    unsafe fn data_subst(self) -> Self::Output
743
    {
744
0
        OwnedArcRepr(Arc::from_raw(Arc::into_raw(self.0) as *const OwnedRepr<B>))
745
0
    }
746
}
747
748
impl<A, B> RawDataSubst<B> for RawViewRepr<*const A>
749
{
750
    type Output = RawViewRepr<*const B>;
751
752
0
    unsafe fn data_subst(self) -> Self::Output
753
    {
754
0
        RawViewRepr::new()
755
0
    }
756
}
757
758
impl<A, B> RawDataSubst<B> for RawViewRepr<*mut A>
759
{
760
    type Output = RawViewRepr<*mut B>;
761
762
0
    unsafe fn data_subst(self) -> Self::Output
763
    {
764
0
        RawViewRepr::new()
765
0
    }
766
}
767
768
impl<'a, A: 'a, B: 'a> RawDataSubst<B> for ViewRepr<&'a A>
769
{
770
    type Output = ViewRepr<&'a B>;
771
772
0
    unsafe fn data_subst(self) -> Self::Output
773
    {
774
0
        ViewRepr::new()
775
0
    }
776
}
777
778
impl<'a, A: 'a, B: 'a> RawDataSubst<B> for ViewRepr<&'a mut A>
779
{
780
    type Output = ViewRepr<&'a mut B>;
781
782
0
    unsafe fn data_subst(self) -> Self::Output
783
    {
784
0
        ViewRepr::new()
785
0
    }
786
}
787
788
impl<'a, A: 'a, B: 'a> RawDataSubst<B> for CowRepr<'a, A>
789
{
790
    type Output = CowRepr<'a, B>;
791
792
0
    unsafe fn data_subst(self) -> Self::Output
793
    {
794
0
        match self {
795
0
            CowRepr::View(view) => CowRepr::View(view.data_subst()),
796
0
            CowRepr::Owned(owned) => CowRepr::Owned(owned.data_subst()),
797
        }
798
0
    }
799
}