Skip to content

Commit 7ce4590

Browse files
committed
Implement SliceIndex for ByteStr
1 parent 3a6d0ae commit 7ce4590

File tree

2 files changed

+97
-88
lines changed

2 files changed

+97
-88
lines changed

library/core/src/bstr/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ impl ByteStr {
9292
pub fn as_bytes(&self) -> &[u8] {
9393
&self.0
9494
}
95+
96+
#[doc(hidden)]
97+
#[unstable(feature = "bstr_internals", issue = "none")]
98+
#[inline]
99+
pub fn as_bytes_mut(&mut self) -> &mut [u8] {
100+
&mut self.0
101+
}
95102
}
96103

97104
#[unstable(feature = "bstr", issue = "134915")]

library/core/src/bstr/traits.rs

+90-88
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22
33
use crate::bstr::ByteStr;
44
use crate::cmp::Ordering;
5-
use crate::hash;
6-
use crate::ops::{
7-
Index, IndexMut, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive,
8-
};
5+
use crate::slice::SliceIndex;
6+
use crate::{hash, ops, range};
97

108
#[unstable(feature = "bstr", issue = "134915")]
119
impl Ord for ByteStr {
@@ -149,127 +147,131 @@ impl_partial_eq_n!(ByteStr, [u8; N]);
149147
impl_partial_eq_n!(ByteStr, &[u8; N]);
150148

151149
#[unstable(feature = "bstr", issue = "134915")]
152-
impl Index<usize> for ByteStr {
153-
type Output = u8;
150+
impl<I> ops::Index<I> for ByteStr
151+
where
152+
I: SliceIndex<ByteStr>,
153+
{
154+
type Output = I::Output;
154155

155156
#[inline]
156-
fn index(&self, idx: usize) -> &u8 {
157-
&self.0[idx]
157+
fn index(&self, index: I) -> &I::Output {
158+
index.index(self)
158159
}
159160
}
160161

161162
#[unstable(feature = "bstr", issue = "134915")]
162-
impl Index<RangeFull> for ByteStr {
163-
type Output = ByteStr;
164-
163+
impl<I> ops::IndexMut<I> for ByteStr
164+
where
165+
I: SliceIndex<ByteStr>,
166+
{
165167
#[inline]
166-
fn index(&self, _: RangeFull) -> &ByteStr {
167-
self
168+
fn index_mut(&mut self, index: I) -> &mut I::Output {
169+
index.index_mut(self)
168170
}
169171
}
170172

171173
#[unstable(feature = "bstr", issue = "134915")]
172-
impl Index<Range<usize>> for ByteStr {
174+
unsafe impl SliceIndex<ByteStr> for ops::RangeFull {
173175
type Output = ByteStr;
174-
175176
#[inline]
176-
fn index(&self, r: Range<usize>) -> &ByteStr {
177-
ByteStr::from_bytes(&self.0[r])
177+
fn get(self, slice: &ByteStr) -> Option<&Self::Output> {
178+
Some(slice)
178179
}
179-
}
180-
181-
#[unstable(feature = "bstr", issue = "134915")]
182-
impl Index<RangeInclusive<usize>> for ByteStr {
183-
type Output = ByteStr;
184-
185180
#[inline]
186-
fn index(&self, r: RangeInclusive<usize>) -> &ByteStr {
187-
ByteStr::from_bytes(&self.0[r])
181+
fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> {
182+
Some(slice)
188183
}
189-
}
190-
191-
#[unstable(feature = "bstr", issue = "134915")]
192-
impl Index<RangeFrom<usize>> for ByteStr {
193-
type Output = ByteStr;
194-
195184
#[inline]
196-
fn index(&self, r: RangeFrom<usize>) -> &ByteStr {
197-
ByteStr::from_bytes(&self.0[r])
185+
unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output {
186+
slice
198187
}
199-
}
200-
201-
#[unstable(feature = "bstr", issue = "134915")]
202-
impl Index<RangeTo<usize>> for ByteStr {
203-
type Output = ByteStr;
204-
205188
#[inline]
206-
fn index(&self, r: RangeTo<usize>) -> &ByteStr {
207-
ByteStr::from_bytes(&self.0[r])
189+
unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output {
190+
slice
208191
}
209-
}
210-
211-
#[unstable(feature = "bstr", issue = "134915")]
212-
impl Index<RangeToInclusive<usize>> for ByteStr {
213-
type Output = ByteStr;
214-
215192
#[inline]
216-
fn index(&self, r: RangeToInclusive<usize>) -> &ByteStr {
217-
ByteStr::from_bytes(&self.0[r])
193+
fn index(self, slice: &ByteStr) -> &Self::Output {
194+
slice
218195
}
219-
}
220-
221-
#[unstable(feature = "bstr", issue = "134915")]
222-
impl IndexMut<usize> for ByteStr {
223196
#[inline]
224-
fn index_mut(&mut self, idx: usize) -> &mut u8 {
225-
&mut self.0[idx]
197+
fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output {
198+
slice
226199
}
227200
}
228201

229202
#[unstable(feature = "bstr", issue = "134915")]
230-
impl IndexMut<RangeFull> for ByteStr {
203+
unsafe impl SliceIndex<ByteStr> for usize {
204+
type Output = u8;
231205
#[inline]
232-
fn index_mut(&mut self, _: RangeFull) -> &mut ByteStr {
233-
self
206+
fn get(self, slice: &ByteStr) -> Option<&Self::Output> {
207+
self.get(slice.as_bytes())
234208
}
235-
}
236-
237-
#[unstable(feature = "bstr", issue = "134915")]
238-
impl IndexMut<Range<usize>> for ByteStr {
239209
#[inline]
240-
fn index_mut(&mut self, r: Range<usize>) -> &mut ByteStr {
241-
ByteStr::from_bytes_mut(&mut self.0[r])
210+
fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> {
211+
self.get_mut(slice.as_bytes_mut())
242212
}
243-
}
244-
245-
#[unstable(feature = "bstr", issue = "134915")]
246-
impl IndexMut<RangeInclusive<usize>> for ByteStr {
247213
#[inline]
248-
fn index_mut(&mut self, r: RangeInclusive<usize>) -> &mut ByteStr {
249-
ByteStr::from_bytes_mut(&mut self.0[r])
214+
unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output {
215+
// SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
216+
unsafe { self.get_unchecked(slice as *const [u8]) }
250217
}
251-
}
252-
253-
#[unstable(feature = "bstr", issue = "134915")]
254-
impl IndexMut<RangeFrom<usize>> for ByteStr {
255218
#[inline]
256-
fn index_mut(&mut self, r: RangeFrom<usize>) -> &mut ByteStr {
257-
ByteStr::from_bytes_mut(&mut self.0[r])
219+
unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output {
220+
// SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
221+
unsafe { self.get_unchecked_mut(slice as *mut [u8]) }
258222
}
259-
}
260-
261-
#[unstable(feature = "bstr", issue = "134915")]
262-
impl IndexMut<RangeTo<usize>> for ByteStr {
263223
#[inline]
264-
fn index_mut(&mut self, r: RangeTo<usize>) -> &mut ByteStr {
265-
ByteStr::from_bytes_mut(&mut self.0[r])
224+
fn index(self, slice: &ByteStr) -> &Self::Output {
225+
self.index(slice.as_bytes())
266226
}
267-
}
268-
269-
#[unstable(feature = "bstr", issue = "134915")]
270-
impl IndexMut<RangeToInclusive<usize>> for ByteStr {
271227
#[inline]
272-
fn index_mut(&mut self, r: RangeToInclusive<usize>) -> &mut ByteStr {
273-
ByteStr::from_bytes_mut(&mut self.0[r])
228+
fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output {
229+
self.index_mut(slice.as_bytes_mut())
274230
}
275231
}
232+
233+
macro_rules! impl_slice_index {
234+
($index:ty) => {
235+
#[unstable(feature = "bstr", issue = "134915")]
236+
unsafe impl SliceIndex<ByteStr> for $index {
237+
type Output = ByteStr;
238+
#[inline]
239+
fn get(self, slice: &ByteStr) -> Option<&Self::Output> {
240+
self.get(slice.as_bytes()).map(ByteStr::from_bytes)
241+
}
242+
#[inline]
243+
fn get_mut(self, slice: &mut ByteStr) -> Option<&mut Self::Output> {
244+
self.get_mut(slice.as_bytes_mut()).map(ByteStr::from_bytes_mut)
245+
}
246+
#[inline]
247+
unsafe fn get_unchecked(self, slice: *const ByteStr) -> *const Self::Output {
248+
// SAFETY: the caller has to uphold the safety contract for `get_unchecked`.
249+
unsafe { self.get_unchecked(slice as *const [u8]) as *const ByteStr }
250+
}
251+
#[inline]
252+
unsafe fn get_unchecked_mut(self, slice: *mut ByteStr) -> *mut Self::Output {
253+
// SAFETY: the caller has to uphold the safety contract for `get_unchecked_mut`.
254+
unsafe { self.get_unchecked_mut(slice as *mut [u8]) as *mut ByteStr }
255+
}
256+
#[inline]
257+
fn index(self, slice: &ByteStr) -> &Self::Output {
258+
ByteStr::from_bytes(self.index(slice.as_bytes()))
259+
}
260+
#[inline]
261+
fn index_mut(self, slice: &mut ByteStr) -> &mut Self::Output {
262+
ByteStr::from_bytes_mut(self.index_mut(slice.as_bytes_mut()))
263+
}
264+
}
265+
};
266+
}
267+
268+
impl_slice_index!(ops::IndexRange);
269+
impl_slice_index!(ops::Range<usize>);
270+
impl_slice_index!(range::Range<usize>);
271+
impl_slice_index!(ops::RangeTo<usize>);
272+
impl_slice_index!(ops::RangeFrom<usize>);
273+
impl_slice_index!(range::RangeFrom<usize>);
274+
impl_slice_index!(ops::RangeInclusive<usize>);
275+
impl_slice_index!(range::RangeInclusive<usize>);
276+
impl_slice_index!(ops::RangeToInclusive<usize>);
277+
impl_slice_index!((ops::Bound<usize>, ops::Bound<usize>));

0 commit comments

Comments
 (0)