eh_tcp_echo.dhover×202all
#!/usr/bin/env dub
/+ dub.sdl:
    name "eh_tcp_echo"
    dependency "sparkles:event-horizon" path="../../../../.."
    buildType "checked" {
        buildOptions "optimize" "inline" "debugInfo"
    }
    platforms "linux"
+/
import 
(package) core
core
.
(module) core.lifetime
lifetime
:
(alias template) eh_tcp_echo.move = core.lifetime.move(T)(ref T source, ref T target)

Moves source into target, via a destructive copy when necessary.

If T is a struct with a destructor or postblit defined, source is reset to its .init value after it is moved into target, otherwise it is left unchanged.

Preconditions

If source has internal pointers that point to itself and doesn't define opPostMove, it cannot be moved, and will trigger an assertion failure.

@paramsource Data to copy.@paramtarget Where to copy into. The destructor, if any, is invoked before the copy is performed.
move
;
import
(package) std
std
.
(module) std.stdio
Category Symbols
File handles _popen File isFileHandle openNetwork stderr stdin stdout
Reading chunks lines readf readfln readln
Writing toFile write writef writefln writeln
Misc KeepTerminator LockType StdioException

Standard I/O functions that extend core.stdc.stdio. core.stdc.stdio is publically imported when importing std.stdio.

There are three layers of I/O:

  1. The lowest layer is the operating system layer. The two main schemes are Windows and Posix.

  2. C's stdio.h which unifies the two operating system schemes.

  3. std.stdio, this module, unifies the various stdio.h implementations into a high level package for D programs.

Source

std/stdio.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Alex Rønne Petersen
stdio
:
(alias template) eh_tcp_echo.writeln = std.stdio.writeln(T...)(T args)

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
;
import
(package) sparkles
sparkles
.
(package) sparkles.base
base
.
(module) sparkles.base.buffer

A @nogc container with Small Buffer Optimization (SBO).

Provides an append-only buffer that stores small amounts of data inline (avoiding heap allocation) and automatically switches to heap storage when capacity is exceeded.

Primary use case: appending elements in a temporary scope where GC allocation is not desired.

buffer
:
(alias template) eh_tcp_echo.UniqueBuffer = sparkles.base.buffer.UniqueBuffer(T, ulong N = max(size_t(1), (T[]).sizeof / T.sizeof))

Small-buffer optimization with a sole owner: inline while the elements fit, heap when they do not, and copying is disabled.

Disabling copies is what removes the reference count from the grow path — there is no second owner to consult. Hand a finished one to the shared world with toShared, which consumes it and transfers any heap block without reallocating.

UniqueBuffer
;
import
(package) sparkles
sparkles
.
(module) sparkles.event_horizon

sparkles:event-horizon — the completion-first event loop with a native algebraic-effect layer. This package module re-exports the public surface (SPEC §16); import sparkles.event_horizon`` for the whole API, or a specific module for a narrower dependency.

event_horizon
;
void
void D main()
main
()
{
(struct) sparkles.event_horizon.group.LoopGroup

A running loop group. Non-copyable; owns its worker scheduler(s).

LoopGroup
(local variable) sparkles.event_horizon.group.LoopGroup group
group
;
if (
(struct) sparkles.event_horizon.group.LoopGroup

A running loop group. Non-copyable; owns its worker scheduler(s).

LoopGroup
.
expected.Expected!(void, IoError, NoGcHook) sparkles.event_horizon.group.LoopGroup.start(out sparkles.event_horizon.group.LoopGroup group, in sparkles.event_horizon.group.LoopGroupConfig cfg = LoopGroupConfig(Topology.single, 0u, 256u, Flag.yes, Flag.yes, 256u, Flag.no))

Probes the kernel and starts the group. io_uring probe failure is a hard error (SPEC §3.4 — no epoll fallback).

start
(
(local variable) sparkles.event_horizon.group.LoopGroup group
group
).
bool expected.Expected!(void, sparkles.base.io.errors.IoError, sparkles.base.text.errors.NoGcHook).hasError!()() const pure nothrow @nogc @property @safe

Checks if Expected has error

hasError
)
assert(false, "no completion backend"); scope (exit)
(local variable) sparkles.event_horizon.group.LoopGroup group
group
.
void sparkles.event_horizon.group.LoopGroup.shutdown(core.time.Duration grace = dur(5L)) nothrow @safe

Tears down the group's workers.

shutdown
();
auto
(local variable) _error_ run
run
=
(local variable) sparkles.event_horizon.group.LoopGroup group
group
.
group.run
run
((ref
(alias) sparkles.event_horizon.group.RootScope = sparkles.event_horizon.scope_.Scope!(Sched, IoError)

The blessed live scope instantiation handed to the root fiber (SPEC §7.2, §11): a Scope over the ring-backed Sched executor with the IoError channel.

RootScope
(parameter) sparkles.event_horizon.scope_.Scope!(Sched, IoError) sc
sc
, ref
(alias) sparkles.event_horizon.live.Env = sparkles.event_horizon.capability.Ctx!(RingClock, RingVfs, RingNet, RingProc)

The default live capability row handed to the root fiber (SPEC §11). fs is on every backend: RingVfs needs no ring file operations (SPEC §10.5).

Env
(parameter) sparkles.event_horizon.capability.Ctx!(RingClock, RingVfs, RingNet, RingProc) env
env
) {
auto
(local variable) expected.Expected!(Listener, IoError, NoGcHook) listening
listening
=
(parameter) sparkles.event_horizon.capability.Ctx!(RingClock, RingVfs, RingNet, RingProc) env
env
.net.
expected.Expected!(Listener, IoError, NoGcHook) sparkles.event_horizon.live.RingNet.listen(sparkles.event_horizon.net.SockAddr at, int backlog = 128) nothrow @trusted

Creates a TCP socket, binds it to at, and listens.

listen
(
sparkles.event_horizon.net.SockAddr sparkles.event_horizon.net.ipv4(string dottedQuad, ushort port) pure nothrow @nogc @safe

Builds an IPv4 SockAddr (AF_INET, network byte order).

ipv4
("127.0.0.1", 0));
assert(
(local variable) expected.Expected!(Listener, IoError, NoGcHook) listening
listening
.
bool expected.Expected!(sparkles.event_horizon.io.Listener, sparkles.base.io.errors.IoError, sparkles.base.text.errors.NoGcHook).hasValue!()() const pure nothrow @nogc @property @safe

Checks if Expected has value

hasValue
);
auto
(local variable) sparkles.event_horizon.io.Listener listener
listener
=
sparkles.event_horizon.io.Listener core.lifetime.move!(sparkles.event_horizon.io.Listener)(ref return scope sparkles.event_horizon.io.Listener source) pure nothrow @nogc @safe

Examples

Non-copyable structs can still be moved:

struct S
{
    int a = 1;
    @disable this(this);
    ~this() pure nothrow @safe @nogc {}
}
S s1;
s1.a = 2;
S s2 = move(s1);
assert(s1.a == 1);
assert(s2.a == 2);
move
(
(local variable) expected.Expected!(Listener, IoError, NoGcHook) listening
listening
.
inout(sparkles.event_horizon.io.Listener) expected.Expected!(sparkles.event_horizon.io.Listener, sparkles.base.io.errors.IoError, sparkles.base.text.errors.NoGcHook).value!()() inout pure nothrow @nogc @property ref @safe

Returns the expected value if there is one.

With default Abort hook, it asserts when there is no value. It calls hook's onAccessEmptyValue otherwise.

It returns T.init when hook doesn't provide onAccessEmptyValue.

value
);
scope (exit)
(local variable) sparkles.event_horizon.io.Listener listener
listener
.
void sparkles.event_horizon.io.Listener.close() nothrow @nogc @trusted
close
();
const
(local variable) const(ushort) port
port
=
ushort eh_tcp_echo.boundPort(ref sparkles.event_horizon.io.Listener l) @trusted
boundPort
(
(local variable) sparkles.event_horizon.io.Listener listener
listener
);
// The server is a joined child, handling one five-byte exchange. assert(
(parameter) sparkles.event_horizon.scope_.Scope!(Sched, IoError) sc
sc
.
bool sparkles.event_horizon.scope_.Scope!(sparkles.event_horizon.sched.Sched, sparkles.base.io.errors.IoError).spawn(void delegate() body_) nothrow @safe

Spawns a child bound to this scope; its defect (escaped Throwable) feeds the failure policy as Cause.die. body_ is an ordinary delegate (see Sched.spawn`` — a capturing closure's frame must outlive this call). Returns whether a fiber slot was accepted; a rejection still records the scope's ordinary ENOBUFS failure.

spawn
({
auto
(local variable) expected.Expected!(Stream, IoError, NoGcHook) conn
conn
=
(local variable) sparkles.event_horizon.io.Listener listener
listener
.
expected.Expected!(Stream, IoError, NoGcHook) sparkles.event_horizon.io.accept(ref sparkles.event_horizon.io.Listener l)

Parks until a connection arrives; the result is the connected stream.

accept
; // parks until a client arrives
assert(
(local variable) expected.Expected!(Stream, IoError, NoGcHook) conn
conn
.
bool expected.Expected!(sparkles.event_horizon.io.Stream, sparkles.base.io.errors.IoError, sparkles.base.text.errors.NoGcHook).hasValue!()() const pure nothrow @nogc @property @safe

Checks if Expected has value

hasValue
);
void eh_tcp_echo.echo(sparkles.event_horizon.io.Stream conn)
echo
(
(local variable) expected.Expected!(Stream, IoError, NoGcHook) conn
conn
.
inout(sparkles.event_horizon.io.Stream) expected.Expected!(sparkles.event_horizon.io.Stream, sparkles.base.io.errors.IoError, sparkles.base.text.errors.NoGcHook).value!()() inout pure nothrow @nogc @property ref @safe

Returns the expected value if there is one.

With default Abort hook, it asserts when there is no value. It calls hook's onAccessEmptyValue otherwise.

It returns T.init when hook doesn't provide onAccessEmptyValue.

value
);
})); // The client, in the same loop. auto
(local variable) expected.Expected!(Stream, IoError, NoGcHook) connected
connected
=
(parameter) sparkles.event_horizon.capability.Ctx!(RingClock, RingVfs, RingNet, RingProc) env
env
.net.
expected.Expected!(Stream, IoError, NoGcHook) sparkles.event_horizon.live.RingNet.connect(sparkles.event_horizon.net.SockAddr to)

Creates a TCP socket and connects it to to (parks on the ring).

connect
(
sparkles.event_horizon.net.SockAddr sparkles.event_horizon.net.ipv4(string dottedQuad, ushort port) pure nothrow @nogc @safe

Builds an IPv4 SockAddr (AF_INET, network byte order).

ipv4
("127.0.0.1",
(local variable) const(ushort) port
port
));
assert(
(local variable) expected.Expected!(Stream, IoError, NoGcHook) connected
connected
.
bool expected.Expected!(sparkles.event_horizon.io.Stream, sparkles.base.io.errors.IoError, sparkles.base.text.errors.NoGcHook).hasValue!()() const pure nothrow @nogc @property @safe

Checks if Expected has value

hasValue
);
auto
(local variable) sparkles.event_horizon.io.Stream client
client
=
sparkles.event_horizon.io.Stream core.lifetime.move!(sparkles.event_horizon.io.Stream)(ref return scope sparkles.event_horizon.io.Stream source) pure nothrow @nogc @safe

Examples

Non-copyable structs can still be moved:

struct S
{
    int a = 1;
    @disable this(this);
    ~this() pure nothrow @safe @nogc {}
}
S s1;
s1.a = 2;
S s2 = move(s1);
assert(s1.a == 1);
assert(s2.a == 2);
move
(
(local variable) expected.Expected!(Stream, IoError, NoGcHook) connected
connected
.
inout(sparkles.event_horizon.io.Stream) expected.Expected!(sparkles.event_horizon.io.Stream, sparkles.base.io.errors.IoError, sparkles.base.text.errors.NoGcHook).value!()() inout pure nothrow @nogc @property ref @safe

Returns the expected value if there is one.

With default Abort hook, it asserts when there is no value. It calls hook's onAccessEmptyValue otherwise.

It returns T.init when hook doesn't provide onAccessEmptyValue.

value
);
scope (exit)
(local variable) sparkles.event_horizon.io.Stream client
client
.
void sparkles.event_horizon.io.Stream.close() nothrow @nogc @trusted

Explicit close (handles are copyable views; exactly one owner should close). Winsock sockets close via closesocket.

close
();
void eh_tcp_echo.sendText(ref sparkles.event_horizon.io.Stream conn, scope const(char)[] bytes)
sendText
(
(local variable) sparkles.event_horizon.io.Stream client
client
, "hello");
(alias) sparkles.base.buffer.UniqueBuffer!(ubyte, 64LU) = sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)

Small-buffer optimization with a sole owner: inline while the elements fit, heap when they do not, and copying is disabled.

Disabling copies is what removes the reference count from the grow path — there is no second owner to consult. Hand a finished one to the shared world with toShared, which consumes it and transfers any heap block without reallocating.

UniqueBuffer
!(ubyte, 64)
(local variable) sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) back
back
;
(alias) object.string = string
string
(local variable) string response
response
;
while (
(local variable) string response
response
.
(field) ulong string.length
length
< 5)
{
(local variable) sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) back
back
.
void sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u).length(ulong newLength) pure nothrow @nogc @property @trusted

