Repository: vorner/arc-swap (language: rust)

Issue:
const construct for ArcSwapOption
It would be really nice if there were a const construct for ArcSwapOption.


Discussion / hints:
For the empty one? :thinking: 

I'll have to check that:
* `const fn` is working all the way back to what the crate promises to support.
* That the internal locking strategy is actually const-constructible.

But it might be possible

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b025051..336f496 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# 1.4.0
+
+* Allow const-initializing ArcSwapOption (`const_empty` method).
+
 # 1.3.2
 
 * More helpful description of the `AsRaw` trait (isn't implemented for owned
diff --git a/Cargo.lock b/Cargo.lock
index 9f4640b..9488509 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -10,7 +10,7 @@ checksum = "0ccb55436ce9ad9dbd99e726649f8ae4ae3644f5011b822ed805358da37e7e00"
 
 [[package]]
 name = "arc-swap"
-version = "1.3.2"
+version = "1.4.0"
 dependencies = [
  "adaptive-barrier",
  "criterion",
diff --git a/Cargo.toml b/Cargo.toml
index 9569469..9da7a48 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "arc-swap"
-version = "1.3.2"
+version = "1.4.0"
 authors = ["Michal 'vorner' Vaner <vorner@vorner.cz>"]
 description = "Atomically swappable Arc"
 documentation = "https://docs.rs/arc-swap"
diff --git a/src/lib.rs b/src/lib.rs
index e959ad4..2dba712 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -148,6 +148,7 @@ use crate::access::{Access, Map};
 pub use crate::as_raw::AsRaw;
 pub use crate::cache::Cache;
 pub use crate::ref_cnt::RefCnt;
+use crate::strategy::hybrid::{DefaultConfig, HybridStrategy};
 use crate::strategy::sealed::Protected;
 use crate::strategy::{CaS, Strategy};
 pub use crate::strategy::{DefaultStrategy, IndependentStrategy};
@@ -737,6 +738,37 @@ impl<T, S: Strategy<Option<Arc<T>>>> ArcSwapAny<Option<Arc<T>>, S> {
     }
 }
 
+impl<T> ArcSwapOption<T> {
+    /// A const-fn equilavent of [empty].
+    ///
+    /// Just like [empty], this creates an `None`-holding `ArcSwapOption`. The [empty] is, however,
+    /// more general ‒ this is available only for the default strategy, while [empty] is for any
+    /// [Default]-constructible strategy (current or future one).
+    ///
+    /// [empty]: ArcSwapAny::empty
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use std::sync::Arc;
+    /// # use arc_swap::ArcSwapOption;
+    /// static GLOBAL_DATA: ArcSwapOption<usize> = ArcSwapOption::const_empty();
+    ///
+    /// assert!(GLOBAL_DATA.load().is_none());
+    /// GLOBAL_DATA.store(Some(Arc::new(42)));
+    /// assert_eq!(42, **GLOBAL_DATA.load().as_ref().unwrap());
+    /// ```
+    pub const fn const_empty() -> Self {
+        Self {
+            ptr: AtomicPtr::new(ptr::null_mut()),
+            _phantom_arc: PhantomData,
+            strategy: HybridStrategy {
+                _config: DefaultConfig,
+            },
+        }
+    }
+}
+
 /// An atomic storage that doesn't share the internal generation locks with others.
 ///
 /// This makes it bigger and it also might suffer contention (on the HW level) if used from many
diff --git a/src/strategy/hybrid.rs b/src/strategy/hybrid.rs
index bf79edf..e7c15dd 100644
--- a/src/strategy/hybrid.rs
+++ b/src/strategy/hybrid.rs
@@ -171,7 +171,7 @@ impl Config for DefaultConfig {
 
 #[derive(Clone, Default)]
 pub struct HybridStrategy<Cfg> {
-    _config: Cfg,
+    pub(crate) _config: Cfg,
 }
 
 impl<T, Cfg> InnerStrategy<T> for HybridStrategy<Cfg>
diff --git a/src/strategy/mod.rs b/src/strategy/mod.rs
index 2a25a04..50e8c5a 100644
--- a/src/strategy/mod.rs
+++ b/src/strategy/mod.rs
@@ -41,7 +41,7 @@ use std::sync::atomic::AtomicPtr;
 
 use crate::ref_cnt::RefCnt;
 
-mod hybrid;
+pub(crate) mod hybrid;
 mod rw_lock;
 // Do not use from outside of the crate.
 #[cfg(feature = "internal-test-strategies")]


Test patch: