use std::ops::{Deref, DerefMut};
use std::sync::Arc;
use crate::ThreadAware;
use crate::affinity::Affinity;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)]
#[repr(transparent)]
pub struct Unaware<T>(pub T);
impl<T> From<T> for Unaware<T> {
fn from(value: T) -> Self {
Self(value)
}
}
impl<T> Deref for Unaware<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for Unaware<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T: Send> ThreadAware for Unaware<T> {
fn relocate(&mut self, _source: Option<Affinity>, _destination: Affinity) {}
}
impl<T> Unaware<T> {
pub fn into_inner(self) -> T {
self.0
}
pub fn into_arc(self: Arc<Self>) -> Arc<T> {
unsafe { std::mem::transmute(self) }
}
}
pub const fn unaware<T>(value: T) -> Unaware<T> {
Unaware(value)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::affinity::pinned_affinities;
#[test]
fn test_unaware_construction() {
let value = Unaware(42);
assert_eq!(value.0, 42);
let string_value = Unaware("hello".to_string());
assert_eq!(string_value.0, "hello");
let value = unaware(100);
assert_eq!(value.0, 100);
let vec_value = unaware(vec![1, 2, 3]);
assert_eq!(vec_value.0, vec![1, 2, 3]);
}
#[test]
fn test_unaware_deref() {
let mut value = Unaware(vec![1, 2, 3]);
assert_eq!(value.len(), 3);
assert_eq!(value[0], 1);
value.push(4);
assert_eq!(value.len(), 4);
assert_eq!(value[3], 4);
}
#[test]
fn test_unaware_clone_and_copy() {
let original = Unaware(42);
let cloned = original;
assert_eq!(original.0, 42);
assert_eq!(cloned.0, 42);
let original = Unaware(42);
let copied = original;
assert_eq!(original.0, 42);
assert_eq!(copied.0, 42);
}
#[test]
fn test_unaware_derived_traits() {
use std::collections::HashSet;
let value = Unaware(42);
let debug_str = format!("{value:?}");
assert!(debug_str.contains("Unaware"));
assert!(debug_str.contains("42"));
let value1 = Unaware(42);
let value2 = Unaware(42);
let value3 = Unaware(43);
assert_eq!(value1, value2);
assert_ne!(value1, value3);
let mut set = HashSet::new();
set.insert(Unaware(1));
set.insert(Unaware(2));
set.insert(Unaware(1)); assert_eq!(set.len(), 2);
assert!(set.contains(&Unaware(1)));
assert!(set.contains(&Unaware(2)));
}
#[test]
fn test_unaware_default() {
let default_i32: Unaware<i32> = Unaware::default();
assert_eq!(default_i32.0, 0);
let default_string: Unaware<String> = Unaware::default();
assert_eq!(default_string.0, "");
let default_vec: Unaware<Vec<i32>> = Unaware::default();
assert_eq!(default_vec.0.len(), 0);
}
#[test]
fn test_unaware_thread_aware() {
use std::collections::HashMap;
let affinities = pinned_affinities(&[2]);
let source = Some(affinities[0]);
let destination = affinities[1];
let mut value = Unaware(42);
value.relocate(source, destination);
assert_eq!(value.0, 42);
let mut value = Unaware("test string".to_string());
value.relocate(source, destination);
assert_eq!(value.0, "test string");
let mut map = HashMap::new();
map.insert("key1", 100);
map.insert("key2", 200);
let mut value = Unaware(map);
value.relocate(source, destination);
assert_eq!(value.0.get("key1"), Some(&100));
assert_eq!(value.0.get("key2"), Some(&200));
}
#[test]
fn test_unaware_into_arc() {
let value = Unaware(42);
let arc_unaware = Arc::new(value);
let arc_inner: Arc<i32> = arc_unaware.into_arc();
assert_eq!(*arc_inner, 42);
let value = Unaware("hello".to_string());
let arc_unaware = Arc::new(value);
let arc_inner: Arc<String> = arc_unaware.into_arc();
assert_eq!(*arc_inner, "hello");
let value = Unaware(vec![1, 2, 3, 4, 5]);
let arc_unaware = Arc::new(value);
let arc_inner: Arc<Vec<i32>> = arc_unaware.into_arc();
assert_eq!(*arc_inner, vec![1, 2, 3, 4, 5]);
}
#[test]
fn test_unaware_into_inner_preserves_arc_count() {
let value = Unaware(100);
let arc_unaware = Arc::new(value);
let _arc_clone = Arc::clone(&arc_unaware);
assert_eq!(Arc::strong_count(&arc_unaware), 2);
let arc_inner: Arc<i32> = arc_unaware.into_arc();
assert_eq!(Arc::strong_count(&arc_inner), 2);
}
#[test]
fn test_unaware_with_arc_inside() {
use std::sync::Mutex;
let inner_arc = Arc::new(Mutex::new(42));
let mut unaware_wrapper = Unaware(Arc::clone(&inner_arc));
let affinities = pinned_affinities(&[2]);
let source = Some(affinities[0]);
let destination = affinities[1];
unaware_wrapper.relocate(source, destination);
assert_eq!(Arc::strong_count(&inner_arc), 2);
assert_eq!(Arc::strong_count(&unaware_wrapper.0), 2);
}
#[test]
fn test_unaware_field_access() {
let value = Unaware(vec![10, 20, 30]);
assert_eq!(value.0[0], 10);
assert_eq!(value.0[1], 20);
assert_eq!(value.0[2], 30);
assert_eq!(value.first(), Some(&10));
assert_eq!(value.last(), Some(&30));
}
#[test]
fn test_unaware_nested_structure() {
#[derive(Debug, PartialEq)]
struct Complex {
id: i32,
name: String,
values: Vec<i32>,
}
let complex = Complex {
id: 1,
name: "test".to_string(),
values: vec![1, 2, 3],
};
let mut unaware_complex = Unaware(complex);
assert_eq!(unaware_complex.0.id, 1);
assert_eq!(unaware_complex.0.name, "test");
assert_eq!(unaware_complex.0.values, vec![1, 2, 3]);
let affinities = pinned_affinities(&[2]);
let source = Some(affinities[0]);
let destination = affinities[1];
unaware_complex.relocate(source, destination);
assert_eq!(unaware_complex.0.id, 1);
assert_eq!(unaware_complex.0.name, "test");
}
#[test]
fn test_unaware_const_function() {
const VALUE: Unaware<i32> = unaware(42);
assert_eq!(VALUE.0, 42);
}
#[test]
fn test_unaware_into_inner() {
let value = unaware(55);
let inner = value.into_inner();
assert_eq!(inner, 55);
}
#[test]
fn test_from_impl() {
let value: Unaware<i32> = 99.into();
assert_eq!(value.0, 99);
let string_value: Unaware<String> = "from impl".to_string().into();
assert_eq!(string_value.0, "from impl");
}
}