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
/*! Macros for indexing slices/arrays with multiple compile-time indices/ranges. These indexing macros check that the indices/ranges don't overlap, erroring at compile-time if they do, then return tuples of references to elements / arrays / slices, based on each passed-in argument. # Shared Macro docs Because the indexing macros are all very similar in how they work, they have [shared documentation] with all of what they share in common. # Examples ### Parsing integers This example demonstrates how you can fallibly get the first 4 bytes of a slice as an array, and the remainder as a slice. ```rust use multindex::multiget; let mut slice = &[0, 0, 1, 10, 20][..]; assert_eq!(grab_u32(&mut slice), Some(266)); assert_eq!(slice, &[20]); assert_eq!(grab_u32(&mut slice), None); assert_eq!(slice, &[20]); fn grab_u32(slice: &mut &[u8]) -> Option<u32> { let (u32_bytes, rem) = multiget!(*slice; ..4, ..)?; *slice = rem; Some(u32::from_be_bytes(*u32_bytes)) } ``` ### Splitting an array This example demonstrates how you can split an array into reference to smaller arrays. ```rust use multindex::multindex; const ROW_SIZE: usize = 5; let array: [u16; ROW_SIZE * 4] = [ 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, ]; type Row = [u16; ROW_SIZE]; // The type annotation is for the reader, the type can be inferred. let (row0, row1, row2, row3): (&Row, &Row, &Row, &Row) = multindex!(array; ..ROW_SIZE, ..ROW_SIZE * 2, ..ROW_SIZE * 3, ..ROW_SIZE * 4); assert_eq!(row0, &[1, 2, 3, 5, 8]); assert_eq!(row1, &[13, 21, 34, 55, 89]); assert_eq!(row2, &[144, 233, 377, 610, 987]); assert_eq!(row3, &[1597, 2584, 4181, 6765, 10946]); ``` # Minimum Supported Rust Version This crate requires at least Rust 1.46.0 . It uses branching and looping at compile-time, to check that the indices/ranges passed to the macros don't overlap (required for macros that index mutably). # no-std support This crate is `#[no-std]`. If newer versions add features that require std, they'll be conditional on a "std" feature being enabled (it won't be enabled by default). [shared documentation]: ./indexing_macro_docs/index.html */ #![allow(non_camel_case_types)] #![cfg_attr(not(any(test, feature = "testing")), no_std)] #[doc(hidden)] pub extern crate core; pub mod indexing_macro_docs; #[doc(hidden)] #[macro_use] pub mod macros; #[doc(hidden)] pub mod index_argument; #[doc(hidden)] pub mod error; #[doc(hidden)] pub mod index_properties; #[doc(hidden)] pub mod ptr_indexing; #[doc(hidden)] pub mod std_const_fns; #[doc(hidden)] pub mod are_disjoint; #[doc(hidden)] pub mod utils; #[doc(hidden)] #[cfg(feature = "testing")] pub mod test_utils; #[doc(hidden)] #[cfg(feature = "testing")] pub mod doc_based_tests; #[doc(hidden)] pub use error::Error; #[doc(hidden)] pub mod pmr { pub use crate::{ are_disjoint::AreAllDisjoint, error::{ErrorPicker, ErrorTuple, NoErrorsFound}, index_argument::{ IK_Index, IK_Range, IK_RangeFrom, IndexArgument, IndexKind, IndexKindPicker, IntoPrenormIndex, PrenormIndex, }, index_properties::{ ComputedConstants, IndexArgumentStats, IndexArgumentsAndStats, IndexProperties, }, ptr_indexing::{IndexPointer, Indexer, IndexerParams}, std_const_fns::result_m::is_err, utils::{panic_on_oob_max_index, AssocType, BorrowSelf, SliceParts, SlicePartsMut}, }; pub use core::option::Option::{self, None, Some}; pub use core::result::Result::Err; } #[cfg(all(test, not(feature = "testing")))] compile_error! { "tests must be run with the \"testing\" feature" }