From 3043a39d1de95f9355dedde50860f7f3d4c2ef3e Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Thu, 16 Sep 2021 17:33:12 +0200 Subject: [PATCH] Const ArcSwapOption initialization Unfortunately, as a separate function, as `fn empty` already promises to work for any `S: Default` strategy. Closes #62. --- CHANGELOG.md | 4 ++++ Cargo.lock | 2 +- Cargo.toml | 2 +- src/lib.rs | 32 ++++++++++++++++++++++++++++++++ src/strategy/hybrid.rs | 2 +- src/strategy/mod.rs | 2 +- 6 files changed, 40 insertions(+), 4 deletions(-) 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 "] 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>>> ArcSwapAny>, S> { } } +impl ArcSwapOption { + /// 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 = 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 { - _config: Cfg, + pub(crate) _config: Cfg, } impl InnerStrategy for HybridStrategy 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")]