Sets the element count. Growing appends T.init-filled elements (one storage growth); shrinking drops elements from the back and keeps the storage, whichever it is (BUF13) — a buffer that has spilled to the heap stays there until clear or the destructor, so a shrink costs neither a copy back into the inline slots nor a free.

Output range interface: appends a single element.

length
= 64;
auto
(local variable) sparkles.event_horizon.io.BufResult!(Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)) got
got
=
(local variable) sparkles.event_horizon.io.Stream client
client
.
sparkles.event_horizon.io.BufResult!(Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)) sparkles.event_horizon.io.recv!(sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u))(ref sparkles.event_horizon.io.Stream s, sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) buf) nothrow @safe

Receives into the buffer's view.

recv
(
sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) core.lifetime.move!(sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u))(ref return scope sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) source) pure nothrow @nogc @safe

Examples

Non-copyable structs can still be moved:

struct S
{
    int a = 1;
    @disable this(this);
    ~this() pure nothrow @safe @nogc {}
}
S s1;
s1.a = 2;
S s2 = move(s1);
assert(s1.a == 1);
assert(s2.a == 2);
move
(
(local variable) sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) back
back
));
(local variable) sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) back
back
=
sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u).opAssign(scope sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) rhs) pure nothrow @nogc ref return scope @trusted

