forked from starkware-libs/cairo
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.cairo
More file actions
166 lines (159 loc) · 5.07 KB
/
Copy pathindex.cairo
File metadata and controls
166 lines (159 loc) · 5.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
//! Indexing traits for indexing operations on collections.
//!
//! This module provides traits for implementing the indexing operator `[]`, offering two distinct
//! approaches to access elements in collections:
//!
//! * [`IndexView`] - For snapshot-based access
//! * [`Index`] - For reference-based access
//!
//! For safe indexing operations that return `Option`, see the unstable [`Get`] trait
//! in the [`get`] module.
//!
//! # When to use which trait
//!
//! - Use [`IndexView`] when the collection can be accessed in a read-only context and is not
//! mutated by a read access. This is the most common case in Cairo.
//! - Use [`Index`] when the input type needs to be passed as `ref`. This is mainly useful for types
//! depending on a [`Felt252Dict`], where dictionary accesses are modifying the data structure
//! itself.
//!
//! Only one of these traits should be implemented for any given type, not both.
//!
//! [`Felt252Dict`]: core::dict::Felt252Dict
//! [`Get`]: crate::ops::get::Get
//! [`get`]: crate::ops::get
#[feature("deprecated-index-traits")]
use crate::traits::{Index as DeprecatedIndex, IndexView as DeprecatedIndexView};
/// A trait for indexing operations (`container[index]`) where the input type is not modified.
///
/// `container[index]` is syntactic sugar for `container.index(index)`.
///
/// # Examples
///
/// The following example implements `IndexView` on a `NucleotideCount` container, which can be
/// indexed without modifying the input, enabling individual counts to be retrieved with index
/// syntax.
///
/// ```
/// use core::ops::IndexView;
///
/// #[derive(Copy, Drop)]
/// enum Nucleotide {
/// A,
/// C,
/// G,
/// T,
/// }
///
/// #[derive(Copy, Drop)]
/// struct NucleotideCount {
/// a: usize,
/// c: usize,
/// g: usize,
/// t: usize,
/// }
///
/// impl NucleotideIndex of IndexView<NucleotideCount, Nucleotide> {
/// type Target = usize;
///
/// fn index(self: @NucleotideCount, index: Nucleotide) -> Self::Target {
/// match index {
/// Nucleotide::A => *self.a,
/// Nucleotide::C => *self.c,
/// Nucleotide::G => *self.g,
/// Nucleotide::T => *self.t,
/// }
/// }
/// }
///
/// let nucleotide_count = NucleotideCount {a: 14, c: 9, g: 10, t: 12};
/// assert!(nucleotide_count[Nucleotide::A] == 14);
/// assert!(nucleotide_count[Nucleotide::C] == 9);
/// assert!(nucleotide_count[Nucleotide::G] == 10);
/// assert!(nucleotide_count[Nucleotide::T] == 12);
/// ```
pub trait IndexView<C, I> {
/// The returned type after indexing.
type Target;
/// Performs the indexing (`container[index]`) operation.
///
/// # Panics
///
/// May panic if the index is out of bounds.
fn index(self: @C, index: I) -> Self::Target;
}
impl DeprecatedIndexViewImpl<
C, I, V, impl Deprecated: DeprecatedIndexView<C, I, V>,
> of crate::ops::IndexView<C, I> {
type Target = V;
fn index(self: @C, index: I) -> Self::Target {
Deprecated::index(self, index)
}
}
/// A trait for indexing operations (`container[index]`) where the input type is mutated.
///
/// This trait should be implemented when you want to implement indexing operations on a type that's
/// mutated by a read access. This is useful for any type depending on a [`Felt252Dict`], where
/// dictionary accesses are modifying the data structure itself.
///
/// `container[index]` is syntactic sugar for `container.index(index)`.
///
/// # Examples
///
/// The following example implements `Index` on a `Stack` type. This `Stack` is implemented based on
/// a [`Felt252Dict`], where dictionary accesses are modifying the dictionary itself. As such, we
/// must implement the `Index` trait instead of the `IndexView` trait.
///
/// [`Felt252Dict`]: core::dict::Felt252Dict
///
/// ```
/// use core::ops::Index;
///
/// #[derive(Destruct, Default)]
/// struct Stack {
/// items: Felt252Dict<u128>,
/// len: usize
/// }
///
/// #[generate_trait]
/// impl StackImpl of StackTrait {
/// fn push(ref self: Stack, item: u128) {
/// self.items.insert(self.len.into(), item);
/// self.len += 1;
/// }
/// }
///
/// impl StackIndex of Index<Stack, usize> {
/// type Target = u128;
///
/// fn index(ref self: Stack, index: usize) -> Self::Target {
/// if index >= self.len {
/// panic!("Index out of bounds");
/// }
/// self.items.get(index.into())
/// }
/// }
///
/// let mut stack: Stack = Default::default();
/// stack.push(1);
/// assert!(stack[0] == 1);
/// ```
pub trait Index<C, I> {
/// The returned type after indexing.
type Target;
/// Performs the indexing (`container[index]`) operation.
///
/// # Panics
///
/// May panic if the index is out of bounds.
fn index(ref self: C, index: I) -> Self::Target;
}
#[feature("deprecated-index-traits")]
impl DeprecatedIndexImpl<
C, I, V, impl Deprecated: DeprecatedIndex<C, I, V>,
> of crate::ops::Index<C, I> {
type Target = V;
fn index(ref self: C, index: I) -> Self::Target {
Deprecated::index(ref self, index)
}
}