Skip to content

Commit ffb8aba

Browse files
author
Thom Chiovoloni
committed
Allow initialization using a const fn.
1 parent 65aee91 commit ffb8aba

File tree

1 file changed

+31
-23
lines changed

1 file changed

+31
-23
lines changed

src/lib.rs

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -139,34 +139,16 @@ macro_rules! static_atomic_ref {
139139
static_atomic_ref!(@PUB, $(#[$attr])* static $N : $T; $($t)*);
140140
};
141141
(@$VIS:ident, $(#[$attr:meta])* static $N:ident : $T:ty; $($t:tt)*) => {
142-
static_atomic_ref!(@MAKE TY, $VIS, $(#[$attr])*, $N);
143-
impl $crate::core_ops::Deref for $N {
144-
type Target = $crate::AtomicRef<'static, $T>;
145-
#[allow(unsafe_code)]
146-
fn deref<'a>(&'a self) -> &'a $crate::AtomicRef<'static, $T> {
147-
static STORAGE: $crate::AtomicRef<'static, u8> = $crate::ATOMIC_U8_REF_INIT;
148-
unsafe { $crate::core_mem::transmute(&STORAGE) }
149-
}
150-
}
142+
static_atomic_ref!(@MAKE TY, $VIS, $(#[$attr])*, $N, $T);
151143
static_atomic_ref!($($t)*);
152144
};
153-
(@MAKE TY, PUB, $(#[$attr:meta])*, $N:ident) => {
154-
#[allow(missing_copy_implementations)]
155-
#[allow(non_camel_case_types)]
156-
#[allow(dead_code)]
145+
(@MAKE TY, PUB, $(#[$attr:meta])*, $N:ident, $T:ty) => {
157146
$(#[$attr])*
158-
pub struct $N { _private: () }
159-
#[doc(hidden)]
160-
pub static $N: $N = $N { _private: () };
147+
pub static $N: $crate::AtomicRef<'static, $T> = $crate::AtomicRef::static_none();
161148
};
162-
(@MAKE TY, PRIV, $(#[$attr:meta])*, $N:ident) => {
163-
#[allow(missing_copy_implementations)]
164-
#[allow(non_camel_case_types)]
165-
#[allow(dead_code)]
149+
(@MAKE TY, PRIV, $(#[$attr:meta])*, $N:ident, $T:ty) => {
166150
$(#[$attr])*
167-
struct $N { _private: () }
168-
#[doc(hidden)]
169-
static $N: $N = $N { _private: () };
151+
static $N: $crate::AtomicRef<'static, $T> = $crate::AtomicRef::static_none();
170152
};
171153
() => ();
172154
}
@@ -186,6 +168,32 @@ unsafe fn to_opt<'a, T>(p: usize) -> Option<&'a T> {
186168
(p as *const T).as_ref()
187169
}
188170

171+
impl<T: 'static> AtomicRef<'static, T> {
172+
// Putting this inside `static_none` hits a "no mutable references in const
173+
// fn" limitation, because of the `PhantomData`. Other methods of enforcing
174+
// invariance hit the same sort of problem (`fn` isn't allowed either).
175+
const NONE: Self = Self {
176+
data: AtomicUsize::new(0),
177+
_marker: PhantomData,
178+
};
179+
/// Returns a `AtomicRef<'static, T>` with a value of `None`.
180+
///
181+
/// This is useful as it is implemented as a `const fn`, and thus can
182+
/// initialize an `AtomicRef` used as a `static`.
183+
///
184+
/// # Examples
185+
///
186+
/// ```
187+
/// use atomic_ref::AtomicRef;
188+
///
189+
/// pub static SOME_REFERENCE: AtomicRef<'static, u64> = AtomicRef::static_none();
190+
/// ```
191+
#[inline]
192+
pub const fn static_none() -> Self {
193+
Self::NONE
194+
}
195+
}
196+
189197
impl<'a, T> AtomicRef<'a, T> {
190198
/// Creates a new `AtomicRef`.
191199
///

0 commit comments

Comments
 (0)