Move assignment from an rvalue: release current storage, then steal rhs's storage (no refcount change — ownership transfers). rhs is neutralized so its destructor frees nothing.

move
(
sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u).opAssign(scope sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) rhs) pure nothrow @nogc ref return scope @trusted

Move assignment from an rvalue: release current storage, then steal rhs's storage (no refcount change — ownership transfers). rhs is neutralized so its destructor frees nothing.

got
.
(field) sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) sparkles.event_horizon.io.BufResult!(sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)).buf

ownership returned — the kernel is done with it

buf
);
assert(
(local variable) sparkles.event_horizon.io.BufResult!(Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)) got
got
.
(field) expected.Expected!(uint, IoError, NoGcHook) sparkles.event_horizon.io.BufResult!(sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)).res

bytes transferred, or the error

res
.
bool expected.Expected!(uint, sparkles.base.io.errors.IoError, sparkles.base.text.errors.NoGcHook).hasValue!()() const pure nothrow @nogc @property @safe

Checks if Expected has value

hasValue
&&
(local variable) sparkles.event_horizon.io.BufResult!(Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)) got
got
.
(field) expected.Expected!(uint, IoError, NoGcHook) sparkles.event_horizon.io.BufResult!(sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)).res

bytes transferred, or the error

res
.
inout(uint) expected.Expected!(uint, sparkles.base.io.errors.IoError, sparkles.base.text.errors.NoGcHook).value!()() inout pure nothrow @nogc @property ref @safe

Returns the expected value if there is one.

With default Abort hook, it asserts when there is no value. It calls hook's onAccessEmptyValue otherwise.

It returns T.init when hook doesn't provide onAccessEmptyValue.

value
> 0);
(local variable) string response
response
~= cast(const(char)[])
(local variable) sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) back
back
[][0 ..
(local variable) sparkles.event_horizon.io.BufResult!(Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)) got
got
.
(field) expected.Expected!(uint, IoError, NoGcHook) sparkles.event_horizon.io.BufResult!(sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)).res

bytes transferred, or the error

res
.
inout(uint) expected.Expected!(uint, sparkles.base.io.errors.IoError, sparkles.base.text.errors.NoGcHook).value!()() inout pure nothrow @nogc @property ref @safe

Returns the expected value if there is one.

With default Abort hook, it asserts when there is no value. It calls hook's onAccessEmptyValue otherwise.

It returns T.init when hook doesn't provide onAccessEmptyValue.

value
];
} assert(
(local variable) string response
response
== "hello");
void std.stdio.writeln!(string, string)(string __param_0, string __param_1) @safe

