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
//! [`ParallelVec`] is a generic collection of contiguously stored heterogenous values with
//! an API similar to that of a `Vec<(T1, T2, ...)>` but stores the data laid out as a
//! separate slice per field, using a [structures of arrays](https://en.wikipedia.org/wiki/AoS_and_SoA#Structure_of_arrays)
//! layout. The advantage of this layout is that cache utilization may be signifgantly improved
//! when iterating over the data.
//!
//! This approach is common to game engines, and Entity-Component-Systems in particular but is
//! applicable anywhere that cache coherency and memory bandwidth are important for performance.
//!
//! Unlike a struct of `Vec`s, only one length and capacity field is stored, and only one contiguous
//! allocation is made for the entire data structs. Upon reallocation, a struct of `Vec` may apply
//! additional allocation pressure. `ParallelVec` only allocates once per resize.
//!
//! ## Example
//! ```rust
//! use parallel_vec::ParallelVec;
//!
//! /// Some 'entity' data.
//! # #[derive(Copy, Clone)]
//! struct Position { x: f64, y: f64 }
//! # #[derive(Copy, Clone)]
//! struct Velocity { dx: f64, dy: f64 }
//! struct ColdData { /* Potentially many fields omitted here */ }
//!
//! # use std::ops::Add;
//! # impl Add<Velocity> for Position { type Output=Self; fn add(self, other: Velocity) -> Self { Self { x: self.x + other.dx, y: self.y + other.dy } } }
//! // Create a vec of entities
//! let mut entities: ParallelVec<(Position, Velocity, ColdData)> = ParallelVec::new();
//! entities.push((Position {x: 1.0, y: 2.0}, Velocity { dx: 0.0, dy: 0.5 }, ColdData {}));
//! entities.push((Position {x: 0.0, y: 2.0}, Velocity { dx: 0.5, dy: 0.5 }, ColdData {}));
//!
//! // Update entities. This loop only loads position and velocity data, while skipping over
//! // the ColdData which is not necessary for the physics simulation.
//! for (position, velocity, _) in entities.iter_mut() {
//! *position = *position + *velocity;
//! }
//!
//! // Remove an entity
//! entities.swap_remove(0);
//! ```
//!
//! ## Nightly
//! This crate requires use of GATs and therefore requires the following nightly features:
//! * `generic_associated_types`
//!
//! ## `no_std` Support
//! By default, this crate requires the standard library. Disabling the default features
//! enables this crate to compile in `#![no_std]` environments. There must be a set global
//! allocator and heap support for this crate to work.
//!
//! ## `serde` Support
//! `ParallelVec` can be serialized if it's parameters can be serialized. This is disabled by
//! default. Use the `serde` feature to enable support for serialization and deserialization.
extern crate alloc;
extern crate std;
/// A collection of iterators types for [`ParallelVec`].
/// Implementations for [`ParallelParam`].
pub use crate*;
pub use ParallelParam;
pub use ;
pub use ParallelVec;
/// Error when attempting to convert types to [`ParallelVec`].
pub
pub
pub