astd/
ptr.rs

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
//! A module that provides utility support for Pointers.
//!
//! This is largely a module containing iterators, thoguh it also offers basic
//! functionality that is either missing from the standard crate, or is otherwise
//! unavailabile due to instability.`

use core::ffi::c_uint;
use std::ops::Range;

/// An iterator over a contiguous sequence created from a pointer and the size.
pub struct Iter<'a, T>(std::slice::Iter<'a, T>);

impl<'a, T> std::ops::Deref for Iter<'a, T> {
  type Target = std::slice::Iter<'a, T>;

  fn deref(&self) -> &Self::Target {
    &self.0
  }
}

impl<'a, T> std::ops::DerefMut for Iter<'a, T> {
  fn deref_mut(&mut self) -> &mut Self::Target {
    &mut self.0
  }
}

impl<'a, T> Iterator for Iter<'a, T> {
  type Item = &'a T;
  fn next(&mut self) -> Option<Self::Item> {
    self.0.next()
  }
}

impl<'a, T> Iter<'a, T> {
  /// Constructs this [`PtrIter`] from a pointer and length.
  ///
  /// # Parameters
  ///
  /// * `ptr` - the pointer to the start of the contiguous data
  /// * `len` - the length of the contiguous sequence
  ///
  /// # Safety
  ///
  /// This iterator requires that `ptr` and `len` accurately model the amount
  /// of storage that is contiguously accessible.
  pub unsafe fn from_ptr_unchecked(ptr: *const T, len: c_uint) -> Self {
    let slice = std::slice::from_raw_parts(ptr, len as usize);
    Self::from_slice(slice)
  }

  /// Constructs this [`PtrIter`] from a range of pointer entries.
  ///
  /// # Parameters
  ///
  /// * `range` - the range of pointer entries
  ///
  /// # Safety
  ///
  /// This iterator requires that the `range.start <= range.end`, otherwise this
  /// will exhibit undefined behavior.
  pub unsafe fn from_ptr_range(range: Range<*const T>) -> Self {
    debug_assert!(range.start < range.end);
    Self::from_ptr_unchecked(range.start, range.start.offset_from(range.end) as c_uint)
  }

  /// Constructs this [`PtrIter`] from a slice of objects.
  ///
  /// # Parameters
  ///
  /// * `slice` - the slice to construct from
  #[inline(always)]
  pub fn from_slice(slice: &'a [T]) -> Self {
    Self(slice.iter())
  }
}

/// An iterator over a mutable contiguous sequence created from a pointer and
/// the size.
pub struct IterMut<'a, T>(std::slice::IterMut<'a, T>);

impl<'a, T> std::ops::Deref for IterMut<'a, T> {
  type Target = std::slice::IterMut<'a, T>;

  fn deref(&self) -> &Self::Target {
    &self.0
  }
}

impl<'a, T> std::ops::DerefMut for IterMut<'a, T> {
  fn deref_mut(&mut self) -> &mut Self::Target {
    &mut self.0
  }
}

impl<'a, T> Iterator for IterMut<'a, T> {
  type Item = &'a mut T;
  fn next(&mut self) -> Option<Self::Item> {
    self.0.next()
  }
}

impl<'a, T> IterMut<'a, T> {
  /// Constructs this [`PtrIter`] from a pointer and length.
  ///
  /// # Parameters
  ///
  /// * `ptr` - the pointer to the start of the contiguous data
  /// * `len` - the length of the contiguous sequence
  ///
  /// # Safety
  ///
  /// This iterator requires that `ptr` and `len` accurately model the amount
  /// of storage that is contiguously accessible.
  pub unsafe fn from_ptr_unchecked(ptr: *mut T, len: c_uint) -> Self {
    let slice = std::slice::from_raw_parts_mut(ptr, len as usize);
    Self::from_slice(slice)
  }

  /// Constructs this [`PtrIter`] from a range of pointer entries.
  ///
  /// # Parameters
  ///
  /// * `range` - the range of pointer entries
  ///
  /// # Safety
  ///
  /// This iterator requires that the `range.start <= range.end`, otherwise this
  /// will exhibit undefined behavior.
  pub unsafe fn from_ptr_range(range: Range<*mut T>) -> Self {
    debug_assert!(range.start < range.end);
    Self::from_ptr_unchecked(range.start, range.start.offset_from(range.end) as c_uint)
  }

  /// Constructs this [`PtrIter`] from a slice of objects.
  ///
  /// # Parameters
  ///
  /// * `slice` - the slice to construct from
  #[inline(always)]
  pub fn from_slice(slice: &'a mut [T]) -> Self {
    Self(slice.iter_mut())
  }
}