Skip to content

Commit 37ad800

Browse files
committed
Add [f32]::sort_floats and [f64]::sort_floats
It's inconvenient to sort a slice or Vec of floats, compared to sorting integers. To simplify numeric code, add a convenience method to `[f32]` and `[f64]` to sort them using `sort_unstable_by` with `total_cmp`. Add lang items slice_f32 and slice_f64 to handle the two new impl blocks.
1 parent 21b4a9c commit 37ad800

File tree

7 files changed

+98
-4
lines changed

7 files changed

+98
-4
lines changed

compiler/rustc_hir/src/lang_items.rs

+2
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ language_item_table! {
169169
Str, sym::str, str_impl, Target::Impl, GenericRequirement::None;
170170
Array, sym::array, array_impl, Target::Impl, GenericRequirement::None;
171171
Slice, sym::slice, slice_impl, Target::Impl, GenericRequirement::None;
172+
SliceF32, sym::slice_f32, slice_f32_impl, Target::Impl, GenericRequirement::None;
173+
SliceF64, sym::slice_f64, slice_f64_impl, Target::Impl, GenericRequirement::None;
172174
SliceU8, sym::slice_u8, slice_u8_impl, Target::Impl, GenericRequirement::None;
173175
StrAlloc, sym::str_alloc, str_alloc_impl, Target::Impl, GenericRequirement::None;
174176
SliceAlloc, sym::slice_alloc, slice_alloc_impl, Target::Impl, GenericRequirement::None;

compiler/rustc_span/src/symbol.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1295,6 +1295,8 @@ symbols! {
12951295
skip,
12961296
slice,
12971297
slice_alloc,
1298+
slice_f32,
1299+
slice_f64,
12981300
slice_len_fn,
12991301
slice_patterns,
13001302
slice_u8,

compiler/rustc_typeck/src/check/method/probe.rs

+2
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
668668
ty::Slice(_) => {
669669
for lang_def_id in [
670670
lang_items.slice_impl(),
671+
lang_items.slice_f32_impl(),
672+
lang_items.slice_f64_impl(),
671673
lang_items.slice_u8_impl(),
672674
lang_items.slice_alloc_impl(),
673675
lang_items.slice_u8_alloc_impl(),

compiler/rustc_typeck/src/coherence/inherent_impls.rs

+22
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,28 @@ impl<'tcx> ItemLikeVisitor<'_> for InherentCollect<'tcx> {
114114
assoc_items,
115115
);
116116
}
117+
ty::Slice(slice_item) if slice_item == self.tcx.types.f32 => {
118+
self.check_primitive_impl(
119+
item.def_id,
120+
lang_items.slice_f32_impl(),
121+
None,
122+
"slice_f32",
123+
"[f32]",
124+
item.span,
125+
assoc_items,
126+
);
127+
}
128+
ty::Slice(slice_item) if slice_item == self.tcx.types.f64 => {
129+
self.check_primitive_impl(
130+
item.def_id,
131+
lang_items.slice_f64_impl(),
132+
None,
133+
"slice_f64",
134+
"[f64]",
135+
item.span,
136+
assoc_items,
137+
);
138+
}
117139
ty::Slice(_) => {
118140
self.check_primitive_impl(
119141
item.def_id,

library/core/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@
151151
#![feature(variant_count)]
152152
#![feature(const_array_from_ref)]
153153
#![feature(const_slice_from_ref)]
154+
// Library features:
155+
#![feature(total_cmp)]
154156
//
155157
// Language features:
156158
#![feature(abi_unadjusted)]

library/core/src/slice/mod.rs

+62
Original file line numberDiff line numberDiff line change
@@ -3983,6 +3983,68 @@ impl<T> [T] {
39833983
}
39843984
}
39853985

3986+
#[cfg(not(bootstrap))]
3987+
#[cfg(not(test))]
3988+
#[lang = "slice_f32"]
3989+
impl [f32] {
3990+
/// Sorts the slice of floats.
3991+
///
3992+
/// This sort is in-place (i.e. does not allocate), *O*(*n* \* log(*n*)) worst-case, and uses
3993+
/// the ordering defined by [`f32::total_cmp`].
3994+
///
3995+
/// # Current implementation
3996+
///
3997+
/// This uses the same sorting algorithm as [`sort_unstable_by`](slice::sort_unstable_by).
3998+
///
3999+
/// # Examples
4000+
///
4001+
/// ```
4002+
/// #![feature(sort_floats)]
4003+
/// let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
4004+
///
4005+
/// v.sort_floats();
4006+
/// let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
4007+
/// assert_eq!(&v[..8], &sorted[..8]);
4008+
/// assert!(v[8].is_nan());
4009+
/// ```
4010+
#[unstable(feature = "sort_floats", issue = "93396")]
4011+
#[inline]
4012+
pub fn sort_floats(&mut self) {
4013+
self.sort_unstable_by(f32::total_cmp);
4014+
}
4015+
}
4016+
4017+
#[cfg(not(bootstrap))]
4018+
#[cfg(not(test))]
4019+
#[lang = "slice_f64"]
4020+
impl [f64] {
4021+
/// Sorts the slice of floats.
4022+
///
4023+
/// This sort is in-place (i.e. does not allocate), *O*(*n* \* log(*n*)) worst-case, and uses
4024+
/// the ordering defined by [`f64::total_cmp`].
4025+
///
4026+
/// # Current implementation
4027+
///
4028+
/// This uses the same sorting algorithm as [`sort_unstable_by`](slice::sort_unstable_by).
4029+
///
4030+
/// # Examples
4031+
///
4032+
/// ```
4033+
/// #![feature(sort_floats)]
4034+
/// let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
4035+
///
4036+
/// v.sort_floats();
4037+
/// let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
4038+
/// assert_eq!(&v[..8], &sorted[..8]);
4039+
/// assert!(v[8].is_nan());
4040+
/// ```
4041+
#[unstable(feature = "sort_floats", issue = "93396")]
4042+
#[inline]
4043+
pub fn sort_floats(&mut self) {
4044+
self.sort_unstable_by(f64::total_cmp);
4045+
}
4046+
}
4047+
39864048
trait CloneFromSpec<T> {
39874049
fn spec_clone_from(&mut self, src: &[T]);
39884050
}

src/librustdoc/clean/types.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1648,18 +1648,18 @@ impl PrimitiveType {
16481648
}
16491649
}
16501650

1651-
crate fn impls(&self, tcx: TyCtxt<'_>) -> &'static ArrayVec<DefId, 4> {
1651+
crate fn impls(&self, tcx: TyCtxt<'_>) -> &'static ArrayVec<DefId, 6> {
16521652
Self::all_impls(tcx).get(self).expect("missing impl for primitive type")
16531653
}
16541654

1655-
crate fn all_impls(tcx: TyCtxt<'_>) -> &'static FxHashMap<PrimitiveType, ArrayVec<DefId, 4>> {
1656-
static CELL: OnceCell<FxHashMap<PrimitiveType, ArrayVec<DefId, 4>>> = OnceCell::new();
1655+
crate fn all_impls(tcx: TyCtxt<'_>) -> &'static FxHashMap<PrimitiveType, ArrayVec<DefId, 6>> {
1656+
static CELL: OnceCell<FxHashMap<PrimitiveType, ArrayVec<DefId, 6>>> = OnceCell::new();
16571657

16581658
CELL.get_or_init(move || {
16591659
use self::PrimitiveType::*;
16601660

16611661
let single = |a: Option<DefId>| a.into_iter().collect();
1662-
let both = |a: Option<DefId>, b: Option<DefId>| -> ArrayVec<_, 4> {
1662+
let both = |a: Option<DefId>, b: Option<DefId>| -> ArrayVec<_, 6> {
16631663
a.into_iter().chain(b).collect()
16641664
};
16651665

@@ -1686,6 +1686,8 @@ impl PrimitiveType {
16861686
lang_items
16871687
.slice_impl()
16881688
.into_iter()
1689+
.chain(lang_items.slice_f32_impl())
1690+
.chain(lang_items.slice_f64_impl())
16891691
.chain(lang_items.slice_u8_impl())
16901692
.chain(lang_items.slice_alloc_impl())
16911693
.chain(lang_items.slice_u8_alloc_impl())

0 commit comments

Comments
 (0)