diff --git a/.lock b/.lock new file mode 100644 index 0000000..e69de29 diff --git a/crates.js b/crates.js new file mode 100644 index 0000000..af218ab --- /dev/null +++ b/crates.js @@ -0,0 +1,2 @@ +window.ALL_CRATES = ["flatten_objects"]; +//{"start":21,"fragment_lengths":[17]} \ No newline at end of file diff --git a/flatten_objects/all.html b/flatten_objects/all.html new file mode 100644 index 0000000..82cc785 --- /dev/null +++ b/flatten_objects/all.html @@ -0,0 +1 @@ +
FlattenObjects
is a container that stores numbered objects.
Objects can be added to the FlattenObjects
, a unique ID will be assigned
+to the object. The ID can be used to retrieve the object later.
use flatten_objects::FlattenObjects;
+
+let mut objects = FlattenObjects::<u32, 20>::new();
+
+// Add `23` 10 times and assign them IDs from 0 to 9.
+for i in 0..=9 {
+ objects.add_at(i, 23).unwrap();
+ assert!(objects.is_assigned(i));
+}
+
+// Remove the object with ID 6.
+assert_eq!(objects.remove(6), Some(23));
+assert!(!objects.is_assigned(6));
+
+// Add `42` (the ID 6 is available now).
+let id = objects.add(42).unwrap();
+assert_eq!(id, 6);
+assert!(objects.is_assigned(id));
+assert_eq!(objects.get(id), Some(&42));
+assert_eq!(objects.remove(id), Some(42));
+assert!(!objects.is_assigned(id));
pub struct FlattenObjects<T, const CAP: usize> { /* private fields */ }
A container that stores numbered objects.
+See the crate-level documentation for more details.
+CAP
is the maximum number of objects that can be held. It also equals the
+maximum ID that can be assigned plus one. Currently, CAP
must not be
+greater than 1024.
Creates a new empty FlattenObjects
.
Panics if CAP
is greater than 1024.
use flatten_objects::FlattenObjects;
+
+let objects = FlattenObjects::<u32, 20>::new();
+assert_eq!(objects.capacity(), 20);
use flatten_objects::FlattenObjects;
+
+let objects = FlattenObjects::<u32, 1025>::new();
Returns the maximum number of objects that can be held.
+It also equals the maximum ID that can be assigned plus one.
+use flatten_objects::FlattenObjects;
+
+let objects = FlattenObjects::<u32, 20>::new();
+assert_eq!(objects.capacity(), 20);
Returns the number of objects that have been added.
+use flatten_objects::FlattenObjects;
+
+let mut objects = FlattenObjects::<u32, 20>::new();
+assert_eq!(objects.count(), 0);
+objects.add(23); // Assign ID 0.
+assert_eq!(objects.count(), 1);
+objects.add(42); // Assign ID 1.
+assert_eq!(objects.count(), 2);
+objects.remove(0); // ID 0 is assigned.
+assert_eq!(objects.count(), 1);
+objects.remove(10); // ID 10 is not assigned.
+assert_eq!(objects.count(), 1);
Checks if the given id
is assigned.
Returns false
if the id
is out of range.
use flatten_objects::FlattenObjects;
+
+let mut objects = FlattenObjects::<u32, 20>::new();
+objects.add(23); // Assign ID 0.
+objects.add_at(5, 42); // Assign ID 5.
+assert!(objects.is_assigned(0));
+assert!(!objects.is_assigned(1));
+assert!(objects.is_assigned(5));
+assert!(!objects.is_assigned(10));
Returns the reference of the element with the given id
if it already
+be assigned. Otherwise, returns None
.
use flatten_objects::FlattenObjects;
+
+let mut objects = FlattenObjects::<u32, 20>::new();
+objects.add(23); // Assign ID 0.
+objects.add_at(5, 42); // Assign ID 5.
+assert_eq!(objects.get(0), Some(&23));
+assert_eq!(objects.get(1), None);
+assert_eq!(objects.get(5), Some(&42));
+assert_eq!(objects.get(10), None);
Returns the mutable reference of the element with the given id
if it
+exists. Otherwise, returns None
.
use flatten_objects::FlattenObjects;
+
+let mut objects = FlattenObjects::<u32, 20>::new();
+objects.add(23); // Assign ID 0.
+objects.add_at(5, 42); // Assign ID 5.
+*objects.get_mut(0).unwrap() = 24;
+assert_eq!(objects.get_mut(1), None);
+*objects.get_mut(5).unwrap() = 43;
+assert_eq!(objects.get_mut(10), None);
+assert_eq!(objects.get(0), Some(&24));
+assert_eq!(objects.get(5), Some(&43));
Add an object and assigns it the smallest available ID.
+Returns the ID if there is one available. Otherwise, returns the object
+itself wrapped in Err
.
use flatten_objects::FlattenObjects;
+
+let mut objects = FlattenObjects::<u32, 3>::new();
+assert_eq!(objects.add(23), Ok(0));
+assert_eq!(objects.add(42), Ok(1));
+assert_eq!(objects.add(23), Ok(2));
+assert_eq!(objects.add(42), Err(42));
+objects.remove(1);
+assert_eq!(objects.add(42), Ok(1));
Add an object with the given ID.
+Returns the ID if the object is added successfully. Otherwise, returns
+the object itself wrapped in Err
.
use flatten_objects::FlattenObjects;
+
+let mut objects = FlattenObjects::<u32, 20>::new();
+assert_eq!(objects.add_at(5, 23), Ok(5));
+assert_eq!(objects.add_at(5, 42), Err(42));
+assert_eq!(objects.add_at(20, 42), Err(42));
Adds an object with the given ID, replacing and returning the old object +if the ID is already assigned.
+Returns the ID if the object is added successfully. Returns Err(Some(old))
+if the ID is already assigned. Returns Err(None)
if the ID is out of
+range.
use flatten_objects::FlattenObjects;
+
+let mut objects = FlattenObjects::<u32, 20>::new();
+assert_eq!(objects.add_or_replace_at(5, 23), Ok(5));
+assert_eq!(objects.add_or_replace_at(5, 42), Err(Some(23)));
+assert_eq!(objects.get(5), Some(&42));
+assert_eq!(objects.add_or_replace_at(20, 42), Err(None));
Removes and returns the object with the given ID.
+After this operation, the ID is freed and can be assigned for next +object again.
+use flatten_objects::FlattenObjects;
+
+let mut objects = FlattenObjects::<u32, 20>::new();
+let id = objects.add(23).unwrap();
+assert_eq!(objects.remove(id), Some(23));
+assert!(!objects.is_assigned(id));
+assert_eq!(objects.remove(id), None);
FlattenObjects
is a container that stores numbered objects.\nA container that stores numbered objects.\nAdd an object and assigns it the smallest available ID.\nAdd an object with the given ID.\nAdds an object with the given ID, replacing and returning …\nReturns the maximum number of objects that can be held.\nReturns the number of objects that have been added.\nReturns the argument unchanged.\nReturns the reference of the element with the given id
if …\nReturns the mutable reference of the element with the …\nCalls U::from(self)
.\nChecks if the given id
is assigned.\nCreates a new empty FlattenObjects
.\nRemoves and returns the object with the given ID.")
\ No newline at end of file
diff --git a/settings.html b/settings.html
new file mode 100644
index 0000000..15abc43
--- /dev/null
+++ b/settings.html
@@ -0,0 +1 @@
++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 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323
//! [`FlattenObjects`] is a container that stores numbered objects.
+//!
+//! Objects can be added to the [`FlattenObjects`], a unique ID will be assigned
+//! to the object. The ID can be used to retrieve the object later.
+//!
+//! # Example
+//!
+//! ```
+//! use flatten_objects::FlattenObjects;
+//!
+//! let mut objects = FlattenObjects::<u32, 20>::new();
+//!
+//! // Add `23` 10 times and assign them IDs from 0 to 9.
+//! for i in 0..=9 {
+//! objects.add_at(i, 23).unwrap();
+//! assert!(objects.is_assigned(i));
+//! }
+//!
+//! // Remove the object with ID 6.
+//! assert_eq!(objects.remove(6), Some(23));
+//! assert!(!objects.is_assigned(6));
+//!
+//! // Add `42` (the ID 6 is available now).
+//! let id = objects.add(42).unwrap();
+//! assert_eq!(id, 6);
+//! assert!(objects.is_assigned(id));
+//! assert_eq!(objects.get(id), Some(&42));
+//! assert_eq!(objects.remove(id), Some(42));
+//! assert!(!objects.is_assigned(id));
+//! ```
+
+#![no_std]
+#![feature(maybe_uninit_uninit_array)]
+
+use bitmaps::Bitmap;
+use core::mem::MaybeUninit;
+
+/// A container that stores numbered objects.
+///
+/// See the [crate-level documentation](crate) for more details.
+///
+/// `CAP` is the maximum number of objects that can be held. It also equals the
+/// maximum ID that can be assigned plus one. Currently, `CAP` must not be
+/// greater than 1024.
+pub struct FlattenObjects<T, const CAP: usize> {
+ objects: [MaybeUninit<T>; CAP],
+ id_bitmap: Bitmap<1024>,
+ count: usize,
+}
+
+impl<T, const CAP: usize> FlattenObjects<T, CAP> {
+ /// Creates a new empty `FlattenObjects`.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `CAP` is greater than 1024.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use flatten_objects::FlattenObjects;
+ ///
+ /// let objects = FlattenObjects::<u32, 20>::new();
+ /// assert_eq!(objects.capacity(), 20);
+ /// ```
+ ///
+ /// ```should_panic
+ /// use flatten_objects::FlattenObjects;
+ ///
+ /// let objects = FlattenObjects::<u32, 1025>::new();
+ /// ```
+ pub const fn new() -> Self {
+ assert!(CAP <= 1024);
+ Self {
+ objects: MaybeUninit::uninit_array(),
+ // SAFETY: zero initialization is OK for `id_bitmap` (an array of integers).
+ id_bitmap: unsafe { MaybeUninit::zeroed().assume_init() },
+ count: 0,
+ }
+ }
+
+ /// Returns the maximum number of objects that can be held.
+ ///
+ /// It also equals the maximum ID that can be assigned plus one.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use flatten_objects::FlattenObjects;
+ ///
+ /// let objects = FlattenObjects::<u32, 20>::new();
+ /// assert_eq!(objects.capacity(), 20);
+ /// ```
+ #[inline]
+ pub const fn capacity(&self) -> usize {
+ CAP
+ }
+
+ /// Returns the number of objects that have been added.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use flatten_objects::FlattenObjects;
+ ///
+ /// let mut objects = FlattenObjects::<u32, 20>::new();
+ /// assert_eq!(objects.count(), 0);
+ /// objects.add(23); // Assign ID 0.
+ /// assert_eq!(objects.count(), 1);
+ /// objects.add(42); // Assign ID 1.
+ /// assert_eq!(objects.count(), 2);
+ /// objects.remove(0); // ID 0 is assigned.
+ /// assert_eq!(objects.count(), 1);
+ /// objects.remove(10); // ID 10 is not assigned.
+ /// assert_eq!(objects.count(), 1);
+ /// ```
+ #[inline]
+ pub const fn count(&self) -> usize {
+ self.count
+ }
+
+ /// Checks if the given `id` is assigned.
+ ///
+ /// Returns `false` if the `id` is out of range.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use flatten_objects::FlattenObjects;
+ ///
+ /// let mut objects = FlattenObjects::<u32, 20>::new();
+ /// objects.add(23); // Assign ID 0.
+ /// objects.add_at(5, 42); // Assign ID 5.
+ /// assert!(objects.is_assigned(0));
+ /// assert!(!objects.is_assigned(1));
+ /// assert!(objects.is_assigned(5));
+ /// assert!(!objects.is_assigned(10));
+ /// ```
+ #[inline]
+ pub fn is_assigned(&self, id: usize) -> bool {
+ id < CAP && self.id_bitmap.get(id)
+ }
+
+ /// Returns the reference of the element with the given `id` if it already
+ /// be assigned. Otherwise, returns `None`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use flatten_objects::FlattenObjects;
+ ///
+ /// let mut objects = FlattenObjects::<u32, 20>::new();
+ /// objects.add(23); // Assign ID 0.
+ /// objects.add_at(5, 42); // Assign ID 5.
+ /// assert_eq!(objects.get(0), Some(&23));
+ /// assert_eq!(objects.get(1), None);
+ /// assert_eq!(objects.get(5), Some(&42));
+ /// assert_eq!(objects.get(10), None);
+ /// ```
+ #[inline]
+ pub fn get(&self, id: usize) -> Option<&T> {
+ if self.is_assigned(id) {
+ // SAFETY: the object at `id` should be initialized by `add` or
+ // `add_at`.
+ unsafe { Some(self.objects[id].assume_init_ref()) }
+ } else {
+ None
+ }
+ }
+
+ /// Returns the mutable reference of the element with the given `id` if it
+ /// exists. Otherwise, returns `None`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use flatten_objects::FlattenObjects;
+ ///
+ /// let mut objects = FlattenObjects::<u32, 20>::new();
+ /// objects.add(23); // Assign ID 0.
+ /// objects.add_at(5, 42); // Assign ID 5.
+ /// *objects.get_mut(0).unwrap() = 24;
+ /// assert_eq!(objects.get_mut(1), None);
+ /// *objects.get_mut(5).unwrap() = 43;
+ /// assert_eq!(objects.get_mut(10), None);
+ /// assert_eq!(objects.get(0), Some(&24));
+ /// assert_eq!(objects.get(5), Some(&43));
+ /// ```
+ #[inline]
+ pub fn get_mut(&mut self, id: usize) -> Option<&mut T> {
+ if self.is_assigned(id) {
+ // SAFETY: the object at `id` should be initialized by `add` or
+ // `add_at`.
+ unsafe { Some(self.objects[id].assume_init_mut()) }
+ } else {
+ None
+ }
+ }
+
+ /// Add an object and assigns it the smallest available ID.
+ ///
+ /// Returns the ID if there is one available. Otherwise, returns the object
+ /// itself wrapped in `Err`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use flatten_objects::FlattenObjects;
+ ///
+ /// let mut objects = FlattenObjects::<u32, 3>::new();
+ /// assert_eq!(objects.add(23), Ok(0));
+ /// assert_eq!(objects.add(42), Ok(1));
+ /// assert_eq!(objects.add(23), Ok(2));
+ /// assert_eq!(objects.add(42), Err(42));
+ /// objects.remove(1);
+ /// assert_eq!(objects.add(42), Ok(1));
+ /// ```
+ pub fn add(&mut self, value: T) -> Result<usize, T> {
+ match self.id_bitmap.first_false_index() {
+ Some(id) if id < CAP => {
+ self.count += 1;
+ self.id_bitmap.set(id, true);
+ self.objects[id].write(value);
+ Ok(id)
+ }
+ _ => Err(value),
+ }
+ }
+
+ /// Add an object with the given ID.
+ ///
+ /// Returns the ID if the object is added successfully. Otherwise, returns
+ /// the object itself wrapped in `Err`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use flatten_objects::FlattenObjects;
+ ///
+ /// let mut objects = FlattenObjects::<u32, 20>::new();
+ /// assert_eq!(objects.add_at(5, 23), Ok(5));
+ /// assert_eq!(objects.add_at(5, 42), Err(42));
+ /// assert_eq!(objects.add_at(20, 42), Err(42));
+ /// ```
+ pub fn add_at(&mut self, id: usize, value: T) -> Result<usize, T> {
+ if id >= CAP || self.is_assigned(id) {
+ return Err(value);
+ }
+ self.count += 1;
+ self.id_bitmap.set(id, true);
+ self.objects[id].write(value);
+ Ok(id)
+ }
+
+ /// Adds an object with the given ID, replacing and returning the old object
+ /// if the ID is already assigned.
+ ///
+ /// Returns the ID if the object is added successfully. Returns `Err(Some(old))`
+ /// if the ID is already assigned. Returns `Err(None)` if the ID is out of
+ /// range.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use flatten_objects::FlattenObjects;
+ ///
+ /// let mut objects = FlattenObjects::<u32, 20>::new();
+ /// assert_eq!(objects.add_or_replace_at(5, 23), Ok(5));
+ /// assert_eq!(objects.add_or_replace_at(5, 42), Err(Some(23)));
+ /// assert_eq!(objects.get(5), Some(&42));
+ /// assert_eq!(objects.add_or_replace_at(20, 42), Err(None));
+ /// ```
+ pub fn add_or_replace_at(&mut self, id: usize, value: T) -> Result<usize, Option<T>> {
+ if id >= CAP {
+ return Err(None);
+ }
+
+ if self.is_assigned(id) {
+ // SAFETY: the object at `id` should be initialized by `add` or
+ // `add_at`, and can not be retrieved by `get` or `get_mut` unless
+ // it be added again.
+ let old = unsafe { Some(self.objects[id].assume_init_read()) };
+ self.objects[id].write(value);
+
+ Err(old)
+ } else {
+ self.count += 1;
+ self.id_bitmap.set(id, true);
+ self.objects[id].write(value);
+
+ Ok(id)
+ }
+ }
+
+ /// Removes and returns the object with the given ID.
+ ///
+ /// After this operation, the ID is freed and can be assigned for next
+ /// object again.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use flatten_objects::FlattenObjects;
+ ///
+ /// let mut objects = FlattenObjects::<u32, 20>::new();
+ /// let id = objects.add(23).unwrap();
+ /// assert_eq!(objects.remove(id), Some(23));
+ /// assert!(!objects.is_assigned(id));
+ /// assert_eq!(objects.remove(id), None);
+ /// ```
+ pub fn remove(&mut self, id: usize) -> Option<T> {
+ if self.is_assigned(id) {
+ self.id_bitmap.set(id, false);
+ self.count -= 1;
+ // SAFETY: the object at `id` should be initialized by `add` or
+ // `add_at`, and can not be retrieved by `get` or `get_mut` unless
+ // it be added again.
+ unsafe { Some(self.objects[id].assume_init_read()) }
+ } else {
+ None
+ }
+ }
+}
+
fn:
) to \
+ restrict the search to a given item kind.","Accepted kinds are: fn
, mod
, struct
, \
+ enum
, trait
, type
, macro
, \
+ and const
.","Search functions by type signature (e.g., vec -> usize
or \
+ -> vec
or String, enum:Cow -> bool
)","You can look for items with an exact name by putting double quotes around \
+ your request: \"string\"
","Look for functions that accept or return \
+ slices and \
+ arrays by writing \
+ square brackets (e.g., -> [u8]
or [] -> Option
)","Look for items inside another one by searching for a path: vec::Vec
",].map(x=>""+x+"
").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="${value.replaceAll(" ", " ")}
`}else{error[index]=value}});output+=`