Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow using a few &Self-taking static methods as inherent &self methods #61

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 33 additions & 33 deletions src/arc_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,23 +494,23 @@
/// ```
/// # use arcstr::ArcStr;
/// let foobar = ArcStr::from("foobar");
/// assert_eq!(Some(1), ArcStr::strong_count(&foobar));
/// assert_eq!(Some(1), foobar.strong_count());
/// let also_foobar = ArcStr::clone(&foobar);
/// assert_eq!(Some(2), ArcStr::strong_count(&foobar));
/// assert_eq!(Some(2), ArcStr::strong_count(&also_foobar));
/// assert_eq!(Some(2), foobar.strong_count());
/// assert_eq!(Some(2), also_foobar.strong_count());
/// ```
///
/// ### Static ArcStr
/// ```
/// # use arcstr::ArcStr;
/// let baz = arcstr::literal!("baz");
/// assert_eq!(None, ArcStr::strong_count(&baz));
/// assert_eq!(None, baz.strong_count());
/// // Similarly:
/// assert_eq!(None, ArcStr::strong_count(&ArcStr::default()));
/// assert_eq!(None, ArcStr::default().string_count());

Check failure on line 509 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - msrv

no method named `string_count` found for struct `ArcStr` in the current scope
/// ```

Check failure on line 510 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - linux

no method named `string_count` found for struct `ArcStr` in the current scope

Check failure on line 510 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - beta

no method named `string_count` found for struct `ArcStr` in the current scope

Check failure on line 510 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - macos

no method named `string_count` found for struct `ArcStr` in the current scope

Check failure on line 510 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - nightly

no method named `string_count` found for struct `ArcStr` in the current scope

Check failure on line 510 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - win64-msvc

no method named `string_count` found for struct `ArcStr` in the current scope

Check failure on line 510 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Miri

no method named `string_count` found for struct `arcstr::ArcStr` in the current scope

Check failure on line 510 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - win32-gnu

no method named `string_count` found for struct `ArcStr` in the current scope

Check failure on line 510 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - win32-msvc

no method named `string_count` found for struct `ArcStr` in the current scope

Check failure on line 510 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - win64-gnu

