mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00
add readonly roc list and roc str to roc_std
This commit is contained in:
parent
0e162a767d
commit
98cde41439
3 changed files with 105 additions and 3 deletions
|
@ -18,8 +18,8 @@ mod roc_str;
|
|||
mod storage;
|
||||
|
||||
pub use roc_box::RocBox;
|
||||
pub use roc_list::{RocList, SendSafeRocList};
|
||||
pub use roc_str::{InteriorNulError, RocStr, SendSafeRocStr};
|
||||
pub use roc_list::{RocList, SendSafeRocList, ReadOnlyRocList};
|
||||
pub use roc_str::{InteriorNulError, RocStr, SendSafeRocStr, ReadOnlyRocStr};
|
||||
pub use storage::Storage;
|
||||
|
||||
// A list of C functions that are being imported
|
||||
|
|
|
@ -172,7 +172,7 @@ where
|
|||
/// There is no way to tell how many references it has and if it is safe to free.
|
||||
/// As such, only values that should have a static lifetime for the entire application run
|
||||
/// should be considered for marking read-only.
|
||||
pub unsafe fn set_readonly(&self) {
|
||||
pub unsafe fn set_readonly(&mut self) {
|
||||
if let Some((_, storage)) = self.elements_and_storage() {
|
||||
storage.set(Storage::Readonly);
|
||||
}
|
||||
|
@ -916,6 +916,64 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct ReadOnlyRocList<T>(RocList<T>)
|
||||
where
|
||||
T: RocRefcounted;
|
||||
|
||||
unsafe impl<T> Send for ReadOnlyRocList<T> where T: Send + RocRefcounted {}
|
||||
unsafe impl<T> Sync for ReadOnlyRocList<T> where T: Sync + RocRefcounted {}
|
||||
|
||||
impl<T> RocRefcounted for ReadOnlyRocList<T>
|
||||
where
|
||||
T: RocRefcounted,
|
||||
{
|
||||
fn inc(&mut self) {
|
||||
}
|
||||
|
||||
fn dec(&mut self) {
|
||||
}
|
||||
|
||||
fn is_refcounted() -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for ReadOnlyRocList<T>
|
||||
where
|
||||
T: Clone + RocRefcounted,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
ReadOnlyRocList(self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<RocList<T>> for ReadOnlyRocList<T>
|
||||
where
|
||||
T: Clone + RocRefcounted,
|
||||
{
|
||||
fn from(mut l: RocList<T>) -> Self {
|
||||
if l.is_unique() {
|
||||
unsafe {l.set_readonly()};
|
||||
}
|
||||
if l.is_readonly() {
|
||||
ReadOnlyRocList(l)
|
||||
} else {
|
||||
// This is not unique, do a deep copy.
|
||||
ReadOnlyRocList::from(RocList::from_slice(&l))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<ReadOnlyRocList<T>> for RocList<T>
|
||||
where
|
||||
T: RocRefcounted,
|
||||
{
|
||||
fn from(l: ReadOnlyRocList<T>) -> Self {
|
||||
l.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
struct RocListVisitor<T>
|
||||
where
|
||||
|
|
|
@ -824,6 +824,50 @@ impl RocRefcounted for RocStr {
|
|||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct ReadOnlyRocStr(RocStr);
|
||||
|
||||
unsafe impl Send for ReadOnlyRocStr {}
|
||||
unsafe impl Sync for ReadOnlyRocStr {}
|
||||
|
||||
impl RocRefcounted for ReadOnlyRocStr {
|
||||
fn inc(&mut self) {
|
||||
}
|
||||
|
||||
fn dec(&mut self) {
|
||||
}
|
||||
|
||||
fn is_refcounted() -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for ReadOnlyRocStr {
|
||||
fn clone(&self) -> Self {
|
||||
ReadOnlyRocStr(self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RocStr> for ReadOnlyRocStr {
|
||||
fn from(mut s: RocStr) -> Self {
|
||||
if s.is_unique() {
|
||||
unsafe {s.set_readonly()};
|
||||
}
|
||||
if s.is_readonly() {
|
||||
ReadOnlyRocStr(s)
|
||||
} else {
|
||||
// This is not readonly or unique, do a deep copy.
|
||||
ReadOnlyRocStr::from(RocStr::from(s.as_str()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ReadOnlyRocStr> for RocStr {
|
||||
fn from(s: ReadOnlyRocStr) -> Self {
|
||||
s.0
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct BigString {
|
||||
elements: NonNull<u8>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue