use core::sync::atomic::{AtomicU32, AtomicU64, Ordering}; pub mod containers; pub mod error; pub mod hash; pub mod interval; pub mod math; pub mod mesh; pub mod noise; pub mod ptr; pub mod quaternion; pub mod rng; pub mod sampling; pub mod sobol; pub mod splines; pub mod transform; pub use ptr::{DevicePtr, Ptr}; pub use transform::{AnimatedTransform, Transform, TransformGeneric}; #[inline] pub fn find_interval(sz: u32, pred: F) -> u32 where F: Fn(u32) -> bool, { let mut first = 0; let mut len = sz; while len > 0 { let half = len >> 1; let middle = first + half; if pred(middle) { first = middle + 1; len -= half + 1; } else { len = half; } } let ret = (first as i32 - 1).max(0) as u32; ret.min(sz.saturating_sub(2)) } #[inline] pub fn partition_slice(data: &mut [T], predicate: F) -> usize where F: Fn(&T) -> bool, { let mut i = 0; for j in 0..data.len() { if predicate(&data[j]) { data.swap(i, j); i += 1; } } i } pub struct AtomicFloat { bits: AtomicU32, } impl AtomicFloat { pub fn new(val: f32) -> Self { Self { bits: AtomicU32::new(val.to_bits()), } } pub fn get(&self) -> f32 { f32::from_bits(self.bits.load(Ordering::Relaxed)) } pub fn set(&self, val: f32) { self.bits.store(val.to_bits(), Ordering::Relaxed); } /// Atomically adds `val` to the current value. /// Uses a Compare-And-Swap (CAS) loop. pub fn add(&self, val: f32) { let mut current_bits = self.bits.load(Ordering::Relaxed); loop { let current_val = f32::from_bits(current_bits); let new_val = current_val + val; let new_bits = new_val.to_bits(); match self.bits.compare_exchange_weak( current_bits, new_bits, Ordering::Relaxed, Ordering::Relaxed, ) { Ok(_) => break, Err(x) => current_bits = x, } } } } pub struct AtomicDouble { bits: AtomicU64, } impl AtomicDouble { pub fn new(val: f64) -> Self { Self { bits: AtomicU64::new(val.to_bits()), } } pub fn get(&self) -> f64 { f64::from_bits(self.bits.load(Ordering::Relaxed)) } pub fn add(&self, val: f64) { let mut current_bits = self.bits.load(Ordering::Relaxed); loop { let current_val = f64::from_bits(current_bits); let new_val = current_val + val; let new_bits = new_val.to_bits(); match self.bits.compare_exchange_weak( current_bits, new_bits, Ordering::Relaxed, Ordering::Relaxed, ) { Ok(_) => break, Err(x) => current_bits = x, } } } }