Skip to content

Commit 0b2adfe

Browse files
authored
Merge pull request #434 from cuviper/const-slice
Make `Slice::{first,last,split_*}` methods `const`
2 parents a4aba99 + afa3caf commit 0b2adfe

File tree

5 files changed

+52
-24
lines changed

5 files changed

+52
-24
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "indexmap"
33
edition = "2021"
4-
version = "2.13.0"
4+
version = "2.13.1"
55
documentation = "https://docs.rs/indexmap/"
66
repository = "https://github.com/indexmap-rs/indexmap"
77
license = "Apache-2.0 OR MIT"

RELEASES.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Releases
22

3+
## 2.13.1 (2026-04-02)
4+
5+
- Made some `Slice` methods `const`:
6+
- `map::Slice::{first,last,split_at,split_at_checked,split_first,split_last}`
7+
- `set::Slice::{first,last,split_at,split_at_checked,split_first,split_last}`
8+
39
## 2.13.0 (2026-01-07)
410

511
- Implemented `Clone` for `IntoKeys` and `IntoValues`.

src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,10 @@ where
172172

173173
impl<K, V> Bucket<K, V> {
174174
// field accessors -- used for `f` instead of closures in `.map(f)`
175-
fn key_ref(&self) -> &K {
175+
const fn key_ref(&self) -> &K {
176176
&self.key
177177
}
178-
fn value_ref(&self) -> &V {
178+
const fn value_ref(&self) -> &V {
179179
&self.value
180180
}
181181
fn value_mut(&mut self) -> &mut V {
@@ -190,7 +190,7 @@ impl<K, V> Bucket<K, V> {
190190
fn key_value(self) -> (K, V) {
191191
(self.key, self.value)
192192
}
193-
fn refs(&self) -> (&K, &V) {
193+
const fn refs(&self) -> (&K, &V) {
194194
(&self.key, &self.value)
195195
}
196196
fn ref_mut(&mut self) -> (&K, &mut V) {

src/map/slice.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,12 @@ impl<K, V> Slice<K, V> {
102102
}
103103

104104
/// Get the first key-value pair.
105-
pub fn first(&self) -> Option<(&K, &V)> {
106-
self.entries.first().map(Bucket::refs)
105+
pub const fn first(&self) -> Option<(&K, &V)> {
106+
if let [first, ..] = &self.entries {
107+
Some(first.refs())
108+
} else {
109+
None
110+
}
107111
}
108112

109113
/// Get the first key-value pair, with mutable access to the value.
@@ -112,8 +116,12 @@ impl<K, V> Slice<K, V> {
112116
}
113117

114118
/// Get the last key-value pair.
115-
pub fn last(&self) -> Option<(&K, &V)> {
116-
self.entries.last().map(Bucket::refs)
119+
pub const fn last(&self) -> Option<(&K, &V)> {
120+
if let [.., last] = &self.entries {
121+
Some(last.refs())
122+
} else {
123+
None
124+
}
117125
}
118126

119127
/// Get the last key-value pair, with mutable access to the value.
@@ -126,7 +134,7 @@ impl<K, V> Slice<K, V> {
126134
/// ***Panics*** if `index > len`.
127135
/// For a non-panicking alternative see [`split_at_checked`][Self::split_at_checked].
128136
#[track_caller]
129-
pub fn split_at(&self, index: usize) -> (&Self, &Self) {
137+
pub const fn split_at(&self, index: usize) -> (&Self, &Self) {
130138
let (first, second) = self.entries.split_at(index);
131139
(Self::from_slice(first), Self::from_slice(second))
132140
}
@@ -144,9 +152,12 @@ impl<K, V> Slice<K, V> {
144152
/// Divides one slice into two at an index.
145153
///
146154
/// Returns `None` if `index > len`.
147-
pub fn split_at_checked(&self, index: usize) -> Option<(&Self, &Self)> {
148-
let (first, second) = self.entries.split_at_checked(index)?;
149-
Some((Self::from_slice(first), Self::from_slice(second)))
155+
pub const fn split_at_checked(&self, index: usize) -> Option<(&Self, &Self)> {
156+
if let Some((first, second)) = self.entries.split_at_checked(index) {
157+
Some((Self::from_slice(first), Self::from_slice(second)))
158+
} else {
159+
None
160+
}
150161
}
151162

152163
/// Divides one mutable slice into two at an index.
@@ -159,7 +170,7 @@ impl<K, V> Slice<K, V> {
159170

160171
/// Returns the first key-value pair and the rest of the slice,
161172
/// or `None` if it is empty.
162-
pub fn split_first(&self) -> Option<((&K, &V), &Self)> {
173+
pub const fn split_first(&self) -> Option<((&K, &V), &Self)> {
163174
if let [first, rest @ ..] = &self.entries {
164175
Some((first.refs(), Self::from_slice(rest)))
165176
} else {
@@ -179,7 +190,7 @@ impl<K, V> Slice<K, V> {
179190

180191
/// Returns the last key-value pair and the rest of the slice,
181192
/// or `None` if it is empty.
182-
pub fn split_last(&self) -> Option<((&K, &V), &Self)> {
193+
pub const fn split_last(&self) -> Option<((&K, &V), &Self)> {
183194
if let [rest @ .., last] = &self.entries {
184195
Some((last.refs(), Self::from_slice(rest)))
185196
} else {

src/set/slice.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,36 +73,47 @@ impl<T> Slice<T> {
7373
}
7474

7575
/// Get the first value.
76-
pub fn first(&self) -> Option<&T> {
77-
self.entries.first().map(Bucket::key_ref)
76+
pub const fn first(&self) -> Option<&T> {
77+
if let [first, ..] = &self.entries {
78+
Some(&first.key)
79+
} else {
80+
None
81+
}
7882
}
7983

8084
/// Get the last value.
81-
pub fn last(&self) -> Option<&T> {
82-
self.entries.last().map(Bucket::key_ref)
85+
pub const fn last(&self) -> Option<&T> {
86+
if let [.., last] = &self.entries {
87+
Some(&last.key)
88+
} else {
89+
None
90+
}
8391
}
8492

8593
/// Divides one slice into two at an index.
8694
///
8795
/// ***Panics*** if `index > len`.
8896
/// For a non-panicking alternative see [`split_at_checked`][Self::split_at_checked].
8997
#[track_caller]
90-
pub fn split_at(&self, index: usize) -> (&Self, &Self) {
98+
pub const fn split_at(&self, index: usize) -> (&Self, &Self) {
9199
let (first, second) = self.entries.split_at(index);
92100
(Self::from_slice(first), Self::from_slice(second))
93101
}
94102

95103
/// Divides one slice into two at an index.
96104
///
97105
/// Returns `None` if `index > len`.
98-
pub fn split_at_checked(&self, index: usize) -> Option<(&Self, &Self)> {
99-
let (first, second) = self.entries.split_at_checked(index)?;
100-
Some((Self::from_slice(first), Self::from_slice(second)))
106+
pub const fn split_at_checked(&self, index: usize) -> Option<(&Self, &Self)> {
107+
if let Some((first, second)) = self.entries.split_at_checked(index) {
108+
Some((Self::from_slice(first), Self::from_slice(second)))
109+
} else {
110+
None
111+
}
101112
}
102113

103114
/// Returns the first value and the rest of the slice,
104115
/// or `None` if it is empty.
105-
pub fn split_first(&self) -> Option<(&T, &Self)> {
116+
pub const fn split_first(&self) -> Option<(&T, &Self)> {
106117
if let [first, rest @ ..] = &self.entries {
107118
Some((&first.key, Self::from_slice(rest)))
108119
} else {
@@ -112,7 +123,7 @@ impl<T> Slice<T> {
112123

113124
/// Returns the last value and the rest of the slice,
114125
/// or `None` if it is empty.
115-
pub fn split_last(&self) -> Option<(&T, &Self)> {
126+
pub const fn split_last(&self) -> Option<(&T, &Self)> {
116127
if let [rest @ .., last] = &self.entries {
117128
Some((&last.key, Self::from_slice(rest)))
118129
} else {

0 commit comments

Comments
 (0)