1use core::sync::atomic::{AtomicBool, AtomicI64, AtomicIsize, AtomicU64, AtomicUsize};
2use std::sync::Arc;
3
4pub use map::{CacheMapExt, EntryExt, TimedValue};
5pub use wrapper::{HashExt, OrdExt, OrdHashExt};
6
7pub mod map;
8pub mod wrapper;
9
10#[macro_export]
11macro_rules! tuple_deref {
12 ($Name:ty) => {
13 impl<T> std::ops::Deref for $Name {
14 type Target = T;
15 #[inline]
16 fn deref(&self) -> &Self::Target {
17 &self.0
18 }
19 }
20 };
21}
22
23#[macro_export]
24macro_rules! tuple_deref_mut {
25 ($Name:ty) => {
26 impl<T> std::ops::DerefMut for $Name {
27 fn deref_mut(&mut self) -> &mut Self::Target {
28 &mut self.0
29 }
30 }
31 };
32}
33
34#[macro_export]
35macro_rules! tuple_take {
36 ($Name:ty) => {
37 impl<T> $Name {
38 #[inline]
39 pub fn take(self) -> T {
40 self.0
41 }
42 }
43 };
44}
45
46impl<T: ?Sized> ArcExt for T {}
47
48pub trait ArcExt {
49 #[inline]
50 fn arc(self) -> Arc<Self>
51 where
52 Self: Sized,
53 {
54 Arc::new(self)
55 }
56}
57
58pub trait AtomicExt<T> {
59 fn atomic(self) -> T;
60}
61
62impl AtomicExt<AtomicUsize> for usize {
63 #[inline]
64 fn atomic(self) -> AtomicUsize {
65 AtomicUsize::new(self)
66 }
67}
68
69impl AtomicExt<AtomicIsize> for isize {
70 #[inline]
71 fn atomic(self) -> AtomicIsize {
72 AtomicIsize::new(self)
73 }
74}
75
76impl AtomicExt<AtomicU64> for u64 {
77 #[inline]
78 fn atomic(self) -> AtomicU64 {
79 AtomicU64::new(self)
80 }
81}
82
83impl AtomicExt<AtomicI64> for i64 {
84 #[inline]
85 fn atomic(self) -> AtomicI64 {
86 AtomicI64::new(self)
87 }
88}
89
90impl AtomicExt<AtomicBool> for bool {
91 #[inline]
92 fn atomic(self) -> AtomicBool {
93 AtomicBool::new(self)
94 }
95}
96
97#[test]
98fn test_atomic() {
99 use std::sync::atomic::Ordering;
100
101 assert_eq!(100usize.atomic().load(Ordering::SeqCst), 100);
102 assert_eq!(100isize.atomic().load(Ordering::SeqCst), 100);
103 assert_eq!(100u64.atomic().load(Ordering::SeqCst), 100);
104 assert_eq!(100i64.atomic().load(Ordering::SeqCst), 100);
105 assert!(true.atomic().load(Ordering::SeqCst))
106}
107
108#[test]
109fn test_arc_ext() {
110 let v = 42.arc();
111 assert_eq!(*v, 42);
112
113 let s = "hello".to_string().arc();
114 assert_eq!(*s, "hello");
115
116 let s2 = s.clone();
118 assert_eq!(*s2, "hello");
119 assert!(Arc::ptr_eq(&s, &s2));
120}
121
122#[test]
123fn test_atomic_ext_usize() {
124 use std::sync::atomic::Ordering;
125 let a = 0usize.atomic();
126 a.store(10, Ordering::SeqCst);
127 assert_eq!(a.load(Ordering::SeqCst), 10);
128}
129
130#[test]
131fn test_atomic_ext_isize() {
132 use std::sync::atomic::Ordering;
133 let a = (-5isize).atomic();
134 assert_eq!(a.load(Ordering::SeqCst), -5);
135}
136
137#[test]
138fn test_atomic_ext_bool() {
139 use std::sync::atomic::Ordering;
140 let a = false.atomic();
141 assert!(!a.load(Ordering::SeqCst));
142 a.store(true, Ordering::SeqCst);
143 assert!(a.load(Ordering::SeqCst));
144}
145
146#[test]
147fn test_tuple_deref_macro() {
148 struct MyWrapper<T>(T);
149 tuple_deref!(MyWrapper<T>);
150
151 let w = MyWrapper(42);
152 assert_eq!(*w, 42);
153}
154
155#[test]
156fn test_tuple_deref_mut_macro() {
157 struct MyWrapper<T>(T);
158 tuple_deref!(MyWrapper<T>);
159 tuple_deref_mut!(MyWrapper<T>);
160
161 let mut w = MyWrapper(42);
162 *w = 100;
163 assert_eq!(*w, 100);
164}
165
166#[test]
167fn test_tuple_take_macro() {
168 struct MyWrapper<T>(T);
169 tuple_take!(MyWrapper<T>);
170
171 let w = MyWrapper(42);
172 assert_eq!(w.take(), 42);
173}
174
175#[test]
176fn test_wrapper_eq_ord() {
177 let a = 1.eq_ord();
178 let b = 2.eq_ord();
179 assert!(a.eq(&b));
181 assert!(a.partial_cmp(&b) == Some(std::cmp::Ordering::Equal));
182 assert!(a.cmp(&b) == std::cmp::Ordering::Equal);
183}
184
185#[test]
186fn test_wrapper_neq_ord() {
187 let a = 1.neq_ord();
188 let b = 1.neq_ord();
189 assert!(a.ne(&b));
191 assert!(a.partial_cmp(&b).is_none());
192 assert!(a.cmp(&b) == std::cmp::Ordering::Greater);
193}
194
195#[test]
196fn test_wrapper_hash() {
197 use std::collections::hash_map::DefaultHasher;
198 use std::hash::{Hash, Hasher};
199
200 let a = 42.hash_value(12345);
201 let mut hasher = DefaultHasher::new();
202 a.hash(&mut hasher);
203 let h1 = hasher.finish();
204
205 let b = 99.hash_value(12345);
206 let mut hasher2 = DefaultHasher::new();
207 b.hash(&mut hasher2);
208 let h2 = hasher2.finish();
209
210 assert_eq!(h1, h2);
212
213 let c = 42.hash_value(54321);
215 let mut hasher3 = DefaultHasher::new();
216 c.hash(&mut hasher3);
217 let h3 = hasher3.finish();
218 assert_ne!(h1, h3);
219}
220
221#[test]
222fn test_empty_hash_wrapper() {
223 use std::collections::hash_map::DefaultHasher;
224 use std::hash::{Hash, Hasher};
225
226 let a = 42.hash_empty();
227 let mut hasher = DefaultHasher::new();
228 a.hash(&mut hasher);
229 let h1 = hasher.finish();
230
231 let b = 99.hash_empty();
232 let mut hasher2 = DefaultHasher::new();
233 b.hash(&mut hasher2);
234 let h2 = hasher2.finish();
235
236 let h_default = DefaultHasher::new().finish();
238 assert_eq!(h1, h_default);
239 assert_eq!(h2, h_default);
240}
241
242#[test]
243fn test_ord_hash_ext_neq_ord_hash() {
244 let a = 1.neq_ord_hash(100);
245 let b = 1.neq_ord_hash(100);
246 assert!(a.ne(&b));
248}
249
250#[test]
251fn test_ord_hash_ext_neq_ord_empty() {
252 let a = 1.neq_ord_empty();
253 let b = 1.neq_ord_empty();
254 assert!(a.ne(&b));
256 assert!(a.cmp(&b) == std::cmp::Ordering::Greater);
257}
258
259#[test]
260fn test_ord_ext_reverse_via_cmp() {
261 let a = 5.eq_ord();
263 assert!(a.cmp(&6.eq_ord()) == std::cmp::Ordering::Equal);
264 assert!(5.neq_ord().cmp(&5.neq_ord()) == std::cmp::Ordering::Greater);
265}