]> git.proxmox.com Git - rustc.git/blame - library/core/src/ops/index.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / library / core / src / ops / index.rs
CommitLineData
3b2f2976 1/// Used for indexing operations (`container[index]`) in immutable contexts.
041b39d2
XL
2///
3/// `container[index]` is actually syntactic sugar for `*container.index(index)`,
4/// but only when used as an immutable value. If a mutable value is requested,
5/// [`IndexMut`] is used instead. This allows nice things such as
3b2f2976 6/// `let value = v[index]` if the type of `value` implements [`Copy`].
041b39d2 7///
041b39d2
XL
8/// # Examples
9///
10/// The following example implements `Index` on a read-only `NucleotideCount`
11/// container, enabling individual counts to be retrieved with index syntax.
12///
13/// ```
14/// use std::ops::Index;
15///
16/// enum Nucleotide {
17/// A,
18/// C,
19/// G,
20/// T,
21/// }
22///
23/// struct NucleotideCount {
24/// a: usize,
25/// c: usize,
26/// g: usize,
27/// t: usize,
28/// }
29///
30/// impl Index<Nucleotide> for NucleotideCount {
31/// type Output = usize;
32///
532ac7d7 33/// fn index(&self, nucleotide: Nucleotide) -> &Self::Output {
041b39d2
XL
34/// match nucleotide {
35/// Nucleotide::A => &self.a,
36/// Nucleotide::C => &self.c,
37/// Nucleotide::G => &self.g,
38/// Nucleotide::T => &self.t,
39/// }
40/// }
41/// }
42///
43/// let nucleotide_count = NucleotideCount {a: 14, c: 9, g: 10, t: 12};
44/// assert_eq!(nucleotide_count[Nucleotide::A], 14);
45/// assert_eq!(nucleotide_count[Nucleotide::C], 9);
46/// assert_eq!(nucleotide_count[Nucleotide::G], 10);
47/// assert_eq!(nucleotide_count[Nucleotide::T], 12);
48/// ```
49#[lang = "index"]
8faf50e0 50#[rustc_on_unimplemented(
60c5eb7d
XL
51 message = "the type `{Self}` cannot be indexed by `{Idx}`",
52 label = "`{Self}` cannot be indexed by `{Idx}`"
8faf50e0 53)]
041b39d2 54#[stable(feature = "rust1", since = "1.0.0")]
83c7162d
XL
55#[doc(alias = "]")]
56#[doc(alias = "[")]
57#[doc(alias = "[]")]
6522a427 58#[const_trait]
041b39d2 59pub trait Index<Idx: ?Sized> {
3b2f2976 60 /// The returned type after indexing.
041b39d2
XL
61 #[stable(feature = "rust1", since = "1.0.0")]
62 type Output: ?Sized;
63
3b2f2976 64 /// Performs the indexing (`container[index]`) operation.
cdc7bbd5
XL
65 ///
66 /// # Panics
67 ///
68 /// May panic if the index is out of bounds.
041b39d2 69 #[stable(feature = "rust1", since = "1.0.0")]
f9f354fc 70 #[track_caller]
041b39d2
XL
71 fn index(&self, index: Idx) -> &Self::Output;
72}
73
3b2f2976 74/// Used for indexing operations (`container[index]`) in mutable contexts.
041b39d2
XL
75///
76/// `container[index]` is actually syntactic sugar for
77/// `*container.index_mut(index)`, but only when used as a mutable value. If
78/// an immutable value is requested, the [`Index`] trait is used instead. This
3b2f2976 79/// allows nice things such as `v[index] = value`.
041b39d2 80///
041b39d2
XL
81/// # Examples
82///
83/// A very simple implementation of a `Balance` struct that has two sides, where
84/// each can be indexed mutably and immutably.
85///
86/// ```
fc512014 87/// use std::ops::{Index, IndexMut};
041b39d2
XL
88///
89/// #[derive(Debug)]
90/// enum Side {
91/// Left,
92/// Right,
93/// }
94///
95/// #[derive(Debug, PartialEq)]
96/// enum Weight {
97/// Kilogram(f32),
98/// Pound(f32),
99/// }
100///
101/// struct Balance {
102/// pub left: Weight,
3b2f2976 103/// pub right: Weight,
041b39d2
XL
104/// }
105///
106/// impl Index<Side> for Balance {
107/// type Output = Weight;
108///
416331ca 109/// fn index(&self, index: Side) -> &Self::Output {
5e7ed085 110/// println!("Accessing {index:?}-side of balance immutably");
041b39d2
XL
111/// match index {
112/// Side::Left => &self.left,
113/// Side::Right => &self.right,
114/// }
115/// }
116/// }
117///
118/// impl IndexMut<Side> for Balance {
416331ca 119/// fn index_mut(&mut self, index: Side) -> &mut Self::Output {
5e7ed085 120/// println!("Accessing {index:?}-side of balance mutably");
041b39d2
XL
121/// match index {
122/// Side::Left => &mut self.left,
123/// Side::Right => &mut self.right,
124/// }
125/// }
126/// }
127///
3b2f2976
XL
128/// let mut balance = Balance {
129/// right: Weight::Kilogram(2.5),
130/// left: Weight::Pound(1.5),
131/// };
132///
133/// // In this case, `balance[Side::Right]` is sugar for
134/// // `*balance.index(Side::Right)`, since we are only *reading*
135/// // `balance[Side::Right]`, not writing it.
136/// assert_eq!(balance[Side::Right], Weight::Kilogram(2.5));
137///
138/// // However, in this case `balance[Side::Left]` is sugar for
139/// // `*balance.index_mut(Side::Left)`, since we are writing
140/// // `balance[Side::Left]`.
141/// balance[Side::Left] = Weight::Kilogram(3.0);
041b39d2
XL
142/// ```
143#[lang = "index_mut"]
8faf50e0 144#[rustc_on_unimplemented(
9fa01778 145 on(
60c5eb7d
XL
146 _Self = "&str",
147 note = "you can use `.chars().nth()` or `.bytes().nth()`
9fa01778
XL
148see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
149 ),
150 on(
60c5eb7d
XL
151 _Self = "str",
152 note = "you can use `.chars().nth()` or `.bytes().nth()`
9fa01778
XL
153see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
154 ),
155 on(
60c5eb7d
XL
156 _Self = "std::string::String",
157 note = "you can use `.chars().nth()` or `.bytes().nth()`
9fa01778
XL
158see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
159 ),
60c5eb7d
XL
160 message = "the type `{Self}` cannot be mutably indexed by `{Idx}`",
161 label = "`{Self}` cannot be mutably indexed by `{Idx}`"
8faf50e0 162)]
041b39d2 163#[stable(feature = "rust1", since = "1.0.0")]
83c7162d
XL
164#[doc(alias = "[")]
165#[doc(alias = "]")]
166#[doc(alias = "[]")]
6522a427
EL
167#[const_trait]
168pub trait IndexMut<Idx: ?Sized>: ~const Index<Idx> {
3b2f2976 169 /// Performs the mutable indexing (`container[index]`) operation.
cdc7bbd5
XL
170 ///
171 /// # Panics
172 ///
173 /// May panic if the index is out of bounds.
041b39d2 174 #[stable(feature = "rust1", since = "1.0.0")]
f9f354fc 175 #[track_caller]
041b39d2
XL
176 fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
177}