Equivalent to write(args, '\n'). Calling writeln without arguments is valid and just prints a newline to the standard output.

Example

Reads stdin and writes it to stdout with an argument counter.

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("echoed: ",
(local variable) string response
response
);
return 0; }); assert(run.
(field) _error_ run.hasValue
hasValue
);
} void
void eh_tcp_echo.echo(sparkles.event_horizon.io.Stream conn)
echo
(
(struct) sparkles.event_horizon.io.Stream

A connected byte-stream socket.

Stream
(parameter) sparkles.event_horizon.io.Stream conn
conn
)
{ scope (exit)
(parameter) sparkles.event_horizon.io.Stream conn
conn
.
void sparkles.event_horizon.io.Stream.close() nothrow @nogc @trusted

Explicit close (handles are copyable views; exactly one owner should close). Winsock sockets close via closesocket.

close
();
(alias) sparkles.base.buffer.UniqueBuffer!(ubyte, 4096LU) = sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u)

Small-buffer optimization with a sole owner: inline while the elements fit, heap when they do not, and copying is disabled.

Disabling copies is what removes the reference count from the grow path — there is no second owner to consult. Hand a finished one to the shared world with toShared, which consumes it and transfers any heap block without reallocating.

UniqueBuffer
!(ubyte, 4096)
(local variable) sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u) buf
buf
;
(alias) object.size_t = ulong
size_t
(local variable) ulong received
received
;
while (
(local variable) ulong received
received
< 5)
{
(local variable) sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u) buf
buf
.
void sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u).length(ulong newLength) pure nothrow @nogc @property @trusted

Sets the element count. Growing appends T.init-filled elements (one storage growth); shrinking drops elements from the back and keeps the storage, whichever it is (BUF13) — a buffer that has spilled to the heap stays there until clear or the destructor, so a shrink costs neither a copy back into the inline slots nor a free.

Output range interface: appends a single element.

length
= 4096;
auto
(local variable) sparkles.event_horizon.io.BufResult!(Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u)) r
r
=
(parameter) sparkles.event_horizon.io.Stream conn
conn
.
sparkles.event_horizon.io.BufResult!(Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u)) sparkles.event_horizon.io.recv!(sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u))(ref sparkles.event_horizon.io.Stream s, sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u) buf) nothrow @safe

Receives into the buffer's view.

recv
(
sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u) core.lifetime.move!(sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u))(ref return scope sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u) source) pure nothrow @nogc @safe

Examples

Non-copyable structs can still be moved:

struct S
{
    int a = 1;
    @disable this(this);
    ~this() pure nothrow @safe @nogc {}
}
S s1;
s1.a = 2;
S s2 = move(s1);
assert(s1.a == 1);
assert(s2.a == 2);
move
(
(local variable) sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u) buf
buf
));
(local variable) sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u) buf
buf
=
sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u) sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u).opAssign(scope sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u) rhs) pure nothrow @nogc ref return scope @trusted

Move assignment from an rvalue: release current storage, then steal rhs's storage (no refcount change — ownership transfers). rhs is neutralized so its destructor frees nothing.

move
(
sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u) sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u).opAssign(scope sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u) rhs) pure nothrow @nogc ref return scope @trusted

Move assignment from an rvalue: release current storage, then steal rhs's storage (no refcount change — ownership transfers). rhs is neutralized so its destructor frees nothing.

r
.
(field) sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u) sparkles.event_horizon.io.BufResult!(sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u)).buf

ownership returned — the kernel is done with it

buf
);
assert(
(local variable) sparkles.event_horizon.io.BufResult!(Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u)) r
r
.
(field) expected.Expected!(uint, IoError, NoGcHook) sparkles.event_horizon.io.BufResult!(sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u)).res

bytes transferred, or the error

res
.
bool expected.Expected!(uint, sparkles.base.io.errors.IoError, sparkles.base.text.errors.NoGcHook).hasValue!()() const pure nothrow @nogc @property @safe

Checks if Expected has value

hasValue
&&
(local variable) sparkles.event_horizon.io.BufResult!(Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u)) r
r
.
(field) expected.Expected!(uint, IoError, NoGcHook) sparkles.event_horizon.io.BufResult!(sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u)).res

bytes transferred, or the error

res
.
inout(uint) expected.Expected!(uint, sparkles.base.io.errors.IoError, sparkles.base.text.errors.NoGcHook).value!()() inout pure nothrow @nogc @property ref @safe

