@@ -82,52 +82,54 @@ Usually one should pass in the result of an `align_of` call.
82
82
Add a new method ` align_offset ` to ` *const T ` and ` *mut T ` , which forwards to the
83
83
` align_offset ` intrinsic.
84
84
85
- Add two new functions ` align_to ` and ` align_to_mut ` to ` core::slice ` and ` std::slice `
86
- with the following signature:
85
+ Add two new methods ` align_to ` and ` align_to_mut ` to the slice type.
87
86
88
87
``` rust
89
- unsafe fn align_to <T , U >(& [U ]) -> (& [U ], & [T ], & [U ]) { /**/ }
90
- unsafe fn align_to_mut <T , U >(& mut [U ]) -> (& mut [U ], & mut [T ], & mut [U ]) { /**/ }
88
+ impl <T > [T ] {
89
+ /* ... other methods ... */
90
+ unsafe fn align_to <U >(& self ) -> (& [T ], & [U ], & [T ]) { /**/ }
91
+ unsafe fn align_to_mut <U >(& mut self ) -> (& mut [T ], & mut [U ], & mut [T ]) { /**/ }
92
+ }
91
93
```
92
94
93
95
` align_to ` can be implemented as
94
96
95
97
``` rust
96
- unsafe fn align_to <T , U >(slice : & [ U ] ) -> (& [U ], & [T ], & [U ]) {
98
+ unsafe fn align_to <U >(& self ) -> (& [T ], & [U ], & [T ]) {
97
99
use core :: mem :: {size_of, align_of};
98
- assert! (size_of :: <T >() != 0 && size_of :: <U >() != 0 , " don't use `align_to` with zsts" );
99
- if size_of :: <T >() % size_of :: <U >() == 0 {
100
- let align = align_of :: <T >();
101
- let size = size_of :: <T >();
102
- let source_size = size_of :: <U >();
100
+ assert! (size_of :: <U >() != 0 && size_of :: <T >() != 0 , " don't use `align_to` with zsts" );
101
+ if size_of :: <U >() % size_of :: <T >() == 0 {
102
+ let align = align_of :: <U >();
103
+ let size = size_of :: <U >();
104
+ let source_size = size_of :: <T >();
103
105
// number of bytes that need to be skipped until the pointer is aligned
104
- let offset = slice . as_ptr (). align_offset (align );
105
- // if `align_of::<T >() <= align_of::<U >()`, or if pointer is accidentally aligned, then `offset == 0`
106
+ let offset = self . as_ptr (). align_offset (align );
107
+ // if `align_of::<U >() <= align_of::<T >()`, or if pointer is accidentally aligned, then `offset == 0`
106
108
//
107
- // due to `size_of::<T >() % size_of::<U >() == 0`,
108
- // the fact that `size_of::<U >() > align_of::<U >()`,
109
- // and the fact that `align_of::<T >() > align_of::<U >()` if `offset != 0` we know
109
+ // due to `size_of::<U >() % size_of::<T >() == 0`,
110
+ // the fact that `size_of::<T >() > align_of::<T >()`,
111
+ // and the fact that `align_of::<U >() > align_of::<T >()` if `offset != 0` we know
110
112
// that `offset % source_size == 0`
111
113
let head_count = offset / source_size ;
112
- let split_position = core :: cmp :: max (slice . len (), head_count );
113
- let (head , tail ) = slice . split_at (split_position );
114
+ let split_position = core :: cmp :: max (self . len (), head_count );
115
+ let (head , tail ) = self . split_at (split_position );
114
116
// might be zero if not enough elements
115
117
let mid_count = tail . len () * source_size / size ;
116
- let mid = core :: slice :: from_raw_parts :: <T >(tail . as_ptr () as * const _ , mid_count );
117
- let tail = & tail [mid_count * size_of :: <T >().. ];
118
+ let mid = core :: slice :: from_raw_parts :: <U >(tail . as_ptr () as * const _ , mid_count );
119
+ let tail = & tail [mid_count * size_of :: <U >().. ];
118
120
(head , mid , tail )
119
121
} else {
120
- // can't properly fit a T into a sequence of `U `
121
- // FIXME: use GCD(size_of::<T >(), size_of::<U >()) as minimum `mid` size
122
- (slice , & [], & [])
122
+ // can't properly fit a U into a sequence of `T `
123
+ // FIXME: use GCD(size_of::<U >(), size_of::<T >()) as minimum `mid` size
124
+ (self , & [], & [])
123
125
}
124
126
}
125
127
```
126
128
127
129
on all current platforms. ` align_to_mut ` is expanded accordingly.
128
130
129
131
Users of the functions must process all the returned slices and
130
- cannot rely on any behaviour except that the ` &[T ] ` 's elements are correctly
132
+ cannot rely on any behaviour except that the ` &[U ] ` 's elements are correctly
131
133
aligned and that all bytes of the original slice are present in the resulting
132
134
three slices.
133
135
@@ -235,7 +237,7 @@ With the `align_to` function this could be written as
235
237
let len = text . len ();
236
238
let ptr = text . as_ptr ();
237
239
238
- let (head , mid , tail ) = std :: slice :: align_to :: <(usize , usize ), _ >( text );
240
+ let (head , mid , tail ) = text . align_to :: <(usize , usize )>( );
239
241
240
242
// search up to an aligned boundary
241
243
if let Some (index ) = head . iter (). position (| elt | * elt == x ) {
@@ -266,7 +268,7 @@ tail.iter().position(|elt| *elt == x).map(|i| head.len() + mid.len() + i)
266
268
A lint could be added to ` clippy ` which detects hand-written alignment checks and
267
269
suggests to use the ` align_to ` function instead.
268
270
269
- The ` std::mem::align ` function's documentation should point to ` std::slice ::align_to`
271
+ The ` std::mem::align ` function's documentation should point to ` [T] ::align_to`
270
272
in order to increase the visibility of the function. The documentation of
271
273
` std::mem::align ` should note that it is unidiomatic to manually align pointers,
272
274
since that might not be supported on all platforms and is prone to implementation
0 commit comments