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;
|
mod storage;
|
||||||
|
|
||||||
pub use roc_box::RocBox;
|
pub use roc_box::RocBox;
|
||||||
pub use roc_list::{RocList, SendSafeRocList};
|
pub use roc_list::{RocList, SendSafeRocList, ReadOnlyRocList};
|
||||||
pub use roc_str::{InteriorNulError, RocStr, SendSafeRocStr};
|
pub use roc_str::{InteriorNulError, RocStr, SendSafeRocStr, ReadOnlyRocStr};
|
||||||
pub use storage::Storage;
|
pub use storage::Storage;
|
||||||
|
|
||||||
// A list of C functions that are being imported
|
// 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.
|
/// 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
|
/// As such, only values that should have a static lifetime for the entire application run
|
||||||
/// should be considered for marking read-only.
|
/// 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() {
|
if let Some((_, storage)) = self.elements_and_storage() {
|
||||||
storage.set(Storage::Readonly);
|
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")]
|
#[cfg(feature = "serde")]
|
||||||
struct RocListVisitor<T>
|
struct RocListVisitor<T>
|
||||||
where
|
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)]
|
#[repr(C)]
|
||||||
struct BigString {
|
struct BigString {
|
||||||
elements: NonNull<u8>,
|
elements: NonNull<u8>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue