]> git.proxmox.com Git - rustc.git/blob - src/libcore/ops/index.rs
New upstream version 1.27.1+dfsg1
[rustc.git] / src / libcore / ops / index.rs
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /// Used for indexing operations (`container[index]`) in immutable contexts.
12 ///
13 /// `container[index]` is actually syntactic sugar for `*container.index(index)`,
14 /// but only when used as an immutable value. If a mutable value is requested,
15 /// [`IndexMut`] is used instead. This allows nice things such as
16 /// `let value = v[index]` if the type of `value` implements [`Copy`].
17 ///
18 /// [`IndexMut`]: ../../std/ops/trait.IndexMut.html
19 /// [`Copy`]: ../../std/marker/trait.Copy.html
20 ///
21 /// # Examples
22 ///
23 /// The following example implements `Index` on a read-only `NucleotideCount`
24 /// container, enabling individual counts to be retrieved with index syntax.
25 ///
26 /// ```
27 /// use std::ops::Index;
28 ///
29 /// enum Nucleotide {
30 /// A,
31 /// C,
32 /// G,
33 /// T,
34 /// }
35 ///
36 /// struct NucleotideCount {
37 /// a: usize,
38 /// c: usize,
39 /// g: usize,
40 /// t: usize,
41 /// }
42 ///
43 /// impl Index<Nucleotide> for NucleotideCount {
44 /// type Output = usize;
45 ///
46 /// fn index(&self, nucleotide: Nucleotide) -> &usize {
47 /// match nucleotide {
48 /// Nucleotide::A => &self.a,
49 /// Nucleotide::C => &self.c,
50 /// Nucleotide::G => &self.g,
51 /// Nucleotide::T => &self.t,
52 /// }
53 /// }
54 /// }
55 ///
56 /// let nucleotide_count = NucleotideCount {a: 14, c: 9, g: 10, t: 12};
57 /// assert_eq!(nucleotide_count[Nucleotide::A], 14);
58 /// assert_eq!(nucleotide_count[Nucleotide::C], 9);
59 /// assert_eq!(nucleotide_count[Nucleotide::G], 10);
60 /// assert_eq!(nucleotide_count[Nucleotide::T], 12);
61 /// ```
62 #[lang = "index"]
63 #[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
64 #[stable(feature = "rust1", since = "1.0.0")]
65 #[doc(alias = "]")]
66 #[doc(alias = "[")]
67 #[doc(alias = "[]")]
68 pub trait Index<Idx: ?Sized> {
69 /// The returned type after indexing.
70 #[stable(feature = "rust1", since = "1.0.0")]
71 type Output: ?Sized;
72
73 /// Performs the indexing (`container[index]`) operation.
74 #[stable(feature = "rust1", since = "1.0.0")]
75 fn index(&self, index: Idx) -> &Self::Output;
76 }
77
78 /// Used for indexing operations (`container[index]`) in mutable contexts.
79 ///
80 /// `container[index]` is actually syntactic sugar for
81 /// `*container.index_mut(index)`, but only when used as a mutable value. If
82 /// an immutable value is requested, the [`Index`] trait is used instead. This
83 /// allows nice things such as `v[index] = value`.
84 ///
85 /// [`Index`]: ../../std/ops/trait.Index.html
86 ///
87 /// # Examples
88 ///
89 /// A very simple implementation of a `Balance` struct that has two sides, where
90 /// each can be indexed mutably and immutably.
91 ///
92 /// ```
93 /// use std::ops::{Index,IndexMut};
94 ///
95 /// #[derive(Debug)]
96 /// enum Side {
97 /// Left,
98 /// Right,
99 /// }
100 ///
101 /// #[derive(Debug, PartialEq)]
102 /// enum Weight {
103 /// Kilogram(f32),
104 /// Pound(f32),
105 /// }
106 ///
107 /// struct Balance {
108 /// pub left: Weight,
109 /// pub right: Weight,
110 /// }
111 ///
112 /// impl Index<Side> for Balance {
113 /// type Output = Weight;
114 ///
115 /// fn index<'a>(&'a self, index: Side) -> &'a Weight {
116 /// println!("Accessing {:?}-side of balance immutably", index);
117 /// match index {
118 /// Side::Left => &self.left,
119 /// Side::Right => &self.right,
120 /// }
121 /// }
122 /// }
123 ///
124 /// impl IndexMut<Side> for Balance {
125 /// fn index_mut<'a>(&'a mut self, index: Side) -> &'a mut Weight {
126 /// println!("Accessing {:?}-side of balance mutably", index);
127 /// match index {
128 /// Side::Left => &mut self.left,
129 /// Side::Right => &mut self.right,
130 /// }
131 /// }
132 /// }
133 ///
134 /// let mut balance = Balance {
135 /// right: Weight::Kilogram(2.5),
136 /// left: Weight::Pound(1.5),
137 /// };
138 ///
139 /// // In this case, `balance[Side::Right]` is sugar for
140 /// // `*balance.index(Side::Right)`, since we are only *reading*
141 /// // `balance[Side::Right]`, not writing it.
142 /// assert_eq!(balance[Side::Right], Weight::Kilogram(2.5));
143 ///
144 /// // However, in this case `balance[Side::Left]` is sugar for
145 /// // `*balance.index_mut(Side::Left)`, since we are writing
146 /// // `balance[Side::Left]`.
147 /// balance[Side::Left] = Weight::Kilogram(3.0);
148 /// ```
149 #[lang = "index_mut"]
150 #[rustc_on_unimplemented = "the type `{Self}` cannot be mutably indexed by `{Idx}`"]
151 #[stable(feature = "rust1", since = "1.0.0")]
152 #[doc(alias = "[")]
153 #[doc(alias = "]")]
154 #[doc(alias = "[]")]
155 pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
156 /// Performs the mutable indexing (`container[index]`) operation.
157 #[stable(feature = "rust1", since = "1.0.0")]
158 fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
159 }