Under heavy development. This site describes the intended 1.0 language. Current features and performance vary. Development status
Sn50SnThe SnAPI programming language
0.2.0 Preview 1 · Frozen documentation

Shared

Retains shared readonly observation of one allocator-owned payload.

Sn is under heavy development. Reference extracted from this release’s bundled standard library. Public API examples are not an exhaustive compatibility test. Read the matching release guide for tested workflows and limitations. Read the status →

Module std.memory

import std.memory;

Public declaration contracts and authored examples. A page can document several related symbols. Implementation bodies are excluded.

Shared

pub final class Shared<T, A = DefaultAllocator>
    where T: Movable where A: Allocator, Defaultable, Movable

Retains shared readonly observation of one allocator-owned payload.

Copies retain the same payload without copying T or allocating; explicit moves transfer a handle and leave the source empty. Separate published handles may retain/release concurrently. Mutating the same handle requires synchronization; atomic lifetime retention does not make arbitrary payload operations safe. Value borrows readonly without retaining: keep a live unchanged strong owner for the entire borrow. Creation may allocate; copy/move/downgrade do not. Final strong cleanup may execute the payload destructor on the releasing thread. T: Movable owned payload, never copied by handle operations. A: Movable Defaultable allocator owning payload and control storage.

Example

module example.shared_ownership;
from std.memory import Shared, Weak;
fn Main() -> i32 {
    var Owner = switch Shared<i32>.TryCreate(42) {
        case .Ok { Value = Value } => break Value;
        case .Err { Error = _ } => return 1;
    };
    var Observer = Owner.Downgrade();
    // Weak copies retain only control storage; moves leave an empty source.
    var WeakCopy = Observer;
    if Observer.IsEmpty || WeakCopy.IsEmpty { return 6; }
    var WeakMoved = move(WeakCopy);
    if !WeakCopy.IsEmpty || WeakMoved.IsEmpty { return 7; }
    var WeakAssigned = Weak<i32>();
    if !WeakAssigned.IsEmpty { return 8; }
    WeakAssigned = Observer;
    if WeakAssigned.IsEmpty || Observer.IsEmpty { return 9; }
    var WeakTransferred = Weak<i32>();
    WeakTransferred = move(WeakAssigned);
    if !WeakAssigned.IsEmpty || WeakTransferred.IsEmpty { return 10; }
    var Copy = Owner;
    Owner.Clear();
    if Copy.Value().Unwrap() != 42 { return 2; }
    {
        var Upgraded = Observer.Upgrade();
        if (Upgraded is .None) { return 3; }
        var Retained = move(Upgraded).Unwrap();
        if Retained.Value().Unwrap() != 42 { return 4; }
    }
    Copy.Clear();
    if Observer.Upgrade() is .Some { Value = _ } { return 5; }
    // Extra weak leases never keep the payload alive or permit resurrection.
    if WeakMoved.Upgrade() is .Some { Value = _ } { return 11; }
    if WeakTransferred.Upgrade() is .Some { Value = _ } { return 12; }
    WeakMoved.Clear(); WeakTransferred.Clear();
    if !WeakMoved.IsEmpty || !WeakTransferred.IsEmpty { return 13; }
    Observer.Clear();
    if !Observer.IsEmpty { return 14; }
    return 0;
}

Shared.init

pub init()

Creates an empty handle without allocation.

Shared.init

pub init(Source: readonly Self&)

Retains the source payload without copying it or allocating. Source: Existing strong owner, or empty handle.

Shared.init

pub init(Source: mut Self&&)

Transfers one strong lease without another retain. Source: Writable handle left empty.

Shared.operator

pub fn operator =(Source: readonly Self&) -> void

Retains the source before releasing the replaced strong lease. Source: Existing strong owner; exact self-assignment is unchanged. Return: No value; payload copies and allocation are not introduced.

Shared.operator

pub fn operator =(Source: mut Self&&) -> void

Releases old ownership and transfers Source. Source: Writable handle left empty; exact self-move is unchanged. Return: No value.

Shared.TryCreate

pub static fn TryCreate(mut Value: T) -> Result<Self, SharedCreationError<T>>

Acquires shared payload/control storage with the default allocator. Value: Owned payload transferred on success, retained by the error on failure. Return: Strong owner or recoverable error retaining the input value.

Shared.TryCreate

pub static fn TryCreate(mut Value: T, mut AllocatorValue: A) -> Result<Self, SharedCreationError<T>>

Acquires shared payload/control storage with a transferred allocator. Value: Owned payload moved only after all raw allocations succeed. AllocatorValue: Allocator transferred on either outcome, cleaned up on failure. Return: Strong owner or error retaining Value; lifecycle traps do not roll back.

Shared.IsEmpty

pub IsEmpty: bool;

Reports whether this handle owns no strong lease. Return: True for empty/moved-from handles.

Shared.Value

pub readonly fn Value() -> readonly T&?

Borrows the payload readonly without copying or retaining it. Return: Readonly reference or none for an empty handle; requires a protecting live owner. Warning: Handle release/replacement/move may end the protecting lifetime.

Shared.Downgrade

pub readonly fn Downgrade() -> Weak<T, A>

Creates a weak observer that retains control storage without retaining the payload. Return: Weak observer or empty Weak when this handle is empty; no allocation.

Shared.Clear

pub fn Clear() -> void

Drops this strong lease, possibly destroying the final payload. Return: No value; this handle is empty before final cleanup begins. Warning: Final destruction runs on this thread and invalidates unprotected payload borrows.

Documentation snapshot: October 24, 2026 About versions ↗
Searching Development · language & standard library