Under heavy development. This site describes the intended 1.0 language. Current features and performance vary. Development status
Sn50SnThe SnAPI programming language
Development · Evolving reference

Shared

Retains shared readonly observation of one allocator-owned payload.

Sn is under heavy development. This reference includes the intended 1.0 design; features may be incomplete in the current compiler. 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