Returns the expected value if there is one.

With default Abort hook, it asserts when there is no value. It calls hook's onAccessEmptyValue otherwise.

It returns T.init when hook doesn't provide onAccessEmptyValue.

value
> 0);
(local variable) ulong received
received
+=
(local variable) sparkles.event_horizon.io.BufResult!(Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u)) r
r
.
(field) expected.Expected!(uint, IoError, NoGcHook) sparkles.event_horizon.io.BufResult!(sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u)).res

bytes transferred, or the error

res
.
inout(uint) expected.Expected!(uint, sparkles.base.io.errors.IoError, sparkles.base.text.errors.NoGcHook).value!()() inout pure nothrow @nogc @property ref @safe

Returns the expected value if there is one.

With default Abort hook, it asserts when there is no value. It calls hook's onAccessEmptyValue otherwise.

It returns T.init when hook doesn't provide onAccessEmptyValue.

value
;
void eh_tcp_echo.sendText(ref sparkles.event_horizon.io.Stream conn, scope const(char)[] bytes)
sendText
(
(parameter) sparkles.event_horizon.io.Stream conn
conn
, cast(const(char)[])
(local variable) sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u) buf
buf
[][0 ..
(local variable) sparkles.event_horizon.io.BufResult!(Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u)) r
r
.
(field) expected.Expected!(uint, IoError, NoGcHook) sparkles.event_horizon.io.BufResult!(sparkles.base.buffer.Buffer!(ubyte, 4096LU, cast(Storage)cast(ubyte)7u)).res

bytes transferred, or the error

res
.
inout(uint) expected.Expected!(uint, sparkles.base.io.errors.IoError, sparkles.base.text.errors.NoGcHook).value!()() inout pure nothrow @nogc @property ref @safe

Returns the expected value if there is one.

With default Abort hook, it asserts when there is no value. It calls hook's onAccessEmptyValue otherwise.

It returns T.init when hook doesn't provide onAccessEmptyValue.

value
]);
} } // Copies the unsent suffix into an owned buffer on each attempt. This is a // small correctness example, not a claim of zero-copy networking. void
void eh_tcp_echo.sendText(ref sparkles.event_horizon.io.Stream conn, scope const(char)[] bytes)
sendText
(ref
(struct) sparkles.event_horizon.io.Stream

A connected byte-stream socket.

Stream
(parameter) sparkles.event_horizon.io.Stream conn
conn
, scope const(char)[]
(parameter) const(char)[] bytes
bytes
)
{
(alias) object.size_t = ulong
size_t
(local variable) ulong offset
offset
;
while (
(local variable) ulong offset
offset
<
(parameter) const(char)[] bytes
bytes
.
(field) ulong const(char)[].length
length
)
{
(alias) sparkles.base.buffer.UniqueBuffer!(ubyte, 64LU) = sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)

Small-buffer optimization with a sole owner: inline while the elements fit, heap when they do not, and copying is disabled.

Disabling copies is what removes the reference count from the grow path — there is no second owner to consult. Hand a finished one to the shared world with toShared, which consumes it and transfers any heap block without reallocating.

UniqueBuffer
!(ubyte, 64)
(local variable) sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) buf
buf
;
(local variable) sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) buf
buf
~= cast(const(ubyte)[])
(parameter) const(char)[] bytes
bytes
[
(local variable) ulong offset
offset
.. $];
auto
(local variable) sparkles.event_horizon.io.BufResult!(Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)) sent
sent
=
(parameter) sparkles.event_horizon.io.Stream conn
conn
.
sparkles.event_horizon.io.BufResult!(Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)) sparkles.event_horizon.io.send!(sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u))(ref sparkles.event_horizon.io.Stream s, sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) buf) nothrow @safe

Sends the buffer's view.

send
(
sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) core.lifetime.move!(sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u))(ref return scope sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) source) pure nothrow @nogc @safe

Examples

Non-copyable structs can still be moved:

struct S
{
    int a = 1;
    @disable this(this);
    ~this() pure nothrow @safe @nogc {}
}
S s1;
s1.a = 2;
S s2 = move(s1);
assert(s1.a == 1);
assert(s2.a == 2);
move
(
(local variable) sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u) buf
buf
));
assert(
(local variable) sparkles.event_horizon.io.BufResult!(Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)) sent
sent
.
(field) expected.Expected!(uint, IoError, NoGcHook) sparkles.event_horizon.io.BufResult!(sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)).res