no method named `string_count` found for struct `ArcStr` in the current scope
#[inline]
pub fn strong_count(this: &Self) -> Option<usize> {
let cf = Self::load_count_flag(this, Ordering::Acquire)?;
pub fn strong_count(&self) -> Option<usize> {
let cf = Self::load_count_flag(self, Ordering::Acquire)?;
if cf.flag_part() {
None
} else {
Expand Down Expand Up @@ -556,13 +556,13 @@
/// # // doctests?). Instead, we test this in tests/arc_str.rs
/// # use arcstr::ArcStr;
/// let s = ArcStr::from("foobar");
/// assert!(!ArcStr::is_static(&s));
/// assert!(ArcStr::as_static(&s).is_none());
/// assert!(!s.is_static());
/// assert!(s.as_static().is_none());
///
/// let leaked: &'static str = s.leak();
/// assert_eq!(leaked, s);
/// assert!(ArcStr::is_static(&s));
/// assert_eq!(ArcStr::as_static(&s), Some("foobar"));
/// assert!(s.is_static());
/// assert_eq!(s.as_static(), Some("foobar"));
/// ```
#[inline]
pub fn leak(&self) -> &'static str {
Expand Down Expand Up @@ -617,33 +617,36 @@
Self::bytes_ptr(this) as *const str
}

/// Returns true if `this` is a "static" ArcStr. For example, if it was
/// created from a call to [`arcstr::literal!`][crate::literal]),
/// returned by `ArcStr::new`, etc.
/// Returns true if `self` is a "static" ArcStr. For example, if it was
/// created from a call to [`arcstr::literal!`][crate::literal]), returned
/// by [`ArcStr::new`], previously leaked with [`ArcStr::leak`], etc.
///
/// Static `ArcStr`s can be converted to `&'static str` for free using
/// [`ArcStr::as_static`], without leaking memory — they're static constants
/// in the program (somewhere).
/// [`ArcStr::as_static`], without leaking memory — they're either static
/// constants in the program, or they're strings which have already been
/// deliberately leaked earlier (via [`ArcStr::leak`]).
///
/// This function is morally equivalent to `self.as_static().is_some()`.
///
/// # Examples
///
/// ```

Check failure on line 633 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - msrv

mismatched closing delimiter: `)`
/// # use arcstr::ArcStr;

Check failure on line 634 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - linux

mismatched closing delimiter: `)`

Check failure on line 634 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - beta

mismatched closing delimiter: `)`

Check failure on line 634 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - macos

mismatched closing delimiter: `)`

Check failure on line 634 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - nightly

mismatched closing delimiter: `)`

Check failure on line 634 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - win64-msvc

mismatched closing delimiter: `)`

Check failure on line 634 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Miri

mismatched closing delimiter: `)`

Check failure on line 634 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - win32-gnu

mismatched closing delimiter: `)`

Check failure on line 634 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - win32-msvc

mismatched closing delimiter: `)`

Check failure on line 634 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - win64-gnu

mismatched closing delimiter: `)`
/// const STATIC: ArcStr = arcstr::literal!("Electricity!");
/// assert!(ArcStr::is_static(&STATIC));
/// assert!(STATIC.is_static());
///
/// let still_static = arcstr::literal!("Shocking!");
/// assert!(ArcStr::is_static(&still_static));
/// assert!(still_static.is_static());
/// assert!(
/// ArcStr::is_static(&still_static.clone()),
/// still_static.is_static().clone()),
/// "Cloned statics are still static"
/// );
///
/// let nonstatic = ArcStr::from("Grounded...");
/// assert!(!ArcStr::is_static(&nonstatic));
/// assert!(!nonstatic.is_static());
/// ```

Check failure on line 647 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - msrv

unexpected closing delimiter: `}`
#[inline]

Check failure on line 648 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - linux

unexpected closing delimiter: `}`

Check failure on line 648 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - beta

unexpected closing delimiter: `}`

Check failure on line 648 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - macos

unexpected closing delimiter: `}`

Check failure on line 648 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - nightly

unexpected closing delimiter: `}`

Check failure on line 648 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - win64-msvc

unexpected closing delimiter: `}`

Check failure on line 648 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Miri

unexpected closing delimiter: `}`

Check failure on line 648 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - win32-gnu

unexpected closing delimiter: `}`

Check failure on line 648 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - win32-msvc

unexpected closing delimiter: `}`

Check failure on line 648 in src/arc_str.rs

View workflow job for this annotation

GitHub Actions / Test Rust - win64-gnu

unexpected closing delimiter: `}`
pub fn is_static(this: &Self) -> bool {
pub fn is_static(&self) -> bool {
// We align this to 16 bytes and keep the `is_static` flags in the same
// place. In theory this means that if `cfg(target_feature = "avx")`
// (where aligned 16byte loads are atomic), the compiler *could*
Expand All @@ -661,8 +664,8 @@
// since Rust's semantics don't allow me to make that change
// optimization on my own (that load isn't considered atomic, for
// example).
this.get_inner_len_flag().flag_part()
|| unsafe { Self::load_count_flag_raw(this, Ordering::Relaxed).flag_part() }
self.get_inner_len_flag().flag_part()
|| unsafe { Self::load_count_flag_raw(self, Ordering::Relaxed).flag_part() }
}

/// This is true for any `ArcStr` that has been static from the time when it
Expand All @@ -672,13 +675,10 @@
this.get_inner_len_flag().flag_part()
}

/// Returns true if `this` is a "static"/`"literal"` ArcStr. For example, if
/// it was created from a call to [`literal!`][crate::literal]), returned by
/// `ArcStr::new`, etc.
///
/// Static `ArcStr`s can be converted to `&'static str` for free using
/// [`ArcStr::as_static`], without leaking memory — they're static constants
/// in the program (somewhere).
/// Returns `Some` of the string data as a `&'static str` if `self` is a
/// "static" ArcStr. For example, if it was created from a call to
/// [`literal!`][crate::literal]), returned by [`ArcStr::new`], previously
/// leaked with [`ArcStr::leak`], etc.
///
/// # Examples
///
Expand All @@ -698,10 +698,10 @@
/// assert_eq!(ArcStr::as_static(&nonstatic), None);
/// ```
#[inline]
pub fn as_static(this: &Self) -> Option<&'static str> {
if Self::is_static(this) {
pub fn as_static(&self) -> Option<&'static str> {
if Self::is_static(self) {
// We know static strings live forever, so they can have a static lifetime.
Some(unsafe { &*(this.as_str() as *const str) })
Some(unsafe { &*(self.as_str() as *const str) })
} else {
None
}
Expand Down
Loading