From 0f5d5f0079127cbcc0fbd3ccf5c25b86a3c89d22 Mon Sep 17 00:00:00 2001 From: Zachary Harrold Date: Sun, 29 Dec 2024 16:54:49 +1100 Subject: [PATCH 1/4] Initial Commit --- Cargo.toml | 8 ++++++++ src/lib.rs | 8 +++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index e89e0e8..65eb00c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,10 @@ all-features = true serde = { version = "1.0", optional = true, default-features = false } borsh = { version = "1.4.0", optional = true, default-features = false } arbitrary = { version = "1.3", optional = true } +portable-atomic = { version = "1", default-features = false, optional = true } +portable-atomic-util = { version = "0.2.4", features = [ + "alloc", +], optional = true } [dev-dependencies] proptest = "1.5" @@ -24,3 +28,7 @@ serde = { version = "1.0", features = ["derive"] } [features] default = ["std"] std = ["serde?/std", "borsh?/std"] +portable-atomic = [ + "dep:portable-atomic", + "dep:portable-atomic-util", +] diff --git a/src/lib.rs b/src/lib.rs index bf88f57..3c3f98b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,7 @@ extern crate alloc; -use alloc::{borrow::Cow, boxed::Box, string::String, sync::Arc}; +use alloc::{borrow::Cow, boxed::Box, string::String}; use core::{ borrow::Borrow, cmp::{self, Ordering}, @@ -12,6 +12,12 @@ use core::{ str::FromStr, }; +#[cfg(feature = "portable-atomic")] +use portable_atomic_util::Arc; + +#[cfg(not(feature = "portable-atomic"))] +use alloc::sync::Arc; + /// A `SmolStr` is a string type that has the following properties: /// /// * `size_of::() == 24` (therefor `== size_of::()` on 64 bit platforms) From 3859e146dcae8daf7a2304d7d805dcfcc47d6777 Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Tue, 28 Jan 2025 09:13:15 +1100 Subject: [PATCH 2/4] Ensure appropriate `From` implementations are always available. --- src/lib.rs | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3c3f98b..0b8af60 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,12 +12,17 @@ use core::{ str::FromStr, }; -#[cfg(feature = "portable-atomic")] +#[cfg(all(not(target_has_atomic = "ptr"), feature = "portable-atomic"))] use portable_atomic_util::Arc; -#[cfg(not(feature = "portable-atomic"))] +#[cfg(target_has_atomic = "ptr")] use alloc::sync::Arc; +#[cfg(all(not(target_has_atomic = "ptr"), not(feature = "portable-atomic")))] +compile_error!( + "Targets without support for atomic pointers must enable the `portable-atomic` feature" +); + /// A `SmolStr` is a string type that has the following properties: /// /// * `size_of::() == 24` (therefor `== size_of::()` on 64 bit platforms) @@ -383,9 +388,19 @@ impl From> for SmolStr { } } -impl From> for SmolStr { +#[cfg(target_has_atomic = "ptr")] +impl From> for SmolStr { + #[inline] + fn from(s: alloc::sync::Arc) -> SmolStr { + let repr = Repr::new_on_stack(s.as_ref()).unwrap_or_else(|| Repr::Heap(s)); + Self(repr) + } +} + +#[cfg(all(not(target_has_atomic = "ptr"), feature = "portable-atomic"))] +impl From> for SmolStr { #[inline] - fn from(s: Arc) -> SmolStr { + fn from(s: portable_atomic_util::Arc) -> SmolStr { let repr = Repr::new_on_stack(s.as_ref()).unwrap_or_else(|| Repr::Heap(s)); Self(repr) } @@ -398,7 +413,8 @@ impl<'a> From> for SmolStr { } } -impl From for Arc { +#[cfg(target_has_atomic = "ptr")] +impl From for alloc::sync::Arc { #[inline(always)] fn from(text: SmolStr) -> Self { match text.0 { @@ -408,6 +424,17 @@ impl From for Arc { } } +#[cfg(all(not(target_has_atomic = "ptr"), feature = "portable-atomic"))] +impl From for portable_atomic_util::Arc { + #[inline(always)] + fn from(text: SmolStr) -> Self { + match text.0 { + Repr::Heap(data) => data.into(), + _ => text.as_str().into(), + } + } +} + impl From for String { #[inline(always)] fn from(text: SmolStr) -> Self { From fe7f32322548597a7816c29bde4878893df9107b Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Tue, 28 Jan 2025 09:28:16 +1100 Subject: [PATCH 3/4] Simplify implementation --- src/lib.rs | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 0b8af60..bb9435a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -388,19 +388,9 @@ impl From> for SmolStr { } } -#[cfg(target_has_atomic = "ptr")] -impl From> for SmolStr { +impl From> for SmolStr { #[inline] - fn from(s: alloc::sync::Arc) -> SmolStr { - let repr = Repr::new_on_stack(s.as_ref()).unwrap_or_else(|| Repr::Heap(s)); - Self(repr) - } -} - -#[cfg(all(not(target_has_atomic = "ptr"), feature = "portable-atomic"))] -impl From> for SmolStr { - #[inline] - fn from(s: portable_atomic_util::Arc) -> SmolStr { + fn from(s: Arc) -> SmolStr { let repr = Repr::new_on_stack(s.as_ref()).unwrap_or_else(|| Repr::Heap(s)); Self(repr) } @@ -413,8 +403,7 @@ impl<'a> From> for SmolStr { } } -#[cfg(target_has_atomic = "ptr")] -impl From for alloc::sync::Arc { +impl From for Arc { #[inline(always)] fn from(text: SmolStr) -> Self { match text.0 { @@ -424,17 +413,6 @@ impl From for alloc::sync::Arc { } } -#[cfg(all(not(target_has_atomic = "ptr"), feature = "portable-atomic"))] -impl From for portable_atomic_util::Arc { - #[inline(always)] - fn from(text: SmolStr) -> Self { - match text.0 { - Repr::Heap(data) => data.into(), - _ => text.as_str().into(), - } - } -} - impl From for String { #[inline(always)] fn from(text: SmolStr) -> Self { From 454c32fd1ced2922dc7f39aabe156be834ce66c8 Mon Sep 17 00:00:00 2001 From: Zac Harrold Date: Tue, 28 Jan 2025 14:19:44 +1100 Subject: [PATCH 4/4] Ensure `portable-atomic` is only brought in when required --- Cargo.toml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 65eb00c..f856271 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,10 +15,6 @@ all-features = true serde = { version = "1.0", optional = true, default-features = false } borsh = { version = "1.4.0", optional = true, default-features = false } arbitrary = { version = "1.3", optional = true } -portable-atomic = { version = "1", default-features = false, optional = true } -portable-atomic-util = { version = "0.2.4", features = [ - "alloc", -], optional = true } [dev-dependencies] proptest = "1.5" @@ -32,3 +28,9 @@ portable-atomic = [ "dep:portable-atomic", "dep:portable-atomic-util", ] + +[target.'cfg(not(target_has_atomic = "ptr"))'.dependencies] +portable-atomic = { version = "1", default-features = false, optional = true } +portable-atomic-util = { version = "0.2.4", features = [ + "alloc", +], optional = true } \ No newline at end of file