pasture_core/containers/
slice.rs

1use std::ops::Range;
2
3use crate::layout::{PointAttributeDefinition, PointAttributeMember, PointLayout};
4
5use super::{
6    BorrowedBuffer, BorrowedMutBuffer, ColumnarBuffer, ColumnarBufferMut, InterleavedBuffer,
7    InterleavedBufferMut,
8};
9
10/// Trait for buffers that support slicing, similar to the builtin slice type
11///
12/// # Note
13///
14/// If there would be better support for custom DSTs, the `BufferSlice` type could be a DST and
15/// we could use the `Index` trait instead.
16pub trait SliceBuffer<'a>
17where
18    Self: 'a,
19{
20    /// The slice type
21    type SliceType: BorrowedBuffer<'a>;
22
23    /// Take a immutable slice to this buffer using the given `range` of points
24    ///
25    /// # Panics
26    ///
27    /// May panic if `range` is out of bounds
28    fn slice(&'a self, range: Range<usize>) -> Self::SliceType;
29}
30
31/// Trait for buffers that support mutable slicing
32pub trait SliceBufferMut<'a>: SliceBuffer<'a>
33where
34    Self: 'a,
35{
36    type SliceTypeMut: BorrowedMutBuffer<'a>;
37    /// Take a mutable slice to this buffer using the given `range` of points
38    ///
39    /// # Panics
40    ///
41    /// May panic if `range` is out of bounds
42    fn slice_mut(&'a mut self, range: Range<usize>) -> Self::SliceTypeMut;
43}
44
45/// Converts a local point index to a global point index given the `point_range` of a slice. Performs
46/// bounds checks while converting
47///
48/// # Panics
49///
50/// If `local_index` is out of bounds of `point_range`
51fn get_and_check_global_point_index(local_index: usize, point_range: &Range<usize>) -> usize {
52    assert!(local_index < point_range.len());
53    local_index + point_range.start
54}
55
56/// Converts a local range of points ot a global range of points given the `point_range` of a slice.
57/// Performs bounds checks while converting
58///
59/// # Panics
60///
61/// If `local_range` is out of bounds of `point_range`
62fn get_and_check_global_point_range(
63    local_range: Range<usize>,
64    point_range: &Range<usize>,
65) -> Range<usize> {
66    assert!(local_range.end <= point_range.len());
67    if local_range.start >= local_range.end {
68        // Doesn't matter what range we return, as long as it is empty
69        point_range.end..point_range.end
70    } else {
71        (local_range.start + point_range.start)..(local_range.end + point_range.start)
72    }
73}
74
75/// An immutable slice to a point buffer. In terms of memory layout, the slice will have the same
76/// capabilities as the underlying buffer, i.e. if `T` implements `InterleavedBuffer`, so does this
77/// slice, and similar for the other memory layout traits.
78pub struct BufferSlice<'a, T: BorrowedBuffer<'a> + ?Sized> {
79    buffer: &'a T,
80    point_range: Range<usize>,
81}
82
83impl<'a, T: BorrowedBuffer<'a> + ?Sized> BufferSlice<'a, T> {
84    /// Creates a new `BufferSlice` for the given `point_range` in the given `buffer`
85    pub fn new(buffer: &'a T, point_range: Range<usize>) -> Self {
86        Self {
87            buffer,
88            point_range,
89        }
90    }
91}
92
93impl<'a, T: BorrowedBuffer<'a> + ?Sized> BorrowedBuffer<'a> for BufferSlice<'a, T> {
94    fn len(&self) -> usize {
95        self.point_range.end - self.point_range.start
96    }
97
98    fn point_layout(&self) -> &PointLayout {
99        self.buffer.point_layout()
100    }
101
102    fn get_point(&self, index: usize, data: &mut [u8]) {
103        self.buffer.get_point(
104            get_and_check_global_point_index(index, &self.point_range),
105            data,
106        )
107    }
108
109    fn get_point_range(&self, range: Range<usize>, data: &mut [u8]) {
110        self.buffer.get_point_range(
111            get_and_check_global_point_range(range, &self.point_range),
112            data,
113        )
114    }
115
116    fn get_attribute(&self, attribute: &PointAttributeDefinition, index: usize, data: &mut [u8]) {
117        self.buffer.get_attribute(
118            attribute,
119            get_and_check_global_point_index(index, &self.point_range),
120            data,
121        )
122    }
123
124    unsafe fn get_attribute_unchecked(
125        &self,
126        attribute_member: &PointAttributeMember,
127        index: usize,
128        data: &mut [u8],
129    ) {
130        self.buffer.get_attribute_unchecked(
131            attribute_member,
132            get_and_check_global_point_index(index, &self.point_range),
133            data,
134        )
135    }
136}
137
138impl<'a, T: InterleavedBuffer<'a> + ?Sized> InterleavedBuffer<'a> for BufferSlice<'a, T> {
139    fn get_point_ref<'c>(&'c self, index: usize) -> &'c [u8]
140    where
141        'a: 'c,
142    {
143        self.buffer
144            .get_point_ref(get_and_check_global_point_index(index, &self.point_range))
145    }
146
147    fn get_point_range_ref<'c>(&'c self, range: Range<usize>) -> &'c [u8]
148    where
149        'a: 'c,
150    {
151        self.buffer
152            .get_point_range_ref(get_and_check_global_point_range(range, &self.point_range))
153    }
154}
155
156impl<'a, T: ColumnarBuffer<'a> + ?Sized> ColumnarBuffer<'a> for BufferSlice<'a, T> {
157    fn get_attribute_ref<'c>(
158        &'c self,
159        attribute: &PointAttributeDefinition,
160        index: usize,
161    ) -> &'c [u8]
162    where
163        'a: 'c,
164    {
165        self.buffer.get_attribute_ref(
166            attribute,
167            get_and_check_global_point_index(index, &self.point_range),
168        )
169    }
170
171    fn get_attribute_range_ref<'c>(
172        &'c self,
173        attribute: &PointAttributeDefinition,
174        range: Range<usize>,
175    ) -> &'c [u8]
176    where
177        'a: 'c,
178    {
179        self.buffer.get_attribute_range_ref(
180            attribute,
181            get_and_check_global_point_range(range, &self.point_range),
182        )
183    }
184}
185
186impl<'a, T: BorrowedBuffer<'a> + ?Sized> SliceBuffer<'a> for BufferSlice<'a, T> {
187    type SliceType = BufferSlice<'a, T>;
188
189    fn slice(&self, range: Range<usize>) -> BufferSlice<'a, T> {
190        assert!(range.start <= self.len());
191        assert!(range.end <= self.len());
192        let global_range = if range.start > range.end {
193            (self.point_range.start + range.end)..(self.point_range.start + range.end)
194        } else {
195            (self.point_range.start + range.start)..(self.point_range.start + range.end)
196        };
197        BufferSlice {
198            buffer: self.buffer,
199            point_range: global_range,
200        }
201    }
202}
203
204/// A mutable slice to a point buffer. Works like [`BufferSlice`], but allows mutable access to the
205/// underlying buffer. This type conditionally implements the [`InterleavedBufferMut`] and [`ColumnarBufferMut`]
206/// traits if `T` implements them
207pub struct BufferSliceMut<'a, T: BorrowedMutBuffer<'a> + ?Sized> {
208    buffer: &'a mut T,
209    point_range: Range<usize>,
210}
211
212impl<'a, T: BorrowedMutBuffer<'a> + ?Sized> BufferSliceMut<'a, T> {
213    /// Creates a new `BufferSliceMut` for the given `point_range` in the given `buffer`
214    pub fn new(buffer: &'a mut T, point_range: Range<usize>) -> Self {
215        Self {
216            buffer,
217            point_range,
218        }
219    }
220
221    fn get_and_check_global_point_index(&self, local_index: usize) -> usize {
222        assert!(local_index < self.point_range.end);
223        local_index + self.point_range.start
224    }
225
226    fn get_and_check_global_point_range(&self, local_range: Range<usize>) -> Range<usize> {
227        assert!(local_range.end <= self.point_range.end);
228        if local_range.start >= local_range.end {
229            // Doesn't matter what range we return, as long as it is empty
230            self.point_range.end..self.point_range.end
231        } else {
232            (local_range.start + self.point_range.start)..(local_range.end + self.point_range.start)
233        }
234    }
235}
236
237impl<'a, T: BorrowedMutBuffer<'a> + ?Sized> BorrowedBuffer<'a> for BufferSliceMut<'a, T> {
238    fn len(&self) -> usize {
239        self.point_range.end - self.point_range.start
240    }
241
242    fn point_layout(&self) -> &PointLayout {
243        self.buffer.point_layout()
244    }
245
246    fn get_point(&self, index: usize, data: &mut [u8]) {
247        self.buffer
248            .get_point(self.get_and_check_global_point_index(index), data)
249    }
250
251    fn get_point_range(&self, range: Range<usize>, data: &mut [u8]) {
252        self.buffer
253            .get_point_range(self.get_and_check_global_point_range(range), data)
254    }
255
256    fn get_attribute(&self, attribute: &PointAttributeDefinition, index: usize, data: &mut [u8]) {
257        self.buffer.get_attribute(
258            attribute,
259            self.get_and_check_global_point_index(index),
260            data,
261        )
262    }
263
264    unsafe fn get_attribute_unchecked(
265        &self,
266        attribute_member: &PointAttributeMember,
267        index: usize,
268        data: &mut [u8],
269    ) {
270        self.buffer.get_attribute_unchecked(
271            attribute_member,
272            self.get_and_check_global_point_index(index),
273            data,
274        )
275    }
276}
277
278impl<'a, T: BorrowedMutBuffer<'a> + ?Sized> BorrowedMutBuffer<'a> for BufferSliceMut<'a, T> {
279    unsafe fn set_point(&mut self, index: usize, point_data: &[u8]) {
280        self.buffer
281            .set_point(self.get_and_check_global_point_index(index), point_data)
282    }
283
284    unsafe fn set_attribute(
285        &mut self,
286        attribute: &PointAttributeDefinition,
287        index: usize,
288        attribute_data: &[u8],
289    ) {
290        self.buffer.set_attribute(
291            attribute,
292            self.get_and_check_global_point_index(index),
293            attribute_data,
294        )
295    }
296
297    fn swap(&mut self, from_index: usize, to_index: usize) {
298        self.buffer.swap(
299            self.get_and_check_global_point_index(from_index),
300            self.get_and_check_global_point_index(to_index),
301        )
302    }
303
304    unsafe fn set_point_range(&mut self, point_range: Range<usize>, point_data: &[u8]) {
305        self.buffer.set_point_range(
306            self.get_and_check_global_point_range(point_range),
307            point_data,
308        )
309    }
310
311    unsafe fn set_attribute_range(
312        &mut self,
313        attribute: &PointAttributeDefinition,
314        point_range: Range<usize>,
315        attribute_data: &[u8],
316    ) {
317        self.buffer.set_attribute_range(
318            attribute,
319            self.get_and_check_global_point_range(point_range),
320            attribute_data,
321        )
322    }
323}
324
325impl<'a, T: InterleavedBuffer<'a> + BorrowedMutBuffer<'a> + ?Sized> InterleavedBuffer<'a>
326    for BufferSliceMut<'a, T>
327{
328    fn get_point_ref<'b>(&'b self, index: usize) -> &'b [u8]
329    where
330        'a: 'b,
331    {
332        self.buffer
333            .get_point_ref(self.get_and_check_global_point_index(index))
334    }
335
336    fn get_point_range_ref<'b>(&'b self, range: Range<usize>) -> &'b [u8]
337    where
338        'a: 'b,
339    {
340        self.buffer
341            .get_point_range_ref(self.get_and_check_global_point_range(range))
342    }
343}
344
345impl<'a, T: InterleavedBufferMut<'a> + BorrowedMutBuffer<'a> + ?Sized> InterleavedBufferMut<'a>
346    for BufferSliceMut<'a, T>
347{
348    fn get_point_mut<'b>(&'b mut self, index: usize) -> &'b mut [u8]
349    where
350        'a: 'b,
351    {
352        self.buffer
353            .get_point_mut(self.get_and_check_global_point_index(index))
354    }
355
356    fn get_point_range_mut<'b>(&'b mut self, range: Range<usize>) -> &'b mut [u8]
357    where
358        'a: 'b,
359    {
360        self.buffer
361            .get_point_range_mut(self.get_and_check_global_point_range(range))
362    }
363}
364
365impl<'a, T: ColumnarBuffer<'a> + BorrowedMutBuffer<'a> + ?Sized> ColumnarBuffer<'a>
366    for BufferSliceMut<'a, T>
367{
368    fn get_attribute_ref<'b>(
369        &'b self,
370        attribute: &PointAttributeDefinition,
371        index: usize,
372    ) -> &'b [u8]
373    where
374        'a: 'b,
375    {
376        self.buffer
377            .get_attribute_ref(attribute, self.get_and_check_global_point_index(index))
378    }
379
380    fn get_attribute_range_ref<'b>(
381        &'b self,
382        attribute: &PointAttributeDefinition,
383        range: Range<usize>,
384    ) -> &'b [u8]
385    where
386        'a: 'b,
387    {
388        self.buffer
389            .get_attribute_range_ref(attribute, self.get_and_check_global_point_range(range))
390    }
391}
392
393impl<'a, T: ColumnarBufferMut<'a> + BorrowedMutBuffer<'a> + ?Sized> ColumnarBufferMut<'a>
394    for BufferSliceMut<'a, T>
395{
396    fn get_attribute_mut<'b>(
397        &'b mut self,
398        attribute: &PointAttributeDefinition,
399        index: usize,
400    ) -> &'b mut [u8]
401    where
402        'a: 'b,
403    {
404        self.buffer
405            .get_attribute_mut(attribute, self.get_and_check_global_point_index(index))
406    }
407
408    fn get_attribute_range_mut<'b>(
409        &'b mut self,
410        attribute: &PointAttributeDefinition,
411        range: Range<usize>,
412    ) -> &'b mut [u8]
413    where
414        'a: 'b,
415    {
416        self.buffer
417            .get_attribute_range_mut(attribute, self.get_and_check_global_point_range(range))
418    }
419}
420
421impl<'a, T: BorrowedBuffer<'a> + BorrowedMutBuffer<'a> + ?Sized> SliceBuffer<'a>
422    for BufferSliceMut<'a, T>
423{
424    type SliceType = BufferSlice<'a, T>;
425
426    fn slice(&'a self, range: Range<usize>) -> Self::SliceType {
427        assert!(range.start <= self.len());
428        assert!(range.end <= self.len());
429        let global_range = if range.start > range.end {
430            (self.point_range.start + range.end)..(self.point_range.start + range.end)
431        } else {
432            (self.point_range.start + range.start)..(self.point_range.start + range.end)
433        };
434        BufferSlice {
435            buffer: self.buffer,
436            point_range: global_range,
437        }
438    }
439}
440
441impl<'a, T: BorrowedBuffer<'a> + BorrowedMutBuffer<'a> + ?Sized> SliceBufferMut<'a>
442    for BufferSliceMut<'a, T>
443{
444    type SliceTypeMut = BufferSliceMut<'a, T>;
445
446    fn slice_mut(&'a mut self, range: Range<usize>) -> Self::SliceTypeMut {
447        assert!(range.start <= self.len());
448        assert!(range.end <= self.len());
449        let global_range = if range.start > range.end {
450            (self.point_range.start + range.end)..(self.point_range.start + range.end)
451        } else {
452            (self.point_range.start + range.start)..(self.point_range.start + range.end)
453        };
454        BufferSliceMut {
455            buffer: self.buffer,
456            point_range: global_range,
457        }
458    }
459}
460
461/// A buffer slice for an interleaved buffer
462pub struct BufferSliceInterleaved<'a, T: InterleavedBuffer<'a> + ?Sized>(BufferSlice<'a, T>);
463
464impl<'a, T: InterleavedBuffer<'a> + ?Sized> BufferSliceInterleaved<'a, T> {
465    pub fn new(buffer: &'a T, point_range: Range<usize>) -> Self {
466        Self(BufferSlice::new(buffer, point_range))
467    }
468}
469
470impl<'a, T: InterleavedBuffer<'a> + ?Sized> BorrowedBuffer<'a> for BufferSliceInterleaved<'a, T> {
471    fn len(&self) -> usize {
472        self.0.len()
473    }
474
475    fn point_layout(&self) -> &PointLayout {
476        self.0.point_layout()
477    }
478
479    fn get_point(&self, index: usize, data: &mut [u8]) {
480        self.0.get_point(index, data)
481    }
482
483    fn get_point_range(&self, range: Range<usize>, data: &mut [u8]) {
484        self.0.get_point_range(range, data)
485    }
486
487    unsafe fn get_attribute_unchecked(
488        &self,
489        attribute_member: &PointAttributeMember,
490        index: usize,
491        data: &mut [u8],
492    ) {
493        self.0
494            .get_attribute_unchecked(attribute_member, index, data)
495    }
496
497    fn as_interleaved(&self) -> Option<&dyn InterleavedBuffer<'a>> {
498        Some(self)
499    }
500}
501
502impl<'a, T: InterleavedBuffer<'a> + ?Sized> InterleavedBuffer<'a>
503    for BufferSliceInterleaved<'a, T>
504{
505    fn get_point_ref<'c>(&'c self, index: usize) -> &'c [u8]
506    where
507        'a: 'c,
508    {
509        self.0.get_point_ref(index)
510    }
511
512    fn get_point_range_ref<'c>(&'c self, range: Range<usize>) -> &'c [u8]
513    where
514        'a: 'c,
515    {
516        self.0.get_point_range_ref(range)
517    }
518}
519
520impl<'a, T: InterleavedBuffer<'a> + ?Sized> SliceBuffer<'a> for BufferSliceInterleaved<'a, T> {
521    type SliceType = Self;
522
523    fn slice(&'a self, range: Range<usize>) -> Self::SliceType {
524        Self(self.0.slice(range))
525    }
526}
527
528/// A mutable buffer slice for an interleaved buffer
529pub struct BufferSliceInterleavedMut<'a, T: InterleavedBufferMut<'a> + ?Sized>(
530    BufferSliceMut<'a, T>,
531);
532
533impl<'a, T: InterleavedBufferMut<'a> + ?Sized> BufferSliceInterleavedMut<'a, T> {
534    pub fn new(buffer: &'a mut T, point_range: Range<usize>) -> Self {
535        Self(BufferSliceMut::new(buffer, point_range))
536    }
537}
538
539impl<'a, T: InterleavedBufferMut<'a> + ?Sized> BorrowedBuffer<'a>
540    for BufferSliceInterleavedMut<'a, T>
541{
542    fn len(&self) -> usize {
543        self.0.len()
544    }
545
546    fn point_layout(&self) -> &PointLayout {
547        self.0.point_layout()
548    }
549
550    fn get_point(&self, index: usize, data: &mut [u8]) {
551        self.0.get_point(index, data)
552    }
553
554    fn get_point_range(&self, range: Range<usize>, data: &mut [u8]) {
555        self.0.get_point_range(range, data)
556    }
557
558    unsafe fn get_attribute_unchecked(
559        &self,
560        attribute_member: &PointAttributeMember,
561        index: usize,
562        data: &mut [u8],
563    ) {
564        self.0
565            .get_attribute_unchecked(attribute_member, index, data)
566    }
567
568    fn as_interleaved(&self) -> Option<&dyn InterleavedBuffer<'a>> {
569        Some(self)
570    }
571}
572
573impl<'a, T: InterleavedBufferMut<'a> + ?Sized> BorrowedMutBuffer<'a>
574    for BufferSliceInterleavedMut<'a, T>
575{
576    unsafe fn set_point(&mut self, index: usize, point_data: &[u8]) {
577        self.0.set_point(index, point_data)
578    }
579
580    unsafe fn set_point_range(&mut self, point_range: Range<usize>, point_data: &[u8]) {
581        self.0.set_point_range(point_range, point_data)
582    }
583
584    unsafe fn set_attribute(
585        &mut self,
586        attribute: &PointAttributeDefinition,
587        index: usize,
588        attribute_data: &[u8],
589    ) {
590        self.0.set_attribute(attribute, index, attribute_data)
591    }
592
593    unsafe fn set_attribute_range(
594        &mut self,
595        attribute: &PointAttributeDefinition,
596        point_range: Range<usize>,
597        attribute_data: &[u8],
598    ) {
599        self.0
600            .set_attribute_range(attribute, point_range, attribute_data)
601    }
602
603    fn swap(&mut self, from_index: usize, to_index: usize) {
604        self.0.swap(from_index, to_index)
605    }
606
607    fn as_interleaved_mut(&mut self) -> Option<&mut dyn InterleavedBufferMut<'a>> {
608        Some(self)
609    }
610}
611
612impl<'a, T: InterleavedBufferMut<'a> + ?Sized> InterleavedBuffer<'a>
613    for BufferSliceInterleavedMut<'a, T>
614{
615    fn get_point_ref<'b>(&'b self, index: usize) -> &'b [u8]
616    where
617        'a: 'b,
618    {
619        self.0.get_point_ref(index)
620    }
621
622    fn get_point_range_ref<'b>(&'b self, range: Range<usize>) -> &'b [u8]
623    where
624        'a: 'b,
625    {
626        self.0.get_point_range_ref(range)
627    }
628}
629
630impl<'a, T: InterleavedBufferMut<'a> + ?Sized> InterleavedBufferMut<'a>
631    for BufferSliceInterleavedMut<'a, T>
632{
633    fn get_point_mut<'b>(&'b mut self, index: usize) -> &'b mut [u8]
634    where
635        'a: 'b,
636    {
637        self.0.get_point_mut(index)
638    }
639
640    fn get_point_range_mut<'b>(&'b mut self, range: Range<usize>) -> &'b mut [u8]
641    where
642        'a: 'b,
643    {
644        self.0.get_point_range_mut(range)
645    }
646}
647
648impl<'a, T: InterleavedBufferMut<'a> + ?Sized> SliceBuffer<'a>
649    for BufferSliceInterleavedMut<'a, T>
650{
651    type SliceType = BufferSliceInterleaved<'a, T>;
652
653    fn slice(&'a self, range: Range<usize>) -> Self::SliceType {
654        BufferSliceInterleaved(self.0.slice(range))
655    }
656}
657
658impl<'a, T: InterleavedBufferMut<'a> + ?Sized> SliceBufferMut<'a>
659    for BufferSliceInterleavedMut<'a, T>
660{
661    type SliceTypeMut = Self;
662
663    fn slice_mut(&'a mut self, range: Range<usize>) -> Self::SliceTypeMut {
664        Self(self.0.slice_mut(range))
665    }
666}
667
668/// A buffer slice for a columnar buffer
669pub struct BufferSliceColumnar<'a, T: ColumnarBuffer<'a> + ?Sized>(BufferSlice<'a, T>);
670
671impl<'a, T: ColumnarBuffer<'a> + ?Sized> BufferSliceColumnar<'a, T> {
672    pub fn new(buffer: &'a T, point_range: Range<usize>) -> Self {
673        Self(BufferSlice::new(buffer, point_range))
674    }
675}
676
677impl<'a, T: ColumnarBuffer<'a> + ?Sized> BorrowedBuffer<'a> for BufferSliceColumnar<'a, T> {
678    fn len(&self) -> usize {
679        self.0.len()
680    }
681
682    fn point_layout(&self) -> &PointLayout {
683        self.0.point_layout()
684    }
685
686    fn get_point(&self, index: usize, data: &mut [u8]) {
687        self.0.get_point(index, data)
688    }
689
690    fn get_point_range(&self, range: Range<usize>, data: &mut [u8]) {
691        self.0.get_point_range(range, data)
692    }
693
694    unsafe fn get_attribute_unchecked(
695        &self,
696        attribute_member: &PointAttributeMember,
697        index: usize,
698        data: &mut [u8],
699    ) {
700        self.0
701            .get_attribute_unchecked(attribute_member, index, data)
702    }
703
704    fn as_columnar(&self) -> Option<&dyn ColumnarBuffer<'a>> {
705        Some(self)
706    }
707}
708
709impl<'a, T: ColumnarBuffer<'a> + ?Sized> ColumnarBuffer<'a> for BufferSliceColumnar<'a, T> {
710    fn get_attribute_ref<'c>(
711        &'c self,
712        attribute: &PointAttributeDefinition,
713        index: usize,
714    ) -> &'c [u8]
715    where
716        'a: 'c,
717    {
718        self.0.get_attribute_ref(attribute, index)
719    }
720
721    fn get_attribute_range_ref<'c>(
722        &'c self,
723        attribute: &PointAttributeDefinition,
724        range: Range<usize>,
725    ) -> &'c [u8]
726    where
727        'a: 'c,
728    {
729        self.0.get_attribute_range_ref(attribute, range)
730    }
731}
732
733/// A mutable buffer slice for a columnar buffer
734pub struct BufferSliceColumnarMut<'a, T: ColumnarBufferMut<'a> + ?Sized>(BufferSliceMut<'a, T>);
735
736impl<'a, T: ColumnarBufferMut<'a> + ?Sized> BufferSliceColumnarMut<'a, T> {
737    pub fn new(buffer: &'a mut T, point_range: Range<usize>) -> Self {
738        Self(BufferSliceMut::new(buffer, point_range))
739    }
740}
741
742impl<'a, T: ColumnarBufferMut<'a> + ?Sized> BorrowedBuffer<'a> for BufferSliceColumnarMut<'a, T> {
743    fn len(&self) -> usize {
744        self.0.len()
745    }
746
747    fn point_layout(&self) -> &PointLayout {
748        self.0.point_layout()
749    }
750
751    fn get_point(&self, index: usize, data: &mut [u8]) {
752        self.0.get_point(index, data)
753    }
754
755    fn get_point_range(&self, range: Range<usize>, data: &mut [u8]) {
756        self.0.get_point_range(range, data)
757    }
758
759    unsafe fn get_attribute_unchecked(
760        &self,
761        attribute_member: &PointAttributeMember,
762        index: usize,
763        data: &mut [u8],
764    ) {
765        self.0
766            .get_attribute_unchecked(attribute_member, index, data)
767    }
768
769    fn as_columnar(&self) -> Option<&dyn ColumnarBuffer<'a>> {
770        Some(self)
771    }
772}
773
774impl<'a, T: ColumnarBufferMut<'a> + ?Sized> BorrowedMutBuffer<'a>
775    for BufferSliceColumnarMut<'a, T>
776{
777    unsafe fn set_point(&mut self, index: usize, point_data: &[u8]) {
778        self.0.set_point(index, point_data)
779    }
780
781    unsafe fn set_point_range(&mut self, point_range: Range<usize>, point_data: &[u8]) {
782        self.0.set_point_range(point_range, point_data)
783    }
784
785    unsafe fn set_attribute(
786        &mut self,
787        attribute: &PointAttributeDefinition,
788        index: usize,
789        attribute_data: &[u8],
790    ) {
791        self.0.set_attribute(attribute, index, attribute_data)
792    }
793
794    unsafe fn set_attribute_range(
795        &mut self,
796        attribute: &PointAttributeDefinition,
797        point_range: Range<usize>,
798        attribute_data: &[u8],
799    ) {
800        self.0
801            .set_attribute_range(attribute, point_range, attribute_data)
802    }
803
804    fn swap(&mut self, from_index: usize, to_index: usize) {
805        self.0.swap(from_index, to_index)
806    }
807
808    fn as_columnar_mut(&mut self) -> Option<&mut dyn ColumnarBufferMut<'a>> {
809        Some(self)
810    }
811}
812
813impl<'a, T: ColumnarBufferMut<'a> + ?Sized> ColumnarBuffer<'a> for BufferSliceColumnarMut<'a, T> {
814    fn get_attribute_ref<'b>(
815        &'b self,
816        attribute: &PointAttributeDefinition,
817        index: usize,
818    ) -> &'b [u8]
819    where
820        'a: 'b,
821    {
822        self.0.get_attribute_ref(attribute, index)
823    }
824
825    fn get_attribute_range_ref<'b>(
826        &'b self,
827        attribute: &PointAttributeDefinition,
828        range: Range<usize>,
829    ) -> &'b [u8]
830    where
831        'a: 'b,
832    {
833        self.0.get_attribute_range_ref(attribute, range)
834    }
835}
836
837impl<'a, T: ColumnarBufferMut<'a> + ?Sized> ColumnarBufferMut<'a>
838    for BufferSliceColumnarMut<'a, T>
839{
840    fn get_attribute_mut<'b>(
841        &'b mut self,
842        attribute: &PointAttributeDefinition,
843        index: usize,
844    ) -> &'b mut [u8]
845    where
846        'a: 'b,
847    {
848        self.0.get_attribute_mut(attribute, index)
849    }
850
851    fn get_attribute_range_mut<'b>(
852        &'b mut self,
853        attribute: &PointAttributeDefinition,
854        range: Range<usize>,
855    ) -> &'b mut [u8]
856    where
857        'a: 'b,
858    {
859        self.0.get_attribute_range_mut(attribute, range)
860    }
861}
862
863macro_rules! impl_slice_buffer_for_trait_object {
864    ($buffer_trait:ident, $slice_type:ident) => {
865        impl<'a> SliceBuffer<'a> for dyn $buffer_trait<'a> + 'a {
866            type SliceType = $slice_type<'a, dyn $buffer_trait<'a> + 'a>;
867
868            fn slice(&'a self, range: Range<usize>) -> Self::SliceType {
869                $slice_type::new(self, range)
870            }
871        }
872    };
873}
874
875impl_slice_buffer_for_trait_object! {BorrowedBuffer, BufferSlice}
876impl_slice_buffer_for_trait_object! {BorrowedMutBuffer, BufferSlice}
877impl_slice_buffer_for_trait_object! {InterleavedBuffer, BufferSliceInterleaved}
878impl_slice_buffer_for_trait_object! {InterleavedBufferMut, BufferSliceInterleaved}
879impl_slice_buffer_for_trait_object! {ColumnarBuffer, BufferSliceColumnar}
880impl_slice_buffer_for_trait_object! {ColumnarBufferMut, BufferSliceColumnar}
881
882macro_rules! impl_slice_buffer_mut_for_trait_object {
883    ($buffer_trait:ident, $slice_type:ident) => {
884        impl<'a> SliceBufferMut<'a> for dyn $buffer_trait<'a> + 'a {
885            type SliceTypeMut = $slice_type<'a, dyn $buffer_trait<'a> + 'a>;
886
887            fn slice_mut(&'a mut self, range: Range<usize>) -> Self::SliceTypeMut {
888                $slice_type::new(self, range)
889            }
890        }
891    };
892}
893
894impl_slice_buffer_mut_for_trait_object! {BorrowedMutBuffer, BufferSliceMut}
895impl_slice_buffer_mut_for_trait_object! {InterleavedBufferMut, BufferSliceInterleavedMut}
896impl_slice_buffer_mut_for_trait_object! {ColumnarBufferMut, BufferSliceColumnarMut}
897
898#[cfg(test)]
899mod tests {
900    use rand::{thread_rng, Rng};
901
902    use crate::{
903        containers::{HashMapBuffer, VectorBuffer},
904        test_utils::{CustomPointTypeBig, DefaultPointDistribution},
905    };
906
907    use super::*;
908
909    #[test]
910    fn slices_on_trait_objects() {
911        const COUNT: usize = 16;
912        let test_data: Vec<CustomPointTypeBig> = thread_rng()
913            .sample_iter(DefaultPointDistribution)
914            .take(COUNT)
915            .collect();
916
917        let mut vector_buffer: VectorBuffer = test_data.iter().copied().collect();
918
919        {
920            let dyn_buffer = vector_buffer.as_interleaved().unwrap();
921            let dyn_buffer_slice = dyn_buffer.slice(0..2);
922            assert_eq!(2, dyn_buffer_slice.len());
923        }
924        {
925            let dyn_buffer_mut = vector_buffer.as_interleaved_mut().unwrap();
926            let dyn_buffer_mut_slice = dyn_buffer_mut.slice(0..2);
927            assert_eq!(2, dyn_buffer_mut_slice.len());
928        }
929        {
930            let dyn_buffer_mut = vector_buffer.as_interleaved_mut().unwrap();
931            let dyn_buffer_mut_slice_mut = dyn_buffer_mut.slice_mut(0..2);
932            assert_eq!(2, dyn_buffer_mut_slice_mut.len());
933        }
934
935        let mut hashmap_buffer: HashMapBuffer = test_data.iter().copied().collect();
936
937        {
938            let dyn_buffer = hashmap_buffer.as_columnar().unwrap();
939            let dyn_buffer_slice = dyn_buffer.slice(0..2);
940            assert_eq!(2, dyn_buffer_slice.len());
941        }
942        {
943            let dyn_buffer_mut = hashmap_buffer.as_columnar_mut().unwrap();
944            let dyn_buffer_mut_slice = dyn_buffer_mut.slice(0..2);
945            assert_eq!(2, dyn_buffer_mut_slice.len());
946        }
947        {
948            let dyn_buffer_mut = hashmap_buffer.as_columnar_mut().unwrap();
949            let dyn_buffer_mut_slice_mut = dyn_buffer_mut.slice_mut(0..2);
950            assert_eq!(2, dyn_buffer_mut_slice_mut.len());
951        }
952    }
953}