bytes transferred, or the error

res
.
bool expected.Expected!(uint, sparkles.base.io.errors.IoError, sparkles.base.text.errors.NoGcHook).hasValue!()() const pure nothrow @nogc @property @safe

Checks if Expected has value

hasValue
&&
(local variable) sparkles.event_horizon.io.BufResult!(Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)) sent
sent
.
(field) expected.Expected!(uint, IoError, NoGcHook) sparkles.event_horizon.io.BufResult!(sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)).res

bytes transferred, or the error

res
.
inout(uint) expected.Expected!(uint, sparkles.base.io.errors.IoError, sparkles.base.text.errors.NoGcHook).value!()() inout pure nothrow @nogc @property ref @safe

Returns the expected value if there is one.

With default Abort hook, it asserts when there is no value. It calls hook's onAccessEmptyValue otherwise.

It returns T.init when hook doesn't provide onAccessEmptyValue.

value
> 0);
(local variable) ulong offset
offset
+=
(local variable) sparkles.event_horizon.io.BufResult!(Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)) sent
sent
.
(field) expected.Expected!(uint, IoError, NoGcHook) sparkles.event_horizon.io.BufResult!(sparkles.base.buffer.Buffer!(ubyte, 64LU, cast(Storage)cast(ubyte)7u)).res

bytes transferred, or the error

res
.
inout(uint) expected.Expected!(uint, sparkles.base.io.errors.IoError, sparkles.base.text.errors.NoGcHook).value!()() inout pure nothrow @nogc @property ref @safe

Returns the expected value if there is one.

With default Abort hook, it asserts when there is no value. It calls hook's onAccessEmptyValue otherwise.

It returns T.init when hook doesn't provide onAccessEmptyValue.

value
;
} } ushort
ushort eh_tcp_echo.boundPort(ref sparkles.event_horizon.io.Listener l) @trusted
boundPort
(ref
(struct) sparkles.event_horizon.io.Listener

A listening socket; accept yields Streams.

Listener
(parameter) sparkles.event_horizon.io.Listener l
l
) @trusted
{ import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(package) core.sys.posix.arpa
arpa
.
(module) core.sys.posix.arpa.inet

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly@standardsThe Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
inet
:
(alias) ntohs = ushort core.sys.posix.arpa.inet.ntohs(ushort) pure nothrow @nogc @trusted
ntohs
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(package) core.sys.posix.netinet
netinet
.
(module) core.sys.posix.netinet.in_

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly@standardsThe Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
in_
:
(struct) core.sys.posix.netinet.in_.sockaddr_in
sockaddr_in
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(package) core.sys.posix.sys
sys
.
(module) core.sys.posix.sys.socket

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly, Alex Rønne Petersen@standardsThe Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
socket
:
(alias) getsockname = int core.sys.posix.sys.socket.getsockname(int, scope core.sys.posix.sys.socket.sockaddr*, scope uint*) nothrow @nogc
getsockname
,
(struct) core.sys.posix.sys.socket.sockaddr
sockaddr
, socklen_t;
(struct) core.sys.posix.netinet.in_.sockaddr_in
sockaddr_in
(local variable) core.sys.posix.netinet.in_.sockaddr_in a
a
;
socklen_t
(local variable) uint len
len
=
(local variable) core.sys.posix.netinet.in_.sockaddr_in a
a
.
(constant) ulong core.sys.posix.netinet.in_.sockaddr_in.sizeof = 16LU
sizeof
;
assert(
int core.sys.posix.sys.socket.getsockname(int, scope core.sys.posix.sys.socket.sockaddr*, scope uint*) nothrow @nogc
getsockname
(
(parameter) sparkles.event_horizon.io.Listener l
l
.
(field) int sparkles.event_horizon.io.Listener.fd
fd
, cast(
(struct) core.sys.posix.sys.socket.sockaddr
sockaddr
*) &
(local variable) core.sys.posix.netinet.in_.sockaddr_in a
a
, &
(local variable) uint len
len
) == 0);
return
ushort core.sys.posix.arpa.inet.ntohs(ushort) pure nothrow @nogc @trusted
ntohs
(
(local variable) core.sys.posix.netinet.in_.sockaddr_in a
a
.
(field) ushort core.sys.posix.netinet.in_.sockaddr_in.sin_port
sin_port
);
}