use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ExecutionPolicy {
SequencedPolicy,
ParallelPolicy,
ParallelUnsequencedPolicy,
UnsequencedPolicy,
}
impl ExecutionPolicy {
pub fn is_parallel(&self) -> bool {
matches!(self, Self::ParallelPolicy | Self::ParallelUnsequencedPolicy)
}
pub fn allows_vectorization(&self) -> bool {
matches!(self, Self::ParallelUnsequencedPolicy | Self::UnsequencedPolicy)
}
pub fn name(&self) -> &str {
match self {
Self::SequencedPolicy => "seq",
Self::ParallelPolicy => "par",
Self::ParallelUnsequencedPolicy => "par_unseq",
Self::UnsequencedPolicy => "unseq",
}
}
}
impl fmt::Display for ExecutionPolicy {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "std::execution::{}", self.name())
}
}
#[derive(Debug, Clone)]
pub struct ParallelAlgorithmConfig {
pub policy: ExecutionPolicy,
pub chunk_size: usize,
pub min_elements_for_parallel: usize,
pub vectorization_width: Option<usize>,
}
impl ParallelAlgorithmConfig {
pub fn new(policy: ExecutionPolicy) -> Self {
Self { policy, chunk_size: 2048, min_elements_for_parallel: 10000, vectorization_width: None }
}
pub fn should_parallelize(&self, element_count: usize) -> bool {
self.policy.is_parallel() && element_count >= self.min_elements_for_parallel
}
pub fn parallel_for_each<T>(&self, data: &[T], mut f: impl FnMut(&T)) {
let n = data.len();
if self.should_parallelize(n) {
let chunks = (n + self.chunk_size - 1) / self.chunk_size;
for chunk in 0..chunks {
let start = chunk * self.chunk_size;
let end = std::cmp::min(start + self.chunk_size, n);
for i in start..end { f(&data[i]); }
}
} else {
for item in data { f(item); }
}
}
}
#[derive(Debug, Clone)]
pub struct Latch {
count: isize,
initial_count: isize,
}
impl Latch {
pub fn new(count: isize) -> Self {
assert!(count >= 0, "Latch count must be non-negative");
Self { count, initial_count: count }
}
pub fn count_down(&mut self, n: isize) {
self.count = std::cmp::max(0, self.count - n);
}
pub fn count_down_one(&mut self) {
self.count_down(1);
}
pub fn try_wait(&self) -> bool {
self.count == 0
}
pub fn wait(&self) {
while self.count > 0 { std::hint::spin_loop(); }
}
pub fn arrive_and_wait(&mut self, n: isize) {
self.count_down(n);
self.wait();
}
pub fn reset(&mut self) {
self.count = self.initial_count;
}
pub fn current_count(&self) -> isize {
self.count
}
}
pub type BarrierCompletionFn = Box<dyn Fn() + Send>;
#[derive(Debug)]
pub struct Barrier {
expected: usize,
arrived: usize,
phase: BarrierPhase,
completion: Option<BarrierCompletionFn>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BarrierPhase { Phase0, Phase1 }
impl Barrier {
pub fn new(expected: usize) -> Self {
Self { expected, arrived: 0, phase: BarrierPhase::Phase0, completion: None }
}
pub fn with_completion(expected: usize, f: BarrierCompletionFn) -> Self {
Self { expected, arrived: 0, phase: BarrierPhase::Phase0, completion: Some(f) }
}
pub fn arrive(&mut self, n: usize) -> BarrierArrivalToken {
self.arrived += n;
BarrierArrivalToken { phase: self.phase }
}
pub fn arrive_one(&mut self) -> BarrierArrivalToken {
self.arrive(1)
}
pub fn wait(&self, token: BarrierArrivalToken) {
if token.phase != self.phase { return; }
while self.arrived < self.expected { std::hint::spin_loop(); }
}
pub fn arrive_and_wait(&mut self) {
self.arrived += 1;
while self.arrived < self.expected { std::hint::spin_loop(); }
if self.arrived >= self.expected {
self.arrived = 0;
self.phase = match self.phase {
BarrierPhase::Phase0 => BarrierPhase::Phase1,
BarrierPhase::Phase1 => BarrierPhase::Phase0,
};
if let Some(ref f) = self.completion { f(); }
}
}
pub fn arrive_and_drop(&mut self) {
self.expected -= 1;
}
pub fn expected_count(&self) -> usize { self.expected }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BarrierArrivalToken {
phase: BarrierPhase,
}
#[derive(Debug, Clone)]
pub struct CountingSemaphore<const LEAST_MAX: isize = { isize::MAX }> {
count: isize,
max_count: isize,
}
pub type BinarySemaphore = CountingSemaphore<1>;
impl<const N: isize> CountingSemaphore<N> {
pub fn new(desired: isize) -> Self {
assert!(desired >= 0 && desired <= N, "Semaphore count out of range");
Self { count: desired, max_count: N }
}
pub fn release(&mut self, update: isize) {
assert!(update > 0, "Release requires positive update");
let new_count = self.count.saturating_add(update);
self.count = std::cmp::min(new_count, self.max_count);
}
pub fn release_one(&mut self) { self.release(1); }
pub fn acquire(&mut self) {
while self.count == 0 { std::hint::spin_loop(); }
self.count -= 1;
}
pub fn try_acquire(&mut self) -> bool {
if self.count > 0 { self.count -= 1; true } else { false }
}
pub fn try_acquire_for(&mut self, timeout_ms: u64) -> bool {
let start = std::time::Instant::now();
while self.count == 0 {
if start.elapsed().as_millis() as u64 >= timeout_ms { return false; }
std::hint::spin_loop();
}
self.count -= 1;
true
}
pub fn max(&self) -> isize { self.max_count }
}
#[derive(Debug, Clone)]
pub struct BasicOsyncstream {
buffer: Vec<u8>,
target: Option<String>,
emit_on_sync: bool,
}
impl BasicOsyncstream {
pub fn new(target: Option<&str>) -> Self {
Self { buffer: Vec::new(), target: target.map(|s| s.to_string()), emit_on_sync: true }
}
pub fn write(&mut self, data: &str) { self.buffer.extend_from_slice(data.as_bytes()); }
pub fn write_bytes(&mut self, data: &[u8]) { self.buffer.extend_from_slice(data); }
pub fn emit(&mut self) -> Vec<u8> {
let result = self.buffer.clone();
self.buffer.clear();
result
}
pub fn flush(&mut self) -> Vec<u8> { self.emit() }
pub fn get_buffer(&self) -> &[u8] { &self.buffer }
pub fn set_emit_on_sync(&mut self, flag: bool) { self.emit_on_sync = flag; }
}
impl fmt::Write for BasicOsyncstream {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.write(s);
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct SpanStreamBuffer {
data: Vec<u8>,
read_pos: usize,
write_pos: usize,
}
impl SpanStreamBuffer {
pub fn new(capacity: usize) -> Self {
Self { data: vec![0u8; capacity], read_pos: 0, write_pos: 0 }
}
pub fn from_slice(slice: &[u8]) -> Self {
Self { data: slice.to_vec(), read_pos: 0, write_pos: slice.len() }
}
pub fn read(&mut self, buf: &mut [u8]) -> usize {
let available = self.write_pos - self.read_pos;
let to_read = std::cmp::min(available, buf.len());
buf[..to_read].copy_from_slice(&self.data[self.read_pos..self.read_pos + to_read]);
self.read_pos += to_read;
to_read
}
pub fn write(&mut self, buf: &[u8]) -> usize {
let available = self.data.len() - self.write_pos;
let to_write = std::cmp::min(available, buf.len());
self.data[self.write_pos..self.write_pos + to_write].copy_from_slice(&buf[..to_write]);
self.write_pos += to_write;
to_write
}
pub fn available_for_read(&self) -> usize { self.write_pos - self.read_pos }
pub fn available_for_write(&self) -> usize { self.data.len() - self.write_pos }
pub fn span(&self) -> &[u8] { &self.data[..self.write_pos] }
pub fn reset(&mut self) { self.read_pos = 0; self.write_pos = 0; }
}
#[derive(Debug, Clone)]
pub struct BasicIspanstream {
buffer: SpanStreamBuffer,
}
impl BasicIspanstream {
pub fn new(data: &[u8]) -> Self { Self { buffer: SpanStreamBuffer::from_slice(data) } }
pub fn read(&mut self, buf: &mut [u8]) -> usize { self.buffer.read(buf) }
pub fn available(&self) -> usize { self.buffer.available_for_read() }
}
#[derive(Debug, Clone)]
pub struct BasicOspanstream {
buffer: SpanStreamBuffer,
}
impl BasicOspanstream {
pub fn new(capacity: usize) -> Self { Self { buffer: SpanStreamBuffer::new(capacity) } }
pub fn write(&mut self, data: &[u8]) -> usize { self.buffer.write(data) }
pub fn span(&self) -> &[u8] { self.buffer.span() }
pub fn available(&self) -> usize { self.buffer.available_for_write() }
}
#[derive(Debug, Clone)]
pub struct FlatMap<K: Ord, V> {
entries: Vec<(K, V)>,
}
impl<K: Ord + Clone, V: Clone> FlatMap<K, V> {
pub fn new() -> Self { Self { entries: Vec::new() } }
pub fn with_capacity(cap: usize) -> Self { Self { entries: Vec::with_capacity(cap) } }
pub fn insert(&mut self, key: K, value: V) -> Option<V> {
match self.entries.binary_search_by(|(k, _)| k.cmp(&key)) {
Ok(idx) => {
let old = std::mem::replace(&mut self.entries[idx].1, value);
Some(old)
}
Err(idx) => {
self.entries.insert(idx, (key, value));
None
}
}
}
pub fn get(&self, key: &K) -> Option<&V> {
self.entries.binary_search_by(|(k, _)| k.cmp(key))
.ok().map(|idx| &self.entries[idx].1)
}
pub fn remove(&mut self, key: &K) -> Option<V> {
self.entries.binary_search_by(|(k, _)| k.cmp(key))
.ok().map(|idx| self.entries.remove(idx).1)
}
pub fn contains_key(&self, key: &K) -> bool {
self.entries.binary_search_by(|(k, _)| k.cmp(key)).is_ok()
}
pub fn len(&self) -> usize { self.entries.len() }
pub fn is_empty(&self) -> bool { self.entries.is_empty() }
pub fn keys(&self) -> impl Iterator<Item = &K> { self.entries.iter().map(|(k, _)| k) }
pub fn values(&self) -> impl Iterator<Item = &V> { self.entries.iter().map(|(_, v)| v) }
pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> { self.entries.iter().map(|(k, v)| (k, v)) }
pub fn clear(&mut self) { self.entries.clear(); }
}
impl<K: Ord + Clone, V: Clone> Default for FlatMap<K, V> {
fn default() -> Self { Self::new() }
}
#[derive(Debug, Clone)]
pub struct FlatSet<K: Ord> {
entries: Vec<K>,
}
impl<K: Ord + Clone> FlatSet<K> {
pub fn new() -> Self { Self { entries: Vec::new() } }
pub fn with_capacity(cap: usize) -> Self { Self { entries: Vec::with_capacity(cap) } }
pub fn insert(&mut self, key: K) -> bool {
match self.entries.binary_search(&key) {
Ok(_) => false,
Err(idx) => { self.entries.insert(idx, key); true }
}
}
pub fn contains(&self, key: &K) -> bool {
self.entries.binary_search(key).is_ok()
}
pub fn remove(&mut self, key: &K) -> bool {
self.entries.binary_search(key).ok().map(|idx| { self.entries.remove(idx); }).is_some()
}
pub fn len(&self) -> usize { self.entries.len() }
pub fn is_empty(&self) -> bool { self.entries.is_empty() }
pub fn iter(&self) -> impl Iterator<Item = &K> { self.entries.iter() }
pub fn clear(&mut self) { self.entries.clear(); }
}
impl<K: Ord + Clone> Default for FlatSet<K> {
fn default() -> Self { Self::new() }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MdspanLayout {
RowMajor,
ColMajor,
Strided { strides: Vec<usize> },
}
#[derive(Debug, Clone)]
pub struct Mdspan<T: Clone> {
data: Vec<T>,
extents: Vec<usize>,
layout: MdspanLayout,
}
impl<T: Clone + Default> Mdspan<T> {
pub fn new(extents: &[usize]) -> Self {
let total: usize = extents.iter().product();
Self { data: vec![T::default(); total], extents: extents.to_vec(), layout: MdspanLayout::RowMajor }
}
pub fn from_data(data: Vec<T>, extents: &[usize]) -> Self {
let total: usize = extents.iter().product();
assert_eq!(data.len(), total, "Data size mismatch");
Self { data, extents: extents.to_vec(), layout: MdspanLayout::RowMajor }
}
pub fn with_layout(mut self, layout: MdspanLayout) -> Self { self.layout = layout; self }
fn linear_index(&self, indices: &[usize]) -> usize {
assert_eq!(indices.len(), self.extents.len());
match &self.layout {
MdspanLayout::RowMajor => {
let mut idx = 0;
let mut stride = 1;
for i in (0..indices.len()).rev() {
idx += indices[i] * stride;
stride *= self.extents[i];
}
idx
}
MdspanLayout::ColMajor => {
let mut idx = 0;
let mut stride = 1;
for i in 0..indices.len() {
idx += indices[i] * stride;
stride *= self.extents[i];
}
idx
}
MdspanLayout::Strided { strides } => {
indices.iter().zip(strides.iter()).map(|(&i, &s)| i * s).sum()
}
}
}
pub fn get(&self, indices: &[usize]) -> &T {
let idx = self.linear_index(indices);
&self.data[idx]
}
pub fn get_mut(&mut self, indices: &[usize]) -> &mut T {
let idx = self.linear_index(indices);
&mut self.data[idx]
}
pub fn rank(&self) -> usize { self.extents.len() }
pub fn extent(&self, dim: usize) -> usize { self.extents[dim] }
pub fn extents(&self) -> &[usize] { &self.extents }
pub fn size(&self) -> usize { self.data.len() }
pub fn is_empty(&self) -> bool { self.data.is_empty() }
pub fn subspan(&self, offset: &[usize], count: &[usize]) -> Self {
let total: usize = count.iter().product();
let mut result = Self::new(count);
for idx in 0..total {
let mut src = vec![0usize; offset.len()];
let mut remaining = idx;
for i in (0..count.len()).rev() {
src[i] = offset[i] + remaining % count[i];
remaining /= count[i];
}
result.data[idx] = self.get(&src).clone();
}
result
}
}
#[derive(Debug, Clone)]
pub struct StdGenerator<T> {
items: Vec<T>,
position: usize,
}
impl<T: Clone> StdGenerator<T> {
pub fn new() -> Self { Self { items: Vec::new(), position: 0 } }
pub fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Self { items: iter.into_iter().collect(), position: 0 }
}
pub fn from_fn<F: FnMut() -> Option<T>>(mut f: F, count: usize) -> Self {
let mut items = Vec::with_capacity(count);
for _ in 0..count {
if let Some(item) = f() { items.push(item); } else { break; }
}
Self { items, position: 0 }
}
pub fn next(&mut self) -> Option<T> {
if self.position < self.items.len() {
let item = self.items[self.position].clone();
self.position += 1;
Some(item)
} else {
None
}
}
pub fn peek(&self) -> Option<&T> {
self.items.get(self.position)
}
pub fn reset(&mut self) { self.position = 0; }
pub fn remaining(&self) -> usize { self.items.len() - self.position }
pub fn is_done(&self) -> bool { self.position >= self.items.len() }
pub fn map<U: Clone, F: Fn(&T) -> U>(self, f: F) -> StdGenerator<U> {
StdGenerator { items: self.items.iter().map(|x| f(x)).collect(), position: 0 }
}
pub fn filter<F: Fn(&T) -> bool>(self, predicate: F) -> StdGenerator<T> {
StdGenerator { items: self.items.into_iter().filter(|x| predicate(x)).collect(), position: 0 }
}
pub fn collect_all(&mut self) -> Vec<T> {
let result: Vec<T> = self.items[self.position..].to_vec();
self.position = self.items.len();
result
}
}
impl<T: Clone> Default for StdGenerator<T> {
fn default() -> Self { Self::new() }
}
impl<T: Clone> Iterator for StdGenerator<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> { self.next() }
fn size_hint(&self) -> (usize, Option<usize>) {
let rem = self.remaining();
(rem, Some(rem))
}
}
#[derive(Debug, Clone)]
pub struct PrintFormatter {
buffer: String,
locale_sensitive: bool,
}
impl PrintFormatter {
pub fn new() -> Self { Self { buffer: String::new(), locale_sensitive: false } }
pub fn print(&mut self, msg: &str) -> String {
self.buffer.push_str(msg);
self.buffer.clone()
}
pub fn println(&mut self, msg: &str) -> String {
let mut result = String::new();
result.push_str(msg);
result.push('\n');
self.buffer.push_str(&result);
result
}
pub fn flush(&self) -> String { self.buffer.clone() }
}
pub fn std_print(msg: &str) { println!("{}", msg); }
pub fn std_println(msg: &str) { println!("{}", msg); }
#[derive(Debug, Clone)]
pub struct PrintArgs {
pub format_string: String,
pub args: Vec<String>,
}
impl PrintArgs {
pub fn new(fmt: &str, args: Vec<String>) -> Self { Self { format_string: fmt.to_string(), args } }
pub fn to_string(&self) -> String {
let mut result = self.format_string.clone();
for (i, arg) in self.args.iter().enumerate() {
let placeholder = format!("{{{}}}", i);
result = result.replace(&placeholder, arg);
}
result
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StacktraceEntry {
pub description: String,
pub source_file: Option<String>,
pub source_line: Option<u32>,
pub function_name: Option<String>,
pub address: Option<u64>,
}
impl StacktraceEntry {
pub fn new(desc: &str) -> Self {
Self { description: desc.to_string(), source_file: None,
source_line: None, function_name: None, address: None }
}
pub fn with_source(mut self, file: &str, line: u32) -> Self {
self.source_file = Some(file.to_string());
self.source_line = Some(line);
self
}
pub fn with_function(mut self, func: &str) -> Self {
self.function_name = Some(func.to_string());
self
}
pub fn with_address(mut self, addr: u64) -> Self {
self.address = Some(addr);
self
}
}
impl fmt::Display for StacktraceEntry {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(ref func) = self.function_name {
write!(f, "{} at ", func)?;
}
write!(f, "{}", self.description)?;
if let Some(ref file) = self.source_file {
write!(f, " [{}", file)?;
if let Some(line) = self.source_line {
write!(f, ":{}", line)?;
}
write!(f, "]")?;
}
Ok(())
}
}
#[derive(Debug, Clone)]
pub struct BasicStacktrace {
entries: Vec<StacktraceEntry>,
max_depth: usize,
}
impl BasicStacktrace {
pub fn new(max_depth: usize) -> Self {
Self { entries: Vec::with_capacity(max_depth), max_depth }
}
pub fn current() -> Self {
Self { entries: Vec::new(), max_depth: 128 }
}
pub fn with_depth(max_depth: usize) -> Self {
Self { entries: Vec::with_capacity(max_depth), max_depth }
}
pub fn push(&mut self, entry: StacktraceEntry) {
if self.entries.len() < self.max_depth {
self.entries.push(entry);
}
}
pub fn size(&self) -> usize { self.entries.len() }
pub fn is_empty(&self) -> bool { self.entries.is_empty() }
pub fn entries(&self) -> &[StacktraceEntry] { &self.entries }
pub fn get(&self, index: usize) -> Option<&StacktraceEntry> { self.entries.get(index) }
}
impl fmt::Display for BasicStacktrace {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
writeln!(f, "Stack trace ({} frames):", self.entries.len())?;
for (i, entry) in self.entries.iter().enumerate() {
writeln!(f, " #{} {}", i, entry)?;
}
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct DebuggerState {
pub is_present: bool,
pub is_attached: bool,
}
impl DebuggerState {
pub fn new() -> Self { Self { is_present: false, is_attached: false } }
pub fn is_debugger_present(&self) -> bool { self.is_present }
pub fn breakpoint(&self) {
if self.is_present {
eprintln!("BREAKPOINT: Debugger is present.");
}
}
pub fn break_if_debugging(&self, condition: bool) {
if condition && self.is_present { self.breakpoint(); }
}
pub fn set_present(mut self, present: bool) -> Self {
self.is_present = present;
self
}
}
impl Default for DebuggerState {
fn default() -> Self { Self::new() }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum TextEncoding {
Utf8,
Utf16LE,
Utf16BE,
Utf32LE,
Utf32BE,
Ascii,
Latin1,
Windows1252,
ShiftJIS,
EucJp,
Iso2022Jp,
Gb2312,
Gbk,
Gb18030,
Big5,
EucKr,
Koi8R,
Koi8U,
Other { name: String },
Unknown,
}
impl TextEncoding {
pub fn name(&self) -> &str {
match self {
Self::Utf8 => "UTF-8",
Self::Utf16LE => "UTF-16LE",
Self::Utf16BE => "UTF-16BE",
Self::Utf32LE => "UTF-32LE",
Self::Utf32BE => "UTF-32BE",
Self::Ascii => "ASCII",
Self::Latin1 => "ISO-8859-1",
Self::Windows1252 => "Windows-1252",
Self::ShiftJIS => "Shift_JIS",
Self::EucJp => "EUC-JP",
Self::Iso2022Jp => "ISO-2022-JP",
Self::Gb2312 => "GB2312",
Self::Gbk => "GBK",
Self::Gb18030 => "GB18030",
Self::Big5 => "Big5",
Self::EucKr => "EUC-KR",
Self::Koi8R => "KOI8-R",
Self::Koi8U => "KOI8-U",
Self::Other { ref name } => name,
Self::Unknown => "unknown",
}
}
pub fn is_unicode(&self) -> bool {
matches!(self, Self::Utf8 | Self::Utf16LE | Self::Utf16BE | Self::Utf32LE | Self::Utf32BE)
}
pub fn is_multi_byte(&self) -> bool {
matches!(self, Self::Utf8 | Self::ShiftJIS | Self::EucJp | Self::Iso2022Jp |
Self::Gbk | Self::Gb18030 | Self::Big5 | Self::EucKr)
}
pub fn min_bytes_per_char(&self) -> usize {
match self {
Self::Utf8 | Self::Ascii | Self::Latin1 | Self::Windows1252 | Self::Koi8R | Self::Koi8U => 1,
Self::Utf16LE | Self::Utf16BE => 2,
Self::Utf32LE | Self::Utf32BE => 4,
_ => 1,
}
}
pub fn max_bytes_per_char(&self) -> usize {
match self {
Self::Utf8 => 4,
Self::Utf16LE | Self::Utf16BE => 4,
Self::Utf32LE | Self::Utf32BE => 4,
Self::Gb18030 => 4,
_ => self.min_bytes_per_char(),
}
}
pub fn detect_from_bom(bytes: &[u8]) -> Option<Self> {
if bytes.len() >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF {
Some(Self::Utf8)
} else if bytes.len() >= 2 && bytes[0] == 0xFE && bytes[1] == 0xFF {
Some(Self::Utf16BE)
} else if bytes.len() >= 2 && bytes[0] == 0xFF && bytes[1] == 0xFE {
Some(Self::Utf16LE)
} else if bytes.len() >= 4 && bytes[0] == 0x00 && bytes[1] == 0x00 && bytes[2] == 0xFE && bytes[3] == 0xFF {
Some(Self::Utf32BE)
} else if bytes.len() >= 4 && bytes[0] == 0xFF && bytes[1] == 0xFE && bytes[2] == 0x00 && bytes[3] == 0x00 {
Some(Self::Utf32LE)
} else {
None
}
}
pub fn guess_from_content(bytes: &[u8]) -> Self {
if bytes.is_empty() { return Self::Unknown; }
if std::str::from_utf8(bytes).is_ok() { return Self::Utf8; }
if bytes.iter().all(|&b| b < 0x80) { return Self::Ascii; }
Self::Unknown
}
}
impl fmt::Display for TextEncoding {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name())
}
}
#[derive(Debug)]
pub struct InplaceVector<T: Copy, const N: usize> {
data: [Option<T>; N],
len: usize,
}
impl<T: Copy + Default, const N: usize> InplaceVector<T, N> {
pub fn new() -> Self {
Self { data: [None; N], len: 0 }
}
pub fn push_back(&mut self, value: T) -> Result<(), &'static str> {
if self.len >= N { return Err("inplace_vector capacity exceeded"); }
self.data[self.len] = Some(value);
self.len += 1;
Ok(())
}
pub fn pop_back(&mut self) -> Option<T> {
if self.len == 0 { return None; }
self.len -= 1;
self.data[self.len].take()
}
pub fn get(&self, index: usize) -> Option<&T> {
self.data.get(index).and_then(|o| o.as_ref())
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
self.data.get_mut(index).and_then(|o| o.as_mut())
}
pub fn len(&self) -> usize { self.len }
pub fn is_empty(&self) -> bool { self.len == 0 }
pub fn is_full(&self) -> bool { self.len >= N }
pub fn capacity(&self) -> usize { N }
pub fn clear(&mut self) {
for i in 0..self.len { self.data[i] = None; }
self.len = 0;
}
pub fn as_slice(&self) -> &[Option<T>] { &self.data[..self.len] }
}
impl<T: Copy + Default, const N: usize> Default for InplaceVector<T, N> {
fn default() -> Self { Self::new() }
}
impl<T: Copy + Default + fmt::Debug, const N: usize> fmt::Display for InplaceVector<T, N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[")?;
for i in 0..self.len {
if i > 0 { write!(f, ", ")?; }
write!(f, "{:?}", self.data[i])?;
}
write!(f, "]")
}
}
#[derive(Debug, Clone)]
pub struct Hive<T: Clone> {
buckets: Vec<Vec<T>>,
bucket_capacity: usize,
size: usize,
}
impl<T: Clone> Hive<T> {
pub fn new() -> Self {
Self { buckets: vec![Vec::new()], bucket_capacity: 64, size: 0 }
}
pub fn with_bucket_capacity(cap: usize) -> Self {
Self { buckets: vec![Vec::with_capacity(cap)], bucket_capacity: cap, size: 0 }
}
pub fn insert(&mut self, value: T) -> HiveIndex {
if self.buckets.last().map_or(true, |b| b.len() >= self.bucket_capacity) {
self.buckets.push(Vec::with_capacity(self.bucket_capacity));
}
let bucket_idx = self.buckets.len() - 1;
let elem_idx = self.buckets[bucket_idx].len();
self.buckets[bucket_idx].push(value);
self.size += 1;
HiveIndex { bucket: bucket_idx, element: elem_idx }
}
pub fn get(&self, index: &HiveIndex) -> Option<&T> {
self.buckets.get(index.bucket).and_then(|b| b.get(index.element))
}
pub fn remove(&mut self, index: &HiveIndex) -> Option<T> {
if let Some(bucket) = self.buckets.get_mut(index.bucket) {
if index.element < bucket.len() {
let last = bucket.pop().unwrap();
if index.element < bucket.len() {
let removed = std::mem::replace(&mut bucket[index.element], last);
self.size -= 1;
return Some(removed);
} else {
self.size -= 1;
return Some(last);
}
}
}
None
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.buckets.iter().flat_map(|b| b.iter())
}
pub fn len(&self) -> usize { self.size }
pub fn is_empty(&self) -> bool { self.size == 0 }
pub fn bucket_count(&self) -> usize { self.buckets.len() }
}
impl<T: Clone + Default> Default for Hive<T> {
fn default() -> Self { Self::new() }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct HiveIndex {
bucket: usize,
element: usize,
}
#[derive(Debug, Clone)]
pub struct Stl4Registry {
pub execution_policies: bool,
pub latch_enabled: bool,
pub barrier_enabled: bool,
pub counting_semaphore_enabled: bool,
pub syncstream_enabled: bool,
pub spanstream_enabled: bool,
pub flat_map_enabled: bool,
pub flat_set_enabled: bool,
pub mdspan_enabled: bool,
pub generator_enabled: bool,
pub print_enabled: bool,
pub stacktrace_enabled: bool,
pub debugging_enabled: bool,
pub text_encoding_enabled: bool,
pub inplace_vector_enabled: bool,
pub hive_enabled: bool,
pub standard_year: u32,
}
impl Stl4Registry {
pub fn new() -> Self {
Self {
execution_policies: false, latch_enabled: false, barrier_enabled: false,
counting_semaphore_enabled: false, syncstream_enabled: false, spanstream_enabled: false,
flat_map_enabled: false, flat_set_enabled: false, mdspan_enabled: false,
generator_enabled: false, print_enabled: false, stacktrace_enabled: false,
debugging_enabled: false, text_encoding_enabled: false, inplace_vector_enabled: false,
hive_enabled: false, standard_year: 0,
}
}
pub fn with_standard(mut self, year: u32) -> Self {
self.standard_year = year;
match year {
202002 => {
self.execution_policies = true;
self.latch_enabled = true;
self.barrier_enabled = true;
self.counting_semaphore_enabled = true;
self.syncstream_enabled = true;
}
202302 => {
self.execution_policies = true;
self.latch_enabled = true;
self.barrier_enabled = true;
self.counting_semaphore_enabled = true;
self.syncstream_enabled = true;
self.spanstream_enabled = true;
self.flat_map_enabled = true;
self.flat_set_enabled = true;
self.mdspan_enabled = true;
self.generator_enabled = true;
self.print_enabled = true;
self.stacktrace_enabled = true;
}
202602 | _ if year >= 202602 => {
self.execution_policies = true;
self.latch_enabled = true;
self.barrier_enabled = true;
self.counting_semaphore_enabled = true;
self.syncstream_enabled = true;
self.spanstream_enabled = true;
self.flat_map_enabled = true;
self.flat_set_enabled = true;
self.mdspan_enabled = true;
self.generator_enabled = true;
self.print_enabled = true;
self.stacktrace_enabled = true;
self.debugging_enabled = true;
self.text_encoding_enabled = true;
self.inplace_vector_enabled = true;
}
_ => {}
}
self.hive_enabled = true; self
}
pub fn feature_count(&self) -> usize {
let mut count = 0;
if self.execution_policies { count += 1; }
if self.latch_enabled { count += 1; }
if self.barrier_enabled { count += 1; }
if self.counting_semaphore_enabled { count += 1; }
if self.syncstream_enabled { count += 1; }
if self.spanstream_enabled { count += 1; }
if self.flat_map_enabled { count += 1; }
if self.flat_set_enabled { count += 1; }
if self.mdspan_enabled { count += 1; }
if self.generator_enabled { count += 1; }
if self.print_enabled { count += 1; }
if self.stacktrace_enabled { count += 1; }
if self.debugging_enabled { count += 1; }
if self.text_encoding_enabled { count += 1; }
if self.inplace_vector_enabled { count += 1; }
if self.hive_enabled { count += 1; }
count
}
pub fn headers_for_standard(&self) -> Vec<String> {
let mut h = Vec::new();
if self.execution_policies { h.push("<execution>".to_string()); }
if self.latch_enabled { h.push("<latch>".to_string()); }
if self.barrier_enabled { h.push("<barrier>".to_string()); }
if self.counting_semaphore_enabled { h.push("<semaphore>".to_string()); }
if self.syncstream_enabled { h.push("<syncstream>".to_string()); }
if self.spanstream_enabled { h.push("<spanstream>".to_string()); }
if self.flat_map_enabled { h.push("<flat_map>".to_string()); }
if self.flat_set_enabled { h.push("<flat_set>".to_string()); }
if self.mdspan_enabled { h.push("<mdspan>".to_string()); }
if self.generator_enabled { h.push("<generator>".to_string()); }
if self.print_enabled { h.push("<print>".to_string()); }
if self.stacktrace_enabled { h.push("<stacktrace>".to_string()); }
if self.debugging_enabled { h.push("<debugging>".to_string()); }
if self.text_encoding_enabled { h.push("<text_encoding>".to_string()); }
if self.inplace_vector_enabled { h.push("<inplace_vector>".to_string()); }
if self.hive_enabled { h.push("<hive>".to_string()); }
h
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_execution_policy_is_parallel() {
assert!(!ExecutionPolicy::SequencedPolicy.is_parallel());
assert!(ExecutionPolicy::ParallelPolicy.is_parallel());
assert!(ExecutionPolicy::ParallelUnsequencedPolicy.is_parallel());
}
#[test]
fn test_parallel_algorithm_should_parallelize() {
let config = ParallelAlgorithmConfig::new(ExecutionPolicy::ParallelPolicy);
assert!(!config.should_parallelize(100));
assert!(config.should_parallelize(50000));
}
#[test]
fn test_latch_new() { let l = Latch::new(5); assert_eq!(l.current_count(), 5); }
#[test]
fn test_latch_count_down() { let mut l = Latch::new(3); l.count_down_one(); l.count_down_one(); assert_eq!(l.current_count(), 1); }
#[test]
fn test_latch_try_wait() { let l = Latch::new(0); assert!(l.try_wait()); }
#[test]
fn test_latch_reset() { let mut l = Latch::new(3); l.count_down_one(); l.reset(); assert_eq!(l.current_count(), 3); }
#[test]
fn test_barrier_new() { let b = Barrier::new(4); assert_eq!(b.expected_count(), 4); }
#[test]
fn test_barrier_arrive_and_wait() { let mut b = Barrier::new(1); b.arrive_and_wait(); }
#[test]
fn test_barrier_arrive_and_drop() { let mut b = Barrier::new(3); b.arrive_and_drop(); assert_eq!(b.expected_count(), 2); }
#[test]
fn test_counting_semaphore_acquire_release() {
let mut sem: CountingSemaphore<5> = CountingSemaphore::new(2);
assert!(sem.try_acquire());
sem.release_one();
assert_eq!(sem.try_acquire_for(100), true);
}
#[test]
fn test_binary_semaphore() {
let mut sem: BinarySemaphore = BinarySemaphore::new(1);
assert!(sem.try_acquire());
assert!(!sem.try_acquire());
sem.release_one();
assert!(sem.try_acquire());
}
#[test]
fn test_osyncstream_write_emit() {
let mut stream = BasicOsyncstream::new(None);
stream.write("hello");
stream.write(" world");
let result = stream.emit();
assert_eq!(String::from_utf8_lossy(&result), "hello world");
}
#[test]
fn test_ospanstream_write() {
let mut stream = BasicOspanstream::new(256);
assert_eq!(stream.write(b"test"), 4);
assert_eq!(stream.span(), b"test");
}
#[test]
fn test_ispanstream_read() {
let data = b"hello world";
let mut stream = BasicIspanstream::new(data);
let mut buf = [0u8; 5];
assert_eq!(stream.read(&mut buf), 5);
assert_eq!(&buf, b"hello");
}
#[test]
fn test_flat_map_insert_get() {
let mut m: FlatMap<i32, String> = FlatMap::new();
assert!(m.insert(1, "one".into()).is_none());
assert_eq!(m.get(&1), Some(&"one".to_string()));
assert!(m.insert(1, "ONE".into()).is_some());
assert_eq!(m.get(&1), Some(&"ONE".to_string()));
}
#[test]
fn test_flat_map_remove() {
let mut m: FlatMap<i32, i32> = FlatMap::new();
m.insert(1, 100); m.insert(2, 200);
assert_eq!(m.remove(&1), Some(100));
assert_eq!(m.len(), 1);
}
#[test]
fn test_flat_set_insert_contains() {
let mut s: FlatSet<i32> = FlatSet::new();
assert!(s.insert(42));
assert!(s.contains(&42));
assert!(!s.insert(42));
assert!(s.remove(&42));
assert!(!s.contains(&42));
}
#[test]
fn test_mdspan_create_get() {
let data = vec![1, 2, 3, 4, 5, 6];
let span = Mdspan::from_data(data, &[2, 3]);
assert_eq!(span.rank(), 2);
assert_eq!(*span.get(&[0, 0]), 1);
assert_eq!(*span.get(&[1, 2]), 6);
}
#[test]
fn test_mdspan_row_major() {
let data: Vec<i32> = (0..24).collect();
let span = Mdspan::from_data(data, &[2, 3, 4]);
assert_eq!(*span.get(&[1, 2, 3]), 23);
}
#[test]
fn test_generator_from_iter() {
let mut gen = StdGenerator::from_iter(vec![1, 2, 3, 4, 5]);
assert_eq!(gen.next(), Some(1));
assert_eq!(gen.next(), Some(2));
assert_eq!(gen.collect_all(), vec![3, 4, 5]);
assert!(gen.is_done());
}
#[test]
fn test_generator_map() {
let gen = StdGenerator::from_iter(vec![1, 2, 3]);
let mapped = gen.map(|x| *x * 2);
assert_eq!(mapped.items, vec![2, 4, 6]);
}
#[test]
fn test_generator_filter() {
let gen = StdGenerator::from_iter(vec![1, 2, 3, 4, 5, 6]);
let filtered = gen.filter(|x| *x % 2 == 0);
assert_eq!(filtered.items, vec![2, 4, 6]);
}
#[test]
fn test_print_args_to_string() {
let args = PrintArgs::new("Hello {} from {}", vec!["world".into(), "Rust".into()]);
assert_eq!(args.to_string(), "Hello world from Rust");
}
#[test]
fn test_stacktrace_entry_display() {
let entry = StacktraceEntry::new("main.cpp:42")
.with_function("main")
.with_source("main.cpp", 42);
let s = entry.to_string();
assert!(s.contains("main"));
assert!(s.contains("main.cpp"));
}
#[test]
fn test_basic_stacktrace_push() {
let mut st = BasicStacktrace::with_depth(10);
st.push(StacktraceEntry::new("frame0").with_function("f0"));
st.push(StacktraceEntry::new("frame1").with_function("f1"));
assert_eq!(st.size(), 2);
}
#[test]
fn test_debugger_state_default() {
let ds = DebuggerState::new();
assert!(!ds.is_debugger_present());
}
#[test]
fn test_debugger_state_set_present() {
let ds = DebuggerState::new().set_present(true);
assert!(ds.is_debugger_present());
ds.break_if_debugging(true);
}
#[test]
fn test_text_encoding_name() {
assert_eq!(TextEncoding::Utf8.name(), "UTF-8");
assert_eq!(TextEncoding::ShiftJIS.name(), "Shift_JIS");
}
#[test]
fn test_text_encoding_is_unicode() {
assert!(TextEncoding::Utf8.is_unicode());
assert!(!TextEncoding::Ascii.is_unicode());
}
#[test]
fn test_text_encoding_detect_from_bom_utf8() {
let bom = [0xEF, 0xBB, 0xBF, 0x48, 0x65];
assert_eq!(TextEncoding::detect_from_bom(&bom), Some(TextEncoding::Utf8));
}
#[test]
fn test_text_encoding_guess_utf8() {
assert_eq!(TextEncoding::guess_from_content(b"Hello World"), TextEncoding::Utf8);
}
#[test]
fn test_text_encoding_guess_ascii() {
assert_eq!(TextEncoding::guess_from_content(b"ASCII"), TextEncoding::Ascii);
}
#[test]
fn test_inplace_vector_push_pop() {
let mut v: InplaceVector<i32, 5> = InplaceVector::new();
assert!(v.push_back(10).is_ok());
assert!(v.push_back(20).is_ok());
assert_eq!(v.len(), 2);
assert_eq!(v.pop_back(), Some(20));
assert_eq!(v.pop_back(), Some(10));
}
#[test]
fn test_inplace_vector_capacity() {
let mut v: InplaceVector<i32, 3> = InplaceVector::new();
assert!(v.push_back(1).is_ok());
assert!(v.push_back(2).is_ok());
assert!(v.push_back(3).is_ok());
assert!(v.push_back(4).is_err());
assert!(v.is_full());
}
#[test]
fn test_hive_insert_get() {
let mut hive: Hive<i32> = Hive::new();
let idx = hive.insert(42);
assert_eq!(hive.get(&idx), Some(&42));
}
#[test]
fn test_hive_iter() {
let mut hive: Hive<i32> = Hive::new();
hive.insert(1); hive.insert(2); hive.insert(3);
let sum: i32 = hive.iter().sum();
assert_eq!(sum, 6);
}
#[test]
fn test_hive_remove() {
let mut hive: Hive<i32> = Hive::new();
let idx = hive.insert(99);
assert_eq!(hive.remove(&idx), Some(99));
assert_eq!(hive.len(), 0);
}
#[test]
fn test_stl4_registry_default() {
let reg = Stl4Registry::new();
assert_eq!(reg.feature_count(), 0);
}
#[test]
fn test_stl4_registry_cpp20() {
let reg = Stl4Registry::new().with_standard(202002);
assert!(reg.execution_policies);
assert!(reg.latch_enabled);
assert!(!reg.generator_enabled);
assert!(reg.feature_count() >= 6);
}
#[test]
fn test_stl4_registry_cpp23() {
let reg = Stl4Registry::new().with_standard(202302);
assert!(reg.flat_map_enabled);
assert!(reg.mdspan_enabled);
assert!(reg.generator_enabled);
assert!(reg.print_enabled);
assert!(reg.feature_count() >= 13);
}
#[test]
fn test_stl4_registry_cpp26() {
let reg = Stl4Registry::new().with_standard(202602);
assert!(reg.debugging_enabled);
assert!(reg.text_encoding_enabled);
assert!(reg.inplace_vector_enabled);
assert!(reg.feature_count() == 16);
}
#[test]
fn test_stl4_registry_headers_cpp23() {
let reg = Stl4Registry::new().with_standard(202302);
let headers = reg.headers_for_standard();
assert!(headers.contains(&"<flat_map>".to_string()));
assert!(headers.contains(&"<generator>".to_string()));
assert!(!headers.contains(&"<debugging>".to_string()));
}
#[test]
fn test_stl4_registry_headers_cpp26() {
let reg = Stl4Registry::new().with_standard(202602);
let headers = reg.headers_for_standard();
assert!(headers.contains(&"<debugging>".to_string()));
assert!(headers.contains(&"<text_encoding>".to_string()));
}
}
#[derive(Debug, Clone)]
pub enum MdspanSlice {
Single(usize),
Range { start: usize, end: usize },
All,
StridedRange { start: usize, end: usize, stride: usize },
}
impl MdspanSlice {
pub fn count(&self, full_extent: usize) -> usize {
match self {
Self::Single(_) => 1,
Self::Range { start, end } => end - start,
Self::All => full_extent,
Self::StridedRange { start, end, stride } => (end - start + stride - 1) / stride,
}
}
}
#[derive(Debug, Clone)]
pub struct MdspanExt<T: Clone> {
inner: Mdspan<T>,
}
impl<T: Clone + Default> MdspanExt<T> {
pub fn new(extents: &[usize]) -> Self {
Self { inner: Mdspan::new(extents) }
}
pub fn from_data(data: Vec<T>, extents: &[usize]) -> Self {
Self { inner: Mdspan::from_data(data, extents) }
}
pub fn get(&self, indices: &[usize]) -> &T { self.inner.get(indices) }
pub fn get_mut(&mut self, indices: &[usize]) -> &mut T { self.inner.get_mut(indices) }
pub fn rank(&self) -> usize { self.inner.rank() }
pub fn extents(&self) -> &[usize] { self.inner.extents() }
pub fn size(&self) -> usize { self.inner.size() }
pub fn slice(&self, slices: &[MdspanSlice]) -> Self {
assert_eq!(slices.len(), self.rank());
let new_extents: Vec<usize> = slices.iter()
.zip(self.extents().iter())
.map(|(s, &e)| s.count(e))
.collect();
let total: usize = new_extents.iter().product();
let mut new_data = vec![T::default(); total];
for new_idx in 0..total {
let mut remaining = new_idx;
let mut src_indices = vec![0usize; self.rank()];
for dim in (0..self.rank()).rev() {
let base = match &slices[dim] {
MdspanSlice::Single(i) => *i,
MdspanSlice::Range { start, .. } | MdspanSlice::StridedRange { start, .. } => *start,
MdspanSlice::All => 0,
};
src_indices[dim] = base + remaining % new_extents[dim];
remaining /= new_extents[dim];
}
new_data[new_idx] = self.get(&src_indices).clone();
}
MdspanExt { inner: Mdspan::from_data(new_data, &new_extents) }
}
}
#[derive(Debug, Clone)]
pub struct ParallelReducer {
pub policy: ExecutionPolicy,
pub chunk_size: usize,
}
impl ParallelReducer {
pub fn new(policy: ExecutionPolicy) -> Self { Self { policy, chunk_size: 1024 } }
pub fn reduce<T: Clone + std::ops::Add<Output = T> + Default>(
&self, data: &[T]
) -> T {
let n = data.len();
if !self.policy.is_parallel() || n < 10000 {
return data.iter().fold(T::default(), |a, b| a + b.clone());
}
let chunks = (n + self.chunk_size - 1) / self.chunk_size;
let mut partials: Vec<T> = vec![T::default(); chunks];
for (chunk_idx, chunk) in data.chunks(self.chunk_size).enumerate() {
partials[chunk_idx] = chunk.iter().fold(T::default(), |a, b| a + b.clone());
}
partials.into_iter().fold(T::default(), |a, b| a + b)
}
pub fn reduce_by_key<K: Eq + Clone, V: Clone + std::ops::Add<Output = V> + Default>(
&self, keys: &[K], values: &[V]
) -> Vec<(K, V)> {
use std::collections::HashMap;
let mut map: HashMap<K, V> = HashMap::new();
for (k, v) in keys.iter().zip(values.iter()) {
map.entry(k.clone()).or_insert_with(V::default);
if let Some(entry) = map.get_mut(k) {
*entry = entry.clone() + v.clone();
}
}
map.into_iter().collect()
}
pub fn inclusive_scan<T: Clone + std::ops::Add<Output = T> + Default>(
&self, data: &[T]
) -> Vec<T> {
let mut result = Vec::with_capacity(data.len());
let mut acc = T::default();
for item in data {
acc = acc + item.clone();
result.push(acc.clone());
}
result
}
}
#[derive(Debug, Clone)]
pub struct AsyncGenerator<T: Clone> {
items: Vec<T>,
position: usize,
batch_size: usize,
}
impl<T: Clone> AsyncGenerator<T> {
pub fn new(items: Vec<T>) -> Self { Self { items, position: 0, batch_size: 1 } }
pub fn with_batch_size(mut self, size: usize) -> Self { self.batch_size = size; self }
pub fn next_batch(&mut self) -> Vec<T> {
let start = self.position;
let end = std::cmp::min(start + self.batch_size, self.items.len());
let batch: Vec<T> = self.items[start..end].to_vec();
self.position = end;
batch
}
pub fn take(&mut self, n: usize) -> Vec<T> {
let start = self.position;
let end = std::cmp::min(start + n, self.items.len());
let result = self.items[start..end].to_vec();
self.position = end;
result
}
pub fn skip(&mut self, n: usize) { self.position = std::cmp::min(self.position + n, self.items.len()); }
pub fn reset(&mut self) { self.position = 0; }
pub fn remaining(&self) -> usize { self.items.len() - self.position }
}
#[derive(Debug, Clone)]
pub struct SymbolResolver {
pub binary_path: String,
pub symbol_map: std::collections::HashMap<u64, String>,
pub debug_info_available: bool,
}
impl SymbolResolver {
pub fn new(binary_path: &str) -> Self {
Self { binary_path: binary_path.to_string(),
symbol_map: std::collections::HashMap::new(), debug_info_available: false }
}
pub fn resolve(&self, address: u64) -> Option<String> {
self.symbol_map.get(&address).cloned()
}
pub fn add_symbol(&mut self, address: u64, name: &str) {
self.symbol_map.insert(address, name.to_string());
}
pub fn resolve_stacktrace(&self, addresses: &[u64]) -> BasicStacktrace {
let mut st = BasicStacktrace::with_depth(addresses.len());
for &addr in addresses {
let desc = self.resolve(addr).unwrap_or_else(|| format!("0x{:016x}", addr));
st.push(StacktraceEntry::new(&desc).with_address(addr));
}
st
}
}
#[derive(Debug, Clone)]
pub struct TextEncodingConverter {
pub from: TextEncoding,
pub to: TextEncoding,
pub replacement_char: String,
pub strict: bool,
}
impl TextEncodingConverter {
pub fn new(from: TextEncoding, to: TextEncoding) -> Self {
Self { from, to, replacement_char: "\u{FFFD}".to_string(), strict: false }
}
pub fn with_strict(mut self) -> Self { self.strict = true; self }
pub fn convert(&self, input: &[u8]) -> Result<Vec<u8>, String> {
match (self.from, self.to) {
(TextEncoding::Utf8, TextEncoding::Utf8) => Ok(input.to_vec()),
(TextEncoding::Ascii, TextEncoding::Utf8) => {
if self.strict && input.iter().any(|&b| b >= 128) {
return Err("Non-ASCII byte in strict ASCII->UTF-8 conversion".into());
}
Ok(input.to_vec())
}
(TextEncoding::Utf8, TextEncoding::Ascii) => {
let result: Vec<u8> = input.iter().filter(|&&b| b < 128).copied().collect();
Ok(result)
}
(TextEncoding::Latin1, TextEncoding::Utf8) => {
let mut result = Vec::new();
for &b in input {
if b < 128 { result.push(b); }
else { result.push(0xC0 | (b >> 6)); result.push(0x80 | (b & 0x3F)); }
}
Ok(result)
}
_ => {
if self.strict {
Err(format!("Unsupported conversion: {} -> {}", self.from, self.to))
} else {
Ok(input.to_vec())
}
}
}
}
}
#[derive(Debug)]
pub struct MemoryMappedFile {
pub path: String,
pub data: Vec<u8>,
pub offset: usize,
pub length: usize,
}
impl MemoryMappedFile {
pub fn open(path: &str) -> Result<Self, String> {
let data = std::fs::read(path).map_err(|e| format!("Failed to read {}: {}", path, e))?;
let len = data.len();
Ok(Self { path: path.to_string(), data, offset: 0, length: len })
}
pub fn as_span_stream(&self) -> BasicIspanstream {
BasicIspanstream::new(&self.data[self.offset..self.offset + self.length])
}
pub fn slice(&self, offset: usize, length: usize) -> Option<&[u8]> {
let end = offset + length;
if end <= self.data.len() { Some(&self.data[offset..end]) } else { None }
}
}
#[cfg(test)]
mod extended_tests {
use super::*;
#[test]
fn test_reduce_sum() {
let reducer = ParallelReducer::new(ExecutionPolicy::ParallelPolicy);
let data: Vec<i32> = (1..=100).collect();
let result = reducer.reduce(&data);
assert_eq!(result, 5050);
}
#[test]
fn test_reduce_sequential_small() {
let reducer = ParallelReducer::new(ExecutionPolicy::SequencedPolicy);
let data = vec![1, 2, 3];
assert_eq!(reducer.reduce(&data), 6);
}
#[test]
fn test_inclusive_scan() {
let reducer = ParallelReducer::new(ExecutionPolicy::ParallelPolicy);
let data = vec![1, 2, 3, 4];
let result = reducer.inclusive_scan(&data);
assert_eq!(result, vec![1, 3, 6, 10]);
}
#[test]
fn test_async_generator_batch() {
let mut gen = AsyncGenerator::new(vec![1, 2, 3, 4, 5, 6]).with_batch_size(2);
assert_eq!(gen.next_batch(), vec![1, 2]);
assert_eq!(gen.next_batch(), vec![3, 4]);
assert_eq!(gen.next_batch(), vec![5, 6]);
}
#[test]
fn test_async_generator_take_skip() {
let mut gen = AsyncGenerator::new(vec![1, 2, 3, 4, 5]);
gen.skip(2);
assert_eq!(gen.take(2), vec![3, 4]);
}
#[test]
fn test_symbol_resolver_add_resolve() {
let mut sr = SymbolResolver::new("test_binary");
sr.add_symbol(0x401000, "main");
assert_eq!(sr.resolve(0x401000), Some("main".to_string()));
assert_eq!(sr.resolve(0x500000), None);
}
#[test]
fn test_resolve_stacktrace() {
let mut sr = SymbolResolver::new("test");
sr.add_symbol(0x1000, "func_a");
sr.add_symbol(0x2000, "func_b");
let st = sr.resolve_stacktrace(&[0x1000, 0x2000, 0x3000]);
assert_eq!(st.size(), 3);
assert!(st.entries()[0].to_string().contains("func_a"));
}
#[test]
fn test_encoding_converter_ascii_to_utf8() {
let conv = TextEncodingConverter::new(TextEncoding::Ascii, TextEncoding::Utf8);
let result = conv.convert(b"Hello").unwrap();
assert_eq!(result, b"Hello");
}
#[test]
fn test_encoding_converter_latin1_to_utf8() {
let conv = TextEncodingConverter::new(TextEncoding::Latin1, TextEncoding::Utf8);
let input = vec![0xC9]; let result = conv.convert(&input).unwrap();
assert_eq!(result, vec![0xC3, 0x89]); }
#[test]
fn test_encoding_converter_strict_fails() {
let conv = TextEncodingConverter::new(TextEncoding::Ascii, TextEncoding::Utf8).with_strict();
assert!(conv.convert(&[0x80]).is_err());
}
#[test]
fn test_memory_mapped_file_not_found() {
let result = MemoryMappedFile::open("/nonexistent/file.test");
assert!(result.is_err());
}
#[test]
fn test_mdspan_ext_slice_all() {
let data: Vec<i32> = (0..24).collect();
let span = MdspanExt::from_data(data, &[2, 3, 4]);
let sliced = span.slice(&[MdspanSlice::All, MdspanSlice::All, MdspanSlice::All]);
assert_eq!(sliced.extents(), &[2, 3, 4]);
}
#[test]
fn test_mdspan_ext_slice_range() {
let data: Vec<i32> = (0..24).collect();
let span = MdspanExt::from_data(data, &[2, 3, 4]);
let sliced = span.slice(&[MdspanSlice::Single(1), MdspanSlice::Range { start: 0, end: 2 }, MdspanSlice::All]);
assert_eq!(sliced.extents(), &[1, 2, 4]);
}
#[test]
fn test_inplace_vector_as_slice() {
let mut v: InplaceVector<i32, 10> = InplaceVector::new();
v.push_back(1).unwrap();
v.push_back(2).unwrap();
assert_eq!(v.as_slice().len(), 2);
}
#[test]
fn test_inplace_vector_clear() {
let mut v: InplaceVector<i32, 5> = InplaceVector::new();
v.push_back(1).unwrap();
v.push_back(2).unwrap();
v.clear();
assert!(v.is_empty());
assert_eq!(v.len(), 0);
}
#[test]
fn test_hive_bucket_behavior() {
let mut hive: Hive<i32> = Hive::with_bucket_capacity(4);
for i in 0..10 { hive.insert(i); }
assert!(hive.bucket_count() >= 2);
}
}
#[derive(Debug, Clone)]
pub struct FeatureTestMacros {
pub cpp_standard: u32,
}
impl FeatureTestMacros {
pub fn new(std_year: u32) -> Self { Self { cpp_standard: std_year } }
pub fn has_execution(&self) -> bool { self.cpp_standard >= 201703 }
pub fn has_latch(&self) -> bool { self.cpp_standard >= 202002 }
pub fn has_barrier(&self) -> bool { self.cpp_standard >= 202002 }
pub fn has_semaphore(&self) -> bool { self.cpp_standard >= 202002 }
pub fn has_syncstream(&self) -> bool { self.cpp_standard >= 202002 }
pub fn has_spanstream(&self) -> bool { self.cpp_standard >= 202302 }
pub fn has_flat_map(&self) -> bool { self.cpp_standard >= 202302 }
pub fn has_mdspan(&self) -> bool { self.cpp_standard >= 202302 }
pub fn has_generator(&self) -> bool { self.cpp_standard >= 202302 }
pub fn has_print(&self) -> bool { self.cpp_standard >= 202302 }
pub fn has_stacktrace(&self) -> bool { self.cpp_standard >= 202302 }
pub fn has_debugging(&self) -> bool { self.cpp_standard >= 202602 }
pub fn has_text_encoding(&self) -> bool { self.cpp_standard >= 202602 }
pub fn has_inplace_vector(&self) -> bool { self.cpp_standard >= 202602 }
pub fn all_macros(&self) -> Vec<(&str, bool)> {
vec![
("__cpp_lib_execution", self.has_execution()),
("__cpp_lib_latch", self.has_latch()),
("__cpp_lib_barrier", self.has_barrier()),
("__cpp_lib_semaphore", self.has_semaphore()),
("__cpp_lib_syncstream", self.has_syncstream()),
("__cpp_lib_spanstream", self.has_spanstream()),
("__cpp_lib_flat_map", self.has_flat_map()),
("__cpp_lib_mdspan", self.has_mdspan()),
("__cpp_lib_generator", self.has_generator()),
("__cpp_lib_print", self.has_print()),
("__cpp_lib_stacktrace", self.has_stacktrace()),
("__cpp_lib_debugging", self.has_debugging()),
("__cpp_lib_text_encoding", self.has_text_encoding()),
("__cpp_lib_inplace_vector", self.has_inplace_vector()),
]
}
}
#[cfg(test)]
mod feature_tests {
use super::*;
#[test]
fn test_feature_macros_cpp17() {
let ftm = FeatureTestMacros::new(201703);
assert!(ftm.has_execution());
assert!(!ftm.has_latch());
assert!(!ftm.has_generator());
}
#[test]
fn test_feature_macros_cpp20() {
let ftm = FeatureTestMacros::new(202002);
assert!(ftm.has_execution());
assert!(ftm.has_latch());
assert!(ftm.has_barrier());
assert!(!ftm.has_mdspan());
}
#[test]
fn test_feature_macros_cpp23() {
let ftm = FeatureTestMacros::new(202302);
assert!(ftm.has_flat_map());
assert!(ftm.has_mdspan());
assert!(ftm.has_generator());
assert!(ftm.has_print());
assert!(!ftm.has_debugging());
}
#[test]
fn test_feature_macros_cpp26() {
let ftm = FeatureTestMacros::new(202602);
assert!(ftm.has_debugging());
assert!(ftm.has_text_encoding());
assert!(ftm.has_inplace_vector());
}
#[test]
fn test_feature_macros_all_count() {
let ftm = FeatureTestMacros::new(202602);
let all = ftm.all_macros();
assert_eq!(all.len(), 14);
assert!(all.iter().all(|&(_, v)| v));
}
}