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
167
168
169
170
171
//! This crate provides multiple iterators for multiple shared/exclusive
//! references within slices, Vecs and other contiguous data structures.
//! The two basic functions it adds are [select_indices](SelectIndices::select_indices)
//! and [select_indices_mut](SelectIndicesMut::select_indices_mut), which let you provide a list of
//! indices into a given slice, and get back an iterator over each shared
//! or exclusive reference with those indices.
//!
//! If the `rayon` feature is enabled,
//! [par_select_indices](rayon::SelectIndicesPar::par_select_indices) and
//! [par_select_indices_mut](rayon::SelectIndicesParMut::par_select_indices_mut)
//! are also provided for use with [rayon](https://docs.rs/rayon). The latter is extremely
//! useful for efficiently mutating a `Vec` in multi-threaded contexts.
//!
//! # Examples
//! ```
//! # fn main() {
//! use select_indices::prelude::*;
//!
//! struct BankAccount {
//! pub name: String,
//! pub balance: f32,
//! }
//!
//! let mut vec: Vec<BankAccount> = vec![
//! BankAccount { name: "Joey Bag o' Donuts".to_string(), balance: 4.27 },
//! BankAccount { name: "Henry Howard Roosevelt".to_string(), balance: 83.20 },
//! BankAccount { name: "Jenny Jenson".to_string(), balance: 54.32 },
//! BankAccount { name: "The Dude".to_string(), balance: -134.01 },
//! // Assume there's like 300 of these
//! ];
//!
//! vec.select_indices_mut(&[1, 3]).for_each(|account| {
//! account.balance -= 20.00;
//! println!("{} now has ${}", account.name, account.balance);
//! });
//! # }
//! ```
use *;
pub use *;
pub use *;
use ;
/// Seek through a shared slice with a list of indices.
///
/// SelectIndices provides an iterator that can split a contiguous,
/// immutable slice of objects (`&[T]`) into individual, shared references (`&T`).
/// Seek through an exclusive slice with a list of indices.
///
/// SelectIndicesMut provides an iterator that can split a contiguous,
/// mutable slice of objects (`&mut [T]`) into individual, exclusive references (`&mut T`)
///
/// The lifetimes of the references are linked to the original slice,
/// so the iterator cannot produce dangling references.
/// ```compile_fail
/// # use select_indices::prelude::*;
/// let refs: Vec<&mut i8>; // Vec of mutable elements within 'data'
///
/// {
/// let mut data = vec![1, 2, 3, 4, 5];
///
/// // Collect mutable references
/// refs = data.select_indices_mut(&[0,1,2]).collect();
/// }
///
/// // Compiler error: 'data' was dropped, references are invalid
/// refs.into_iter().for_each(|x| *x += 1);
/// ```
///
/// Mutable references collected from the iterator also cannot
/// violate the borrow checker.
///
/// ```compile_fail
/// # use select_indices::prelude::*;
/// let mut refs: Vec<&mut i8>;
/// let mut data = vec![1, 2, 3, 4, 5];
/// {
/// // first mutable borrow
/// refs = data.select_indices_mut(&[0, 1, 2, 3, 4]).collect();
/// }
///
/// data.sort(); // Compiler error: second mutable borrow
/// data[4] = 9; // Compiler error: second mutable borrow
/// *refs[4] = 65; // first borrow used here
/// ```
///
/// Lastly, collected references cannot violate the borrow checker
/// when sent to other threads (as far as I can tell).
/// ```compile_fail
/// # use select_indices::prelude::*;
/// # use std::thread;
/// let mut data = [1,2,3,4,5];
///
/// {
/// let mut refs: Vec<&mut i8> = data.select_indices_mut(&[3,4]).collect();
///
/// // refs is moved out of this thread
/// thread::spawn(move || *refs[0] = 99);
/// }
///
/// data[3] = 57; // Compile error: Assignment to borrowed data
/// ```
/// Additional traits and iterators for use with [rayon](https://docs.rs/rayon)