bench_json.dhover×1414all
/**
 * Machine-readable `--bench-json` reports: every measured row plus a
 * provenance block as one deterministic JSON document, so benchmark baselines
 * can be committed, diffed, and regenerated (see the wired bench's `results/`
 * snapshots).
 *
 * The emission is an explicit writer, not `std.json`: baselines must be
 * byte-stable (fixed field order, sorted label keys) and floats must not
 * render in D's 17-significant-digit default form (which the repo's
 * `pretty-format-json` pre-commit hook rejects) — `jsonNumber` renders
 * integral values as integers and everything else to 6 significant digits,
 * far above benchmark noise. `nan`/infinities (unavailable counters) become
 * `null`, mirroring the table's em dash.
 */
module 
(package) sparkles
sparkles
.
(package) sparkles.test_runner
test_runner
.
(module) sparkles.test_runner.bench_json

Machine-readable --bench-json reports: every measured row plus a provenance block as one deterministic JSON document, so benchmark baselines can be committed, diffed, and regenerated (see the wired bench's results/ snapshots).

The emission is an explicit writer, not std.json: baselines must be byte-stable (fixed field order, sorted label keys) and floats must not render in D's 17-significant-digit default form (which the repo's pretty-format-json pre-commit hook rejects) — jsonNumber renders integral values as integers and everything else to 6 significant digits, far above benchmark noise. nan/infinities (unavailable counters) become null, mirroring the table's em dash.

bench_json
;
import
(package) sparkles
sparkles
.
(package) sparkles.test_runner
test_runner
.
(module) sparkles.test_runner.bench

Benchmark measurement: auto-scaling iteration counts, basic robust statistics, and an optimizer barrier.

@benchmark unittest blocks are executed by the runner's --bench`` mode. By default the whole test body is the measured unit. To time only part of the body (excluding setup), call benchIter inside the test:

@("sort.bench")
@benchmark @safe
unittest
{
    import sparkles.test_runner.bench : benchIter, blackBox;

    auto data = makeInput();          // setup — not measured
    benchIter({ blackBox(data.dup.sort()); });  // measured
}

The measurement protocol follows Rust libtest's Bencher: the iteration count per sample is doubled until a sample takes at least BenchConfig.minSampleTime, then BenchConfig.sampleCount samples are collected and summarized as median / median-absolute-deviation / min / max nanoseconds per iteration.

bench
:
(struct) sparkles.test_runner.bench.BenchConfig

Tuning knobs of one benchmark run.

BenchConfig
,
(struct) sparkles.test_runner.bench.BenchStats

Summary statistics of one benchmark row, in nanoseconds per iteration. A row with a non-empty error is a failure row (its timing fields are unset).

BenchStats
;
import
(package) sparkles
sparkles
.
(package) sparkles.test_runner
test_runner
.
(module) sparkles.test_runner.metrics

The benchmark metric catalog: a unified, named, filterable view over every measured column — client throughput/level Metrics and hardware PerfStats counters today, cheap /proc counters and syscall counts as later sources.

Each column is one named MetricCell (per row), described by a MetricDescriptor (per catalog). A MetricClass tags every metric quantitative (near-zero perturbation — the only inputs a reported number may read) or diagnostic (perturbs — explains a result, never a headline). This is the single seam the reporting layer renders through and that --metrics/`--list-`metrics select over.

Units-of-measure alignment (see the roadmap): a Unit is treated as an open-basis "mint-by-name" symbol label, not a dimension. All unit/rate/format semantics — the scaled/fixed formatters and the rate ÷time derivation in clientCells — live here, so a later sparkles.quantities swap is a localized change to this module and nothing else in the catalog.

metrics
:
(alias) sparkles.test_runner.bench_json.catalog = sparkles.test_runner.metrics.MetricDescriptor[] sparkles.test_runner.metrics.catalog(in sparkles.test_runner.bench.BenchStats[] rows) pure nothrow @safe

The catalog across all rows: client columns (first-seen order, always available) followed by the perf family (available iff any row carries counters). This is the universe --list-metrics and --metrics range over.

catalog
,
(alias) sparkles.test_runner.bench_json.rowCells = sparkles.test_runner.metrics.MetricCell[] sparkles.test_runner.metrics.rowCells(in sparkles.test_runner.bench.BenchStats row) pure nothrow @safe

Every metric cell of one row: client columns first (in call order), then perf, then tier0 — each present only when the row carries that source.

rowCells
;
import
(package) sparkles
sparkles
.
(package) sparkles.test_runner
test_runner
.
(module) sparkles.test_runner.workload

The @workload`` window measurement model: one window, counter deltas.

Where @benchmark runs a body many times and reports per-iteration statistics, a workload runs once (or a few reps) and reports what happened across the window: every open counter source's delta between two edge snapshots, plus a wall-clock decomposition into on-CPU time (rusage), runqueue wait (schedstat), and a clamped residual. Sources are read cumulatively at the edges (no per-iteration ioctl bracket, no RESET — see sparkles.test_runner.perf_group.GroupSnapshot), so the driver's whole-body candidate window and in-body workloadWindow calls overlap freely in a single pass — a workload body is never re-run for counting, because it may be expensive or non-idempotent.

Edge-snapshot nesting order (outer → inner): psi, wall clock, wall source (rusage/schedstat), syscalls, raw, tier-0, perf — so the cycle counters see only the body, and each tier's window contains at most the inner tiers' edge reads (a handful of syscalls per edge, negligible at window granularity and disclosed here rather than hidden). Psi sits outermost — outside even the wall clock and rusage windows — so its six file reads per edge (~20 µs) contribute zero apparatus anywhere in the decomposition; a system-wide µs-resolution integral's own window being a few µs wider than the wall clock is immaterial.

Decomposition honesty: only runqueue wait is a true per-cause duration today; everything else off-CPU — locks, sleeps, disk — lands in offCpuOtherNs, which clamps at zero and says so in note rather than fabricating a cause. PSI stall integrals ride alongside as system-wide diagnostics (WorkloadWindow.psi) — /proc/pressure cannot attribute to the measured thread, so disk attribution waits for M8's cgroup scoping. On Linux the decomposition is thread-scoped (RUSAGE_THREAD + /proc/thread-self/schedstat — the only scoping under which wall = onCpu + runqueue + other is arithmetically meaningful); the process-wide reading is captured too, purely to disclose CPU burned by other threads. Thread coverage caveats (counters follow clone inheritance, the decomposition follows the driving thread) match the bench modes.

workload
:
(struct) sparkles.test_runner.workload.WorkloadWindow

One measured window. Deliberately NOT BenchStats: its per-iteration timing fields would misrepresent a single window — counter stats here are window totals (iters == 1).

WorkloadWindow
;
/// Provenance and the effective measurement knobs stamped onto a report, so a /// committed baseline is self-describing (the budget it was measured under is /// part of the data, not tribal knowledge). struct
(struct) sparkles.test_runner.bench_json.BenchMeta

Provenance and the effective measurement knobs stamped onto a report, so a committed baseline is self-describing (the budget it was measured under is part of the data, not tribal knowledge).

BenchMeta
{
(alias) object.string = string
string
(field) string sparkles.test_runner.bench_json.BenchMeta.date

ISO day, e.g. "2026-07-10"

date
; /// ISO day, e.g. "2026-07-10"
(alias) object.string = string
string
(field) string sparkles.test_runner.bench_json.BenchMeta.hostname

"" when unavailable

hostname
; /// "" when unavailable
(alias) object.string = string
string
(field) string sparkles.test_runner.bench_json.BenchMeta.os
os
;
(alias) object.string = string
string
(field) string sparkles.test_runner.bench_json.BenchMeta.arch
arch
;
(alias) object.string = string
string
(field) string sparkles.test_runner.bench_json.BenchMeta.compiler

e.g. "LDC (front-end 2.111)"

compiler
; /// e.g. "LDC (front-end 2.111)"
(alias) object.string = string
string
(field) string sparkles.test_runner.bench_json.BenchMeta.cpu

/proc/cpuinfo model name; "" off Linux

cpu
; /// /proc/cpuinfo model name; "" off Linux
long
(field) long sparkles.test_runner.bench_json.BenchMeta.minSampleTimeMs

effective per-sample/total budget (--bench-min-time)

minSampleTimeMs
; /// effective per-sample/total budget (--bench-min-time)
uint
(field) uint sparkles.test_runner.bench_json.BenchMeta.sampleCount

effective BenchConfig.sampleCount

sampleCount
; /// effective BenchConfig.sampleCount
const(
(alias) object.string = string
string
)[]
(field) const(string)[] sparkles.test_runner.bench_json.BenchMeta.provenance

suite-registered lines (benchProvenance)

provenance
; /// suite-registered lines (`benchProvenance`)
} /// Collects host/toolchain provenance and the run's effective knobs.
(struct) sparkles.test_runner.bench_json.BenchMeta

Provenance and the effective measurement knobs stamped onto a report, so a committed baseline is self-describing (the budget it was measured under is part of the data, not tribal knowledge).

BenchMeta
sparkles.test_runner.bench_json.BenchMeta sparkles.test_runner.bench_json.collectBenchMeta(in sparkles.test_runner.bench.BenchConfig config) @safe

Collects host/toolchain provenance and the run's effective knobs.

collectBenchMeta
(in
(struct) sparkles.test_runner.bench.BenchConfig

Tuning knobs of one benchmark run.

BenchConfig
(parameter) const(sparkles.test_runner.bench.BenchConfig) config
config
) @safe
{ import
(package) std
std
.
(module) std.compiler

Identify the compiler used and its various features.

Source

std/compiler.d

@copyrightCopyright The D Language Foundation 2000 - 2011.@licenseBoost License 1.0.@authorsWalter Bright, Alex Rønne Petersen
compiler
:
(alias immutable global) name = immutable(string) std.compiler.name

Vendor specific string naming the compiler, for example: "Digital Mars D".

name
,
(alias immutable global) version_major = immutable(uint) std.compiler.version_major

The vendor specific version number, as in version_major.version_minor

version_major
,
(alias immutable global) version_minor = immutable(uint) std.compiler.version_minor

The vendor specific version number, as in version_major.version_minor

version_minor
;
import
(package) std
std
.
(package) std.datetime
datetime
.
(module) std.datetime.date
Category Functions
Main date types Date DateTime
Other date types Month DayOfWeek TimeOfDay
Date checking valid validTimeUnits yearIsLeapYear isTimePoint enforceValid
Date conversion daysToDayOfWeek monthsToMonth
Time units cmpTimeUnits timeStrings
Other AllowDayOverflow DateTimeException

Source

std/datetime/date.d

date
:
(struct) std.datetime.date.Date

Represents a date in the Proleptic Gregorian Calendar ranging from 32,768 B.C. to 32,767 A.D. Positive years are A.D. Non-positive years are B.C.

Year, month, and day are kept separately internally so that Date is optimized for calendar-based operations.

Date uses the Proleptic Gregorian Calendar, so it assumes the Gregorian leap year calculations for its entire length. As per ISO 8601, it treats 1 B.C. as year 0, i.e. 1 B.C. is 0, 2 B.C. is -1, etc. Use yearBC to use B.C. as a positive integer with 1 B.C. being the year prior to 1 A.D.

Year 0 is a leap year.

Examples

import core.time : days;

auto d = Date(2000, 6, 1);

assert(d.dayOfYear == 153);
assert(d.dayOfWeek == DayOfWeek.thu);

d += 10.days;
assert(d == Date(2000, 6, 11));

assert(d.toISOExtString() == "2000-06-11");
assert(d.toISOString() == "20000611");
assert(d.toSimpleString() == "2000-Jun-11");

assert(Date.fromISOExtString("2018-01-01") == Date(2018, 1, 1));
assert(Date.fromISOString("20180101") == Date(2018, 1, 1));
assert(Date.fromSimpleString("2018-Jan-01") == Date(2018, 1, 1));
Date
;
import
(package) std
std
.
(package) std.datetime
datetime
.
(module) std.datetime.systime
Category Functions
Types Clock SysTime DosFileTime
Conversion parseRFC822DateTime DosFileTimeToSysTime FILETIMEToStdTime FILETIMEToSysTime stdTimeToFILETIME stdTimeToUnixTime SYSTEMTIMEToSysTime SysTimeToDosFileTime SysTimeToFILETIME SysTimeToSYSTEMTIME unixTimeToStdTime

Source

std/datetime/systime.d

systime
:
(class) std.datetime.systime.Clock

Effectively a namespace to make it clear that the methods it contains are getting the time from the system clock. It cannot be instantiated.

Examples

Get the current time as a SysTime

import std.datetime.timezone : LocalTime;
SysTime today = Clock.currTime();
assert(today.timezone is LocalTime());
Clock
;
import
(package) std
std
.
(module) std.format

This package provides string formatting functionality using printf style format strings.

Submodule Function Name Description
package
format
Converts its arguments according to a format string into a string.

| package | sformat | Converts its arguments according to a format string into a buffer. |

| package | FormatException | Signals a problem while formatting. |

| write | formattedWrite | Converts its arguments according to a format string and writes the result to an output range. |

| write | formatValue | Formats a value of any type according to a format specifier and writes the result to an output range. |

| read | formattedRead | Reads an input range according to a format string and stores the read values into its arguments. |

| read | unformatValue | Reads a value from the given input range and converts it according to a format specifier. |

| spec | FormatSpec | A general handler for format strings. |

| spec | singleSpec | Helper function that returns a FormatSpec for a single format specifier. |

Limitation

This package does not support localization, but adheres to the rounding mode of the floating point unit, if available.

Format Strings

The functions contained in this package use format strings. A format string describes the layout of another string for reading or writing purposes. A format string is composed of normal text interspersed with format specifiers. A format specifier starts with a percentage sign '%', optionally followed by one or more parameters and ends with a format indicator. A format indicator may be a simple format character or a compound indicator.

Format strings are composed according to the following grammar:

FormatString: FormatStringItem FormatString FormatStringItem: Character FormatSpecifier FormatSpecifier: '%' Parameters FormatIndicator

FormatIndicator: FormatCharacter CompoundIndicator FormatCharacter: see remark below CompoundIndicator: '(' FormatString '%)' '(' FormatString '%|' Delimiter '%)' Delimiter empty Character Delimiter

Parameters: Position Flags Width Precision Separator Position: empty Integer '$'** *Integer* **':'** *Integer* **'$' Integer ':' '$'** *Flags*: *empty* *Flag* *Flags* *Flag*: **'-'**|**'+'**|**' '**|**'0'**|**'#'**|**'='** *Width*: *OptionalPositionalInteger* *Precision*: *empty* **'.'** *OptionalPositionalInteger* *Separator*: *empty* **','** *OptionalInteger* **','** *OptionalInteger* **'?'** *OptionalInteger*: *empty* *Integer* **'*'** *OptionalPositionalInteger*: *OptionalInteger* **'*'** *Integer* **'$'

Character '%%' AnyCharacterExceptPercent Integer: NonZeroDigit Digits Digits: empty Digit Digits NonZeroDigit: '1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' Digit: '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'

Note

FormatCharacter is unspecified. It can be any character that has no other purpose in this grammar, but it is recommended to assign (lower- and uppercase) letters.

Note

The Parameters of a CompoundIndicator are currently limited to a '-' flag.

Format Indicator

The format indicator can either be a single character or an expression surrounded by '%(' and '%)'. It specifies the basic manner in which a value will be formatted and is the minimum requirement to format a value.

The following characters can be used as format characters:

FormatCharacter Semantics
's'
To be formatted in a human readable format.
Can be used with all types.
'c'
To be formatted as a character.
'd'
To be formatted as a signed decimal integer.
'u'
To be formatted as a decimal image of the underlying bit representation.
'b'
To be formatted as a binary image of the underlying bit representation.
'o'
To be formatted as an octal image of the underlying bit representation.
'x' / 'X'
To be formatted as a hexadecimal image of the underlying bit representation.
'e' / 'E'
To be formatted as a real number in decimal scientific notation.
'f' / 'F'
To be formatted as a real number in decimal natural notation.
'g' / 'G'
To be formatted as a real number in decimal short notation.
Depending on the number, a scientific notation or
a natural notation is used.
'a' / 'A'
To be formatted as a real number in hexadecimal scientific notation.
'r'
To be formatted as raw bytes.
The output may not be printable and depends on endianness.

The compound indicator can be used to describe compound types like arrays or structs in more detail. A compound type is enclosed within '%(' and '%)'. The enclosed sub-format string is applied to individual elements. The trailing portion of the sub-format string following the specifier for the element is interpreted as the delimiter, and is therefore omitted following the last element. The '%|' specifier may be used to explicitly indicate the start of the delimiter, so that the preceding portion of the string will be included following the last element.

The format string inside of the compound indicator should contain exactly one format specifier (two in case of associative arrays), which specifies the formatting mode of the elements of the compound type. This format specifier can be a compound indicator itself.

Note

Inside a compound indicator, strings and characters are escaped automatically. To avoid this behavior, use "%-(" instead of "%(".

Flags

There are several flags that affect the outcome of the formatting.

Flag Semantics
'-'
When the formatted result is shorter than the value
given by the width parameter, the output is left
justified. Without the '-' flag, the output remains
right justified.

There are two exceptions where the '-' flag has a different meaning: (1) with 'r' it denotes to use little endian and (2) in case of a compound indicator it means that no special handling of the members is applied. | | '=' | When the formatted result is shorter than the value given by the width parameter, the output is centered. If the central position is not possible it is moved slightly to the right. In this case, if '-' flag is present in addition to the '=' flag, it is moved slightly to the left. | | '+' / *' '* | Applies to numerical values. By default, positive numbers are not formatted to include the + sign. With one of these two flags present, positive numbers are preceded by a plus sign or a space. When both flags are present, a plus sign is used.

In case of 'r', a big endian format is used. | | '0' | Is applied to numerical values that are printed right justified. If the zero flag is present, the space left to the number is filled with zeros instead of spaces. | | '#' | Denotes that an alternative output must be used. This depends on the type to be formatted and the format character used. See the sections below for more information. |

Width, Precision and Separator

The width parameter specifies the minimum width of the result.

The meaning of precision depends on the format indicator. For integers it denotes the minimum number of digits printed, for real numbers it denotes the number of fractional digits and for strings and compound types it denotes the maximum number of elements that are included in the output.

A separator is used for formatting numbers. If it is specified, the output is divided into chunks of three digits, separated by a ','. The number of digits in a chunk can be given explicitly by providing a number or a ''* after the ','.

In all three cases the number of digits can be replaced by a ''*. In this scenario, the next argument is used as the number of digits. If the argument is a negative number, the precision and separator parameters are considered unspecified. For width, the absolute value is used and the '-' flag is set.

The separator can also be followed by a '?'. In that case, an additional argument is used to specify the symbol that should be used to separate the chunks.

Position

By default, the arguments are processed in the provided order. With the position parameter it is possible to address arguments directly. It is also possible to denote a series of arguments with two numbers separated by ':', that are all processed in the same way. The second number can be omitted. In that case the series ends with the last argument.

It's also possible to use positional arguments for width, precision and separator by adding a number and a '$' after the ''*.

Types

This section describes the result of combining types with format characters. It is organized in 2 subsections: a list of general information regarding the formatting of types in the presence of format characters and a table that contains details for every available combination of type and format character.

When formatting types, the following rules apply:

  • If the format character is upper case, the resulting string will be formatted using upper case letters.

  • The default precision for floating point numbers is 6 digits.

  • Rounding of floating point numbers adheres to the rounding mode of the floating point unit, if available.

  • The floating point values NaN and Infinity are formatted as nan and inf, possibly preceded by '+' or '-' sign.

  • Formatting reals is only supported for 64 bit reals and 80 bit reals. All other reals are cast to double before they are formatted. This will cause the result to be inf for very large numbers.

  • Characters and strings formatted with the 's' format character inside of compound types are surrounded by single and double quotes and unprintable characters are escaped. To avoid this, a '-' flag can be specified for the compound specifier (e.g. "%-(%s%)" instead of "%(%s%)" ).

  • Structs, unions, classes and interfaces are formatted by calling a toString method if available. See module std.format.write for more details.

  • Only part of these combinations can be used for reading. See module std.format.read for more detailed information.

This table contains descriptions for every possible combination of type and format character:

<th scope="col" width="20%">Type</th> <th scope="col" width="20%">Format Character</th> Formatted as...
<td rowspan="1">null</td> 's'
null

|<td rowspan="3">bool</td> 's' | false or true |

| 'b', 'd', 'o', 'u', 'x', 'X' | As the integrals 0 or 1 with the same format character.

Please note, that 'o' and 'x' with '#' flag might produce unexpected results due to special handling of the value 0. |

| 'r' | \0 or \1 |

|<td rowspan="4">Integral</td> 's', 'd' | A signed decimal number. The '#' flag is ignored. |

| 'b', 'o', 'u', 'x', 'X' | An unsigned binary, decimal, octal or hexadecimal number.

In case of 'o' and 'x', the '#' flag denotes that the number must be preceded by 0 and 0x, with the exception of the value 0, where this does not apply. For 'b' and 'u' the '#' flag has no effect. |

| 'e', 'E', 'f', 'F', 'g', 'G', 'a', 'A' | As a floating point value with the same specifier.

Default precision is large enough to add all digits of the integral value.

In case of 'a' and 'A', the integral digit can be any hexadecimal digit. |

| 'r' | Characters taken directly from the binary representation. |

|<td rowspan="5">Floating Point</td> 'e', 'E' | Scientific notation: Exactly one integral digit followed by a dot and fractional digits, followed by the exponent. The exponent is formatted as 'e' followed by a '+' or '-' sign, followed by at least two digits.

When there are no fractional digits and the '#' flag is not present, the dot is omitted. |

| 'f', 'F' | Natural notation: Integral digits followed by a dot and fractional digits.

When there are no fractional digits and the '#' flag is not present, the dot is omitted.

Please note: the difference between 'f' and 'F' is only visible for NaN and Infinity. |

| 's', 'g', 'G' | Short notation: If the absolute value is larger than 10 ^^ precision or smaller than 0.0001, the scientific notation is used. If not, the natural notation is applied.

In both cases precision denotes the count of all digits, including the integral digits. Trailing zeros (including a trailing dot) are removed.

If '#' flag is present, trailing zeros are not removed. |

| 'a', 'A' | Hexadecimal scientific notation: 0x followed by 1 (or 0 in case of value zero or denormalized number) followed by a dot, fractional digits in hexadecimal notation and an exponent. The exponent is build by p, followed by a sign and the exponent in decimal notation.

When there are no fractional digits and the '#' flag is not present, the dot is omitted. |

| 'r' | Characters taken directly from the binary representation. |

|<td rowspan="3">Character</td> 's', 'c' | As the character.

Inside of a compound indicator 's' is treated differently: The character is surrounded by single quotes and non printable characters are escaped. This can be avoided by preceding the compound indicator with a '-' flag (e.g. "%-(%s%)"). |

| 'b', 'd', 'o', 'u', 'x', 'X' | As the integral that represents the character. |

| 'r' | Characters taken directly from the binary representation. |

|<td rowspan="3">String</td> 's' | The sequence of characters that form the string.

Inside of a compound indicator the string is surrounded by double quotes and non printable characters are escaped. This can be avoided by preceding the compound indicator with a '-' flag (e.g. "%-(%s%)"). |

| 'r' | The sequence of characters, each formatted with 'r'. |

| compound | As an array of characters. |

|<td rowspan="3">Array</td> 's' | When the elements are characters, the array is formatted as a string. In all other cases the array is surrounded by square brackets and the elements are separated by a comma and a space. If the elements are strings, they are surrounded by double quotes and non printable characters are escaped. |

| 'r' | The sequence of the elements, each formatted with 'r'. |

| compound | The sequence of the elements, each formatted according to the specifications given inside of the compound specifier. |

|<td rowspan="2">Associative Array</td> 's' | As a sequence of the elements in unpredictable order. The output is surrounded by square brackets. The elements are separated by a comma and a space. The elements are formatted as key:value. |

| compound | As a sequence of the elements in unpredictable order. Each element is formatted according to the specifications given inside of the compound specifier. The first specifier is used for formatting the key and the second specifier is used for formatting the value. The order can be changed with positional arguments. For example "%(%2$s (%1$s), %)" will write the value, followed by the key in parenthesis. |

|<td rowspan="2">Enum</td> 's' | The name of the value. If the name is not available, the base value is used, preceeded by a cast. |

| All, but 's' | Enums can be formatted with all format characters that can be used with the base value. In that case they are formatted like the base value. |

|<td rowspan="3">Input Range</td> 's' | When the elements of the range are characters, they are written like a string. In all other cases, the elements are enclosed by square brackets and separated by a comma and a space. |

| 'r' | The sequence of the elements, each formatted with 'r'. |

| compound | The sequence of the elements, each formatted according to the specifications given inside of the compound specifier. |

|<td rowspan="1">Struct</td> 's' | When the struct has neither an applicable toString nor is an input range, it is formatted as follows: StructType(field1, field2, ...). |

|<td rowspan="1">Class</td> 's' | When the class has neither an applicable toString nor is an input range, it is formatted as the fully qualified name of the class. |

|<td rowspan="1">Union</td> 's' | When the union has neither an applicable toString nor is an input range, it is formatted as its base name. |

|<td rowspan="2">Pointer</td> 's' | A null pointer is formatted as 'null'. All other pointers are formatted as hexadecimal numbers with the format character 'X'. |

| 'x', 'X' | Formatted as a hexadecimal number. |

|<td rowspan="3">SIMD vector</td> 's' | The array is surrounded by square brackets and the elements are separated by a comma and a space. |

| 'r' | The sequence of the elements, each formatted with 'r'. |

| compound | The sequence of the elements, each formatted according to the specifications given inside of the compound specifier. |

|<td rowspan="1">Delegate</td> 's', 'r', compound | As the .stringof of this delegate treated as a string.

Please note: The implementation is currently buggy and its use is discouraged. |

Source

std/format/package.d

Examples

Simple use:

// Easiest way is to use `%s` everywhere:
assert(format("I got %s %s for %s euros.", 30, "eggs", 5.27) == "I got 30 eggs for 5.27 euros.");

// Other format characters provide more control:
assert(format("I got %b %(%X%) for %f euros.", 30, "eggs", 5.27) == "I got 11110 65676773 for 5.270000 euros.");

Compound specifiers allow formatting arrays and other compound types:

/*
The trailing end of the sub-format string following the specifier for
each item is interpreted as the array delimiter, and is therefore
omitted following the last array item:
 */
    assert(format("My items are %(%s %).", [1,2,3]) == "My items are 1 2 3.");
    assert(format("My items are %(%s, %).", [1,2,3]) == "My items are 1, 2, 3.");

/*
The "%|" delimiter specifier may be used to indicate where the
delimiter begins, so that the portion of the format string prior to
it will be retained in the last array element:
 */
    assert(format("My items are %(-%s-%|, %).", [1,2,3]) == "My items are -1-, -2-, -3-.");

/*
These compound format specifiers may be nested in the case of a
nested array argument:
 */
    auto mat = [[1, 2, 3],
                [4, 5, 6],
                [7, 8, 9]];

    assert(format("%(%(%d %) - %)", mat), "1 2 3 - 4 5 6 - 7 8 9");
    assert(format("[%(%(%d %) - %)]", mat), "[1 2 3 - 4 5 6 - 7 8 9]");
    assert(format("[%([%(%d %)]%| - %)]", mat), "[1 2 3] - [4 5 6] - [7 8 9]");

/*
Strings and characters are escaped automatically inside compound
format specifiers. To avoid this behavior, use "%-(" instead of "%(":
 */
    assert(format("My friends are %s.", ["John", "Nancy"]) == `My friends are ["John", "Nancy"].`);
    assert(format("My friends are %(%s, %).", ["John", "Nancy"]) == `My friends are "John", "Nancy".`);
    assert(format("My friends are %-(%s, %).", ["John", "Nancy"]) == `My friends are John, Nancy.`);

Using parameters:

// Flags can be used to influence to outcome:
assert(format("%g != %+#g", 3.14, 3.14) == "3.14 != +3.14000");

// Width and precision help to arrange the formatted result:
assert(format(">%10.2f<", 1234.56789) == ">   1234.57<");

// Numbers can be grouped:
assert(format("%,4d", int.max) == "21,4748,3647");

// It's possible to specify the position of an argument:
assert(format("%3$s %1$s", 3, 17, 5) == "5 3");

Providing parameters as arguments:

// Width as argument
assert(format(">%*s<", 10, "abc") == ">       abc<");

// Precision as argument
assert(format(">%.*f<", 5, 123.2) == ">123.20000<");

// Grouping as argument
assert(format("%,*d", 1, int.max) == "2,1,4,7,4,8,3,6,4,7");

// Grouping separator as argument
assert(format("%,3?d", '_', int.max) == "2_147_483_647");

// All at once
assert(format("%*.*,*?d", 20, 15, 6, '/', int.max) == "   000/002147/483647");
@copyrightCopyright The D Language Foundation 2000-2021.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, and Kenji Hara
format
:
(alias template) format = std.format.format(Char, Args...)(in Char[] fmt, Args args) if (isSomeChar!Char)

Converts its arguments according to a format string into a string.

The second version of format takes the format string as template argument. In this case, it is checked for consistency at compile-time and produces slightly faster code, because the length of the output buffer can be estimated in advance.

Params: fmt = a $(MREF_ALTTEXT format string, std,format) args = a variadic list of arguments to be formatted Char = character type of fmt Args = a variadic list of types of the arguments

Returns: The formatted string.

Throws: A $(LREF FormatException) if formatting did not succeed.

See_Also: $(LREF sformat) for a variant, that tries to avoid garbage collection.

format
;
(struct) sparkles.test_runner.bench_json.BenchMeta

Provenance and the effective measurement knobs stamped onto a report, so a committed baseline is self-describing (the budget it was measured under is part of the data, not tribal knowledge).

BenchMeta
(local variable) sparkles.test_runner.bench_json.BenchMeta m
m
;
(local variable) sparkles.test_runner.bench_json.BenchMeta m
m
.
(field) string sparkles.test_runner.bench_json.BenchMeta.date

ISO day, e.g. "2026-07-10"

date
= (cast(
(struct) std.datetime.date.Date

Represents a date in the Proleptic Gregorian Calendar ranging from 32,768 B.C. to 32,767 A.D. Positive years are A.D. Non-positive years are B.C.

Year, month, and day are kept separately internally so that Date is optimized for calendar-based operations.

Date uses the Proleptic Gregorian Calendar, so it assumes the Gregorian leap year calculations for its entire length. As per ISO 8601, it treats 1 B.C. as year 0, i.e. 1 B.C. is 0, 2 B.C. is -1, etc. Use yearBC to use B.C. as a positive integer with 1 B.C. being the year prior to 1 A.D.

Year 0 is a leap year.

Examples

import core.time : days;

auto d = Date(2000, 6, 1);

assert(d.dayOfYear == 153);
assert(d.dayOfWeek == DayOfWeek.thu);

d += 10.days;
assert(d == Date(2000, 6, 11));

assert(d.toISOExtString() == "2000-06-11");
assert(d.toISOString() == "20000611");
assert(d.toSimpleString() == "2000-Jun-11");

assert(Date.fromISOExtString("2018-01-01") == Date(2018, 1, 1));
assert(Date.fromISOString("20180101") == Date(2018, 1, 1));
assert(Date.fromSimpleString("2018-Jan-01") == Date(2018, 1, 1));
Date
)
(class) std.datetime.systime.Clock

Effectively a namespace to make it clear that the methods it contains are getting the time from the system clock. It cannot be instantiated.

Examples

Get the current time as a SysTime

import std.datetime.timezone : LocalTime;
SysTime today = Clock.currTime();
assert(today.timezone is LocalTime());
Clock
.
std.datetime.systime.SysTime std.datetime.systime.Clock.currTime!(ClockType.normal)(immutable(std.datetime.timezone.TimeZone) tz = opCall()) nothrow @safe

Returns the current time in the given time zone.

@paramclockType The ClockType indicates which system clock to use to get the current time. Very few programs need to use anything other than the default.@paramtz The time zone for the SysTime that's returned.@throwsDateTimeException if it fails to get the time.
currTime
).
string std.datetime.date.Date.toISOExtString() const pure nothrow @safe

Converts this Date to a string with the format YYYY-MM-DD. If writer is set, the resulting string will be written directly to it.

Examples

assert(Date(2010, 7, 4).toISOExtString() == "2010-07-04");
assert(Date(1998, 12, 25).toISOExtString() == "1998-12-25");
assert(Date(0, 1, 5).toISOExtString() == "0000-01-05");
assert(Date(-4, 1, 5).toISOExtString() == "-0004-01-05");
@paramwriter A char accepting output range@returnsA string when not using an output range; void otherwise.
toISOExtString
();
(local variable) sparkles.test_runner.bench_json.BenchMeta m
m
.
(field) string sparkles.test_runner.bench_json.BenchMeta.hostname

"" when unavailable

hostname
=
string sparkles.test_runner.bench_json.hostName() @safe
hostName
();
version (
linux
linux
)
(local variable) sparkles.test_runner.bench_json.BenchMeta m
m
.
(field) string sparkles.test_runner.bench_json.BenchMeta.os
os
= "linux";
else version (OSX) m.os = "macos"; else version (Windows) m.os = "windows"; else version (Posix) m.os = "posix"; else m.os = "unknown"; version (
X86_64
X86_64
)
(local variable) sparkles.test_runner.bench_json.BenchMeta m
m
.
(field) string sparkles.test_runner.bench_json.BenchMeta.arch
arch
= "x86_64";
else version (AArch64) m.arch = "aarch64"; else version (X86) m.arch = "x86"; else m.arch = "unknown";
(local variable) sparkles.test_runner.bench_json.BenchMeta m
m
.
(field) string sparkles.test_runner.bench_json.BenchMeta.compiler

e.g. "LDC (front-end 2.111)"

compiler
=
string std.format.format!("%s (front-end %s.%03d)", string, immutable(uint), immutable(uint))(string __param_0, immutable(uint) __param_1, immutable(uint) __param_2) pure @safe

Examples

The format string can be checked at compile-time:

auto s = format!"%s is %s"("Pi", 3.14);
assert(s == "Pi is 3.14");

// This line doesn't compile, because 3.14 cannot be formatted with %d:
// s = format!"%s is %d"("Pi", 3.14);
format
!"%s (front-end %s.%03d)"(
(immutable global) immutable(string) std.compiler.name

Vendor specific string naming the compiler, for example: "Digital Mars D".

name
,
(immutable global) immutable(uint) std.compiler.version_major

The vendor specific version number, as in version_major.version_minor

version_major
,
(immutable global) immutable(uint) std.compiler.version_minor

The vendor specific version number, as in version_major.version_minor

version_minor
);
(local variable) sparkles.test_runner.bench_json.BenchMeta m
m
.
(field) string sparkles.test_runner.bench_json.BenchMeta.cpu

/proc/cpuinfo model name; "" off Linux

cpu
=
string sparkles.test_runner.bench_json.cpuModel() @safe
cpuModel
();
(local variable) sparkles.test_runner.bench_json.BenchMeta m
m
.
(field) long sparkles.test_runner.bench_json.BenchMeta.minSampleTimeMs

effective per-sample/total budget (--bench-min-time)

minSampleTimeMs
=
(parameter) const(sparkles.test_runner.bench.BenchConfig) config
config
.
(field) core.time.Duration sparkles.test_runner.bench.BenchConfig.minSampleTime

Auto-scaling target duration of one sample.

minSampleTime
.
long core.time.Duration.total!"msecs"() const pure nothrow @nogc @property @safe

Returns the total number of the given units in this Duration. So, unlike split, it does not strip out the larger units.

Examples

assert(dur!"weeks"(12).total!"weeks" == 12);
assert(dur!"weeks"(12).total!"days" == 84);

assert(dur!"days"(13).total!"weeks" == 1);
assert(dur!"days"(13).total!"days" == 13);

assert(dur!"hours"(49).total!"days" == 2);
assert(dur!"hours"(49).total!"hours" == 49);

assert(dur!"nsecs"(2007).total!"hnsecs" == 20);
assert(dur!"nsecs"(2007).total!"nsecs" == 2000);
total
!"msecs";
(local variable) sparkles.test_runner.bench_json.BenchMeta m
m
.
(field) uint sparkles.test_runner.bench_json.BenchMeta.sampleCount

effective BenchConfig.sampleCount

sampleCount
=
(parameter) const(sparkles.test_runner.bench.BenchConfig) config
config
.
(field) uint sparkles.test_runner.bench.BenchConfig.sampleCount

Number of samples to collect.

sampleCount
;
return
(local variable) sparkles.test_runner.bench_json.BenchMeta m
m
;
} private
(alias) object.string = string
string
string sparkles.test_runner.bench_json.hostName() @safe
hostName
() @safe
{ version (
Posix
Posix
)
{ import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(module) core.sys.posix.unistd

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly@standardsThe Open Group Base Specifications Issue 8, IEEE Std 1003.1, 2024 Edition
unistd
:
(alias) gethostname = int core.sys.posix.unistd.gethostname(char*, ulong) nothrow @nogc
gethostname
;
char[256]
(local variable) char[256] buf
buf
= 0;
const
(local variable) const(bool) ok
ok
= (() @trusted =>
int core.sys.posix.unistd.gethostname(char*, ulong) nothrow @nogc
gethostname
(
(local variable) char[256] buf
buf
.
(constant) char* char[256].ptr = &buf
ptr
,
(local variable) char[256] buf
buf
.
(constant) ulong char[256].length = 256LU
length
))() == 0;
if (!
(local variable) const(bool) ok
ok
)
return ""; foreach (
(parameter) ulong i
i
,
(parameter) char ch
ch
;
(local variable) char[256] buf
buf
)
if (
(local variable) char ch
ch
== '\0')
return
(local variable) char[256] buf
buf
[0 ..
(local variable) ulong i
i
].
string object.idup!char(char[] a) pure nothrow @property @safe

Provide the .idup array property, which creates an immutable duplicate.

idup
;
return
(local variable) char[256] buf
buf
[].
string object.idup!char(char[] a) pure nothrow @property @safe

Provide the .idup array property, which creates an immutable duplicate.

idup
;
} else version (Windows) { import std.process : environment; return environment.get("COMPUTERNAME", ""); } else return ""; } private
(alias) object.string = string
string
string sparkles.test_runner.bench_json.cpuModel() @safe
cpuModel
() @safe
{ version (
linux
linux
)
{ import
(package) std
std
.
(package) std.algorithm
algorithm
.
(module) std.algorithm.searching

This is a submodule of std.algorithm. It contains generic searching algorithms.

Function Name Description
all all!"a > 0"([1, 2, 3, 4]) returns true because all elements are positive
any any!"a > 0"([1, 2, -3, -4]) returns true because at least one element is positive
balancedParens balancedParens("((1 + 1) / 2)", '(', ')') returns true because the string has balanced parentheses.
boyerMooreFinder find("hello world", boyerMooreFinder("or")) returns "orld" using the Boyer-Moore algorithm.
canFind canFind("hello world", "or") returns true.
count Counts all elements or elements matching a predicate, specific element or sub-range.

count([1, 2, 1]) returns 3, count([1, 2, 1], 1) returns 2 and count!"a < 0"([1, -3, 0]) returns 1. | | countUntil | countUntil(a, b) returns the number of steps taken in a to reach b; for example, countUntil("hello!", "o") returns 4. | | commonPrefix | commonPrefix("parakeet", "parachute") returns "para". | | endsWith | endsWith("rocks", "ks") returns true. | | extrema | extrema([2, 1, 3, 5, 4]) returns [1, 5]. | | find | find("hello world", "or") returns "orld" using linear search. (For binary search refer to SortedRange.) | | findAdjacent | findAdjacent([1, 2, 3, 3, 4]) returns the subrange starting with two equal adjacent elements, i.e. [3, 3, 4]. | | findAmong | findAmong("abcd", "qcx") returns "cd" because 'c' is among "qcx". | | findSkip | If a = "abcde", then findSkip(a, "x") returns false and leaves a unchanged, whereas findSkip(a, "c") advances a to "de" and returns true. | | findSplit | findSplit("abcdefg", "de") returns a tuple of three ranges "abc", "de", and "fg". | | findSplitAfter | findSplitAfter("abcdefg", "de") returns a tuple of two ranges "abcde" and "fg". | | findSplitBefore | findSplitBefore("abcdefg", "de") returns a tuple of two ranges "abc" and "defg". | | minCount | minCount([2, 1, 1, 4, 1]) returns tuple(1, 3). | | maxCount | maxCount([2, 4, 1, 4, 1]) returns tuple(4, 2). | | minElement | Selects the minimal element of a range. minElement([3, 4, 1, 2]) returns 1. | | maxElement | Selects the maximal element of a range. maxElement([3, 4, 1, 2]) returns 4. | | minIndex | Index of the minimal element of a range. minIndex([3, 4, 1, 2]) returns 2. | | maxIndex | Index of the maximal element of a range. maxIndex([3, 4, 1, 2]) returns 1. | | minPos | minPos([2, 3, 1, 3, 4, 1]) returns the subrange [1, 3, 4, 1], i.e., positions the range at the first occurrence of its minimal element. | | maxPos | maxPos([2, 3, 1, 3, 4, 1]) returns the subrange [4, 1], i.e., positions the range at the first occurrence of its maximal element. | | skipOver | Assume a = "blah". Then skipOver(a, "bi") leaves a unchanged and returns false, whereas skipOver(a, "bl") advances a to refer to "ah" and returns true. | | startsWith | startsWith("hello, world", "hello") returns true. | | until | Lazily iterates a range until a specific value is found. |

Source

std/algorithm/searching.d

@copyrightAndrei Alexandrescu 2008-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu
searching
:
(alias template) startsWith = std.algorithm.searching.startsWith(alias pred = (a, b) => a == b, Range, Needles...)(Range doesThisStart, Needles withOneOfThese) if (isInputRange!Range && (Needles.length > 1) && allSatisfy!(canTestStartsWith!(pred, Range), Needles))

Checks whether the given $(REF_ALTTEXT input range, isInputRange, std,range,primitives) starts with (one of) the given needle(s) or, if no needles are given, if its front element fulfils predicate pred.

For more information about pred see $(LREF find).

Params:

    pred = Predicate to use in comparing the elements of the haystack and the
        needle(s). Mandatory if no needles are given.

    doesThisStart = The input range to check.

    withOneOfThese = The needles against which the range is to be checked,
        which may be individual elements or input ranges of elements.

    withThis = The single needle to check, which may be either a single element
        or an input range of elements.

Returns:

0 if the needle(s) do not occur at the beginning of the given range; otherwise the position of the matching needle, that is, 1 if the range starts with withOneOfThese[0], 2 if it starts with withOneOfThese[1], and so on.

In the case where doesThisStart starts with multiple of the ranges or elements in withOneOfThese, then the shortest one matches (if there are two which match which are of the same length (e.g. "a" and 'a'), then the left-most of them in the argument list matches).

In the case when no needle parameters are given, return true iff front of doesThisStart fulfils predicate pred.

startsWith
;
import
(package) std
std
.
(module) std.file

Utilities for manipulating files and scanning directories. Functions in this module handle files as a unit, e.g., read or write one file at a time. For opening files and manipulating them via handles refer to module std.stdio.

Category Functions
General exists isDir isFile isSymlink rename thisExePath
Directories chdir dirEntries getcwd mkdir mkdirRecurse rmdir rmdirRecurse tempDir
Files append copy read readText remove slurp write
Symlinks symlink readLink
Attributes attrIsDir attrIsFile attrIsSymlink getAttributes getLinkAttributes getSize setAttributes
Timestamp getTimes getTimesWin setTimes timeLastModified timeLastAccessed timeStatusChanged
Other DirEntry FileException PreserveAttributes SpanMode getAvailableDiskSpace

Source

std/file.d

@copyrightCopyright The D Language Foundation 2007 - 2011.@seeThe official tutorial for an introduction to working with files in D, module std.stdio for opening files and manipulating them via handles, and module std.path for manipulating path strings.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Jonathan M Davis
file
:
(alias template) readText = std.file.readText(S = string, R)(auto ref R name) if (isSomeString!S && (isSomeFiniteCharInputRange!R || is(StringTypeOf!R)))

Reads and validates (using $(REF validate, std, utf)) a text file. S can be an array of any character type. However, no width or endian conversions are performed. So, if the width or endianness of the characters in the given file differ from the width or endianness of the element type of S, then validation will fail.

    Params:
        S = the string type of the file
        name = string or range of characters representing the file _name

    Returns: Array of characters read.

    Throws: $(LREF FileException) if there is an error reading the file,
            $(REF UTFException, std, utf) on UTF decoding error.

    See_Also: $(REF read, std,file) for reading a binary file.
readText
;
import
(package) std
std
.
(module) std.string

String handling functions.

Category Functions
Searching
column
indexOf
indexOfAny
indexOfNeither
lastIndexOf
lastIndexOfAny
lastIndexOfNeither
Comparison
isNumeric
Mutation
capitalize
Pruning and Filling
center
chomp
chompPrefix
chop
detabber
detab
entab
entabber
leftJustify
outdent
rightJustify
strip
stripLeft
stripRight
wrap
Substitution
abbrev
soundex
soundexer
succ
tr
translate
Miscellaneous
assumeUTF
fromStringz
lineSplitter
representation
splitLines
toStringz
Objects of types string, wstring, and dstring are value types
and cannot be mutated element-by-element. For using mutation during building
strings, use char[], wchar[], or dchar[]. The xxxstring
types are preferable because they don't exhibit undesired aliasing, thus
making code more robust.

The following functions are publicly imported:

Module Functions
Publicly imported functions
std.algorithm
cmp, std,algorithm,comparison
count, std,algorithm,searching
endsWith, std,algorithm,searching
startsWith, std,algorithm,searching
std.array
join, std,array
replace, std,array
replaceInPlace, std,array
split, std,array
empty, std,array
std.format
format, std,format
sformat, std,format
std.uni
icmp, std,uni
toLower, std,uni
toLowerInPlace, std,uni
toUpper, std,uni
toUpperInPlace, std,uni
There is a rich set of functions for string handling defined in other modules.
Functions related to Unicode and ASCII are found in std.uni
and std.ascii, respectively. Other functions that have a
wider generality than just strings can be found in std.algorithm
and std.range.

Source

std/string.d

@seestd.algorithm and std.range for generic range algorithms , std.ascii for functions that work with ASCII strings , std.uni for functions that work with unicode strings@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Jonathan M Davis, and David L. 'SpottedTiger' Davis
string
:
(alias template) indexOf = std.string.indexOf(Range)(Range s, dchar c, CaseSensitive cs = Yes.caseSensitive) if (isInputRange!Range && isSomeChar!(ElementType!Range) && !isSomeString!Range)

Searches for a character in a string or range.

    Params:
        s = string or InputRange of characters to search for `c` in
        c = character to search for in `s`
        startIdx = index to a well-formed code point in `s` to start
            searching from; defaults to 0
        cs = specifies whether comparisons are case-sensitive
            (`Yes.caseSensitive`) or not (`No.caseSensitive`).

    Returns:
        If `c` is found in `s`, then the index of its first occurrence is
        returned. If `c` is not found or `startIdx` is greater than or equal to
        `s.length`, then -1 is returned. If the parameters are not valid UTF,
        the result will still be either -1 or in the range [`startIdx` ..
        `s.length`], but will not be reliable otherwise.

    Throws:
        If the sequence starting at `startIdx` does not represent a well-formed
        code point, then a $(REF UTFException, std,utf) may be thrown.

    See_Also: $(REF countUntil, std,algorithm,searching)
indexOf
,
(alias template) lineSplitter = std.string.lineSplitter(Flag keepTerm = No.keepTerminator, Range)(Range r) if (hasSlicing!Range && hasLength!Range && isSomeChar!(ElementType!Range) && !isSomeString!Range)

Split an array or slicable range of characters into a range of lines using '\r', '\n', '\v', '\f', "\r\n", $(REF lineSep, std,uni), $(REF paraSep, std,uni) and '\u0085' (NEL) as delimiters. If keepTerm is set to Yes.keepTerminator, then the delimiter is included in the slices returned.

    Does not throw on invalid UTF; such is simply passed unchanged
    to the output.

    Adheres to $(HTTP www.unicode.org/versions/Unicode7.0.0/ch05.pdf, Unicode 7.0).

    Does not allocate memory.

Params: r = array of chars, wchars, or dchars or a slicable range keepTerm = whether delimiter is included or not in the results Returns: range of slices of the input range r

See_Also: $(LREF splitLines) $(REF splitter, std,algorithm) $(REF splitter, std,regex)

lineSplitter
,
(alias template) strip = std.string.strip(Range)(Range str) if (isSomeString!Range || isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && !isConvertibleToString!Range && isSomeChar!(ElementEncodingType!Range))

Strips both leading and trailing whitespace (as defined by $(REF isWhite, std,uni)) or as specified in the second argument.

    Params:
        str = string or random access range of characters
        chars = string of characters to be stripped
        leftChars = string of leading characters to be stripped
        rightChars = string of trailing characters to be stripped

    Returns:
        slice of `str` stripped of leading and trailing whitespace
        or characters as specified in the second argument.

    See_Also:
        Generic stripping on ranges: $(REF _strip, std, algorithm, mutation)
strip
;
try { foreach (
(local variable) string line
line
;
string std.file.readText!(string, string)(string name) @safe

Reads and validates (using validate) a text file. S can be an array of any character type. However, no width or endian conversions are performed. So, if the width or endianness of the characters in the given file differ from the width or endianness of the element type of S, then validation will fail.

Examples

Read file with UTF-8 text.

write(deleteme, "abc"); // deleteme is the name of a temporary file
scope(exit) remove(deleteme);
string content = readText(deleteme);
assert(content == "abc");
@paramS the string type of the file@paramname string or range of characters representing the file name@returnsArray of characters read.@throwsFileException if there is an error reading the file, UTFException on UTF decoding error.@seeread for reading a binary file.
readText
("/proc/cpuinfo").
std.string.LineSplitter!(Flag.no, string) std.string.lineSplitter!(Flag.no, immutable(char))(string r) pure nothrow @nogc @safe

Split an array or slicable range of characters into a range of lines using '\r', '\n', '\v', '\f', "\r\n", lineSep, paraSep and '\u0085' (NEL) as delimiters. If keepTerm is set to Yes.keepTerminator, then the delimiter is included in the slices returned.

Does not throw on invalid UTF; such is simply passed unchanged to the output.

Adheres to Unicode 7.0.

Does not allocate memory.

Examples

import std.array : array;

string s = "Hello\nmy\rname\nis";

/* notice the call to 'array' to turn the lazy range created by
lineSplitter comparable to the string[] created by splitLines.
*/
assert(lineSplitter(s).array == splitLines(s));
auto s = "\rpeter\n\rpaul\r\njerry\u2028ice\u2029cream\n\nsunday\nmon\u2030day\n";
auto lines = s.lineSplitter();
static immutable witness = ["", "peter", "", "paul", "jerry", "ice", "cream", "", "sunday", "mon\u2030day"];
uint i;
foreach (line; lines)
{
    assert(line == witness[i++]);
}
assert(i == witness.length);
@paramr array of chars, wchars, or dchars or a slicable range@paramkeepTerm whether delimiter is included or not in the results@returnsrange of slices of the input range r@seesplitLines splitter splitter
lineSplitter
)
if (
(local variable) string line
line
.
bool std.algorithm.searching.startsWith!("a == b", string, string)(string doesThisStart, string withThis) pure nothrow @nogc @safe

Checks whether the given input range starts with (one of) the given needle(s) or, if no needles are given, if its front element fulfils predicate pred.

For more information about pred see find.

@parampred Predicate to use in comparing the elements of the haystack and the needle(s). Mandatory if no needles are given.@paramdoesThisStart The input range to check.@paramwithOneOfThese The needles against which the range is to be checked, which may be individual elements or input ranges of elements.@paramwithThis The single needle to check, which may be either a single element or an input range of elements.@returns

0 if the needle(s) do not occur at the beginning of the given range; otherwise the position of the matching needle, that is, 1 if the range starts with withOneOfThese[0], 2 if it starts with withOneOfThese[1], and so on.

In the case where doesThisStart starts with multiple of the ranges or elements in withOneOfThese, then the shortest one matches (if there are two which match which are of the same length (e.g. "a" and 'a'), then the left-most of them in the argument list matches).

In the case when no needle parameters are given, return true iff front of doesThisStart fulfils predicate pred.

startsWith
("model name"))
{ const
(local variable) const(long) colon
colon
=
(local variable) string line
line
.
long std.string.indexOf!char(scope const(char)[] s, dchar c, std.typecons.Flag!"caseSensitive" cs = Flag.yes) pure nothrow @nogc @safe

Searches for a character in a string or range.

@params string or InputRange of characters to search for c in@paramc character to search for in s@paramstartIdx index to a well-formed code point in s to start searching from; defaults to 0@paramcs specifies whether comparisons are case-sensitive (Yes.caseSensitive) or not (No.caseSensitive).@returnsIf c is found in s, then the index of its first occurrence is returned. If c is not found or startIdx is greater than or equal to s`.length`, then -1 is returned. If the parameters are not valid UTF, the result will still be either -1 or in the range [`startIdx` .. s.length], but will not be reliable otherwise.@throwsIf the sequence starting at startIdx does not represent a well-formed code point, then a UTFException may be thrown.@seecountUntil
indexOf
(':');
if (
(local variable) const(long) colon
colon
>= 0)
return
(local variable) string line
line
[
(local variable) const(long) colon
colon
+ 1 .. $].
string std.string.strip!string(string str) pure nothrow @nogc @safe

Strips both leading and trailing whitespace (as defined by isWhite) or as specified in the second argument.

Examples

import std.uni : lineSep, paraSep;
assert(strip("     hello world     ") ==
       "hello world");
assert(strip("\n\t\v\rhello world\n\t\v\r") ==
       "hello world");
assert(strip("hello world") ==
       "hello world");
assert(strip([lineSep] ~ "hello world" ~ [lineSep]) ==
       "hello world");
assert(strip([paraSep] ~ "hello world" ~ [paraSep]) ==
       "hello world");
@paramstr string or random access range of characters@paramchars string of characters to be stripped@paramleftChars string of leading characters to be stripped@paramrightChars string of trailing characters to be stripped@returnsslice of str stripped of leading and trailing whitespace or characters as specified in the second argument.@seeGeneric stripping on ranges: strip
strip
;
} } catch (
(class) object.Exception

The base class of all errors that are safe to catch and handle.

In principle, only thrown objects derived from this class are safe to catch inside a catch block. Thrown objects not derived from Exception represent runtime errors that should not be caught, as certain runtime guarantees may not hold, making it unsafe to continue program execution.

Examples

bool gotCaught;
try
{
    throw new Exception("msg");
}
catch (Exception e)
{
    gotCaught = true;
    assert(e.msg == "msg");
}
assert(gotCaught);
Exception
)
{ } return ""; } else return ""; } /// One JSON number: `nan`/infinities → `null` (an unavailable counter, the /// table's em dash); integral doubles below 2^53 render as integers; the rest /// to 6 significant digits (never D's 17-digit default). package(sparkles.test_runner)
(alias) object.string = string
string
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(double
(parameter) double v
v
) @safe
{ import
(package) std
std
.
(module) std.format

This package provides string formatting functionality using printf style format strings.

Submodule Function Name Description
package
format
Converts its arguments according to a format string into a string.

| package | sformat | Converts its arguments according to a format string into a buffer. |

| package | FormatException | Signals a problem while formatting. |

| write | formattedWrite | Converts its arguments according to a format string and writes the result to an output range. |

| write | formatValue | Formats a value of any type according to a format specifier and writes the result to an output range. |

| read | formattedRead | Reads an input range according to a format string and stores the read values into its arguments. |

| read | unformatValue | Reads a value from the given input range and converts it according to a format specifier. |

| spec | FormatSpec | A general handler for format strings. |

| spec | singleSpec | Helper function that returns a FormatSpec for a single format specifier. |

Limitation

This package does not support localization, but adheres to the rounding mode of the floating point unit, if available.

Format Strings

The functions contained in this package use format strings. A format string describes the layout of another string for reading or writing purposes. A format string is composed of normal text interspersed with format specifiers. A format specifier starts with a percentage sign '%', optionally followed by one or more parameters and ends with a format indicator. A format indicator may be a simple format character or a compound indicator.

Format strings are composed according to the following grammar:

FormatString: FormatStringItem FormatString FormatStringItem: Character FormatSpecifier FormatSpecifier: '%' Parameters FormatIndicator

FormatIndicator: FormatCharacter CompoundIndicator FormatCharacter: see remark below CompoundIndicator: '(' FormatString '%)' '(' FormatString '%|' Delimiter '%)' Delimiter empty Character Delimiter

Parameters: Position Flags Width Precision Separator Position: empty Integer '$'** *Integer* **':'** *Integer* **'$' Integer ':' '$'** *Flags*: *empty* *Flag* *Flags* *Flag*: **'-'**|**'+'**|**'&nbsp;'**|**'0'**|**'#'**|**'='** *Width*: *OptionalPositionalInteger* *Precision*: *empty* **'.'** *OptionalPositionalInteger* *Separator*: *empty* **','** *OptionalInteger* **','** *OptionalInteger* **'?'** *OptionalInteger*: *empty* *Integer* **'*'** *OptionalPositionalInteger*: *OptionalInteger* **'*'** *Integer* **'$'

Character '%%' AnyCharacterExceptPercent Integer: NonZeroDigit Digits Digits: empty Digit Digits NonZeroDigit: '1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' Digit: '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'

Note

FormatCharacter is unspecified. It can be any character that has no other purpose in this grammar, but it is recommended to assign (lower- and uppercase) letters.

Note

The Parameters of a CompoundIndicator are currently limited to a '-' flag.

Format Indicator

The format indicator can either be a single character or an expression surrounded by '%(' and '%)'. It specifies the basic manner in which a value will be formatted and is the minimum requirement to format a value.

The following characters can be used as format characters:

FormatCharacter Semantics
's'
To be formatted in a human readable format.
Can be used with all types.
'c'
To be formatted as a character.
'd'
To be formatted as a signed decimal integer.
'u'
To be formatted as a decimal image of the underlying bit representation.
'b'
To be formatted as a binary image of the underlying bit representation.
'o'
To be formatted as an octal image of the underlying bit representation.
'x' / 'X'
To be formatted as a hexadecimal image of the underlying bit representation.
'e' / 'E'
To be formatted as a real number in decimal scientific notation.
'f' / 'F'
To be formatted as a real number in decimal natural notation.
'g' / 'G'
To be formatted as a real number in decimal short notation.
Depending on the number, a scientific notation or
a natural notation is used.
'a' / 'A'
To be formatted as a real number in hexadecimal scientific notation.
'r'
To be formatted as raw bytes.
The output may not be printable and depends on endianness.

The compound indicator can be used to describe compound types like arrays or structs in more detail. A compound type is enclosed within '%(' and '%)'. The enclosed sub-format string is applied to individual elements. The trailing portion of the sub-format string following the specifier for the element is interpreted as the delimiter, and is therefore omitted following the last element. The '%|' specifier may be used to explicitly indicate the start of the delimiter, so that the preceding portion of the string will be included following the last element.

The format string inside of the compound indicator should contain exactly one format specifier (two in case of associative arrays), which specifies the formatting mode of the elements of the compound type. This format specifier can be a compound indicator itself.

Note

Inside a compound indicator, strings and characters are escaped automatically. To avoid this behavior, use "%-(" instead of "%(".

Flags

There are several flags that affect the outcome of the formatting.

Flag Semantics
'-'
When the formatted result is shorter than the value
given by the width parameter, the output is left
justified. Without the '-' flag, the output remains
right justified.

There are two exceptions where the '-' flag has a different meaning: (1) with 'r' it denotes to use little endian and (2) in case of a compound indicator it means that no special handling of the members is applied. | | '=' | When the formatted result is shorter than the value given by the width parameter, the output is centered. If the central position is not possible it is moved slightly to the right. In this case, if '-' flag is present in addition to the '=' flag, it is moved slightly to the left. | | '+'&nbsp;/&nbsp;*'&nbsp;'* | Applies to numerical values. By default, positive numbers are not formatted to include the + sign. With one of these two flags present, positive numbers are preceded by a plus sign or a space. When both flags are present, a plus sign is used.

In case of 'r', a big endian format is used. | | '0' | Is applied to numerical values that are printed right justified. If the zero flag is present, the space left to the number is filled with zeros instead of spaces. | | '#' | Denotes that an alternative output must be used. This depends on the type to be formatted and the format character used. See the sections below for more information. |

Width, Precision and Separator

The width parameter specifies the minimum width of the result.

The meaning of precision depends on the format indicator. For integers it denotes the minimum number of digits printed, for real numbers it denotes the number of fractional digits and for strings and compound types it denotes the maximum number of elements that are included in the output.

A separator is used for formatting numbers. If it is specified, the output is divided into chunks of three digits, separated by a ','. The number of digits in a chunk can be given explicitly by providing a number or a ''* after the ','.

In all three cases the number of digits can be replaced by a ''*. In this scenario, the next argument is used as the number of digits. If the argument is a negative number, the precision and separator parameters are considered unspecified. For width, the absolute value is used and the '-' flag is set.

The separator can also be followed by a '?'. In that case, an additional argument is used to specify the symbol that should be used to separate the chunks.

Position

By default, the arguments are processed in the provided order. With the position parameter it is possible to address arguments directly. It is also possible to denote a series of arguments with two numbers separated by ':', that are all processed in the same way. The second number can be omitted. In that case the series ends with the last argument.

It's also possible to use positional arguments for width, precision and separator by adding a number and a '$' after the ''*.

Types

This section describes the result of combining types with format characters. It is organized in 2 subsections: a list of general information regarding the formatting of types in the presence of format characters and a table that contains details for every available combination of type and format character.

When formatting types, the following rules apply:

  • If the format character is upper case, the resulting string will be formatted using upper case letters.

  • The default precision for floating point numbers is 6 digits.

  • Rounding of floating point numbers adheres to the rounding mode of the floating point unit, if available.

  • The floating point values NaN and Infinity are formatted as nan and inf, possibly preceded by '+' or '-' sign.

  • Formatting reals is only supported for 64 bit reals and 80 bit reals. All other reals are cast to double before they are formatted. This will cause the result to be inf for very large numbers.

  • Characters and strings formatted with the 's' format character inside of compound types are surrounded by single and double quotes and unprintable characters are escaped. To avoid this, a '-' flag can be specified for the compound specifier (e.g. "%-(%s%)" instead of "%(%s%)" ).

  • Structs, unions, classes and interfaces are formatted by calling a toString method if available. See module std.format.write for more details.

  • Only part of these combinations can be used for reading. See module std.format.read for more detailed information.

This table contains descriptions for every possible combination of type and format character:

<th scope="col" width="20%">Type</th> <th scope="col" width="20%">Format Character</th> Formatted as...
<td rowspan="1">null</td> 's'
null

|<td rowspan="3">bool</td> 's' | false or true |

| 'b', 'd', 'o', 'u', 'x', 'X' | As the integrals 0 or 1 with the same format character.

Please note, that 'o' and 'x' with '#' flag might produce unexpected results due to special handling of the value 0. |

| 'r' | \0 or \1 |

|<td rowspan="4">Integral</td> 's', 'd' | A signed decimal number. The '#' flag is ignored. |

| 'b', 'o', 'u', 'x', 'X' | An unsigned binary, decimal, octal or hexadecimal number.

In case of 'o' and 'x', the '#' flag denotes that the number must be preceded by 0 and 0x, with the exception of the value 0, where this does not apply. For 'b' and 'u' the '#' flag has no effect. |

| 'e', 'E', 'f', 'F', 'g', 'G', 'a', 'A' | As a floating point value with the same specifier.

Default precision is large enough to add all digits of the integral value.

In case of 'a' and 'A', the integral digit can be any hexadecimal digit. |

| 'r' | Characters taken directly from the binary representation. |

|<td rowspan="5">Floating Point</td> 'e', 'E' | Scientific notation: Exactly one integral digit followed by a dot and fractional digits, followed by the exponent. The exponent is formatted as 'e' followed by a '+' or '-' sign, followed by at least two digits.

When there are no fractional digits and the '#' flag is not present, the dot is omitted. |

| 'f', 'F' | Natural notation: Integral digits followed by a dot and fractional digits.

When there are no fractional digits and the '#' flag is not present, the dot is omitted.

Please note: the difference between 'f' and 'F' is only visible for NaN and Infinity. |

| 's', 'g', 'G' | Short notation: If the absolute value is larger than 10 ^^ precision or smaller than 0.0001, the scientific notation is used. If not, the natural notation is applied.

In both cases precision denotes the count of all digits, including the integral digits. Trailing zeros (including a trailing dot) are removed.

If '#' flag is present, trailing zeros are not removed. |

| 'a', 'A' | Hexadecimal scientific notation: 0x followed by 1 (or 0 in case of value zero or denormalized number) followed by a dot, fractional digits in hexadecimal notation and an exponent. The exponent is build by p, followed by a sign and the exponent in decimal notation.

When there are no fractional digits and the '#' flag is not present, the dot is omitted. |

| 'r' | Characters taken directly from the binary representation. |

|<td rowspan="3">Character</td> 's', 'c' | As the character.

Inside of a compound indicator 's' is treated differently: The character is surrounded by single quotes and non printable characters are escaped. This can be avoided by preceding the compound indicator with a '-' flag (e.g. "%-(%s%)"). |

| 'b', 'd', 'o', 'u', 'x', 'X' | As the integral that represents the character. |

| 'r' | Characters taken directly from the binary representation. |

|<td rowspan="3">String</td> 's' | The sequence of characters that form the string.

Inside of a compound indicator the string is surrounded by double quotes and non printable characters are escaped. This can be avoided by preceding the compound indicator with a '-' flag (e.g. "%-(%s%)"). |

| 'r' | The sequence of characters, each formatted with 'r'. |

| compound | As an array of characters. |

|<td rowspan="3">Array</td> 's' | When the elements are characters, the array is formatted as a string. In all other cases the array is surrounded by square brackets and the elements are separated by a comma and a space. If the elements are strings, they are surrounded by double quotes and non printable characters are escaped. |

| 'r' | The sequence of the elements, each formatted with 'r'. |

| compound | The sequence of the elements, each formatted according to the specifications given inside of the compound specifier. |

|<td rowspan="2">Associative Array</td> 's' | As a sequence of the elements in unpredictable order. The output is surrounded by square brackets. The elements are separated by a comma and a space. The elements are formatted as key:value. |

| compound | As a sequence of the elements in unpredictable order. Each element is formatted according to the specifications given inside of the compound specifier. The first specifier is used for formatting the key and the second specifier is used for formatting the value. The order can be changed with positional arguments. For example "%(%2$s (%1$s), %)" will write the value, followed by the key in parenthesis. |

|<td rowspan="2">Enum</td> 's' | The name of the value. If the name is not available, the base value is used, preceeded by a cast. |

| All, but 's' | Enums can be formatted with all format characters that can be used with the base value. In that case they are formatted like the base value. |

|<td rowspan="3">Input Range</td> 's' | When the elements of the range are characters, they are written like a string. In all other cases, the elements are enclosed by square brackets and separated by a comma and a space. |

| 'r' | The sequence of the elements, each formatted with 'r'. |

| compound | The sequence of the elements, each formatted according to the specifications given inside of the compound specifier. |

|<td rowspan="1">Struct</td> 's' | When the struct has neither an applicable toString nor is an input range, it is formatted as follows: StructType(field1, field2, ...). |

|<td rowspan="1">Class</td> 's' | When the class has neither an applicable toString nor is an input range, it is formatted as the fully qualified name of the class. |

|<td rowspan="1">Union</td> 's' | When the union has neither an applicable toString nor is an input range, it is formatted as its base name. |

|<td rowspan="2">Pointer</td> 's' | A null pointer is formatted as 'null'. All other pointers are formatted as hexadecimal numbers with the format character 'X'. |

| 'x', 'X' | Formatted as a hexadecimal number. |

|<td rowspan="3">SIMD vector</td> 's' | The array is surrounded by square brackets and the elements are separated by a comma and a space. |

| 'r' | The sequence of the elements, each formatted with 'r'. |

| compound | The sequence of the elements, each formatted according to the specifications given inside of the compound specifier. |

|<td rowspan="1">Delegate</td> 's', 'r', compound | As the .stringof of this delegate treated as a string.

Please note: The implementation is currently buggy and its use is discouraged. |

Source

std/format/package.d

Examples

Simple use:

// Easiest way is to use `%s` everywhere:
assert(format("I got %s %s for %s euros.", 30, "eggs", 5.27) == "I got 30 eggs for 5.27 euros.");

// Other format characters provide more control:
assert(format("I got %b %(%X%) for %f euros.", 30, "eggs", 5.27) == "I got 11110 65676773 for 5.270000 euros.");

Compound specifiers allow formatting arrays and other compound types:

/*
The trailing end of the sub-format string following the specifier for
each item is interpreted as the array delimiter, and is therefore
omitted following the last array item:
 */
    assert(format("My items are %(%s %).", [1,2,3]) == "My items are 1 2 3.");
    assert(format("My items are %(%s, %).", [1,2,3]) == "My items are 1, 2, 3.");

/*
The "%|" delimiter specifier may be used to indicate where the
delimiter begins, so that the portion of the format string prior to
it will be retained in the last array element:
 */
    assert(format("My items are %(-%s-%|, %).", [1,2,3]) == "My items are -1-, -2-, -3-.");

/*
These compound format specifiers may be nested in the case of a
nested array argument:
 */
    auto mat = [[1, 2, 3],
                [4, 5, 6],
                [7, 8, 9]];

    assert(format("%(%(%d %) - %)", mat), "1 2 3 - 4 5 6 - 7 8 9");
    assert(format("[%(%(%d %) - %)]", mat), "[1 2 3 - 4 5 6 - 7 8 9]");
    assert(format("[%([%(%d %)]%| - %)]", mat), "[1 2 3] - [4 5 6] - [7 8 9]");

/*
Strings and characters are escaped automatically inside compound
format specifiers. To avoid this behavior, use "%-(" instead of "%(":
 */
    assert(format("My friends are %s.", ["John", "Nancy"]) == `My friends are ["John", "Nancy"].`);
    assert(format("My friends are %(%s, %).", ["John", "Nancy"]) == `My friends are "John", "Nancy".`);
    assert(format("My friends are %-(%s, %).", ["John", "Nancy"]) == `My friends are John, Nancy.`);

Using parameters:

// Flags can be used to influence to outcome:
assert(format("%g != %+#g", 3.14, 3.14) == "3.14 != +3.14000");

// Width and precision help to arrange the formatted result:
assert(format(">%10.2f<", 1234.56789) == ">   1234.57<");

// Numbers can be grouped:
assert(format("%,4d", int.max) == "21,4748,3647");

// It's possible to specify the position of an argument:
assert(format("%3$s %1$s", 3, 17, 5) == "5 3");

Providing parameters as arguments:

// Width as argument
assert(format(">%*s<", 10, "abc") == ">       abc<");

// Precision as argument
assert(format(">%.*f<", 5, 123.2) == ">123.20000<");

// Grouping as argument
assert(format("%,*d", 1, int.max) == "2,1,4,7,4,8,3,6,4,7");

// Grouping separator as argument
assert(format("%,3?d", '_', int.max) == "2_147_483_647");

// All at once
assert(format("%*.*,*?d", 20, 15, 6, '/', int.max) == "   000/002147/483647");
@copyrightCopyright The D Language Foundation 2000-2021.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, and Kenji Hara
format
:
(alias template) format = std.format.format(Char, Args...)(in Char[] fmt, Args args) if (isSomeChar!Char)

Converts its arguments according to a format string into a string.

The second version of format takes the format string as template argument. In this case, it is checked for consistency at compile-time and produces slightly faster code, because the length of the output buffer can be estimated in advance.

Params: fmt = a $(MREF_ALTTEXT format string, std,format) args = a variadic list of arguments to be formatted Char = character type of fmt Args = a variadic list of types of the arguments

Returns: The formatted string.

Throws: A $(LREF FormatException) if formatting did not succeed.

See_Also: $(LREF sformat) for a variant, that tries to avoid garbage collection.

format
;
import
(package) std
std
.
(package) std.math
math
.
(module) std.math.rounding

This is a submodule of std.math.

It contains several functions for rounding floating point numbers.

Source

std/math/rounding.d

@copyrightCopyright The D Language Foundation 2000 - 2011. D implementations of floor, ceil, and lrint functions are based on the CEPHES math library, which is Copyright (C) 2001 Stephen L. Moshier <steve@moshier.net> and are incorporated herein by permission of the author. The author reserves the right to distribute this material elsewhere under different copying permissions. These modifications are distributed here under the following terms:@licenseBoost License 1.0.@authorsWalter Bright, Don Clugston, Conversion of CEPHES math library to D by Iain Buclaw and David Nadlinger
rounding
:
(alias) floor = real std.math.rounding.floor(real x) pure nothrow @nogc @trusted

Returns the value of x rounded downward to the next integer (toward negative infinity).

floor
;
import
(package) std
std
.
(package) std.math
math
.
(module) std.math.traits

This is a submodule of std.math.

It contains several functions for introspection on numerical values.

Source

std/math/traits.d

@copyrightCopyright The D Language Foundation 2000 - 2011.@licenseBoost License 1.0.@authorsWalter Bright, Don Clugston, Conversion of CEPHES math library to D by Iain Buclaw and David Nadlinger
traits
:
(alias template) isFinite = std.math.traits.isFinite(X)(X x)

Determines if $(D_PARAM x) is finite. Params: x = a floating point number. Returns: `true` if $(D_PARAM x) is finite.

isFinite
;
if (!
(parameter) double v
v
.
bool std.math.traits.isFinite!double(double x) pure nothrow @nogc @trusted

Determines if x is finite.

Examples

assert( isFinite(1.23f));
assert( isFinite(float.max));
assert( isFinite(float.min_normal));
assert(!isFinite(float.nan));
assert(!isFinite(float.infinity));
@paramx a floating point number.@returnstrue if x is finite.
isFinite
)
return "null"; if (
(parameter) double v
v
==
double std.math.rounding.floor(double x) pure nothrow @nogc @trusted
floor
(
(parameter) double v
v
) &&
(parameter) double v
v
>= -9_007_199_254_740_992.0 &&
(parameter) double v
v
<= 9_007_199_254_740_992.0)
return
string std.format.format!("%.0f", double)(double __param_0) pure @safe

Examples

The format string can be checked at compile-time:

auto s = format!"%s is %s"("Pi", 3.14);
assert(s == "Pi is 3.14");

// This line doesn't compile, because 3.14 cannot be formatted with %d:
// s = format!"%s is %d"("Pi", 3.14);
format
!"%.0f"(
(parameter) double v
v
);
return
string std.format.format!("%.6g", double)(double __param_0) pure @safe

Examples

The format string can be checked at compile-time:

auto s = format!"%s is %s"("Pi", 3.14);
assert(s == "Pi is 3.14");

// This line doesn't compile, because 3.14 cannot be formatted with %d:
// s = format!"%s is %d"("Pi", 3.14);
format
!"%.6g"(
(parameter) double v
v
);
} @("benchJson.number.formatting") @safe unittest { assert(
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(double.
(constant) double double.nan = nan
nan
) == "null");
assert(
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(double.
(constant) double double.infinity = inf
infinity
) == "null");
assert(
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(3_823_300.0) == "3823300", "integral doubles print as integers");
assert(
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(0.1) == "0.1");
assert(
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(1.651754321e8) == "1.65175e+08", "6 significant digits");
} /// The row's counting-pass iteration count: every counter tier shares one /// per-pass count, so the first present source carries it. `0` = no counting /// pass ran. private ulong
ulong sparkles.test_runner.bench_json.countIterations(in sparkles.test_runner.bench.BenchStats row) pure nothrow @nogc @safe

The row's counting-pass iteration count: every counter tier shares one per-pass count, so the first present source carries it. 0 = no counting pass ran.

countIterations
(in
(struct) sparkles.test_runner.bench.BenchStats

Summary statistics of one benchmark row, in nanoseconds per iteration. A row with a non-empty error is a failure row (its timing fields are unset).

BenchStats
(parameter) const(sparkles.test_runner.bench.BenchStats) row
row
) @safe pure nothrow @nogc
{ if (!
(parameter) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) std.typecons.Nullable!(PerfStats) sparkles.test_runner.bench.BenchStats.perf

hardware counters under --perf`` (empty otherwise)

perf
.
bool std.typecons.Nullable!(sparkles.test_runner.perf.PerfStats).isNull() const pure nothrow @nogc @property @safe

Check if this is in the null state.

@returnstrue iff this is in the null state, otherwise false.
isNull
)
return
(parameter) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) std.typecons.Nullable!(PerfStats) sparkles.test_runner.bench.BenchStats.perf

hardware counters under --perf`` (empty otherwise)

perf
.
inout(sparkles.test_runner.perf.PerfStats) std.typecons.Nullable!(sparkles.test_runner.perf.PerfStats).get() inout pure nothrow @nogc @property ref @safe

Gets the value if not null. If this is in the null state, and the optional parameter fallback was provided, it will be returned. Without fallback, calling get with a null state is invalid.

When the fallback type is different from the Nullable type, ``get(T) returns the common type.

@paramfallback the value to return in case the Nullable is null.@returnsThe value held internally by this Nullable.
get
.
(field) ulong sparkles.test_runner.perf.PerfStats.iters

counting-pass iterations

iters
;
if (!
(parameter) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) std.typecons.Nullable!(Tier0Stats) sparkles.test_runner.bench.BenchStats.tier0

cheap /proc counters when a tier0 metric is selected

tier0
.
bool std.typecons.Nullable!(sparkles.test_runner.tier0.Tier0Stats).isNull() const pure nothrow @nogc @property @safe

Check if this is in the null state.

@returnstrue iff this is in the null state, otherwise false.
isNull
)
return
(parameter) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) std.typecons.Nullable!(Tier0Stats) sparkles.test_runner.bench.BenchStats.tier0

cheap /proc counters when a tier0 metric is selected

tier0
.
inout(sparkles.test_runner.tier0.Tier0Stats) std.typecons.Nullable!(sparkles.test_runner.tier0.Tier0Stats).get() inout pure nothrow @nogc @property ref @safe

Gets the value if not null. If this is in the null state, and the optional parameter fallback was provided, it will be returned. Without fallback, calling get with a null state is invalid.

When the fallback type is different from the Nullable type, ``get(T) returns the common type.

@paramfallback the value to return in case the Nullable is null.@returnsThe value held internally by this Nullable.
get
.
(field) ulong sparkles.test_runner.tier0.Tier0Stats.iters

counting-pass iterations

iters
;
if (!
(parameter) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) std.typecons.Nullable!(SyscallStats) sparkles.test_runner.bench.BenchStats.syscalls

syscall tracepoint counts under --syscalls``

syscalls
.
bool std.typecons.Nullable!(sparkles.test_runner.syscalls.SyscallStats).isNull() const pure nothrow @nogc @property @safe

Check if this is in the null state.

@returnstrue iff this is in the null state, otherwise false.
isNull
)
return
(parameter) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) std.typecons.Nullable!(SyscallStats) sparkles.test_runner.bench.BenchStats.syscalls

syscall tracepoint counts under --syscalls``

syscalls
.
inout(sparkles.test_runner.syscalls.SyscallStats) std.typecons.Nullable!(sparkles.test_runner.syscalls.SyscallStats).get() inout pure nothrow @nogc @property ref @safe

Gets the value if not null. If this is in the null state, and the optional parameter fallback was provided, it will be returned. Without fallback, calling get with a null state is invalid.

When the fallback type is different from the Nullable type, ``get(T) returns the common type.

@paramfallback the value to return in case the Nullable is null.@returnsThe value held internally by this Nullable.
get
.
(field) ulong sparkles.test_runner.syscalls.SyscallStats.iters
iters
;
if (!
(parameter) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) std.typecons.Nullable!(RawStats) sparkles.test_runner.bench.BenchStats.raw

raw hardware events named via --metrics=raw:…

raw
.
bool std.typecons.Nullable!(sparkles.test_runner.raw.RawStats).isNull() const pure nothrow @nogc @property @safe

Check if this is in the null state.

@returnstrue iff this is in the null state, otherwise false.
isNull
)
return
(parameter) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) std.typecons.Nullable!(RawStats) sparkles.test_runner.bench.BenchStats.raw

raw hardware events named via --metrics=raw:…

raw
.
inout(sparkles.test_runner.raw.RawStats) std.typecons.Nullable!(sparkles.test_runner.raw.RawStats).get() inout pure nothrow @nogc @property ref @safe

Gets the value if not null. If this is in the null state, and the optional parameter fallback was provided, it will be returned. Without fallback, calling get with a null state is invalid.

When the fallback type is different from the Nullable type, ``get(T) returns the common type.

@paramfallback the value to return in case the Nullable is null.@returnsThe value held internally by this Nullable.
get
.
(field) ulong sparkles.test_runner.raw.RawStats.iters

counting-pass iterations

iters
;
return 0; } /// RFC 8259 string escaping: `"`, `\`, and control characters. package(sparkles.test_runner)
(alias) object.string = string
string
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(scope const(char)[]
(parameter) const(char)[] s
s
) @safe pure
{ import
(package) std
std
.
(module) std.array

Functions and types that manipulate built-in arrays and associative arrays.

This module provides all kinds of functions to create, manipulate or convert arrays:

Function Name Description

| array | Returns a copy of the input in a newly allocated dynamic array. | | appender | Returns a new Appender or RefAppender initialized with a given array. | | assocArray | Returns a newly allocated associative array from a range/ranges of keys and values. | | byPair | Construct a range iterating over an associative array by key/value tuples. | | insertInPlace | Inserts into an existing array at a given position. | | join | Concatenates a range of ranges into one array. | | minimallyInitializedArray | Returns a new array of type T. | | replace | Returns a new array with all occurrences of a certain subrange replaced. | | replaceFirst | Returns a new array with the first occurrence of a certain subrange replaced. | | replaceInPlace | Replaces all occurrences of a certain subrange and puts the result into a given array. | | replaceInto | Replaces all occurrences of a certain subrange and puts the result into an output range. | | replaceLast | Returns a new array with the last occurrence of a certain subrange replaced. | | replaceSlice | Returns a new array with a given slice replaced. | | replicate | Creates a new array out of several copies of an input array or range. | | sameHead | Checks if the initial segments of two arrays refer to the same place in memory. | | sameTail | Checks if the final segments of two arrays refer to the same place in memory. | | split | Eagerly split a range or string into an array. | | staticArray | Creates a new static array from given data. | | uninitializedArray | Returns a new array of type T without initializing its elements. |

Source

std/array.d

@copyrightCopyright Andrei Alexandrescu 2008- and Jonathan M Davis 2011-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu and Jonathan M Davis
array
:
(alias template) appender = std.array.appender(A)() if (isDynamicArray!A)

Convenience function that returns an $(LREF Appender) instance, optionally initialized with array.

appender
;
import
(package) std
std
.
(module) std.format

This package provides string formatting functionality using printf style format strings.

Submodule Function Name Description
package
format
Converts its arguments according to a format string into a string.

| package | sformat | Converts its arguments according to a format string into a buffer. |

| package | FormatException | Signals a problem while formatting. |

| write | formattedWrite | Converts its arguments according to a format string and writes the result to an output range. |

| write | formatValue | Formats a value of any type according to a format specifier and writes the result to an output range. |

| read | formattedRead | Reads an input range according to a format string and stores the read values into its arguments. |

| read | unformatValue | Reads a value from the given input range and converts it according to a format specifier. |

| spec | FormatSpec | A general handler for format strings. |

| spec | singleSpec | Helper function that returns a FormatSpec for a single format specifier. |

Limitation

This package does not support localization, but adheres to the rounding mode of the floating point unit, if available.

Format Strings

The functions contained in this package use format strings. A format string describes the layout of another string for reading or writing purposes. A format string is composed of normal text interspersed with format specifiers. A format specifier starts with a percentage sign '%', optionally followed by one or more parameters and ends with a format indicator. A format indicator may be a simple format character or a compound indicator.

Format strings are composed according to the following grammar:

FormatString: FormatStringItem FormatString FormatStringItem: Character FormatSpecifier FormatSpecifier: '%' Parameters FormatIndicator

FormatIndicator: FormatCharacter CompoundIndicator FormatCharacter: see remark below CompoundIndicator: '(' FormatString '%)' '(' FormatString '%|' Delimiter '%)' Delimiter empty Character Delimiter

Parameters: Position Flags Width Precision Separator Position: empty Integer '$'** *Integer* **':'** *Integer* **'$' Integer ':' '$'** *Flags*: *empty* *Flag* *Flags* *Flag*: **'-'**|**'+'**|**'&nbsp;'**|**'0'**|**'#'**|**'='** *Width*: *OptionalPositionalInteger* *Precision*: *empty* **'.'** *OptionalPositionalInteger* *Separator*: *empty* **','** *OptionalInteger* **','** *OptionalInteger* **'?'** *OptionalInteger*: *empty* *Integer* **'*'** *OptionalPositionalInteger*: *OptionalInteger* **'*'** *Integer* **'$'

Character '%%' AnyCharacterExceptPercent Integer: NonZeroDigit Digits Digits: empty Digit Digits NonZeroDigit: '1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' Digit: '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'

Note

FormatCharacter is unspecified. It can be any character that has no other purpose in this grammar, but it is recommended to assign (lower- and uppercase) letters.

Note

The Parameters of a CompoundIndicator are currently limited to a '-' flag.

Format Indicator

The format indicator can either be a single character or an expression surrounded by '%(' and '%)'. It specifies the basic manner in which a value will be formatted and is the minimum requirement to format a value.

The following characters can be used as format characters:

FormatCharacter Semantics
's'
To be formatted in a human readable format.
Can be used with all types.
'c'
To be formatted as a character.
'd'
To be formatted as a signed decimal integer.
'u'
To be formatted as a decimal image of the underlying bit representation.
'b'
To be formatted as a binary image of the underlying bit representation.
'o'
To be formatted as an octal image of the underlying bit representation.
'x' / 'X'
To be formatted as a hexadecimal image of the underlying bit representation.
'e' / 'E'
To be formatted as a real number in decimal scientific notation.
'f' / 'F'
To be formatted as a real number in decimal natural notation.
'g' / 'G'
To be formatted as a real number in decimal short notation.
Depending on the number, a scientific notation or
a natural notation is used.
'a' / 'A'
To be formatted as a real number in hexadecimal scientific notation.
'r'
To be formatted as raw bytes.
The output may not be printable and depends on endianness.

The compound indicator can be used to describe compound types like arrays or structs in more detail. A compound type is enclosed within '%(' and '%)'. The enclosed sub-format string is applied to individual elements. The trailing portion of the sub-format string following the specifier for the element is interpreted as the delimiter, and is therefore omitted following the last element. The '%|' specifier may be used to explicitly indicate the start of the delimiter, so that the preceding portion of the string will be included following the last element.

The format string inside of the compound indicator should contain exactly one format specifier (two in case of associative arrays), which specifies the formatting mode of the elements of the compound type. This format specifier can be a compound indicator itself.

Note

Inside a compound indicator, strings and characters are escaped automatically. To avoid this behavior, use "%-(" instead of "%(".

Flags

There are several flags that affect the outcome of the formatting.

Flag Semantics
'-'
When the formatted result is shorter than the value
given by the width parameter, the output is left
justified. Without the '-' flag, the output remains
right justified.

There are two exceptions where the '-' flag has a different meaning: (1) with 'r' it denotes to use little endian and (2) in case of a compound indicator it means that no special handling of the members is applied. | | '=' | When the formatted result is shorter than the value given by the width parameter, the output is centered. If the central position is not possible it is moved slightly to the right. In this case, if '-' flag is present in addition to the '=' flag, it is moved slightly to the left. | | '+'&nbsp;/&nbsp;*'&nbsp;'* | Applies to numerical values. By default, positive numbers are not formatted to include the + sign. With one of these two flags present, positive numbers are preceded by a plus sign or a space. When both flags are present, a plus sign is used.

In case of 'r', a big endian format is used. | | '0' | Is applied to numerical values that are printed right justified. If the zero flag is present, the space left to the number is filled with zeros instead of spaces. | | '#' | Denotes that an alternative output must be used. This depends on the type to be formatted and the format character used. See the sections below for more information. |

Width, Precision and Separator

The width parameter specifies the minimum width of the result.

The meaning of precision depends on the format indicator. For integers it denotes the minimum number of digits printed, for real numbers it denotes the number of fractional digits and for strings and compound types it denotes the maximum number of elements that are included in the output.

A separator is used for formatting numbers. If it is specified, the output is divided into chunks of three digits, separated by a ','. The number of digits in a chunk can be given explicitly by providing a number or a ''* after the ','.

In all three cases the number of digits can be replaced by a ''*. In this scenario, the next argument is used as the number of digits. If the argument is a negative number, the precision and separator parameters are considered unspecified. For width, the absolute value is used and the '-' flag is set.

The separator can also be followed by a '?'. In that case, an additional argument is used to specify the symbol that should be used to separate the chunks.

Position

By default, the arguments are processed in the provided order. With the position parameter it is possible to address arguments directly. It is also possible to denote a series of arguments with two numbers separated by ':', that are all processed in the same way. The second number can be omitted. In that case the series ends with the last argument.

It's also possible to use positional arguments for width, precision and separator by adding a number and a '$' after the ''*.

Types

This section describes the result of combining types with format characters. It is organized in 2 subsections: a list of general information regarding the formatting of types in the presence of format characters and a table that contains details for every available combination of type and format character.

When formatting types, the following rules apply:

  • If the format character is upper case, the resulting string will be formatted using upper case letters.

  • The default precision for floating point numbers is 6 digits.

  • Rounding of floating point numbers adheres to the rounding mode of the floating point unit, if available.

  • The floating point values NaN and Infinity are formatted as nan and inf, possibly preceded by '+' or '-' sign.

  • Formatting reals is only supported for 64 bit reals and 80 bit reals. All other reals are cast to double before they are formatted. This will cause the result to be inf for very large numbers.

  • Characters and strings formatted with the 's' format character inside of compound types are surrounded by single and double quotes and unprintable characters are escaped. To avoid this, a '-' flag can be specified for the compound specifier (e.g. "%-(%s%)" instead of "%(%s%)" ).

  • Structs, unions, classes and interfaces are formatted by calling a toString method if available. See module std.format.write for more details.

  • Only part of these combinations can be used for reading. See module std.format.read for more detailed information.

This table contains descriptions for every possible combination of type and format character:

<th scope="col" width="20%">Type</th> <th scope="col" width="20%">Format Character</th> Formatted as...
<td rowspan="1">null</td> 's'
null

|<td rowspan="3">bool</td> 's' | false or true |

| 'b', 'd', 'o', 'u', 'x', 'X' | As the integrals 0 or 1 with the same format character.

Please note, that 'o' and 'x' with '#' flag might produce unexpected results due to special handling of the value 0. |

| 'r' | \0 or \1 |

|<td rowspan="4">Integral</td> 's', 'd' | A signed decimal number. The '#' flag is ignored. |

| 'b', 'o', 'u', 'x', 'X' | An unsigned binary, decimal, octal or hexadecimal number.

In case of 'o' and 'x', the '#' flag denotes that the number must be preceded by 0 and 0x, with the exception of the value 0, where this does not apply. For 'b' and 'u' the '#' flag has no effect. |

| 'e', 'E', 'f', 'F', 'g', 'G', 'a', 'A' | As a floating point value with the same specifier.

Default precision is large enough to add all digits of the integral value.

In case of 'a' and 'A', the integral digit can be any hexadecimal digit. |

| 'r' | Characters taken directly from the binary representation. |

|<td rowspan="5">Floating Point</td> 'e', 'E' | Scientific notation: Exactly one integral digit followed by a dot and fractional digits, followed by the exponent. The exponent is formatted as 'e' followed by a '+' or '-' sign, followed by at least two digits.

When there are no fractional digits and the '#' flag is not present, the dot is omitted. |

| 'f', 'F' | Natural notation: Integral digits followed by a dot and fractional digits.

When there are no fractional digits and the '#' flag is not present, the dot is omitted.

Please note: the difference between 'f' and 'F' is only visible for NaN and Infinity. |

| 's', 'g', 'G' | Short notation: If the absolute value is larger than 10 ^^ precision or smaller than 0.0001, the scientific notation is used. If not, the natural notation is applied.

In both cases precision denotes the count of all digits, including the integral digits. Trailing zeros (including a trailing dot) are removed.

If '#' flag is present, trailing zeros are not removed. |

| 'a', 'A' | Hexadecimal scientific notation: 0x followed by 1 (or 0 in case of value zero or denormalized number) followed by a dot, fractional digits in hexadecimal notation and an exponent. The exponent is build by p, followed by a sign and the exponent in decimal notation.

When there are no fractional digits and the '#' flag is not present, the dot is omitted. |

| 'r' | Characters taken directly from the binary representation. |

|<td rowspan="3">Character</td> 's', 'c' | As the character.

Inside of a compound indicator 's' is treated differently: The character is surrounded by single quotes and non printable characters are escaped. This can be avoided by preceding the compound indicator with a '-' flag (e.g. "%-(%s%)"). |

| 'b', 'd', 'o', 'u', 'x', 'X' | As the integral that represents the character. |

| 'r' | Characters taken directly from the binary representation. |

|<td rowspan="3">String</td> 's' | The sequence of characters that form the string.

Inside of a compound indicator the string is surrounded by double quotes and non printable characters are escaped. This can be avoided by preceding the compound indicator with a '-' flag (e.g. "%-(%s%)"). |

| 'r' | The sequence of characters, each formatted with 'r'. |

| compound | As an array of characters. |

|<td rowspan="3">Array</td> 's' | When the elements are characters, the array is formatted as a string. In all other cases the array is surrounded by square brackets and the elements are separated by a comma and a space. If the elements are strings, they are surrounded by double quotes and non printable characters are escaped. |

| 'r' | The sequence of the elements, each formatted with 'r'. |

| compound | The sequence of the elements, each formatted according to the specifications given inside of the compound specifier. |

|<td rowspan="2">Associative Array</td> 's' | As a sequence of the elements in unpredictable order. The output is surrounded by square brackets. The elements are separated by a comma and a space. The elements are formatted as key:value. |

| compound | As a sequence of the elements in unpredictable order. Each element is formatted according to the specifications given inside of the compound specifier. The first specifier is used for formatting the key and the second specifier is used for formatting the value. The order can be changed with positional arguments. For example "%(%2$s (%1$s), %)" will write the value, followed by the key in parenthesis. |

|<td rowspan="2">Enum</td> 's' | The name of the value. If the name is not available, the base value is used, preceeded by a cast. |

| All, but 's' | Enums can be formatted with all format characters that can be used with the base value. In that case they are formatted like the base value. |

|<td rowspan="3">Input Range</td> 's' | When the elements of the range are characters, they are written like a string. In all other cases, the elements are enclosed by square brackets and separated by a comma and a space. |

| 'r' | The sequence of the elements, each formatted with 'r'. |

| compound | The sequence of the elements, each formatted according to the specifications given inside of the compound specifier. |

|<td rowspan="1">Struct</td> 's' | When the struct has neither an applicable toString nor is an input range, it is formatted as follows: StructType(field1, field2, ...). |

|<td rowspan="1">Class</td> 's' | When the class has neither an applicable toString nor is an input range, it is formatted as the fully qualified name of the class. |

|<td rowspan="1">Union</td> 's' | When the union has neither an applicable toString nor is an input range, it is formatted as its base name. |

|<td rowspan="2">Pointer</td> 's' | A null pointer is formatted as 'null'. All other pointers are formatted as hexadecimal numbers with the format character 'X'. |

| 'x', 'X' | Formatted as a hexadecimal number. |

|<td rowspan="3">SIMD vector</td> 's' | The array is surrounded by square brackets and the elements are separated by a comma and a space. |

| 'r' | The sequence of the elements, each formatted with 'r'. |

| compound | The sequence of the elements, each formatted according to the specifications given inside of the compound specifier. |

|<td rowspan="1">Delegate</td> 's', 'r', compound | As the .stringof of this delegate treated as a string.

Please note: The implementation is currently buggy and its use is discouraged. |

Source

std/format/package.d

Examples

Simple use:

// Easiest way is to use `%s` everywhere:
assert(format("I got %s %s for %s euros.", 30, "eggs", 5.27) == "I got 30 eggs for 5.27 euros.");

// Other format characters provide more control:
assert(format("I got %b %(%X%) for %f euros.", 30, "eggs", 5.27) == "I got 11110 65676773 for 5.270000 euros.");

Compound specifiers allow formatting arrays and other compound types:

/*
The trailing end of the sub-format string following the specifier for
each item is interpreted as the array delimiter, and is therefore
omitted following the last array item:
 */
    assert(format("My items are %(%s %).", [1,2,3]) == "My items are 1 2 3.");
    assert(format("My items are %(%s, %).", [1,2,3]) == "My items are 1, 2, 3.");

/*
The "%|" delimiter specifier may be used to indicate where the
delimiter begins, so that the portion of the format string prior to
it will be retained in the last array element:
 */
    assert(format("My items are %(-%s-%|, %).", [1,2,3]) == "My items are -1-, -2-, -3-.");

/*
These compound format specifiers may be nested in the case of a
nested array argument:
 */
    auto mat = [[1, 2, 3],
                [4, 5, 6],
                [7, 8, 9]];

    assert(format("%(%(%d %) - %)", mat), "1 2 3 - 4 5 6 - 7 8 9");
    assert(format("[%(%(%d %) - %)]", mat), "[1 2 3 - 4 5 6 - 7 8 9]");
    assert(format("[%([%(%d %)]%| - %)]", mat), "[1 2 3] - [4 5 6] - [7 8 9]");

/*
Strings and characters are escaped automatically inside compound
format specifiers. To avoid this behavior, use "%-(" instead of "%(":
 */
    assert(format("My friends are %s.", ["John", "Nancy"]) == `My friends are ["John", "Nancy"].`);
    assert(format("My friends are %(%s, %).", ["John", "Nancy"]) == `My friends are "John", "Nancy".`);
    assert(format("My friends are %-(%s, %).", ["John", "Nancy"]) == `My friends are John, Nancy.`);

Using parameters:

// Flags can be used to influence to outcome:
assert(format("%g != %+#g", 3.14, 3.14) == "3.14 != +3.14000");

// Width and precision help to arrange the formatted result:
assert(format(">%10.2f<", 1234.56789) == ">   1234.57<");

// Numbers can be grouped:
assert(format("%,4d", int.max) == "21,4748,3647");

// It's possible to specify the position of an argument:
assert(format("%3$s %1$s", 3, 17, 5) == "5 3");

Providing parameters as arguments:

// Width as argument
assert(format(">%*s<", 10, "abc") == ">       abc<");

// Precision as argument
assert(format(">%.*f<", 5, 123.2) == ">123.20000<");

// Grouping as argument
assert(format("%,*d", 1, int.max) == "2,1,4,7,4,8,3,6,4,7");

// Grouping separator as argument
assert(format("%,3?d", '_', int.max) == "2_147_483_647");

// All at once
assert(format("%*.*,*?d", 20, 15, 6, '/', int.max) == "   000/002147/483647");
@copyrightCopyright The D Language Foundation 2000-2021.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, and Kenji Hara
format
:
(alias template) format = std.format.format(Char, Args...)(in Char[] fmt, Args args) if (isSomeChar!Char)

Converts its arguments according to a format string into a string.

The second version of format takes the format string as template argument. In this case, it is checked for consistency at compile-time and produces slightly faster code, because the length of the output buffer can be estimated in advance.

Params: fmt = a $(MREF_ALTTEXT format string, std,format) args = a variadic list of arguments to be formatted Char = character type of fmt Args = a variadic list of types of the arguments

Returns: The formatted string.

Throws: A $(LREF FormatException) if formatting did not succeed.

See_Also: $(LREF sformat) for a variant, that tries to avoid garbage collection.

format
;
auto
(local variable) std.array.Appender!string app
app
=
std.array.Appender!string std.array.appender!string() pure nothrow @safe

Convenience function that returns an Appender instance, optionally initialized with array.

appender
!
(alias) object.string = string
string
;
foreach (
(parameter) const(char) ch
ch
;
(parameter) const(char)[] s
s
)
switch (
(local variable) const(char) ch
ch
)
{ case '"':
(local variable) std.array.Appender!string app
app
~= `\"`; break;
case '\\':
(local variable) std.array.Appender!string app
app
~= `\\`; break;
case '\n':
(local variable) std.array.Appender!string app
app
~= `\n`; break;
case '\r':
(local variable) std.array.Appender!string app
app
~= `\r`; break;
case '\t':
(local variable) std.array.Appender!string app
app
~= `\t`; break;
default: if (
(local variable) const(char) ch
ch
< 0x20)
(local variable) std.array.Appender!string app
app
~=
string std.format.format!("\\u%04x", const(char))(const(char) __param_0) pure @safe

Examples

The format string can be checked at compile-time:

auto s = format!"%s is %s"("Pi", 3.14);
assert(s == "Pi is 3.14");

// This line doesn't compile, because 3.14 cannot be formatted with %d:
// s = format!"%s is %d"("Pi", 3.14);
format
!"\\u%04x"(
(local variable) const(char) ch
ch
);
else
(local variable) std.array.Appender!string app
app
~=
(local variable) const(char) ch
ch
;
} return
(local variable) std.array.Appender!string app
app
[];
} /// The full report document: `{schema, meta, columns, rows}`, pretty-printed /// with 2-space indent. `rows` keep measurement order (grouping/sorting are /// presentation concerns; the group dimensions travel in each row's `labels`, /// whose keys are emitted sorted). `columns` describe the available catalog /// metrics for these rows, so `metrics` keys match `--list-metrics` names. /// Schema 2 adds the optional per-row `estimatedMetrics` array naming the /// `metrics` keys whose values are multiplex-scaled estimates (absent = /// every metric exact), and — when `@workload` tests ran — a `windows` /// sibling array of window objects: wall decomposition fields (`null` = /// unattributable on this host, exactly the table's em dash) and one nested /// per-source totals object per attached source. Window values are window /// TOTALS with their own field names, deliberately never the per-iteration /// `metrics` catalog keys — reusing those names would quietly overload /// their semantics. A run without workloads emits no `windows` key and is /// byte-identical to the pre-window document.
(alias) object.string = string
string
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
(in
(struct) sparkles.test_runner.bench.BenchStats

Summary statistics of one benchmark row, in nanoseconds per iteration. A row with a non-empty error is a failure row (its timing fields are unset).

BenchStats
[]
(parameter) const(sparkles.test_runner.bench.BenchStats[]) rows
rows
, in
(struct) sparkles.test_runner.bench_json.BenchMeta

Provenance and the effective measurement knobs stamped onto a report, so a committed baseline is self-describing (the budget it was measured under is part of the data, not tribal knowledge).

BenchMeta
(parameter) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
,
in
(struct) sparkles.test_runner.workload.WorkloadWindow

One measured window. Deliberately NOT BenchStats: its per-iteration timing fields would misrepresent a single window — counter stats here are window totals (iters == 1).

WorkloadWindow
[]
(parameter) const(sparkles.test_runner.workload.WorkloadWindow[]) windows
windows
= null) @safe
{ import
(package) std
std
.
(package) std.algorithm
algorithm
.
(module) std.algorithm.sorting

This is a submodule of std.algorithm. It contains generic sorting algorithms.

Function Name Description
completeSort If a = [10, 20, 30] and b = [40, 6, 15], then completeSort(a, b) leaves a = [6, 10, 15] and b = [20, 30, 40]. The range a must be sorted prior to the call, and as a result the combination ``chain(a, b) is sorted.
isPartitioned isPartitioned!"a < 0"([-1, -2, 1, 0, 2]) returns true because the predicate is true for a portion of the range and false afterwards.
isSorted isSorted([1, 1, 2, 3]) returns true.
isStrictlyMonotonic isStrictlyMonotonic([1, 1, 2, 3]) returns false.
ordered ordered(1, 1, 2, 3) returns true.
strictlyOrdered strictlyOrdered(1, 1, 2, 3) returns false.
makeIndex Creates a separate index for a range.
merge Lazily merges two or more sorted ranges.
multiSort Sorts by multiple keys.
nextEvenPermutation Computes the next lexicographically greater even permutation of a range in-place.
nextPermutation Computes the next lexicographically greater permutation of a range in-place.
nthPermutation Computes the nth permutation of a range in-place.
partialSort If a = [5, 4, 3, 2, 1], then partialSort(a, 3) leaves a[0 .. 3] = [1, 2, 3]. The other elements of a are left in an unspecified order.
partition Partitions a range according to a unary predicate.
partition3 Partitions a range according to a binary predicate in three parts (less than, equal, greater than the given pivot). Pivot is not given as an index, but instead as an element independent from the range's content.
pivotPartition Partitions a range according to a binary predicate in two parts: less than or equal, and greater than or equal to the given pivot, passed as an index in the range.
schwartzSort Sorts with the help of the Schwartzian transform.
sort Sorts.
topN Separates the top elements in a range, akin to Quickselect.
topNCopy Copies out the top elements of a range.
topNIndex Builds an index of the top elements of a range.

Source

std/algorithm/sorting.d

@copyrightAndrei Alexandrescu 2008-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu
sorting
:
(alias template) sort = std.algorithm.sorting.sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range r)

Sorts a random-access range according to the predicate less.

Performs $(BIGOH r.length * log(r.length)) evaluations of `less`. If `less` involves expensive computations on the _sort key, it may be worthwhile to use $(LREF schwartzSort) instead.

Stable sorting requires hasAssignableElements!Range to be true.

sort returns a $(REF SortedRange, std,range) over the original range, allowing functions that can take advantage of sorted data to know that the range is sorted and adjust accordingly. The $(REF SortedRange, std,range) is a wrapper around the original range, so both it and the original range are sorted. Other functions can't know that the original range has been sorted, but they $(I can) know that $(REF SortedRange, std,range) has been sorted.

Preconditions:

The predicate is expected to satisfy certain rules in order for sort to behave as expected - otherwise, the program may fail on certain inputs (but not others) when not compiled in release mode, due to the cursory assumeSorted check. Specifically, sort expects less(a,b) && less(b,c) to imply less(a,c) (transitivity), and, conversely, !less(a,b) && !less(b,c) to imply !less(a,c). Note that the default predicate ("a < b") does not always satisfy these conditions for floating point types, because the expression will always be false when either a or b is NaN. Use $(REF cmp, std,math) instead.

Params: less = The predicate to sort by. ss = The swapping strategy to use. r = The range to sort.

Returns: The initial range wrapped as a SortedRange with the predicate binaryFun!less.

Algorithms: $(HTTP en.wikipedia.org/wiki/Introsort, Introsort) is used for unstable sorting and $(HTTP en.wikipedia.org/wiki/Timsort, Timsort) is used for stable sorting. Each algorithm has benefits beyond stability. Introsort is generally faster but Timsort may achieve greater speeds on data with low entropy or if predicate calls are expensive. Introsort performs no allocations whereas Timsort will perform one or more allocations per call. Both algorithms have $(BIGOH n log n) worst-case time complexity.

See_Also: $(REF assumeSorted, std,range)$(BR) $(REF SortedRange, std,range)$(BR) $(REF SwapStrategy, std,algorithm,mutation)$(BR) $(REF binaryFun, std,functional)

sort
;
import
(package) std
std
.
(module) std.array

Functions and types that manipulate built-in arrays and associative arrays.

This module provides all kinds of functions to create, manipulate or convert arrays:

Function Name Description

| array | Returns a copy of the input in a newly allocated dynamic array. | | appender | Returns a new Appender or RefAppender initialized with a given array. | | assocArray | Returns a newly allocated associative array from a range/ranges of keys and values. | | byPair | Construct a range iterating over an associative array by key/value tuples. | | insertInPlace | Inserts into an existing array at a given position. | | join | Concatenates a range of ranges into one array. | | minimallyInitializedArray | Returns a new array of type T. | | replace | Returns a new array with all occurrences of a certain subrange replaced. | | replaceFirst | Returns a new array with the first occurrence of a certain subrange replaced. | | replaceInPlace | Replaces all occurrences of a certain subrange and puts the result into a given array. | | replaceInto | Replaces all occurrences of a certain subrange and puts the result into an output range. | | replaceLast | Returns a new array with the last occurrence of a certain subrange replaced. | | replaceSlice | Returns a new array with a given slice replaced. | | replicate | Creates a new array out of several copies of an input array or range. | | sameHead | Checks if the initial segments of two arrays refer to the same place in memory. | | sameTail | Checks if the final segments of two arrays refer to the same place in memory. | | split | Eagerly split a range or string into an array. | | staticArray | Creates a new static array from given data. | | uninitializedArray | Returns a new array of type T without initializing its elements. |

Source

std/array.d

@copyrightCopyright Andrei Alexandrescu 2008- and Jonathan M Davis 2011-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu and Jonathan M Davis
array
:
(alias template) appender = std.array.appender(A)() if (isDynamicArray!A)

Convenience function that returns an $(LREF Appender) instance, optionally initialized with array.

appender
;
import
(package) std
std
.
(module) std.conv

A one-stop shop for converting values from one type to another.

Category Functions
Generic asOriginalType castFrom parse to toChars bitCast
Strings text wtext dtext writeText writeWText writeDText hexString
Numeric octal roundTo signed unsigned
Exceptions ConvException ConvOverflowException

Source

std/conv.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Shin Fujishiro, Adam D. Ruppe, Kenji Hara
conv
:
(alias template) to = std.conv.to(T)

The to template converts a value from one type _to another. The source type is deduced and the target type must be specified, for example the expression to!int(42.0) converts the number 42 from double _to int. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., to!double(42) does not do any checking because any int fits in a double.

Conversions from string _to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings _to signed types, the grammar recognized is: $(PRE $(I Integer): $(I Sign UnsignedInteger) $(I UnsignedInteger) $(I Sign): $(B +) $(B -))

For conversion _to unsigned types, the grammar recognized is: $(PRE $(I UnsignedInteger): $(I DecimalDigit) $(I DecimalDigit) $(I UnsignedInteger))

to
;
auto
(local variable) std.array.Appender!string o
o
=
std.array.Appender!string std.array.appender!string() pure nothrow @safe

Convenience function that returns an Appender instance, optionally initialized with array.

appender
!
(alias) object.string = string
string
;
(local variable) std.array.Appender!string o
o
~= "{\n";
(local variable) std.array.Appender!string o
o
~= " \"schema\": 2,\n";
(local variable) std.array.Appender!string o
o
~= " \"meta\": {\n";
(local variable) std.array.Appender!string o
o
~= " \"date\": \"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(parameter) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
.
(field) string sparkles.test_runner.bench_json.BenchMeta.date

ISO day, e.g. "2026-07-10"

date
) ~ "\",\n";
(local variable) std.array.Appender!string o
o
~= " \"hostname\": \"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(parameter) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
.
(field) string sparkles.test_runner.bench_json.BenchMeta.hostname

"" when unavailable

hostname
) ~ "\",\n";
(local variable) std.array.Appender!string o
o
~= " \"os\": \"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(parameter) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
.
(field) string sparkles.test_runner.bench_json.BenchMeta.os
os
) ~ "\",\n";
(local variable) std.array.Appender!string o
o
~= " \"arch\": \"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(parameter) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
.
(field) string sparkles.test_runner.bench_json.BenchMeta.arch
arch
) ~ "\",\n";
(local variable) std.array.Appender!string o
o
~= " \"compiler\": \"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(parameter) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
.
(field) string sparkles.test_runner.bench_json.BenchMeta.compiler

e.g. "LDC (front-end 2.111)"

compiler
) ~ "\",\n";
(local variable) std.array.Appender!string o
o
~= " \"cpu\": \"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(parameter) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
.
(field) string sparkles.test_runner.bench_json.BenchMeta.cpu

/proc/cpuinfo model name; "" off Linux

cpu
) ~ "\",\n";
(local variable) std.array.Appender!string o
o
~= " \"minSampleTimeMs\": " ~
(parameter) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
.
(field) long sparkles.test_runner.bench_json.BenchMeta.minSampleTimeMs

effective per-sample/total budget (--bench-min-time)

minSampleTimeMs
.
string std.conv.to!string.to!(const(long))(const(long) __param_0) pure nothrow @safe

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!
(alias) object.string = string
string
~ ",\n";
(local variable) std.array.Appender!string o
o
~= " \"sampleCount\": " ~
(parameter) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
.
(field) uint sparkles.test_runner.bench_json.BenchMeta.sampleCount

effective BenchConfig.sampleCount

sampleCount
.
string std.conv.to!string.to!(const(uint))(const(uint) __param_0) pure nothrow @safe

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!
(alias) object.string = string
string
;
// Suite-registered provenance (benchProvenance) — only when present, so // a suite that registers nothing keeps the pre-provenance meta shape. if (
(parameter) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
.
(field) const(string)[] sparkles.test_runner.bench_json.BenchMeta.provenance

suite-registered lines (benchProvenance)

provenance
.
(field) ulong const(string[]).length
length
)
{
(local variable) std.array.Appender!string o
o
~= ",\n \"provenance\": [";
foreach (
(parameter) ulong i
i
,
(parameter) const(string) line
line
;
(parameter) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
.
(field) const(string)[] sparkles.test_runner.bench_json.BenchMeta.provenance

suite-registered lines (benchProvenance)

provenance
)
{
(local variable) std.array.Appender!string o
o
~=
(local variable) ulong i
i
? ", " : " ";
(local variable) std.array.Appender!string o
o
~= "\"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(local variable) const(string) line
line
) ~ "\"";
}
(local variable) std.array.Appender!string o
o
~= " ]";
}
(local variable) std.array.Appender!string o
o
~= "\n },\n";
(local variable) std.array.Appender!string o
o
~= " \"columns\": [";
bool
(local variable) bool firstCol
firstCol
= true;
foreach (ref
(parameter) sparkles.test_runner.metrics.MetricDescriptor d
d
;
sparkles.test_runner.metrics.MetricDescriptor[] sparkles.test_runner.metrics.catalog(in sparkles.test_runner.bench.BenchStats[] rows) pure nothrow @safe

The catalog across all rows: client columns (first-seen order, always available) followed by the perf family (available iff any row carries counters). This is the universe --list-metrics and --metrics range over.

catalog
(
(parameter) const(sparkles.test_runner.bench.BenchStats[]) rows
rows
))
{ if (!
(local variable) sparkles.test_runner.metrics.MetricDescriptor d
d
.
(field) bool sparkles.test_runner.metrics.MetricDescriptor.available

producible on this run (perf opened / present in the rows)

available
)
continue;
(local variable) std.array.Appender!string o
o
~=
(local variable) bool firstCol
firstCol
? "\n" : ",\n";
(local variable) bool firstCol
firstCol
= false;
(local variable) std.array.Appender!string o
o
~= " { \"name\": \"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(local variable) sparkles.test_runner.metrics.MetricDescriptor d
d
.
(field) string sparkles.test_runner.metrics.MetricDescriptor.name
name
)
~ "\", \"header\": \"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(local variable) sparkles.test_runner.metrics.MetricDescriptor d
d
.
(field) string sparkles.test_runner.metrics.MetricDescriptor.header
header
)
~ "\", \"format\": \"" ~
(local variable) sparkles.test_runner.metrics.MetricDescriptor d
d
.
(field) sparkles.test_runner.metrics.MetricFormat sparkles.test_runner.metrics.MetricDescriptor.format
format
.
string std.conv.to!string.to!(sparkles.test_runner.metrics.MetricFormat)(sparkles.test_runner.metrics.MetricFormat __param_0) pure @safe

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!
(alias) object.string = string
string
~ "\", \"class\": \"" ~
(local variable) sparkles.test_runner.metrics.MetricDescriptor d
d
.
(field) sparkles.test_runner.metrics.MetricClass sparkles.test_runner.metrics.MetricDescriptor.cls
cls
.
string std.conv.to!string.to!(sparkles.test_runner.metrics.MetricClass)(sparkles.test_runner.metrics.MetricClass __param_0) pure @safe

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!
(alias) object.string = string
string
~ "\", \"source\": \"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(local variable) sparkles.test_runner.metrics.MetricDescriptor d
d
.
(field) string sparkles.test_runner.metrics.MetricDescriptor.source

"client" | "perf" (later: "tier0" | "syscall")

source
) ~ "\" }";
}
(local variable) std.array.Appender!string o
o
~=
(local variable) bool firstCol
firstCol
? "],\n" : "\n ],\n";
(local variable) std.array.Appender!string o
o
~= " \"rows\": [";
foreach (
(parameter) ulong ri
ri
, ref
(parameter) const(sparkles.test_runner.bench.BenchStats) row
row
;
(parameter) const(sparkles.test_runner.bench.BenchStats[]) rows
rows
)
{
(local variable) std.array.Appender!string o
o
~=
(local variable) ulong ri
ri
? ",\n" : "\n";
const
(local variable) const(bool) isError
isError
=
(local variable) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) string sparkles.test_runner.bench.BenchStats.error

non-empty = an error row (a case whose after reported failure)

error
.
(field) ulong const(string).length
length
> 0;
(local variable) std.array.Appender!string o
o
~= " {\n";
(local variable) std.array.Appender!string o
o
~= " \"name\": \"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(local variable) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) string sparkles.test_runner.bench.BenchStats.name
name
) ~ "\",\n";
(local variable) std.array.Appender!string o
o
~= " \"labels\": {";
auto
(local variable) string[] keys
keys
=
(local variable) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) string[string] sparkles.test_runner.bench.BenchStats.labels

orthogonal grouping dimensions (from the case's labels)

labels
.
string[] object.keys!(const(string), string)(inout(const(string)[string]) aa) pure nothrow @property @safe

Returns a newly allocated dynamic array containing a copy of the keys from the associative array.

Note

emulated by the compiler during CTFE

@paramaa The associative array.@returnsA dynamic array containing a copy of the keys.
keys
;
(local variable) string[] keys
keys
.
std.range.SortedRange!(string[], "a < b", SortedRangeOptions.assumeSorted) std.algorithm.sorting.sort!("a < b", SwapStrategy.unstable, string[])(string[] r) pure nothrow @nogc @safe

Sorts a random-access range according to the predicate less.

Performs O(r.length * log(r.length)) evaluations of less. If less involves expensive computations on the sort key, it may be worthwhile to use schwartzSort instead.

Stable sorting requires hasAssignableElements!Range to be true.

sort returns a SortedRange over the original range, allowing functions that can take advantage of sorted data to know that the range is sorted and adjust accordingly. The SortedRange is a wrapper around the original range, so both it and the original range are sorted. Other functions can't know that the original range has been sorted, but they can know that SortedRange has been sorted.

Preconditions

The predicate is expected to satisfy certain rules in order for sort to behave as expected - otherwise, the program may fail on certain inputs (but not others) when not compiled in release mode, due to the cursory assumeSorted check. Specifically, sort expects less(a,b) && less(b,c) to imply less(a,c) (transitivity), and, conversely, !less(a,b) && !less(b,c) to imply !less(a,c). Note that the default predicate ("a < b") does not always satisfy these conditions for floating point types, because the expression will always be false when either a or b is NaN. Use cmp instead.

Algorithms

Introsort is used for unstable sorting and Timsort is used for stable sorting. Each algorithm has benefits beyond stability. Introsort is generally faster but Timsort may achieve greater speeds on data with low entropy or if predicate calls are expensive. Introsort performs no allocations whereas Timsort will perform one or more allocations per call. Both algorithms have O(n log n) worst-case time complexity.

Examples

int[] array = [ 1, 2, 3, 4 ];

// sort in descending order
array.sort!("a > b");
assert(array == [ 4, 3, 2, 1 ]);

// sort in ascending order
array.sort();
assert(array == [ 1, 2, 3, 4 ]);

// sort with reusable comparator and chain
alias myComp = (x, y) => x > y;
assert(array.sort!(myComp).release == [ 4, 3, 2, 1 ]);
// Showcase stable sorting
import std.algorithm.mutation : SwapStrategy;
string[] words = [ "aBc", "a", "abc", "b", "ABC", "c" ];
sort!("toUpper(a) < toUpper(b)", SwapStrategy.stable)(words);
assert(words == [ "a", "aBc", "abc", "ABC", "b", "c" ]);
// Sorting floating-point numbers in presence of NaN
double[] numbers = [-0.0, 3.0, -2.0, double.nan, 0.0, -double.nan];

import std.algorithm.comparison : equal;
import std.math.operations : cmp;
import std.math.traits : isIdentical;

sort!((a, b) => cmp(a, b) < 0)(numbers);

double[] sorted = [-double.nan, -2.0, -0.0, 0.0, 3.0, double.nan];
assert(numbers.equal!isIdentical(sorted));
@paramless The predicate to sort by.@paramss The swapping strategy to use.@paramr The range to sort.@returnsThe initial range wrapped as a SortedRange with the predicate binaryFun!less.@see

assumeSorted

SortedRange

SwapStrategy

binaryFun

sort
; // AA order is unspecified; baselines must be byte-stable
foreach (
(parameter) ulong ki
ki
,
(parameter) string k
k
;
(local variable) string[] keys
keys
)
{
(local variable) std.array.Appender!string o
o
~=
(local variable) ulong ki
ki
? ", " : " ";
(local variable) std.array.Appender!string o
o
~= "\"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(local variable) string k
k
) ~ "\": \"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(local variable) const(string)* __aaget1277
row
.
(local variable) const(string)* __aaget1277
labels
[
(local variable) string k
k
]) ~ "\"";
}
(local variable) std.array.Appender!string o
o
~=
(local variable) string[] keys
keys
.
(field) ulong string[].length
length
? " },\n" : "},\n";
if (
(local variable) const(bool) isError
isError
)
{
(local variable) std.array.Appender!string o
o
~= " \"iterations\": null,\n";
(local variable) std.array.Appender!string o
o
~= " \"samples\": null,\n";
(local variable) std.array.Appender!string o
o
~= " \"medianNs\": null,\n";
(local variable) std.array.Appender!string o
o
~= " \"deviationNs\": null,\n";
(local variable) std.array.Appender!string o
o
~= " \"minNs\": null,\n";
(local variable) std.array.Appender!string o
o
~= " \"maxNs\": null,\n";
(local variable) std.array.Appender!string o
o
~= " \"metrics\": {},\n";
} else {
(local variable) std.array.Appender!string o
o
~= " \"iterations\": " ~
(local variable) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) ulong sparkles.test_runner.bench.BenchStats.iterations

iterations per sample

iterations
.
string std.conv.to!string.to!(const(ulong))(const(ulong) __param_0) pure nothrow @safe

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!
(alias) object.string = string
string
~ ",\n";
(local variable) std.array.Appender!string o
o
~= " \"samples\": " ~
(local variable) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) ulong sparkles.test_runner.bench.BenchStats.samples
samples
.
string std.conv.to!string.to!(const(ulong))(const(ulong) __param_0) pure nothrow @safe

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!
(alias) object.string = string
string
~ ",\n";
(local variable) std.array.Appender!string o
o
~= " \"medianNs\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) double sparkles.test_runner.bench.BenchStats.nsPerIterMedian
nsPerIterMedian
) ~ ",\n";
(local variable) std.array.Appender!string o
o
~= " \"deviationNs\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) double sparkles.test_runner.bench.BenchStats.nsPerIterDeviation

median absolute deviation

nsPerIterDeviation
) ~ ",\n";
(local variable) std.array.Appender!string o
o
~= " \"minNs\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) double sparkles.test_runner.bench.BenchStats.nsPerIterMin
nsPerIterMin
) ~ ",\n";
(local variable) std.array.Appender!string o
o
~= " \"maxNs\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) double sparkles.test_runner.bench.BenchStats.nsPerIterMax
nsPerIterMax
) ~ ",\n";
(local variable) std.array.Appender!string o
o
~= " \"metrics\": {";
bool
(local variable) bool firstCell
firstCell
= true;
(alias) object.string = string
string
(local variable) string estimated
estimated
;
foreach (ref
(parameter) sparkles.test_runner.metrics.MetricCell c
c
;
sparkles.test_runner.metrics.MetricCell[] sparkles.test_runner.metrics.rowCells(in sparkles.test_runner.bench.BenchStats row) pure nothrow @safe

Every metric cell of one row: client columns first (in call order), then perf, then tier0 — each present only when the row carries that source.

rowCells
(
(local variable) const(sparkles.test_runner.bench.BenchStats) row
row
))
{
(local variable) std.array.Appender!string o
o
~=
(local variable) bool firstCell
firstCell
? " " : ", ";
(local variable) bool firstCell
firstCell
= false;
(local variable) std.array.Appender!string o
o
~= "\"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(local variable) sparkles.test_runner.metrics.MetricCell c
c
.
(field) string sparkles.test_runner.metrics.MetricCell.name

stable id, e.g. "ipc", "instr", "B/s"

name
) ~ "\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) sparkles.test_runner.metrics.MetricCell c
c
.
(field) double sparkles.test_runner.metrics.MetricCell.value
value
);
if (
(local variable) sparkles.test_runner.metrics.MetricCell c
c
.
(field) bool sparkles.test_runner.metrics.MetricCell.estimated

multiplex-scaled estimate, not an exact count (rendered )

estimated
)
(local variable) string estimated
estimated
~= (
(local variable) string estimated
estimated
.
(field) ulong string.length
length
? ", \"" : "\"")
~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(local variable) sparkles.test_runner.metrics.MetricCell c
c
.
(field) string sparkles.test_runner.metrics.MetricCell.name

stable id, e.g. "ipc", "instr", "B/s"

name
) ~ "\"";
}
(local variable) std.array.Appender!string o
o
~=
(local variable) bool firstCell
firstCell
? "},\n" : " },\n";
// Multiplex-scaled estimates are labeled machine-readably too, so // a baseline comparison never mistakes an estimate for an exact // count (schema 2; absent = every metric exact). if (
(local variable) string estimated
estimated
.
(field) ulong string.length
length
)
(local variable) std.array.Appender!string o
o
~= " \"estimatedMetrics\": [ " ~
(local variable) string estimated
estimated
~ " ],\n";
// The effective counting-pass iteration count (shared by every // counter tier), so per-pass totals are auditable — a validator // can multiply per-iteration cells back to what the pass counted. // Absent when no counting pass ran (schema 2). if (const
(local variable) const(ulong) ci
ci
=
ulong sparkles.test_runner.bench_json.countIterations(in sparkles.test_runner.bench.BenchStats row) pure nothrow @nogc @safe

The row's counting-pass iteration count: every counter tier shares one per-pass count, so the first present source carries it. 0 = no counting pass ran.

countIterations
(
(local variable) const(sparkles.test_runner.bench.BenchStats) row
row
))
(local variable) std.array.Appender!string o
o
~= " \"countIterations\": " ~
(local variable) const(ulong) ci
ci
.
string std.conv.to!string.to!(const(ulong))(const(ulong) __param_0) pure nothrow @safe

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!
(alias) object.string = string
string
~ ",\n";
}
(local variable) std.array.Appender!string o
o
~= " \"error\": \"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(local variable) const(sparkles.test_runner.bench.BenchStats) row
row
.
(field) string sparkles.test_runner.bench.BenchStats.error

non-empty = an error row (a case whose after reported failure)

error
) ~ "\"\n";
(local variable) std.array.Appender!string o
o
~= " }";
}
(local variable) std.array.Appender!string o
o
~=
(parameter) const(sparkles.test_runner.bench.BenchStats[]) rows
rows
.
(field) ulong const(sparkles.test_runner.bench.BenchStats[]).length
length
? "\n ]" : "]";
if (
(parameter) const(sparkles.test_runner.workload.WorkloadWindow[]) windows
windows
.
(field) ulong const(sparkles.test_runner.workload.WorkloadWindow[]).length
length
)
{
(local variable) std.array.Appender!string o
o
~= ",\n \"windows\": [";
foreach (
(parameter) ulong wi
wi
, ref
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
;
(parameter) const(sparkles.test_runner.workload.WorkloadWindow[]) windows
windows
)
{
(local variable) std.array.Appender!string o
o
~=
(local variable) ulong wi
wi
? ",\n" : "\n";
(local variable) std.array.Appender!string o
o
~=
string sparkles.test_runner.bench_json.windowJson(in sparkles.test_runner.workload.WorkloadWindow w) @safe

One windows element. Field order is fixed for byte-stable baselines; absent sources omit their keys (the Nullable contract), nan components emit null, and skipped appears only when true.

windowJson
(
(local variable) const(sparkles.test_runner.workload.WorkloadWindow) w
w
);
}
(local variable) std.array.Appender!string o
o
~= "\n ]";
}
(local variable) std.array.Appender!string o
o
~= "\n}\n";
return
(local variable) std.array.Appender!string o
o
[];
} /// The page-cache regime workloadFiles established for a window /// (requested vs verified-effective; fractions nan→null); the note stays /// separate from the wall note here even though the table composes them /// into one cell. Emitted for error/skip windows too — the stamp predates /// the window. private void
void sparkles.test_runner.bench_json.appendRegime!(std.array.Appender!string)(ref std.array.Appender!string o, in sparkles.test_runner.workload.WorkloadWindow w) @safe

The page-cache regime workloadFiles established for a window (requested vs verified-effective; fractions nan→null); the note stays separate from the wall note here even though the table composes them into one cell. Emitted for error/skip windows too — the stamp predates the window.

appendRegime
(O)(ref
(alias) O = std.array.Appender!string
O
(parameter) std.array.Appender!string o
o
, in
(struct) sparkles.test_runner.workload.WorkloadWindow

One measured window. Deliberately NOT BenchStats: its per-iteration timing fields would misrepresent a single window — counter stats here are window totals (iters == 1).

WorkloadWindow
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
)
{ import
(package) std
std
.
(module) std.conv

A one-stop shop for converting values from one type to another.

Category Functions
Generic asOriginalType castFrom parse to toChars bitCast
Strings text wtext dtext writeText writeWText writeDText hexString
Numeric octal roundTo signed unsigned
Exceptions ConvException ConvOverflowException

Source

std/conv.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Shin Fujishiro, Adam D. Ruppe, Kenji Hara
conv
:
(alias template) to = std.conv.to(T)

The to template converts a value from one type _to another. The source type is deduced and the target type must be specified, for example the expression to!int(42.0) converts the number 42 from double _to int. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., to!double(42) does not do any checking because any int fits in a double.

Conversions from string _to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings _to signed types, the grammar recognized is: $(PRE $(I Integer): $(I Sign UnsignedInteger) $(I UnsignedInteger) $(I Sign): $(B +) $(B -))

For conversion _to unsigned types, the grammar recognized is: $(PRE $(I UnsignedInteger): $(I DecimalDigit) $(I DecimalDigit) $(I UnsignedInteger))

to
;
if (
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) std.typecons.Nullable!(CacheRegimeStamp) sparkles.test_runner.workload.WorkloadWindow.regime

what workloadFiles established for this window

regime
.
bool std.typecons.Nullable!(sparkles.test_runner.cache_regime.CacheRegimeStamp).isNull() const pure nothrow @nogc @property @safe

Check if this is in the null state.

@returnstrue iff this is in the null state, otherwise false.
isNull
)
return; const
(local variable) const(sparkles.test_runner.cache_regime.CacheRegimeStamp) g
g
=
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) std.typecons.Nullable!(CacheRegimeStamp) sparkles.test_runner.workload.WorkloadWindow.regime

what workloadFiles established for this window

regime
.
inout(sparkles.test_runner.cache_regime.CacheRegimeStamp) std.typecons.Nullable!(sparkles.test_runner.cache_regime.CacheRegimeStamp).get() inout pure nothrow @nogc @property ref @safe

Gets the value if not null. If this is in the null state, and the optional parameter fallback was provided, it will be returned. Without fallback, calling get with a null state is invalid.

When the fallback type is different from the Nullable type, ``get(T) returns the common type.

@paramfallback the value to return in case the Nullable is null.@returnsThe value held internally by this Nullable.
get
;
(parameter) std.array.Appender!string o
o
~= " \"regime\": { \"requested\": \"" ~
(local variable) const(sparkles.test_runner.cache_regime.CacheRegimeStamp) g
g
.
(field) sparkles.test_runner.attributes.CacheRegime sparkles.test_runner.cache_regime.CacheRegimeStamp.requested
requested
.
string std.conv.to!string.to!(const(sparkles.test_runner.attributes.CacheRegime))(const(sparkles.test_runner.attributes.CacheRegime) __param_0) pure @safe

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!
(alias) object.string = string
string
~ "\", \"effective\": \"" ~
(local variable) const(sparkles.test_runner.cache_regime.CacheRegimeStamp) g
g
.
(field) sparkles.test_runner.attributes.CacheRegime sparkles.test_runner.cache_regime.CacheRegimeStamp.effective
effective
.
string std.conv.to!string.to!(const(sparkles.test_runner.attributes.CacheRegime))(const(sparkles.test_runner.attributes.CacheRegime) __param_0) pure @safe

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!
(alias) object.string = string
string
~ "\", \"residentBefore\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.cache_regime.CacheRegimeStamp) g
g
.
(field) double sparkles.test_runner.cache_regime.CacheRegimeStamp.residentBefore
residentBefore
)
~ ", \"residentAfter\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.cache_regime.CacheRegimeStamp) g
g
.
(field) double sparkles.test_runner.cache_regime.CacheRegimeStamp.residentAfter
residentAfter
);
if (
(local variable) const(sparkles.test_runner.cache_regime.CacheRegimeStamp) g
g
.
(field) string sparkles.test_runner.cache_regime.CacheRegimeStamp.note

fs/downgrade/partial/unverified disclosures, "; "-joined

note
.
(field) ulong const(string).length
length
)
(parameter) std.array.Appender!string o
o
~= ", \"note\": \"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(local variable) const(sparkles.test_runner.cache_regime.CacheRegimeStamp) g
g
.
(field) string sparkles.test_runner.cache_regime.CacheRegimeStamp.note

fs/downgrade/partial/unverified disclosures, "; "-joined

note
) ~ "\"";
(parameter) std.array.Appender!string o
o
~= " },\n";
} /// One `windows` element. Field order is fixed for byte-stable baselines; /// absent sources omit their keys (the `Nullable` contract), `nan` /// components emit `null`, and `skipped` appears only when `true`. private
(alias) object.string = string
string
string sparkles.test_runner.bench_json.windowJson(in sparkles.test_runner.workload.WorkloadWindow w) @safe

One windows element. Field order is fixed for byte-stable baselines; absent sources omit their keys (the Nullable contract), nan components emit null, and skipped appears only when true.

windowJson
(in
(struct) sparkles.test_runner.workload.WorkloadWindow

One measured window. Deliberately NOT BenchStats: its per-iteration timing fields would misrepresent a single window — counter stats here are window totals (iters == 1).

WorkloadWindow
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
) @safe
{ import
(package) std
std
.
(module) std.array

Functions and types that manipulate built-in arrays and associative arrays.

This module provides all kinds of functions to create, manipulate or convert arrays:

Function Name Description

| array | Returns a copy of the input in a newly allocated dynamic array. | | appender | Returns a new Appender or RefAppender initialized with a given array. | | assocArray | Returns a newly allocated associative array from a range/ranges of keys and values. | | byPair | Construct a range iterating over an associative array by key/value tuples. | | insertInPlace | Inserts into an existing array at a given position. | | join | Concatenates a range of ranges into one array. | | minimallyInitializedArray | Returns a new array of type T. | | replace | Returns a new array with all occurrences of a certain subrange replaced. | | replaceFirst | Returns a new array with the first occurrence of a certain subrange replaced. | | replaceInPlace | Replaces all occurrences of a certain subrange and puts the result into a given array. | | replaceInto | Replaces all occurrences of a certain subrange and puts the result into an output range. | | replaceLast | Returns a new array with the last occurrence of a certain subrange replaced. | | replaceSlice | Returns a new array with a given slice replaced. | | replicate | Creates a new array out of several copies of an input array or range. | | sameHead | Checks if the initial segments of two arrays refer to the same place in memory. | | sameTail | Checks if the final segments of two arrays refer to the same place in memory. | | split | Eagerly split a range or string into an array. | | staticArray | Creates a new static array from given data. | | uninitializedArray | Returns a new array of type T without initializing its elements. |

Source

std/array.d

@copyrightCopyright Andrei Alexandrescu 2008- and Jonathan M Davis 2011-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu and Jonathan M Davis
array
:
(alias template) appender = std.array.appender(A)() if (isDynamicArray!A)

Convenience function that returns an $(LREF Appender) instance, optionally initialized with array.

appender
;
import
(package) std
std
.
(module) std.conv

A one-stop shop for converting values from one type to another.

Category Functions
Generic asOriginalType castFrom parse to toChars bitCast
Strings text wtext dtext writeText writeWText writeDText hexString
Numeric octal roundTo signed unsigned
Exceptions ConvException ConvOverflowException

Source

std/conv.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Shin Fujishiro, Adam D. Ruppe, Kenji Hara
conv
:
(alias template) to = std.conv.to(T)

The to template converts a value from one type _to another. The source type is deduced and the target type must be specified, for example the expression to!int(42.0) converts the number 42 from double _to int. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., to!double(42) does not do any checking because any int fits in a double.

Conversions from string _to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings _to signed types, the grammar recognized is: $(PRE $(I Integer): $(I Sign UnsignedInteger) $(I UnsignedInteger) $(I Sign): $(B +) $(B -))

For conversion _to unsigned types, the grammar recognized is: $(PRE $(I UnsignedInteger): $(I DecimalDigit) $(I DecimalDigit) $(I UnsignedInteger))

to
;
auto
(local variable) std.array.Appender!string o
o
=
std.array.Appender!string std.array.appender!string() pure nothrow @safe

Convenience function that returns an Appender instance, optionally initialized with array.

appender
!
(alias) object.string = string
string
;
(local variable) std.array.Appender!string o
o
~= " {\n";
(local variable) std.array.Appender!string o
o
~= " \"name\": \"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) string sparkles.test_runner.workload.WorkloadWindow.name
name
) ~ "\",\n";
(local variable) std.array.Appender!string o
o
~= " \"reps\": " ~
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) uint sparkles.test_runner.workload.WorkloadWindow.reps

times the window content ran inside this window

reps
.
string std.conv.to!string.to!(const(uint))(const(uint) __param_0) pure nothrow @safe

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!
(alias) object.string = string
string
~ ",\n";
if (
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) string sparkles.test_runner.workload.WorkloadWindow.error

non-empty = error (or, with skipped, skip) row

error
.
(field) ulong const(string).length
length
)
{ // Mirror the error-row shape: every always-present key stays // present as null, so consumers can read windows position-blind. // The regime stamp survives — it describes state established // BEFORE the window opened (possibly why the run failed), unlike // the per-source measurements OF the failed window.
(local variable) std.array.Appender!string o
o
~= " \"wallNs\": null,\n";
(local variable) std.array.Appender!string o
o
~= " \"scope\": null,\n";
(local variable) std.array.Appender!string o
o
~= " \"onCpuUserNs\": null,\n";
(local variable) std.array.Appender!string o
o
~= " \"onCpuKernelNs\": null,\n";
(local variable) std.array.Appender!string o
o
~= " \"offCpuRunqueueNs\": null,\n";
(local variable) std.array.Appender!string o
o
~= " \"offCpuDiskNs\": null,\n";
(local variable) std.array.Appender!string o
o
~= " \"offCpuOtherNs\": null,\n";
void sparkles.test_runner.bench_json.appendRegime!(std.array.Appender!string)(ref std.array.Appender!string o, in sparkles.test_runner.workload.WorkloadWindow w) @safe

The page-cache regime workloadFiles established for a window (requested vs verified-effective; fractions nan→null); the note stays separate from the wall note here even though the table composes them into one cell. Emitted for error/skip windows too — the stamp predates the window.

appendRegime
(
(local variable) std.array.Appender!string o
o
,
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
);
if (
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) bool sparkles.test_runner.workload.WorkloadWindow.skipped
skipped
)
(local variable) std.array.Appender!string o
o
~= " \"skipped\": true,\n";
(local variable) std.array.Appender!string o
o
~= " \"error\": \"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) string sparkles.test_runner.workload.WorkloadWindow.error

non-empty = error (or, with skipped, skip) row

error
) ~ "\"\n";
(local variable) std.array.Appender!string o
o
~= " }";
return
(local variable) std.array.Appender!string o
o
[];
}
(local variable) std.array.Appender!string o
o
~= " \"wallNs\": " ~
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) long sparkles.test_runner.workload.WallDecomposition.wallNs

the window's wall-clock duration

wallNs
.
string std.conv.to!string.to!(const(long))(const(long) __param_0) pure nothrow @safe

The to template converts a value from one type to another. The source type is deduced and the target type must be specified, for example the expression to`!int(42.0)` converts the number 42 from `double` to `int`. The conversion is "safe", i.e., it checks for overflow; to!int(4.2e10) would throw the ConvOverflowException exception. Overflow checks are only inserted when necessary, e.g., ``to!double(42) does not do any checking because any int fits in a double.

Conversions from string to numeric types differ from the C equivalents atoi() and atol() by checking for overflow and not allowing whitespace.

For conversion of strings to signed types, the grammar recognized is: Integer: Sign UnsignedInteger UnsignedInteger Sign: + -

For conversion to unsigned types, the grammar recognized is: UnsignedInteger: DecimalDigit DecimalDigit UnsignedInteger

Examples

Converting a value to its own type (useful mostly for generic code) simply returns its argument.

int a = 42;
int b = to!int(a);
double c = to!double(3.14); // c is double with value 3.14

Converting among numeric types is a safe way to cast them around.

Conversions from floating-point types to integral types allow loss of precision (the fractional part of a floating-point number). The conversion is truncating towards zero, the same way a cast would truncate. (To round a floating point value when casting to an integral, use roundTo.)

import std.exception : assertThrown;

int a = 420;
assert(to!long(a) == a);
assertThrown!ConvOverflowException(to!byte(a));

assert(to!int(4.2e6) == 4200000);
assertThrown!ConvOverflowException(to!uint(-3.14));
assert(to!uint(3.14) == 3);
assert(to!uint(3.99) == 3);
assert(to!int(-3.99) == -3);

When converting strings to numeric types, note that D hexadecimal and binary literals are not handled. Neither the prefixes that indicate the base, nor the horizontal bar used to separate groups of digits are recognized. This also applies to the suffixes that indicate the type.

To work around this, you can specify a radix for conversions involving numbers.

auto str = to!string(42, 16);
assert(str == "2A");
auto i = to!int(str, 16);
assert(i == 42);

Conversions from integral types to floating-point types always succeed, but might lose accuracy. The largest integers with a predecessor representable in floating-point format are 2^24-1 for float, 2^53-1 for double, and 2^64-1 for real (when real is 80-bit, e.g. on Intel machines).

// 2^24 - 1, largest proper integer representable as float
int a = 16_777_215;
assert(to!int(to!float(a)) == a);
assert(to!int(to!float(-a)) == -a);

Conversion from string types to char types enforces the input to consist of a single code point, and said code point must fit in the target type. Otherwise, ConvException is thrown.

import std.exception : assertThrown;

assert(to!char("a") == 'a');
assertThrown(to!char("ñ")); // 'ñ' does not fit into a char
assert(to!wchar("ñ") == 'ñ');
assertThrown(to!wchar("😃")); // '😃' does not fit into a wchar
assert(to!dchar("😃") == '😃');

// Using wstring or dstring as source type does not affect the result
assert(to!char("a"w) == 'a');
assert(to!char("a"d) == 'a');

// Two code points cannot be converted to a single one
assertThrown(to!char("ab"));

Converting an array to another array type works by converting each element in turn. Associative arrays can be converted to associative arrays as long as keys and values can in turn be converted.

import std.string : split;

int[] a = [1, 2, 3];
auto b = to!(float[])(a);
assert(b == [1.0f, 2, 3]);
string str = "1 2 3 4 5 6";
auto numbers = to!(double[])(split(str));
assert(numbers == [1.0, 2, 3, 4, 5, 6]);
int[string] c;
c["a"] = 1;
c["b"] = 2;
auto d = to!(double[wstring])(c);
assert(d["a"w] == 1 && d["b"w] == 2);

Conversions operate transitively, meaning that they work on arrays and associative arrays of any complexity.

This conversion works because to`!short` applies to an `int`, to!wstring applies to a string, to`!string` applies to a `double`, and to!(double[]) applies to an int[]. The conversion might throw an exception because ``to!short might fail the range check.

int[string][double[int[]]] a;
auto b = to!(short[wstring][string[double[]]])(a);

Object-to-object conversions by dynamic casting throw exception when the source is non-null and the target is null.

import std.exception : assertThrown;
// Testing object conversions
class A {}
class B : A {}
class C : A {}
A a1 = new A, a2 = new B, a3 = new C;
assert(to!B(a2) is a2);
assert(to!C(a3) is a3);
assertThrown!ConvException(to!B(a3));

Stringize conversion from all types is supported.

  • String to string conversion works for any two string types having (char, wchar, dchar) character widths and any combination of qualifiers (mutable, const, or immutable).

  • Converts array (other than strings) to string. Each element is converted by calling ``to!T.

  • Associative array to string conversion. Each element is converted by calling ``to!T.

  • Object to string conversion calls toString against the object or returns "null" if the object is null.

  • Struct to string conversion calls toString against the struct if it is defined.

  • For structs that do not define toString, the conversion to string produces the list of fields.

  • Enumerated types are converted to strings as their symbolic names.

  • Boolean values are converted to "true" or "false".

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    special case

    : Convert integral value to string in radix radix. radix must be a value from 2 to 36. value is treated as a signed value only if radix is 10. The characters A through Z are used to represent values 10 through 36 and their case is determined by the letterCase parameter.

  • All floating point types to all string types.

  • Pointer to string conversions convert the pointer to a size_t value. If pointer is char*, treat it as C-style strings. In that case, this function is @system.

See formatValue on how toString should be defined.

// Conversion representing dynamic/static array with string
long[] a = [ 1, 3, 5 ];
assert(to!string(a) == "[1, 3, 5]");

// Conversion representing associative array with string
int[string] associativeArray = ["0":1, "1":2];
assert(to!string(associativeArray) == `["0":1, "1":2]` ||
       to!string(associativeArray) == `["1":2, "0":1]`);

// char* to string conversion
assert(to!string(cast(char*) null) == "");
assert(to!string("foo\0".ptr) == "foo");

// Conversion reinterpreting void array to string
auto w = "abcx"w;
const(void)[] b = w;
assert(b.length == 8);

auto c = to!(wchar[])(b);
assert(c == "abcx");

Strings can be converted to enum types. The enum member with the same name as the input string is returned. The comparison is case-sensitive.

A ConvException is thrown if the enum does not have the specified member.

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!
(alias) object.string = string
string
~ ",\n";
(local variable) std.array.Appender!string o
o
~= " \"scope\": \"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) string sparkles.test_runner.workload.WallDecomposition.scope_

"thread" (Linux) or "process"

scope_
) ~ "\",\n";
(local variable) std.array.Appender!string o
o
~= " \"onCpuUserNs\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) double sparkles.test_runner.workload.WallDecomposition.onCpuUserNs

rusage user time (µs resolution)

onCpuUserNs
) ~ ",\n";
(local variable) std.array.Appender!string o
o
~= " \"onCpuKernelNs\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) double sparkles.test_runner.workload.WallDecomposition.onCpuKernelNs

rusage system time

onCpuKernelNs
) ~ ",\n";
(local variable) std.array.Appender!string o
o
~= " \"offCpuRunqueueNs\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) double sparkles.test_runner.workload.WallDecomposition.offCpuRunqueueNs

schedstat runqueue wait

offCpuRunqueueNs
) ~ ",\n";
(local variable) std.array.Appender!string o
o
~= " \"offCpuDiskNs\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) double sparkles.test_runner.workload.WallDecomposition.offCpuDiskNs

Disk-stall attribution — always nan today: /proc/pressure is system-scoped, so a thread-scoped attribution would report other processes' stalls as this workload's; it lands with M8's cgroup-scoped PSI. The system-wide integrals ship as diagnostics (WorkloadWindow.psi, the io-stall column) meanwhile.

offCpuDiskNs
) ~ ",\n";
(local variable) std.array.Appender!string o
o
~= " \"offCpuOtherNs\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) double sparkles.test_runner.workload.WallDecomposition.offCpuOtherNs

clamped residual: locks, sleeps, the rest

offCpuOtherNs
) ~ ",\n";
if (!
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) std.typecons.Nullable!(PerfStats) sparkles.test_runner.workload.WorkloadWindow.perf
perf
.
bool std.typecons.Nullable!(sparkles.test_runner.perf.PerfStats).isNull() const pure nothrow @nogc @property @safe

Check if this is in the null state.

@returnstrue iff this is in the null state, otherwise false.
isNull
)
{ const
(local variable) const(sparkles.test_runner.perf.PerfStats) p
p
=
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) std.typecons.Nullable!(PerfStats) sparkles.test_runner.workload.WorkloadWindow.perf
perf
.
inout(sparkles.test_runner.perf.PerfStats) std.typecons.Nullable!(sparkles.test_runner.perf.PerfStats).get() inout pure nothrow @nogc @property ref @safe

Gets the value if not null. If this is in the null state, and the optional parameter fallback was provided, it will be returned. Without fallback, calling get with a null state is invalid.

When the fallback type is different from the Nullable type, ``get(T) returns the common type.

@paramfallback the value to return in case the Nullable is null.@returnsThe value held internally by this Nullable.
get
;
(local variable) std.array.Appender!string o
o
~= " \"perf\": { \"instructions\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.perf.PerfStats) p
p
.
(field) double sparkles.test_runner.perf.PerfStats.instructions

retired instructions per iteration

instructions
)
~ ", \"cycles\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.perf.PerfStats) p
p
.
(field) double sparkles.test_runner.perf.PerfStats.cycles

CPU cycles per iteration

cycles
)
~ ", \"branches\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.perf.PerfStats) p
p
.
(field) double sparkles.test_runner.perf.PerfStats.branches

branch instructions per iteration

branches
)
~ ", \"branchMisses\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.perf.PerfStats) p
p
.
(field) double sparkles.test_runner.perf.PerfStats.branchMisses

mispredicted branches per iteration

branchMisses
)
~ ", \"cacheReferences\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.perf.PerfStats) p
p
.
(field) double sparkles.test_runner.perf.PerfStats.cacheReferences

LLC references per iteration

cacheReferences
)
~ ", \"cacheMisses\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.perf.PerfStats) p
p
.
(field) double sparkles.test_runner.perf.PerfStats.cacheMisses

LLC misses per iteration

cacheMisses
)
~ ", \"pageFaults\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.perf.PerfStats) p
p
.
(field) double sparkles.test_runner.perf.PerfStats.pageFaults

page faults per iteration

pageFaults
)
~ ", \"scale\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.perf.PerfStats) p
p
.
(field) double sparkles.test_runner.perf.PerfStats.scale

counter running/enabled ratio (1 = clean)

scale
)
~ ", \"userOnly\": " ~ (
(local variable) const(sparkles.test_runner.perf.PerfStats) p
p
.
(field) bool sparkles.test_runner.perf.PerfStats.userOnly

true = kernel-side counting was refused

userOnly
? "true" : "false") ~ " },\n";
} if (!
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) std.typecons.Nullable!(Tier0Stats) sparkles.test_runner.workload.WorkloadWindow.tier0
tier0
.
bool std.typecons.Nullable!(sparkles.test_runner.tier0.Tier0Stats).isNull() const pure nothrow @nogc @property @safe

Check if this is in the null state.

@returnstrue iff this is in the null state, otherwise false.
isNull
)
{ const
(local variable) const(sparkles.test_runner.tier0.Tier0Stats) t
t
=
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) std.typecons.Nullable!(Tier0Stats) sparkles.test_runner.workload.WorkloadWindow.tier0
tier0
.
inout(sparkles.test_runner.tier0.Tier0Stats) std.typecons.Nullable!(sparkles.test_runner.tier0.Tier0Stats).get() inout pure nothrow @nogc @property ref @safe

Gets the value if not null. If this is in the null state, and the optional parameter fallback was provided, it will be returned. Without fallback, calling get with a null state is invalid.

When the fallback type is different from the Nullable type, ``get(T) returns the common type.

@paramfallback the value to return in case the Nullable is null.@returnsThe value held internally by this Nullable.
get
;
(local variable) std.array.Appender!string o
o
~= " \"tier0\": { \"minflt\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.tier0.Tier0Stats) t
t
.
(field) double sparkles.test_runner.tier0.Tier0Stats.minflt

minor page faults per iteration (getrusage)

minflt
)
~ ", \"majflt\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.tier0.Tier0Stats) t
t
.
(field) double sparkles.test_runner.tier0.Tier0Stats.majflt

major page faults per iteration (getrusage)

majflt
)
~ ", \"volCs\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.tier0.Tier0Stats) t
t
.
(field) double sparkles.test_runner.tier0.Tier0Stats.volCs

voluntary context switches per iteration (blocked on I/O)

volCs
)
~ ", \"involCs\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.tier0.Tier0Stats) t
t
.
(field) double sparkles.test_runner.tier0.Tier0Stats.involCs

involuntary context switches per iteration (preempted)

involCs
)
~ ", \"syscr\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.tier0.Tier0Stats) t
t
.
(field) double sparkles.test_runner.tier0.Tier0Stats.syscr

read syscalls per iteration (/proc/self/io)

syscr
)
~ ", \"syscw\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.tier0.Tier0Stats) t
t
.
(field) double sparkles.test_runner.tier0.Tier0Stats.syscw

write syscalls per iteration

syscw
)
~ ", \"rchar\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.tier0.Tier0Stats) t
t
.
(field) double sparkles.test_runner.tier0.Tier0Stats.rdChars

bytes read through the syscall layer (cache included)

rdChars
)
~ ", \"wchar\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.tier0.Tier0Stats) t
t
.
(field) double sparkles.test_runner.tier0.Tier0Stats.wrChars

bytes written through the syscall layer

wrChars
)
~ ", \"readBytes\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.tier0.Tier0Stats) t
t
.
(field) double sparkles.test_runner.tier0.Tier0Stats.rdBytes

bytes that actually hit the block device (reads)

rdBytes
)
~ ", \"writeBytes\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.tier0.Tier0Stats) t
t
.
(field) double sparkles.test_runner.tier0.Tier0Stats.wrBytes

bytes that actually hit the block device (writes)

wrBytes
) ~ " },\n";
} if (!
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) std.typecons.Nullable!(SyscallStats) sparkles.test_runner.workload.WorkloadWindow.syscalls
syscalls
.
bool std.typecons.Nullable!(sparkles.test_runner.syscalls.SyscallStats).isNull() const pure nothrow @nogc @property @safe

Check if this is in the null state.

@returnstrue iff this is in the null state, otherwise false.
isNull
)
{ const
(local variable) const(sparkles.test_runner.syscalls.SyscallStats) s
s
=
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) std.typecons.Nullable!(SyscallStats) sparkles.test_runner.workload.WorkloadWindow.syscalls
syscalls
.
inout(sparkles.test_runner.syscalls.SyscallStats) std.typecons.Nullable!(sparkles.test_runner.syscalls.SyscallStats).get() inout pure nothrow @nogc @property ref @safe

Gets the value if not null. If this is in the null state, and the optional parameter fallback was provided, it will be returned. Without fallback, calling get with a null state is invalid.

When the fallback type is different from the Nullable type, ``get(T) returns the common type.

@paramfallback the value to return in case the Nullable is null.@returnsThe value held internally by this Nullable.
get
;
(local variable) std.array.Appender!string o
o
~= " \"syscalls\": { \"total\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.syscalls.SyscallStats) s
s
.
(field) double sparkles.test_runner.syscalls.SyscallStats.total
total
)
~ ", \"named\": {"; foreach (
(parameter) ulong i
i
,
(parameter) const(string) name
name
;
(local variable) const(sparkles.test_runner.syscalls.SyscallStats) s
s
.
(field) const(string)[] sparkles.test_runner.syscalls.SyscallStats.named
named
)
{
(local variable) std.array.Appender!string o
o
~=
(local variable) ulong i
i
? ", " : " ";
(local variable) std.array.Appender!string o
o
~= "\"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(local variable) const(string) name
name
) ~ "\": "
~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) ulong i
i
<
(local variable) const(sparkles.test_runner.syscalls.SyscallStats) s
s
.
(field) double[] sparkles.test_runner.syscalls.SyscallStats.counts
counts
.
(field) ulong const(double[]).length
length
?
(local variable) const(sparkles.test_runner.syscalls.SyscallStats) s
s
.
(field) double[] sparkles.test_runner.syscalls.SyscallStats.counts
counts
[
(local variable) ulong i
i
] : double.
(constant) double double.nan = nan
nan
);
}
(local variable) std.array.Appender!string o
o
~=
(local variable) const(sparkles.test_runner.syscalls.SyscallStats) s
s
.
(field) const(string)[] sparkles.test_runner.syscalls.SyscallStats.named
named
.
(field) ulong const(string[]).length
length
? " }" : "}";
(local variable) std.array.Appender!string o
o
~= ", \"scale\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.syscalls.SyscallStats) s
s
.
(field) double sparkles.test_runner.syscalls.SyscallStats.scale
scale
) ~ " },\n";
} if (!
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) std.typecons.Nullable!(RawStats) sparkles.test_runner.workload.WorkloadWindow.raw
raw
.
bool std.typecons.Nullable!(sparkles.test_runner.raw.RawStats).isNull() const pure nothrow @nogc @property @safe

Check if this is in the null state.

@returnstrue iff this is in the null state, otherwise false.
isNull
)
{ const
(local variable) const(sparkles.test_runner.raw.RawStats) r
r
=
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) std.typecons.Nullable!(RawStats) sparkles.test_runner.workload.WorkloadWindow.raw
raw
.
inout(sparkles.test_runner.raw.RawStats) std.typecons.Nullable!(sparkles.test_runner.raw.RawStats).get() inout pure nothrow @nogc @property ref @safe

Gets the value if not null. If this is in the null state, and the optional parameter fallback was provided, it will be returned. Without fallback, calling get with a null state is invalid.

When the fallback type is different from the Nullable type, ``get(T) returns the common type.

@paramfallback the value to return in case the Nullable is null.@returnsThe value held internally by this Nullable.
get
;
(local variable) std.array.Appender!string o
o
~= " \"raw\": { \"events\": {";
foreach (
(parameter) ulong i
i
,
(parameter) const(string) sel
sel
;
(local variable) const(sparkles.test_runner.raw.RawStats) r
r
.
(field) const(string)[] sparkles.test_runner.raw.RawStats.selectors

requested selectors, in request order

selectors
)
{
(local variable) std.array.Appender!string o
o
~=
(local variable) ulong i
i
? ", " : " ";
(local variable) std.array.Appender!string o
o
~= "\"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(local variable) const(string) sel
sel
) ~ "\": "
~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) ulong i
i
<
(local variable) const(sparkles.test_runner.raw.RawStats) r
r
.
(field) double[] sparkles.test_runner.raw.RawStats.values

per-iteration averages (nan = unavailable)

values
.
(field) ulong const(double[]).length
length
?
(local variable) const(sparkles.test_runner.raw.RawStats) r
r
.
(field) double[] sparkles.test_runner.raw.RawStats.values

per-iteration averages (nan = unavailable)

values
[
(local variable) ulong i
i
] : double.
(constant) double double.nan = nan
nan
);
}
(local variable) std.array.Appender!string o
o
~=
(local variable) const(sparkles.test_runner.raw.RawStats) r
r
.
(field) const(string)[] sparkles.test_runner.raw.RawStats.selectors

requested selectors, in request order

selectors
.
(field) ulong const(string[]).length
length
? " }" : "}";
(local variable) std.array.Appender!string o
o
~= ", \"scale\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.raw.RawStats) r
r
.
(field) double sparkles.test_runner.raw.RawStats.scale

running/enabled ratio of the pass (1 = clean)

scale
) ~ " },\n";
} if (!
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) std.typecons.Nullable!(PsiStats) sparkles.test_runner.workload.WorkloadWindow.psi

system-wide stall deltas — diagnostics, not attribution

psi
.
bool std.typecons.Nullable!(sparkles.test_runner.workload.PsiStats).isNull() const pure nothrow @nogc @property @safe

Check if this is in the null state.

@returnstrue iff this is in the null state, otherwise false.
isNull
)
{ // System-wide stall integrals — diagnostics, self-described by the // scope field (M8's cgroup-scoped source will emit "cgroup"). const
(local variable) const(sparkles.test_runner.workload.PsiStats) p
p
=
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) std.typecons.Nullable!(PsiStats) sparkles.test_runner.workload.WorkloadWindow.psi

system-wide stall deltas — diagnostics, not attribution

psi
.
inout(sparkles.test_runner.workload.PsiStats) std.typecons.Nullable!(sparkles.test_runner.workload.PsiStats).get() inout pure nothrow @nogc @property ref @safe

Gets the value if not null. If this is in the null state, and the optional parameter fallback was provided, it will be returned. Without fallback, calling get with a null state is invalid.

When the fallback type is different from the Nullable type, ``get(T) returns the common type.

@paramfallback the value to return in case the Nullable is null.@returnsThe value held internally by this Nullable.
get
;
(local variable) std.array.Appender!string o
o
~= " \"psi\": { \"scope\": \"system\""
~ ", \"ioSomeNs\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.workload.PsiStats) p
p
.
(field) double sparkles.test_runner.workload.PsiStats.ioSomeNs

≥ 1 task stalled on io

ioSomeNs
)
~ ", \"ioFullNs\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.workload.PsiStats) p
p
.
(field) double sparkles.test_runner.workload.PsiStats.ioFullNs

all non-idle tasks stalled on io

ioFullNs
)
~ ", \"memSomeNs\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.workload.PsiStats) p
p
.
(field) double sparkles.test_runner.workload.PsiStats.memSomeNs
memSomeNs
)
~ ", \"memFullNs\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.workload.PsiStats) p
p
.
(field) double sparkles.test_runner.workload.PsiStats.memFullNs
memFullNs
)
~ ", \"cpuSomeNs\": " ~
string sparkles.test_runner.bench_json.jsonNumber(double v) @safe

One JSON number: nan/infinities → null (an unavailable counter, the table's em dash); integral doubles below 2^53 render as integers; the rest to 6 significant digits (never D's 17-digit default).

jsonNumber
(
(local variable) const(sparkles.test_runner.workload.PsiStats) p
p
.
(field) double sparkles.test_runner.workload.PsiStats.cpuSomeNs
cpuSomeNs
) ~ " },\n";
}
void sparkles.test_runner.bench_json.appendRegime!(std.array.Appender!string)(ref std.array.Appender!string o, in sparkles.test_runner.workload.WorkloadWindow w) @safe

The page-cache regime workloadFiles established for a window (requested vs verified-effective; fractions nan→null); the note stays separate from the wall note here even though the table composes them into one cell. Emitted for error/skip windows too — the stamp predates the window.

appendRegime
(
(local variable) std.array.Appender!string o
o
,
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
);
if (
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) string sparkles.test_runner.workload.WallDecomposition.note

clamp/absence/cross-thread disclosures, "; "-joined

note
.
(field) ulong const(string).length
length
)
(local variable) std.array.Appender!string o
o
~= " \"note\": \"" ~
string sparkles.test_runner.bench_json.jsonEscape(scope const(char)[] s) pure @safe

RFC 8259 string escaping: ", \, and control characters.

jsonEscape
(
(parameter) const(sparkles.test_runner.workload.WorkloadWindow) w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) string sparkles.test_runner.workload.WallDecomposition.note

clamp/absence/cross-thread disclosures, "; "-joined

note
) ~ "\",\n";
(local variable) std.array.Appender!string o
o
~= " \"error\": \"\"\n";
(local variable) std.array.Appender!string o
o
~= " }";
return
(local variable) std.array.Appender!string o
o
[];
} @("benchJson.document.roundTrips") @system unittest { import
(package) std
std
.
(module) std.json

Implements functionality to read and write JavaScript Object Notation values.

JavaScript Object Notation is a lightweight data interchange format commonly used in web services and configuration files. It's easy for humans to read and write, and it's easy for machines to parse and generate.

Warning: While JSONValue is fine for small-scale use, at the range of hundreds of megabytes it is known to cause and exacerbate GC problems. If you encounter problems, try replacing it with a stream parser. See also https://forum.dlang.org/post/dzfyaxypmkdrpakmycjv@forum.dlang.org.

References

http://json.org/, https://seriot.ch/projects/parsing_json.html

Source

std/json.d

Examples

import std.conv : to;

// parse a file or string of json into a usable structure
string s = `{ "language": "D", "rating": 3.5, "code": "42" }`;
JSONValue j = parseJSON(s);
// j and j["language"] return JSONValue,
// j["language"].str returns a string
assert(j["language"].str == "D");
assert(j["rating"].floating == 3.5);

// check a type
long x;
if (const(JSONValue)* code = "code" in j)
{
    if (code.type() == JSONType.integer)
        x = code.integer;
    else
        x = to!int(code.str);
}

// create a json struct
JSONValue jj = [ "language": "D" ];
// rating doesnt exist yet, so use .object to assign
jj.object["rating"] = JSONValue(3.5);
// create an array to assign to list
jj.object["list"] = JSONValue( ["a", "b", "c"] );
// list already exists, so .object optional
jj["list"].array ~= JSONValue("D");

string jjStr = `{"language":"D","list":["a","b","c","D"],"rating":3.5}`;
assert(jj.toString == jjStr);
@copyrightCopyright Jeremie Pelletier 2008 - 2009.@licenseBoost License 1.0.@authorsJeremie Pelletier, David Herberth
json
:
(enum) std.json.JSONType

Enumeration of JSON types

JSONType
,
(alias template) parseJSON = std.json.parseJSON(T)(T json, int maxDepth = -1, JSONOptions options = JSONOptions.none) if (isSomeFiniteCharInputRange!T)

Parses a serialized string and returns a tree of JSON values. Throws: $(LREF JSONException) if string does not follow the JSON grammar or the depth exceeds the max depth, $(LREF ConvException) if a number in the input cannot be represented by a native D type. Params: json = json-formatted string to parse maxDepth = maximum depth of nesting allowed, -1 disables depth checking options = enable decoding string representations of NaN/Inf as float values

parseJSON
;
import
(package) std
std
.
(module) std.typecons

This module implements a variety of type constructors, i.e., templates that allow construction of new, useful general-purpose types.

Category Symbols
Tuple isTuple Tuple tuple reverse
Flags BitFlags isBitFlagEnum Flag No Yes
Reference Counting borrow RefCountedAutoInitialize RefCounted refCounted SafeRefCounted safeRefCounted
Memory allocation scoped Unique
Code generation AutoImplement BlackHole generateAssertTrap generateEmptyFunction NotImplementedError WhiteHole
Nullable apply Nullable nullable NullableRef nullableRef
Proxies Proxy rebindable Rebindable unwrap wrap
Types alignForSize ReplaceType ReplaceTypeUnless Ternary Typedef TypedefType UnqualRef

Source

std/typecons.d

Examples

Value tuples

alias Coord = Tuple!(int, "x", int, "y", int, "z");
Coord c;
c[1] = 1;       // access by index
c.z = 1;        // access by given name
assert(c == Coord(0, 1, 1));

// names can be omitted, types can be mixed
alias DictEntry = Tuple!(string, int);
auto dict = DictEntry("seven", 7);

// element types can be inferred
assert(tuple(2, 3, 4)[1] == 3);
// type inference works with names too
auto tup = tuple!("x", "y", "z")(2, 3, 4);
assert(tup.y == 3);

Rebindable references to const and immutable objects

class Widget
{
    void foo() const @safe {}
}
const w1 = new Widget, w2 = new Widget;
w1.foo();
// w1 = w2 would not work; can't rebind const object

auto r = Rebindable!(const Widget)(w1);
// invoke method as if r were a Widget object
r.foo();
// rebind r to refer to another object
r = w2;
@copyrightCopyright the respective authors, 2008-@licenseBoost License 1.0.@authorsAndrei Alexandrescu, Bartosz Milewski, Don Clugston, Shin Fujishiro, Kenji Hara
typecons
:
(alias struct) Nullable = std.typecons.Nullable(T)

Defines a value paired with a distinctive "null" state that denotes the absence of a value. If default constructed, a $(D Nullable!T) object starts in the null state. Assigning it renders it non-null. Calling nullify can nullify it again.

Practically Nullable!T stores a T and a bool.

See also: $(LREF apply), an alternative way to use the payload.

Nullable
;
import
(package) sparkles
sparkles
.
(package) sparkles.test_runner
test_runner
.
(module) sparkles.test_runner.bench

Benchmark measurement: auto-scaling iteration counts, basic robust statistics, and an optimizer barrier.

@benchmark unittest blocks are executed by the runner's --bench`` mode. By default the whole test body is the measured unit. To time only part of the body (excluding setup), call benchIter inside the test:

@("sort.bench")
@benchmark @safe
unittest
{
    import sparkles.test_runner.bench : benchIter, blackBox;

    auto data = makeInput();          // setup — not measured
    benchIter({ blackBox(data.dup.sort()); });  // measured
}

The measurement protocol follows Rust libtest's Bencher: the iteration count per sample is doubled until a sample takes at least BenchConfig.minSampleTime, then BenchConfig.sampleCount samples are collected and summarized as median / median-absolute-deviation / min / max nanoseconds per iteration.

bench
:
(struct) sparkles.test_runner.bench.Metric

A measurement attached to a benchmark case: amount units of work per timed iteration. Reported as a per-second rate (amount ÷ iteration-time, a quantity of dimension unit·s⁻¹) or as a per-iteration level (as-is).

Metric
,
(struct) sparkles.test_runner.bench.Unit

A unit of measure for a benchmark metric. A forward-compatible stand-in for sparkles.quantities' runtime unit — today just the symbol (its identity). Domain counts ("tweet", "frame", "req") are open-basis units minted by name; "B"/"s" map to SI base dimensions once the quantities library lands.

Unit
;
import
(package) sparkles
sparkles
.
(package) sparkles.test_runner
test_runner
.
(module) sparkles.test_runner.perf

Hardware performance counters via perf_event_open(2), in pure D.

One counter group (cycles leader; instructions, branches, branch-misses, cache-references, cache-misses, plus the page-fault software event) is opened once and reused: a benchmark's counting pass — separate from the wall-clock measurement — brackets only the timed body with PERF_EVENT_IOC_ENABLE/DISABLE, so the per-iteration ioctls never pollute the reported timings and any between() cleanup is never counted.

Counters answer why two implementations differ: IPC, cycles and instructions per iteration, branch/cache miss rates, and the page-fault (allocation) signature. On kernels that refuse perf_event_open (perf_event_paranoid, seccomp) — and on platforms with no backend at all — this degrades gracefully: PerfGroup.available is false and callers simply omit the counter columns.

The binding is pure D over druntime's core.sys.linux.perf_event (which carries the arch-specific syscall numbers, the perf_event_attr layout, and a perf_event_open wrapper) plus ioctl/read/close — no ImportC, so the module source-includes cleanly into every host package's test build.

On macOS the same PerfGroup surface is backed by proc_pid_rusage(RUSAGE_INFO_V4) — the unprivileged XNU fixed counters: true retired instructions and core cycles (process-wide, user+kernel, all threads), so --perf`` renders IPC and instr/iter with the other columns honestly absent. Everything richer is a capability ad, not a backend: kpc is root-or-blessed with the RESTRICT_TO_KNOWN allowlist, and sampling is Instruments/xctrace-brokered only.

perf
:
(struct) sparkles.test_runner.perf.PerfStats

Per-iteration counter averages of one counting pass. A field is nan when the event could not be opened on this machine (e.g. the LLC pair was dropped to avoid multiplexing, or the PMU exposes fewer events).

PerfStats
;
(struct) sparkles.test_runner.bench.BenchStats

Summary statistics of one benchmark row, in nanoseconds per iteration. A row with a non-empty error is a failure row (its timing fields are unset).

BenchStats
(local variable) sparkles.test_runner.bench.BenchStats measured
measured
;
(local variable) sparkles.test_runner.bench.BenchStats measured
measured
.
(field) string sparkles.test_runner.bench.BenchStats.name
name
= "mir-ion";
(local variable) sparkles.test_runner.bench.BenchStats measured
measured
.
(field) string[string] sparkles.test_runner.bench.BenchStats.labels

orthogonal grouping dimensions (from the case's labels)

labels
= ["operation": "parse", "dataset": "twitter"];
(local variable) sparkles.test_runner.bench.BenchStats measured
measured
.
(field) ulong sparkles.test_runner.bench.BenchStats.iterations

iterations per sample

iterations
= 1;
(local variable) sparkles.test_runner.bench.BenchStats measured
measured
.
(field) ulong sparkles.test_runner.bench.BenchStats.samples
samples
= 42;
(local variable) sparkles.test_runner.bench.BenchStats measured
measured
.
(field) double sparkles.test_runner.bench.BenchStats.nsPerIterMedian
nsPerIterMedian
= 3_823_300;
(local variable) sparkles.test_runner.bench.BenchStats measured
measured
.
(field) double sparkles.test_runner.bench.BenchStats.nsPerIterDeviation

median absolute deviation

nsPerIterDeviation
= 41_200;
(local variable) sparkles.test_runner.bench.BenchStats measured
measured
.
(field) double sparkles.test_runner.bench.BenchStats.nsPerIterMin
nsPerIterMin
= 3_615_100;
(local variable) sparkles.test_runner.bench.BenchStats measured
measured
.
(field) double sparkles.test_runner.bench.BenchStats.nsPerIterMax
nsPerIterMax
= 4_891_000;
(local variable) sparkles.test_runner.bench.BenchStats measured
measured
.
(field) sparkles.test_runner.bench.Metric[] sparkles.test_runner.bench.BenchStats.metrics

client throughput / level metrics (empty = none)

metrics
= [
(struct) sparkles.test_runner.bench.Metric

A measurement attached to a benchmark case: amount units of work per timed iteration. Reported as a per-second rate (amount ÷ iteration-time, a quantity of dimension unit·s⁻¹) or as a per-iteration level (as-is).

Metric
(
(struct) sparkles.test_runner.bench.Unit

A unit of measure for a benchmark metric. A forward-compatible stand-in for sparkles.quantities' runtime unit — today just the symbol (its identity). Domain counts ("tweet", "frame", "req") are open-basis units minted by name; "B"/"s" map to SI base dimensions once the quantities library lands.

Unit
("B"), 1000.0,
(struct) sparkles.test_runner.bench.Metric

A measurement attached to a benchmark case: amount units of work per timed iteration. Reported as a per-second rate (amount ÷ iteration-time, a quantity of dimension unit·s⁻¹) or as a per-iteration level (as-is).

Metric
.
(enum) sparkles.test_runner.bench.Metric.Mode

How the runner reports amount.

Mode
.
(enum value) sparkles.test_runner.bench.Metric.Mode.rate = 0

amount ÷ iteration-time<unit>/s

rate
)];
(struct) sparkles.test_runner.perf.PerfStats

Per-iteration counter averages of one counting pass. A field is nan when the event could not be opened on this machine (e.g. the LLC pair was dropped to avoid multiplexing, or the PMU exposes fewer events).

PerfStats
(local variable) sparkles.test_runner.perf.PerfStats p
p
;
(local variable) sparkles.test_runner.perf.PerfStats p
p
.
(field) double sparkles.test_runner.perf.PerfStats.cycles

CPU cycles per iteration

cycles
= 100;
(local variable) sparkles.test_runner.perf.PerfStats p
p
.
(field) double sparkles.test_runner.perf.PerfStats.instructions

retired instructions per iteration

instructions
= 200;
(local variable) sparkles.test_runner.bench.BenchStats measured
measured
.
(field) std.typecons.Nullable!(PerfStats) sparkles.test_runner.bench.BenchStats.perf

hardware counters under --perf`` (empty otherwise)

perf
=
std.typecons.Nullable!(PerfStats) std.typecons.Nullable!(sparkles.test_runner.perf.PerfStats).opAssign!()(sparkles.test_runner.perf.PerfStats value) pure nothrow @nogc return ref @safe

Assigns value to the internally-held state. If the assignment succeeds, this becomes non-null.

@paramvalue A value of type T to assign to this Nullable.
p
;
(struct) sparkles.test_runner.bench.BenchStats

Summary statistics of one benchmark row, in nanoseconds per iteration. A row with a non-empty error is a failure row (its timing fields are unset).

BenchStats
(local variable) sparkles.test_runner.bench.BenchStats plain
plain
;
(local variable) sparkles.test_runner.bench.BenchStats plain
plain
.
(field) string sparkles.test_runner.bench.BenchStats.name
name
= "sum/64";
(local variable) sparkles.test_runner.bench.BenchStats plain
plain
.
(field) ulong sparkles.test_runner.bench.BenchStats.iterations

iterations per sample

iterations
= 1;
(local variable) sparkles.test_runner.bench.BenchStats plain
plain
.
(field) ulong sparkles.test_runner.bench.BenchStats.samples
samples
= 32;
(local variable) sparkles.test_runner.bench.BenchStats plain
plain
.
(field) double sparkles.test_runner.bench.BenchStats.nsPerIterMedian
nsPerIterMedian
= 110;
const
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
=
(struct) sparkles.test_runner.bench_json.BenchMeta

Provenance and the effective measurement knobs stamped onto a report, so a committed baseline is self-describing (the budget it was measured under is part of the data, not tribal knowledge).

BenchMeta
(date: "2026-07-10", hostname: "h", os: "linux",
arch: "x86_64", compiler: "LDC (front-end 2.111)", cpu: "cpu", minSampleTimeMs: 5, sampleCount: 32); const
(local variable) const(std.json.JSONValue) doc
doc
=
std.json.JSONValue std.json.parseJSON!string(string json, int maxDepth = -1, std.json.JSONOptions options = JSONOptions.none) pure @safe

Parses a serialized string and returns a tree of JSON values.

@throwsJSONException if string does not follow the JSON grammar or the depth exceeds the max depth, ConvException if a number in the input cannot be represented by a native D type.@paramjson json-formatted string to parse@parammaxDepth maximum depth of nesting allowed, -1 disables depth checking@paramoptions enable decoding string representations of NaN/Inf as float values
parseJSON
(
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
([
(local variable) sparkles.test_runner.bench.BenchStats measured
measured
,
(local variable) sparkles.test_runner.bench.BenchStats plain
plain
],
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
));
assert(
(local variable) const(std.json.JSONValue) doc
doc
["schema"].
long std.json.JSONValue.integer() const pure @property @safe

Value getter/setter for JSONType.integer``.

@throwsJSONException for read access if type is not JSONType.integer``.
integer
== 2);
assert(
(local variable) const(std.json.JSONValue) doc
doc
["meta"]["minSampleTimeMs"].
long std.json.JSONValue.integer() const pure @property @safe

Value getter/setter for JSONType.integer``.

@throwsJSONException for read access if type is not JSONType.integer``.
integer
== 5);
assert(
(local variable) const(std.json.JSONValue) doc
doc
["rows"].
inout(std.json.JSONValue[]) std.json.JSONValue.array() inout pure @property return ref scope @system

Value getter/setter for JSONType.array``.

Note

This is @system because of the following pattern:

auto a = &(json.array());
json.uinteger = 0;  // overwrite array pointer
(*a)[0] = "world";  // segmentation fault
@throwsJSONException for read access if type is not JSONType.array``.
array
.
(field) ulong const(std.json.JSONValue[]).length
length
== 2);
assert(
(local variable) const(std.json.JSONValue) doc
doc
["rows"][0]["labels"]["dataset"].
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
== "twitter");
assert(
(local variable) const(std.json.JSONValue) doc
doc
["rows"][0]["metrics"]["ipc"].
inout(double) std.json.JSONValue.get!double() inout const pure @property @safe

A convenience getter that returns this JSONValue as the specified D type.

Note

Only numeric types, bool, string, JSONValue[string], and JSONValue[] types are accepted

@throwsJSONException if T cannot hold the contents of this JSONValue ConvException in case of integer overflow when converting to T
get
!double == 2.0);
assert("estimatedMetrics" !in
(local variable) const(std.json.JSONValue) doc
doc
["rows"][0],
"exact counts carry no estimate list"); assert(
(local variable) const(std.json.JSONValue) doc
doc
["rows"][0]["medianNs"].
long std.json.JSONValue.integer() const pure @property @safe

Value getter/setter for JSONType.integer``.

@throwsJSONException for read access if type is not JSONType.integer``.
integer
== 3_823_300);
assert(
(local variable) const(std.json.JSONValue) doc
doc
["rows"][1]["metrics"].
inout(std.json.JSONValue[string]) std.json.JSONValue.object() inout pure @property return ref @system

Value getter/setter for unordered JSONType.object``.

Note

This is @system because of the following pattern:

auto a = &(json.object());
json.uinteger = 0;        // overwrite AA pointer
(*a)["hello"] = "world";  // segmentation fault
@throwsJSONException for read access if type is not JSONType.object`` or the object is ordered.
object
.
(field) ulong const(std.json.JSONValue[string]).length
length
== 0 || "ipc" !in
(local variable) const(std.json.JSONValue) doc
doc
["rows"][1]["metrics"]);
bool
(local variable) bool sawIpc
sawIpc
;
foreach (
(parameter) const(std.json.JSONValue) col
col
;
(local variable) const(std.json.JSONValue) doc
doc
["columns"].
inout(std.json.JSONValue[]) std.json.JSONValue.array() inout pure @property return ref scope @system

Value getter/setter for JSONType.array``.

Note

This is @system because of the following pattern:

auto a = &(json.array());
json.uinteger = 0;  // overwrite array pointer
(*a)[0] = "world";  // segmentation fault
@throwsJSONException for read access if type is not JSONType.array``.
array
)
if (
(local variable) const(std.json.JSONValue) col
col
["name"].
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
== "ipc")
{
(local variable) bool sawIpc
sawIpc
= true;
assert(
(local variable) const(std.json.JSONValue) col
col
["source"].
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
== "perf");
} assert(
(local variable) bool sawIpc
sawIpc
);
} @("benchJson.errorRow.nullTiming") @system unittest { import
(package) std
std
.
(module) std.json

Implements functionality to read and write JavaScript Object Notation values.

JavaScript Object Notation is a lightweight data interchange format commonly used in web services and configuration files. It's easy for humans to read and write, and it's easy for machines to parse and generate.

Warning: While JSONValue is fine for small-scale use, at the range of hundreds of megabytes it is known to cause and exacerbate GC problems. If you encounter problems, try replacing it with a stream parser. See also https://forum.dlang.org/post/dzfyaxypmkdrpakmycjv@forum.dlang.org.

References

http://json.org/, https://seriot.ch/projects/parsing_json.html

Source

std/json.d

Examples

import std.conv : to;

// parse a file or string of json into a usable structure
string s = `{ "language": "D", "rating": 3.5, "code": "42" }`;
JSONValue j = parseJSON(s);
// j and j["language"] return JSONValue,
// j["language"].str returns a string
assert(j["language"].str == "D");
assert(j["rating"].floating == 3.5);

// check a type
long x;
if (const(JSONValue)* code = "code" in j)
{
    if (code.type() == JSONType.integer)
        x = code.integer;
    else
        x = to!int(code.str);
}

// create a json struct
JSONValue jj = [ "language": "D" ];
// rating doesnt exist yet, so use .object to assign
jj.object["rating"] = JSONValue(3.5);
// create an array to assign to list
jj.object["list"] = JSONValue( ["a", "b", "c"] );
// list already exists, so .object optional
jj["list"].array ~= JSONValue("D");

string jjStr = `{"language":"D","list":["a","b","c","D"],"rating":3.5}`;
assert(jj.toString == jjStr);
@copyrightCopyright Jeremie Pelletier 2008 - 2009.@licenseBoost License 1.0.@authorsJeremie Pelletier, David Herberth
json
:
(enum) std.json.JSONType

Enumeration of JSON types

JSONType
,
(alias template) parseJSON = std.json.parseJSON(T)(T json, int maxDepth = -1, JSONOptions options = JSONOptions.none) if (isSomeFiniteCharInputRange!T)

Parses a serialized string and returns a tree of JSON values. Throws: $(LREF JSONException) if string does not follow the JSON grammar or the depth exceeds the max depth, $(LREF ConvException) if a number in the input cannot be represented by a native D type. Params: json = json-formatted string to parse maxDepth = maximum depth of nesting allowed, -1 disables depth checking options = enable decoding string representations of NaN/Inf as float values

parseJSON
;
(struct) sparkles.test_runner.bench.BenchStats

Summary statistics of one benchmark row, in nanoseconds per iteration. A row with a non-empty error is a failure row (its timing fields are unset).

BenchStats
(local variable) sparkles.test_runner.bench.BenchStats bad
bad
;
(local variable) sparkles.test_runner.bench.BenchStats bad
bad
.
(field) string sparkles.test_runner.bench.BenchStats.name
name
= "crashed";
(local variable) sparkles.test_runner.bench.BenchStats bad
bad
.
(field) string[string] sparkles.test_runner.bench.BenchStats.labels

orthogonal grouping dimensions (from the case's labels)

labels
= ["dataset": "canada"];
(local variable) sparkles.test_runner.bench.BenchStats bad
bad
.
(field) string sparkles.test_runner.bench.BenchStats.error

non-empty = an error row (a case whose after reported failure)

error
= "object.Exception: boom";
const
(local variable) const(std.json.JSONValue) doc
doc
=
std.json.JSONValue std.json.parseJSON!string(string json, int maxDepth = -1, std.json.JSONOptions options = JSONOptions.none) pure @safe

Parses a serialized string and returns a tree of JSON values.

@throwsJSONException if string does not follow the JSON grammar or the depth exceeds the max depth, ConvException if a number in the input cannot be represented by a native D type.@paramjson json-formatted string to parse@parammaxDepth maximum depth of nesting allowed, -1 disables depth checking@paramoptions enable decoding string representations of NaN/Inf as float values
parseJSON
(
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
([
(local variable) sparkles.test_runner.bench.BenchStats bad
bad
],
(struct) sparkles.test_runner.bench_json.BenchMeta

Provenance and the effective measurement knobs stamped onto a report, so a committed baseline is self-describing (the budget it was measured under is part of the data, not tribal knowledge).

BenchMeta
(date: "2026-07-10")));
const
(local variable) const(std.json.JSONValue) row
row
=
(local variable) const(std.json.JSONValue) doc
doc
["rows"][0];
assert(
(local variable) const(std.json.JSONValue) row
row
["error"].
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
== "object.Exception: boom");
assert(
(local variable) const(std.json.JSONValue) row
row
["medianNs"].
std.json.JSONType std.json.JSONValue.type() const pure nothrow @nogc @property @safe

Returns the JSONType of the value stored in this structure.

Examples

string s = "{ \"language\": \"D\" }";
JSONValue j = parseJSON(s);
assert(j.type == JSONType.object);
assert(j["language"].type == JSONType.string);
type
==
(enum) std.json.JSONType

Enumeration of JSON types

JSONType
.
(enum value) std.json.JSONType.null_ = cast(byte)0

Indicates the type of a JSONValue.

null_
);
assert(
(local variable) const(std.json.JSONValue) row
row
["iterations"].
std.json.JSONType std.json.JSONValue.type() const pure nothrow @nogc @property @safe

Returns the JSONType of the value stored in this structure.

Examples

string s = "{ \"language\": \"D\" }";
JSONValue j = parseJSON(s);
assert(j.type == JSONType.object);
assert(j["language"].type == JSONType.string);
type
==
(enum) std.json.JSONType

Enumeration of JSON types

JSONType
.
(enum value) std.json.JSONType.null_ = cast(byte)0

Indicates the type of a JSONValue.

null_
);
assert(
(local variable) const(std.json.JSONValue) row
row
["metrics"].
inout(std.json.JSONValue[string]) std.json.JSONValue.object() inout pure @property return ref @system

Value getter/setter for unordered JSONType.object``.

Note

This is @system because of the following pattern:

auto a = &(json.object());
json.uinteger = 0;        // overwrite AA pointer
(*a)["hello"] = "world";  // segmentation fault
@throwsJSONException for read access if type is not JSONType.object`` or the object is ordered.
object
.
(field) ulong const(std.json.JSONValue[string]).length
length
== 0);
assert(
(local variable) const(std.json.JSONValue) row
row
["labels"]["dataset"].
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
== "canada");
} @("benchJson.deterministic.sortedLabels") @system unittest {
(struct) sparkles.test_runner.bench.BenchStats

Summary statistics of one benchmark row, in nanoseconds per iteration. A row with a non-empty error is a failure row (its timing fields are unset).

BenchStats
(local variable) sparkles.test_runner.bench.BenchStats a
a
,
(local variable) sparkles.test_runner.bench.BenchStats b
b
;
(local variable) sparkles.test_runner.bench.BenchStats a
a
.
(field) string sparkles.test_runner.bench.BenchStats.name
name
=
(local variable) sparkles.test_runner.bench.BenchStats b
b
.
(field) string sparkles.test_runner.bench.BenchStats.name
name
= "x";
(local variable) sparkles.test_runner.bench.BenchStats a
a
.
(field) ulong sparkles.test_runner.bench.BenchStats.iterations

iterations per sample

iterations
=
(local variable) sparkles.test_runner.bench.BenchStats b
b
.
(field) ulong sparkles.test_runner.bench.BenchStats.iterations

iterations per sample

iterations
= 1;
// Different insertion orders must emit identical documents.
(local variable) sparkles.test_runner.bench.BenchStats a
a
.
(field) string[string] sparkles.test_runner.bench.BenchStats.labels

orthogonal grouping dimensions (from the case's labels)

labels
= ["k1": "v1", "k2": "v2"];
(local variable) sparkles.test_runner.bench.BenchStats b
b
.
(field) string[string] sparkles.test_runner.bench.BenchStats.labels

orthogonal grouping dimensions (from the case's labels)

labels
= ["k2": "v2"];
string* core.internal.newaa._d_aaGetY!(string, string, string[string], string, string, string)(ref scope string[string] aa, string key, out bool found) pure nothrow @safe

Lookup key in aa. Called only from implementation of (aakey) expressions when value is mutable.

@paramaa associative array@paramkey reference to the key value@paramfound returns whether the key was found or a new entry was added@returnsif key was in the aa, a mutable pointer to the existing value. If key was not in the aa, a mutable pointer to newly inserted value which is set to zero
b
.
string* core.internal.newaa._d_aaGetY!(string, string, string[string], string, string, string)(ref scope string[string] aa, string key, out bool found) pure nothrow @safe

Lookup key in aa. Called only from implementation of (aakey) expressions when value is mutable.

@paramaa associative array@paramkey reference to the key value@paramfound returns whether the key was found or a new entry was added@returnsif key was in the aa, a mutable pointer to the existing value. If key was not in the aa, a mutable pointer to newly inserted value which is set to zero
labels
["k1"] = "v1";
const
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
=
(struct) sparkles.test_runner.bench_json.BenchMeta

Provenance and the effective measurement knobs stamped onto a report, so a committed baseline is self-describing (the budget it was measured under is part of the data, not tribal knowledge).

BenchMeta
(date: "2026-07-10");
const
(local variable) const(string) one
one
=
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
([
(local variable) sparkles.test_runner.bench.BenchStats a
a
],
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
);
assert(
(local variable) const(string) one
one
==
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
([
(local variable) sparkles.test_runner.bench.BenchStats b
b
],
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
));
assert(
(local variable) const(string) one
one
==
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
([
(local variable) sparkles.test_runner.bench.BenchStats a
a
],
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
), "re-emission is byte-identical");
} @("benchJson.escaping") @system unittest { import
(package) std
std
.
(module) std.json

Implements functionality to read and write JavaScript Object Notation values.

JavaScript Object Notation is a lightweight data interchange format commonly used in web services and configuration files. It's easy for humans to read and write, and it's easy for machines to parse and generate.

Warning: While JSONValue is fine for small-scale use, at the range of hundreds of megabytes it is known to cause and exacerbate GC problems. If you encounter problems, try replacing it with a stream parser. See also https://forum.dlang.org/post/dzfyaxypmkdrpakmycjv@forum.dlang.org.

References

http://json.org/, https://seriot.ch/projects/parsing_json.html

Source

std/json.d

Examples

import std.conv : to;

// parse a file or string of json into a usable structure
string s = `{ "language": "D", "rating": 3.5, "code": "42" }`;
JSONValue j = parseJSON(s);
// j and j["language"] return JSONValue,
// j["language"].str returns a string
assert(j["language"].str == "D");
assert(j["rating"].floating == 3.5);

// check a type
long x;
if (const(JSONValue)* code = "code" in j)
{
    if (code.type() == JSONType.integer)
        x = code.integer;
    else
        x = to!int(code.str);
}

// create a json struct
JSONValue jj = [ "language": "D" ];
// rating doesnt exist yet, so use .object to assign
jj.object["rating"] = JSONValue(3.5);
// create an array to assign to list
jj.object["list"] = JSONValue( ["a", "b", "c"] );
// list already exists, so .object optional
jj["list"].array ~= JSONValue("D");

string jjStr = `{"language":"D","list":["a","b","c","D"],"rating":3.5}`;
assert(jj.toString == jjStr);
@copyrightCopyright Jeremie Pelletier 2008 - 2009.@licenseBoost License 1.0.@authorsJeremie Pelletier, David Herberth
json
:
(alias template) parseJSON = std.json.parseJSON(T)(T json, int maxDepth = -1, JSONOptions options = JSONOptions.none) if (isSomeFiniteCharInputRange!T)

Parses a serialized string and returns a tree of JSON values. Throws: $(LREF JSONException) if string does not follow the JSON grammar or the depth exceeds the max depth, $(LREF ConvException) if a number in the input cannot be represented by a native D type. Params: json = json-formatted string to parse maxDepth = maximum depth of nesting allowed, -1 disables depth checking options = enable decoding string representations of NaN/Inf as float values

parseJSON
;
(struct) sparkles.test_runner.bench.BenchStats

Summary statistics of one benchmark row, in nanoseconds per iteration. A row with a non-empty error is a failure row (its timing fields are unset).

BenchStats
(local variable) sparkles.test_runner.bench.BenchStats row
row
;
(local variable) sparkles.test_runner.bench.BenchStats row
row
.
(field) string sparkles.test_runner.bench.BenchStats.name
name
= "quote \" back \\ newline \n tab \t";
(local variable) sparkles.test_runner.bench.BenchStats row
row
.
(field) ulong sparkles.test_runner.bench.BenchStats.iterations

iterations per sample

iterations
= 1;
const
(local variable) const(std.json.JSONValue) doc
doc
=
std.json.JSONValue std.json.parseJSON!string(string json, int maxDepth = -1, std.json.JSONOptions options = JSONOptions.none) pure @safe

Parses a serialized string and returns a tree of JSON values.

@throwsJSONException if string does not follow the JSON grammar or the depth exceeds the max depth, ConvException if a number in the input cannot be represented by a native D type.@paramjson json-formatted string to parse@parammaxDepth maximum depth of nesting allowed, -1 disables depth checking@paramoptions enable decoding string representations of NaN/Inf as float values
parseJSON
(
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
([
(local variable) sparkles.test_runner.bench.BenchStats row
row
],
(struct) sparkles.test_runner.bench_json.BenchMeta

Provenance and the effective measurement knobs stamped onto a report, so a committed baseline is self-describing (the budget it was measured under is part of the data, not tribal knowledge).

BenchMeta
(date: "2026-07-10")));
assert(
(local variable) const(std.json.JSONValue) doc
doc
["rows"][0]["name"].
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
==
(local variable) sparkles.test_runner.bench.BenchStats row
row
.
(field) string sparkles.test_runner.bench.BenchStats.name
name
, "escaping round-trips");
} @("benchJson.meta.collect") @system unittest { import
(package) core
core
.
(module) core.time

Module containing core time functionality, such as Duration (which represents a duration of time) or MonoTime (which represents a timestamp of the system's monotonic clock).

Various functions take a string (or strings) to represent a unit of time (e.g. convert!("days", "hours")(numDays)). The valid strings to use with such functions are "years", "months", "weeks", "days", "hours", "minutes", "seconds", "msecs" (milliseconds), "usecs" (microseconds), "hnsecs" (hecto-nanoseconds - i.e. 100 ns) or some subset thereof. There are a few functions that also allow "nsecs", but very little actually has precision greater than hnsecs.

Symbol Description
Types
Duration Represents a duration of time of weeks or less (kept internally as hnsecs). (e.g. 22 days or 700 seconds).
TickDuration DEPRECATED Represents a duration of time in system clock ticks, using the highest precision that the system provides.
MonoTime Represents a monotonic timestamp in system clock ticks, using the highest precision that the system provides.
Functions
convert Generic way of converting between two time units.
dur Allows constructing a Duration from the given time units with the given length.
weeks&nbsp;days&nbsp;hours

minutes&nbsp;seconds&nbsp;msecs

usecs&nbsp;hnsecs&nbsp;nsecs | Convenience aliases for dur. | | abs | Returns the absolute value of a duration. |

From Duration
From TickDuration
From units
To Duration
tickDuration.to, std,conv!Duration()
dur!"msecs"(5) or 5.msecs()

| To TickDuration | duration.to, std,conv!TickDuration() |

  • | TickDuration.from!"msecs"(msecs) |

| To units | duration.total!"days" | tickDuration.msecs | convert!("days", "msecs")(msecs) |

Source

core/time.d

@copyrightCopyright 2010 - 2012@licenseBoost License 1.0.@authorsJonathan M Davis and Kato Shoichi
time
: msecs;
import
(package) std
std
.
(package) std.algorithm
algorithm
.
(module) std.algorithm.searching

This is a submodule of std.algorithm. It contains generic searching algorithms.

Function Name Description
all all!"a > 0"([1, 2, 3, 4]) returns true because all elements are positive
any any!"a > 0"([1, 2, -3, -4]) returns true because at least one element is positive
balancedParens balancedParens("((1 + 1) / 2)", '(', ')') returns true because the string has balanced parentheses.
boyerMooreFinder find("hello world", boyerMooreFinder("or")) returns "orld" using the Boyer-Moore algorithm.
canFind canFind("hello world", "or") returns true.
count Counts all elements or elements matching a predicate, specific element or sub-range.

count([1, 2, 1]) returns 3, count([1, 2, 1], 1) returns 2 and count!"a < 0"([1, -3, 0]) returns 1. | | countUntil | countUntil(a, b) returns the number of steps taken in a to reach b; for example, countUntil("hello!", "o") returns 4. | | commonPrefix | commonPrefix("parakeet", "parachute") returns "para". | | endsWith | endsWith("rocks", "ks") returns true. | | extrema | extrema([2, 1, 3, 5, 4]) returns [1, 5]. | | find | find("hello world", "or") returns "orld" using linear search. (For binary search refer to SortedRange.) | | findAdjacent | findAdjacent([1, 2, 3, 3, 4]) returns the subrange starting with two equal adjacent elements, i.e. [3, 3, 4]. | | findAmong | findAmong("abcd", "qcx") returns "cd" because 'c' is among "qcx". | | findSkip | If a = "abcde", then findSkip(a, "x") returns false and leaves a unchanged, whereas findSkip(a, "c") advances a to "de" and returns true. | | findSplit | findSplit("abcdefg", "de") returns a tuple of three ranges "abc", "de", and "fg". | | findSplitAfter | findSplitAfter("abcdefg", "de") returns a tuple of two ranges "abcde" and "fg". | | findSplitBefore | findSplitBefore("abcdefg", "de") returns a tuple of two ranges "abc" and "defg". | | minCount | minCount([2, 1, 1, 4, 1]) returns tuple(1, 3). | | maxCount | maxCount([2, 4, 1, 4, 1]) returns tuple(4, 2). | | minElement | Selects the minimal element of a range. minElement([3, 4, 1, 2]) returns 1. | | maxElement | Selects the maximal element of a range. maxElement([3, 4, 1, 2]) returns 4. | | minIndex | Index of the minimal element of a range. minIndex([3, 4, 1, 2]) returns 2. | | maxIndex | Index of the maximal element of a range. maxIndex([3, 4, 1, 2]) returns 1. | | minPos | minPos([2, 3, 1, 3, 4, 1]) returns the subrange [1, 3, 4, 1], i.e., positions the range at the first occurrence of its minimal element. | | maxPos | maxPos([2, 3, 1, 3, 4, 1]) returns the subrange [4, 1], i.e., positions the range at the first occurrence of its maximal element. | | skipOver | Assume a = "blah". Then skipOver(a, "bi") leaves a unchanged and returns false, whereas skipOver(a, "bl") advances a to refer to "ah" and returns true. | | startsWith | startsWith("hello, world", "hello") returns true. | | until | Lazily iterates a range until a specific value is found. |

Source

std/algorithm/searching.d

@copyrightAndrei Alexandrescu 2008-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu
searching
:
(alias template) canFind = std.algorithm.searching.canFind(alias pred = "a == b")

Convenience function. Like find, but only returns whether or not the search was successful.

For more information about pred see $(LREF find).

See_Also: $(REF among, std,algorithm,comparison) for checking a value against multiple arguments.

canFind
;
const
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
=
sparkles.test_runner.bench_json.BenchMeta sparkles.test_runner.bench_json.collectBenchMeta(in sparkles.test_runner.bench.BenchConfig config) @safe

Collects host/toolchain provenance and the run's effective knobs.

collectBenchMeta
(
(struct) sparkles.test_runner.bench.BenchConfig

Tuning knobs of one benchmark run.

BenchConfig
(minSampleTime: 2000.msecs));
assert(
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
.
(field) long sparkles.test_runner.bench_json.BenchMeta.minSampleTimeMs

effective per-sample/total budget (--bench-min-time)

minSampleTimeMs
== 2000);
assert(
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
.
(field) uint sparkles.test_runner.bench_json.BenchMeta.sampleCount

effective BenchConfig.sampleCount

sampleCount
== 32);
assert(
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
.
(field) string sparkles.test_runner.bench_json.BenchMeta.compiler

e.g. "LDC (front-end 2.111)"

compiler
.
bool std.algorithm.searching.canFind!().canFind!(string, string)(string haystack, scope string needle) pure nothrow @nogc @safe

Convenience function. Like find, but only returns whether or not the search was successful.

For more information about pred see find.

Examples

const arr = [0, 1, 2, 3];
assert(canFind(arr, 2));
assert(!canFind(arr, 4));

// find one of several needles
assert(arr.canFind(3, 2));
assert(arr.canFind(3, 2) == 2); // second needle found
assert(arr.canFind([1, 3], 2) == 2);

assert(canFind(arr, [1, 2], [2, 3]));
assert(canFind(arr, [1, 2], [2, 3]) == 1);
assert(canFind(arr, [1, 7], [2, 3]));
assert(canFind(arr, [1, 7], [2, 3]) == 2);
assert(!canFind(arr, [1, 3], [2, 4]));
assert(canFind(arr, [1, 3], [2, 4]) == 0);

Example using a custom predicate. Note that the needle appears as the second argument of the predicate.

auto words = [
    "apple",
    "beeswax",
    "cardboard"
];
assert(!canFind(words, "bees"));
assert( canFind!((string elem, string needle) => elem.startsWith(needle))(words, "bees"));

Search for multiple items in an array of items (search for needles in an array of haystacks)

string s1 = "aaa111aaa";
string s2 = "aaa222aaa";
string s3 = "aaa333aaa";
string s4 = "aaa444aaa";
const hay = [s1, s2, s3, s4];
assert(hay.canFind!(e => e.canFind("111", "222")));
@see

among for checking a value against multiple arguments.

Returns true if and only if needle can be found in range. Performs O(haystack.length) evaluations of pred.

canFind
("front-end"));
assert(
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
.
(field) string sparkles.test_runner.bench_json.BenchMeta.os
os
.
(field) ulong const(string).length
length
&&
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
.
(field) string sparkles.test_runner.bench_json.BenchMeta.arch
arch
.
(field) ulong const(string).length
length
);
assert(
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
.
(field) string sparkles.test_runner.bench_json.BenchMeta.date

ISO day, e.g. "2026-07-10"

date
.
(field) ulong const(string).length
length
== 10); // ISO day
} @("benchJson.rows.estimatedMetrics") @system unittest { import
(package) std
std
.
(module) std.json

Implements functionality to read and write JavaScript Object Notation values.

JavaScript Object Notation is a lightweight data interchange format commonly used in web services and configuration files. It's easy for humans to read and write, and it's easy for machines to parse and generate.

Warning: While JSONValue is fine for small-scale use, at the range of hundreds of megabytes it is known to cause and exacerbate GC problems. If you encounter problems, try replacing it with a stream parser. See also https://forum.dlang.org/post/dzfyaxypmkdrpakmycjv@forum.dlang.org.

References

http://json.org/, https://seriot.ch/projects/parsing_json.html

Source

std/json.d

Examples

import std.conv : to;

// parse a file or string of json into a usable structure
string s = `{ "language": "D", "rating": 3.5, "code": "42" }`;
JSONValue j = parseJSON(s);
// j and j["language"] return JSONValue,
// j["language"].str returns a string
assert(j["language"].str == "D");
assert(j["rating"].floating == 3.5);

// check a type
long x;
if (const(JSONValue)* code = "code" in j)
{
    if (code.type() == JSONType.integer)
        x = code.integer;
    else
        x = to!int(code.str);
}

// create a json struct
JSONValue jj = [ "language": "D" ];
// rating doesnt exist yet, so use .object to assign
jj.object["rating"] = JSONValue(3.5);
// create an array to assign to list
jj.object["list"] = JSONValue( ["a", "b", "c"] );
// list already exists, so .object optional
jj["list"].array ~= JSONValue("D");

string jjStr = `{"language":"D","list":["a","b","c","D"],"rating":3.5}`;
assert(jj.toString == jjStr);
@copyrightCopyright Jeremie Pelletier 2008 - 2009.@licenseBoost License 1.0.@authorsJeremie Pelletier, David Herberth
json
:
(alias template) parseJSON = std.json.parseJSON(T)(T json, int maxDepth = -1, JSONOptions options = JSONOptions.none) if (isSomeFiniteCharInputRange!T)

Parses a serialized string and returns a tree of JSON values. Throws: $(LREF JSONException) if string does not follow the JSON grammar or the depth exceeds the max depth, $(LREF ConvException) if a number in the input cannot be represented by a native D type. Params: json = json-formatted string to parse maxDepth = maximum depth of nesting allowed, -1 disables depth checking options = enable decoding string representations of NaN/Inf as float values

parseJSON
;
import
(package) sparkles
sparkles
.
(package) sparkles.test_runner
test_runner
.
(module) sparkles.test_runner.perf

Hardware performance counters via perf_event_open(2), in pure D.

One counter group (cycles leader; instructions, branches, branch-misses, cache-references, cache-misses, plus the page-fault software event) is opened once and reused: a benchmark's counting pass — separate from the wall-clock measurement — brackets only the timed body with PERF_EVENT_IOC_ENABLE/DISABLE, so the per-iteration ioctls never pollute the reported timings and any between() cleanup is never counted.

Counters answer why two implementations differ: IPC, cycles and instructions per iteration, branch/cache miss rates, and the page-fault (allocation) signature. On kernels that refuse perf_event_open (perf_event_paranoid, seccomp) — and on platforms with no backend at all — this degrades gracefully: PerfGroup.available is false and callers simply omit the counter columns.

The binding is pure D over druntime's core.sys.linux.perf_event (which carries the arch-specific syscall numbers, the perf_event_attr layout, and a perf_event_open wrapper) plus ioctl/read/close — no ImportC, so the module source-includes cleanly into every host package's test build.

On macOS the same PerfGroup surface is backed by proc_pid_rusage(RUSAGE_INFO_V4) — the unprivileged XNU fixed counters: true retired instructions and core cycles (process-wide, user+kernel, all threads), so --perf`` renders IPC and instr/iter with the other columns honestly absent. Everything richer is a capability ad, not a backend: kpc is root-or-blessed with the RESTRICT_TO_KNOWN allowlist, and sampling is Instruments/xctrace-brokered only.

perf
:
(struct) sparkles.test_runner.perf.PerfStats

Per-iteration counter averages of one counting pass. A field is nan when the event could not be opened on this machine (e.g. the LLC pair was dropped to avoid multiplexing, or the PMU exposes fewer events).

PerfStats
;
(struct) sparkles.test_runner.bench.BenchStats

Summary statistics of one benchmark row, in nanoseconds per iteration. A row with a non-empty error is a failure row (its timing fields are unset).

BenchStats
(local variable) sparkles.test_runner.bench.BenchStats row
row
;
(local variable) sparkles.test_runner.bench.BenchStats row
row
.
(field) string sparkles.test_runner.bench.BenchStats.name
name
= "scaled";
(local variable) sparkles.test_runner.bench.BenchStats row
row
.
(field) ulong sparkles.test_runner.bench.BenchStats.iterations

iterations per sample

iterations
= 1;
(local variable) sparkles.test_runner.bench.BenchStats row
row
.
(field) ulong sparkles.test_runner.bench.BenchStats.samples
samples
= 32;
(local variable) sparkles.test_runner.bench.BenchStats row
row
.
(field) double sparkles.test_runner.bench.BenchStats.nsPerIterMedian
nsPerIterMedian
= 100;
(struct) sparkles.test_runner.perf.PerfStats

Per-iteration counter averages of one counting pass. A field is nan when the event could not be opened on this machine (e.g. the LLC pair was dropped to avoid multiplexing, or the PMU exposes fewer events).

PerfStats
(local variable) sparkles.test_runner.perf.PerfStats p
p
;
(local variable) sparkles.test_runner.perf.PerfStats p
p
.
(field) double sparkles.test_runner.perf.PerfStats.cycles

CPU cycles per iteration

cycles
= 100;
(local variable) sparkles.test_runner.perf.PerfStats p
p
.
(field) double sparkles.test_runner.perf.PerfStats.instructions

retired instructions per iteration

instructions
= 200;
(local variable) sparkles.test_runner.perf.PerfStats p
p
.
(field) double sparkles.test_runner.perf.PerfStats.scale

counter running/enabled ratio (1 = clean)

scale
= 0.5; // a half-scheduled pass: values are estimates
(local variable) sparkles.test_runner.bench.BenchStats row
row
.
(field) std.typecons.Nullable!(PerfStats) sparkles.test_runner.bench.BenchStats.perf

hardware counters under --perf`` (empty otherwise)

perf
=
std.typecons.Nullable!(PerfStats) std.typecons.Nullable!(sparkles.test_runner.perf.PerfStats).opAssign!()(sparkles.test_runner.perf.PerfStats value) pure nothrow @nogc return ref @safe

Assigns value to the internally-held state. If the assignment succeeds, this becomes non-null.

@paramvalue A value of type T to assign to this Nullable.
p
;
const
(local variable) const(std.json.JSONValue) doc
doc
=
std.json.JSONValue std.json.parseJSON!string(string json, int maxDepth = -1, std.json.JSONOptions options = JSONOptions.none) pure @safe

Parses a serialized string and returns a tree of JSON values.

@throwsJSONException if string does not follow the JSON grammar or the depth exceeds the max depth, ConvException if a number in the input cannot be represented by a native D type.@paramjson json-formatted string to parse@parammaxDepth maximum depth of nesting allowed, -1 disables depth checking@paramoptions enable decoding string representations of NaN/Inf as float values
parseJSON
(
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
([
(local variable) sparkles.test_runner.bench.BenchStats row
row
],
(struct) sparkles.test_runner.bench_json.BenchMeta

Provenance and the effective measurement knobs stamped onto a report, so a committed baseline is self-describing (the budget it was measured under is part of the data, not tribal knowledge).

BenchMeta
(date: "2026-07-10")));
const
(local variable) const(std.json.JSONValue[]) est
est
=
(local variable) const(std.json.JSONValue) doc
doc
["rows"][0]["estimatedMetrics"].
inout(std.json.JSONValue[]) std.json.JSONValue.array() inout pure @property return ref scope @system

Value getter/setter for JSONType.array``.

Note

This is @system because of the following pattern:

auto a = &(json.array());
json.uinteger = 0;  // overwrite array pointer
(*a)[0] = "world";  // segmentation fault
@throwsJSONException for read access if type is not JSONType.array``.
array
;
assert(
(local variable) const(std.json.JSONValue[]) est
est
.
(field) ulong const(std.json.JSONValue[]).length
length
> 0);
bool
(local variable) bool foundIpc
foundIpc
;
foreach (
(parameter) const(std.json.JSONValue) e
e
;
(local variable) const(std.json.JSONValue[]) est
est
)
(local variable) bool foundIpc
foundIpc
|=
(local variable) const(std.json.JSONValue) e
e
.
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
== "ipc";
assert(
(local variable) bool foundIpc
foundIpc
, "the scaled perf cells are named");
} @("benchJson.meta.provenance") @system unittest { import
(package) std
std
.
(module) std.json

Implements functionality to read and write JavaScript Object Notation values.

JavaScript Object Notation is a lightweight data interchange format commonly used in web services and configuration files. It's easy for humans to read and write, and it's easy for machines to parse and generate.

Warning: While JSONValue is fine for small-scale use, at the range of hundreds of megabytes it is known to cause and exacerbate GC problems. If you encounter problems, try replacing it with a stream parser. See also https://forum.dlang.org/post/dzfyaxypmkdrpakmycjv@forum.dlang.org.

References

http://json.org/, https://seriot.ch/projects/parsing_json.html

Source

std/json.d

Examples

import std.conv : to;

// parse a file or string of json into a usable structure
string s = `{ "language": "D", "rating": 3.5, "code": "42" }`;
JSONValue j = parseJSON(s);
// j and j["language"] return JSONValue,
// j["language"].str returns a string
assert(j["language"].str == "D");
assert(j["rating"].floating == 3.5);

// check a type
long x;
if (const(JSONValue)* code = "code" in j)
{
    if (code.type() == JSONType.integer)
        x = code.integer;
    else
        x = to!int(code.str);
}

// create a json struct
JSONValue jj = [ "language": "D" ];
// rating doesnt exist yet, so use .object to assign
jj.object["rating"] = JSONValue(3.5);
// create an array to assign to list
jj.object["list"] = JSONValue( ["a", "b", "c"] );
// list already exists, so .object optional
jj["list"].array ~= JSONValue("D");

string jjStr = `{"language":"D","list":["a","b","c","D"],"rating":3.5}`;
assert(jj.toString == jjStr);
@copyrightCopyright Jeremie Pelletier 2008 - 2009.@licenseBoost License 1.0.@authorsJeremie Pelletier, David Herberth
json
:
(alias template) parseJSON = std.json.parseJSON(T)(T json, int maxDepth = -1, JSONOptions options = JSONOptions.none) if (isSomeFiniteCharInputRange!T)

Parses a serialized string and returns a tree of JSON values. Throws: $(LREF JSONException) if string does not follow the JSON grammar or the depth exceeds the max depth, $(LREF ConvException) if a number in the input cannot be represented by a native D type. Params: json = json-formatted string to parse maxDepth = maximum depth of nesting allowed, -1 disables depth checking options = enable decoding string representations of NaN/Inf as float values

parseJSON
;
(struct) sparkles.test_runner.bench.BenchStats

Summary statistics of one benchmark row, in nanoseconds per iteration. A row with a non-empty error is a failure row (its timing fields are unset).

BenchStats
(local variable) sparkles.test_runner.bench.BenchStats row
row
;
(local variable) sparkles.test_runner.bench.BenchStats row
row
.
(field) string sparkles.test_runner.bench.BenchStats.name
name
= "x";
(local variable) sparkles.test_runner.bench.BenchStats row
row
.
(field) ulong sparkles.test_runner.bench.BenchStats.iterations

iterations per sample

iterations
= 1;
const
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
=
(struct) sparkles.test_runner.bench_json.BenchMeta

Provenance and the effective measurement knobs stamped onto a report, so a committed baseline is self-describing (the budget it was measured under is part of the data, not tribal knowledge).

BenchMeta
(date: "2026-07-12",
provenance: ["glibc malloc trim/mmap thresholds raised to 64 MiB", "codegen: library-inline"]); const
(local variable) const(std.json.JSONValue) doc
doc
=
std.json.JSONValue std.json.parseJSON!string(string json, int maxDepth = -1, std.json.JSONOptions options = JSONOptions.none) pure @safe

Parses a serialized string and returns a tree of JSON values.

@throwsJSONException if string does not follow the JSON grammar or the depth exceeds the max depth, ConvException if a number in the input cannot be represented by a native D type.@paramjson json-formatted string to parse@parammaxDepth maximum depth of nesting allowed, -1 disables depth checking@paramoptions enable decoding string representations of NaN/Inf as float values
parseJSON
(
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
([
(local variable) sparkles.test_runner.bench.BenchStats row
row
],
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
));
const
(local variable) const(std.json.JSONValue[]) p
p
=
(local variable) const(std.json.JSONValue) doc
doc
["meta"]["provenance"].
inout(std.json.JSONValue[]) std.json.JSONValue.array() inout pure @property return ref scope @system

Value getter/setter for JSONType.array``.

Note

This is @system because of the following pattern:

auto a = &(json.array());
json.uinteger = 0;  // overwrite array pointer
(*a)[0] = "world";  // segmentation fault
@throwsJSONException for read access if type is not JSONType.array``.
array
;
assert(
(local variable) const(std.json.JSONValue[]) p
p
.
(field) ulong const(std.json.JSONValue[]).length
length
== 2);
assert(
(local variable) const(std.json.JSONValue[]) p
p
[0].
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
== "glibc malloc trim/mmap thresholds raised to 64 MiB");
assert(
(local variable) const(std.json.JSONValue[]) p
p
[1].
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
== "codegen: library-inline");
const
(local variable) const(std.json.JSONValue) bare
bare
=
std.json.JSONValue std.json.parseJSON!string(string json, int maxDepth = -1, std.json.JSONOptions options = JSONOptions.none) pure @safe

Parses a serialized string and returns a tree of JSON values.

@throwsJSONException if string does not follow the JSON grammar or the depth exceeds the max depth, ConvException if a number in the input cannot be represented by a native D type.@paramjson json-formatted string to parse@parammaxDepth maximum depth of nesting allowed, -1 disables depth checking@paramoptions enable decoding string representations of NaN/Inf as float values
parseJSON
(
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
([
(local variable) sparkles.test_runner.bench.BenchStats row
row
],
(struct) sparkles.test_runner.bench_json.BenchMeta

Provenance and the effective measurement knobs stamped onto a report, so a committed baseline is self-describing (the budget it was measured under is part of the data, not tribal knowledge).

BenchMeta
(date: "2026-07-12")));
assert("provenance" !in
(local variable) const(std.json.JSONValue) bare
bare
["meta"], "no lines registered — no key");
} @("benchJson.rows.countIterations") @system unittest { import
(package) std
std
.
(module) std.json

Implements functionality to read and write JavaScript Object Notation values.

JavaScript Object Notation is a lightweight data interchange format commonly used in web services and configuration files. It's easy for humans to read and write, and it's easy for machines to parse and generate.

Warning: While JSONValue is fine for small-scale use, at the range of hundreds of megabytes it is known to cause and exacerbate GC problems. If you encounter problems, try replacing it with a stream parser. See also https://forum.dlang.org/post/dzfyaxypmkdrpakmycjv@forum.dlang.org.

References

http://json.org/, https://seriot.ch/projects/parsing_json.html

Source

std/json.d

Examples

import std.conv : to;

// parse a file or string of json into a usable structure
string s = `{ "language": "D", "rating": 3.5, "code": "42" }`;
JSONValue j = parseJSON(s);
// j and j["language"] return JSONValue,
// j["language"].str returns a string
assert(j["language"].str == "D");
assert(j["rating"].floating == 3.5);

// check a type
long x;
if (const(JSONValue)* code = "code" in j)
{
    if (code.type() == JSONType.integer)
        x = code.integer;
    else
        x = to!int(code.str);
}

// create a json struct
JSONValue jj = [ "language": "D" ];
// rating doesnt exist yet, so use .object to assign
jj.object["rating"] = JSONValue(3.5);
// create an array to assign to list
jj.object["list"] = JSONValue( ["a", "b", "c"] );
// list already exists, so .object optional
jj["list"].array ~= JSONValue("D");

string jjStr = `{"language":"D","list":["a","b","c","D"],"rating":3.5}`;
assert(jj.toString == jjStr);
@copyrightCopyright Jeremie Pelletier 2008 - 2009.@licenseBoost License 1.0.@authorsJeremie Pelletier, David Herberth
json
:
(alias template) parseJSON = std.json.parseJSON(T)(T json, int maxDepth = -1, JSONOptions options = JSONOptions.none) if (isSomeFiniteCharInputRange!T)

Parses a serialized string and returns a tree of JSON values. Throws: $(LREF JSONException) if string does not follow the JSON grammar or the depth exceeds the max depth, $(LREF ConvException) if a number in the input cannot be represented by a native D type. Params: json = json-formatted string to parse maxDepth = maximum depth of nesting allowed, -1 disables depth checking options = enable decoding string representations of NaN/Inf as float values

parseJSON
;
import
(package) sparkles
sparkles
.
(package) sparkles.test_runner
test_runner
.
(module) sparkles.test_runner.perf

Hardware performance counters via perf_event_open(2), in pure D.

One counter group (cycles leader; instructions, branches, branch-misses, cache-references, cache-misses, plus the page-fault software event) is opened once and reused: a benchmark's counting pass — separate from the wall-clock measurement — brackets only the timed body with PERF_EVENT_IOC_ENABLE/DISABLE, so the per-iteration ioctls never pollute the reported timings and any between() cleanup is never counted.

Counters answer why two implementations differ: IPC, cycles and instructions per iteration, branch/cache miss rates, and the page-fault (allocation) signature. On kernels that refuse perf_event_open (perf_event_paranoid, seccomp) — and on platforms with no backend at all — this degrades gracefully: PerfGroup.available is false and callers simply omit the counter columns.

The binding is pure D over druntime's core.sys.linux.perf_event (which carries the arch-specific syscall numbers, the perf_event_attr layout, and a perf_event_open wrapper) plus ioctl/read/close — no ImportC, so the module source-includes cleanly into every host package's test build.

On macOS the same PerfGroup surface is backed by proc_pid_rusage(RUSAGE_INFO_V4) — the unprivileged XNU fixed counters: true retired instructions and core cycles (process-wide, user+kernel, all threads), so --perf`` renders IPC and instr/iter with the other columns honestly absent. Everything richer is a capability ad, not a backend: kpc is root-or-blessed with the RESTRICT_TO_KNOWN allowlist, and sampling is Instruments/xctrace-brokered only.

perf
:
(struct) sparkles.test_runner.perf.PerfStats

Per-iteration counter averages of one counting pass. A field is nan when the event could not be opened on this machine (e.g. the LLC pair was dropped to avoid multiplexing, or the PMU exposes fewer events).

PerfStats
;
(struct) sparkles.test_runner.bench.BenchStats

Summary statistics of one benchmark row, in nanoseconds per iteration. A row with a non-empty error is a failure row (its timing fields are unset).

BenchStats
(local variable) sparkles.test_runner.bench.BenchStats counted
counted
;
(local variable) sparkles.test_runner.bench.BenchStats counted
counted
.
(field) string sparkles.test_runner.bench.BenchStats.name
name
= "counted";
(local variable) sparkles.test_runner.bench.BenchStats counted
counted
.
(field) ulong sparkles.test_runner.bench.BenchStats.iterations

iterations per sample

iterations
= 1;
(struct) sparkles.test_runner.perf.PerfStats

Per-iteration counter averages of one counting pass. A field is nan when the event could not be opened on this machine (e.g. the LLC pair was dropped to avoid multiplexing, or the PMU exposes fewer events).

PerfStats
(local variable) sparkles.test_runner.perf.PerfStats p
p
;
(local variable) sparkles.test_runner.perf.PerfStats p
p
.
(field) ulong sparkles.test_runner.perf.PerfStats.iters

counting-pass iterations

iters
= 7;
(local variable) sparkles.test_runner.perf.PerfStats p
p
.
(field) double sparkles.test_runner.perf.PerfStats.cycles

CPU cycles per iteration

cycles
= 100;
(local variable) sparkles.test_runner.bench.BenchStats counted
counted
.
(field) std.typecons.Nullable!(PerfStats) sparkles.test_runner.bench.BenchStats.perf

hardware counters under --perf`` (empty otherwise)

perf
=
std.typecons.Nullable!(PerfStats) std.typecons.Nullable!(sparkles.test_runner.perf.PerfStats).opAssign!()(sparkles.test_runner.perf.PerfStats value) pure nothrow @nogc return ref @safe

Assigns value to the internally-held state. If the assignment succeeds, this becomes non-null.

@paramvalue A value of type T to assign to this Nullable.
p
;
(struct) sparkles.test_runner.bench.BenchStats

Summary statistics of one benchmark row, in nanoseconds per iteration. A row with a non-empty error is a failure row (its timing fields are unset).

BenchStats
(local variable) sparkles.test_runner.bench.BenchStats uncounted
uncounted
;
(local variable) sparkles.test_runner.bench.BenchStats uncounted
uncounted
.
(field) string sparkles.test_runner.bench.BenchStats.name
name
= "plain";
(local variable) sparkles.test_runner.bench.BenchStats uncounted
uncounted
.
(field) ulong sparkles.test_runner.bench.BenchStats.iterations

iterations per sample

iterations
= 1;
const
(local variable) const(std.json.JSONValue) doc
doc
=
std.json.JSONValue std.json.parseJSON!string(string json, int maxDepth = -1, std.json.JSONOptions options = JSONOptions.none) pure @safe

Parses a serialized string and returns a tree of JSON values.

@throwsJSONException if string does not follow the JSON grammar or the depth exceeds the max depth, ConvException if a number in the input cannot be represented by a native D type.@paramjson json-formatted string to parse@parammaxDepth maximum depth of nesting allowed, -1 disables depth checking@paramoptions enable decoding string representations of NaN/Inf as float values
parseJSON
(
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
([
(local variable) sparkles.test_runner.bench.BenchStats counted
counted
,
(local variable) sparkles.test_runner.bench.BenchStats uncounted
uncounted
],
(struct) sparkles.test_runner.bench_json.BenchMeta

Provenance and the effective measurement knobs stamped onto a report, so a committed baseline is self-describing (the budget it was measured under is part of the data, not tribal knowledge).

BenchMeta
(date: "2026-07-12")));
assert(
(local variable) const(std.json.JSONValue) doc
doc
["rows"][0]["countIterations"].
long std.json.JSONValue.integer() const pure @property @safe

Value getter/setter for JSONType.integer``.

@throwsJSONException for read access if type is not JSONType.integer``.
integer
== 7);
assert("countIterations" !in
(local variable) const(std.json.JSONValue) doc
doc
["rows"][1], "no counting pass — no key");
} @("benchJson.windows.roundTrip") @system unittest { import
(package) std
std
.
(module) std.json

Implements functionality to read and write JavaScript Object Notation values.

JavaScript Object Notation is a lightweight data interchange format commonly used in web services and configuration files. It's easy for humans to read and write, and it's easy for machines to parse and generate.

Warning: While JSONValue is fine for small-scale use, at the range of hundreds of megabytes it is known to cause and exacerbate GC problems. If you encounter problems, try replacing it with a stream parser. See also https://forum.dlang.org/post/dzfyaxypmkdrpakmycjv@forum.dlang.org.

References

http://json.org/, https://seriot.ch/projects/parsing_json.html

Source

std/json.d

Examples

import std.conv : to;

// parse a file or string of json into a usable structure
string s = `{ "language": "D", "rating": 3.5, "code": "42" }`;
JSONValue j = parseJSON(s);
// j and j["language"] return JSONValue,
// j["language"].str returns a string
assert(j["language"].str == "D");
assert(j["rating"].floating == 3.5);

// check a type
long x;
if (const(JSONValue)* code = "code" in j)
{
    if (code.type() == JSONType.integer)
        x = code.integer;
    else
        x = to!int(code.str);
}

// create a json struct
JSONValue jj = [ "language": "D" ];
// rating doesnt exist yet, so use .object to assign
jj.object["rating"] = JSONValue(3.5);
// create an array to assign to list
jj.object["list"] = JSONValue( ["a", "b", "c"] );
// list already exists, so .object optional
jj["list"].array ~= JSONValue("D");

string jjStr = `{"language":"D","list":["a","b","c","D"],"rating":3.5}`;
assert(jj.toString == jjStr);
@copyrightCopyright Jeremie Pelletier 2008 - 2009.@licenseBoost License 1.0.@authorsJeremie Pelletier, David Herberth
json
:
(enum) std.json.JSONType

Enumeration of JSON types

JSONType
,
(alias template) parseJSON = std.json.parseJSON(T)(T json, int maxDepth = -1, JSONOptions options = JSONOptions.none) if (isSomeFiniteCharInputRange!T)

Parses a serialized string and returns a tree of JSON values. Throws: $(LREF JSONException) if string does not follow the JSON grammar or the depth exceeds the max depth, $(LREF ConvException) if a number in the input cannot be represented by a native D type. Params: json = json-formatted string to parse maxDepth = maximum depth of nesting allowed, -1 disables depth checking options = enable decoding string representations of NaN/Inf as float values

parseJSON
;
import
(package) std
std
.
(module) std.typecons

This module implements a variety of type constructors, i.e., templates that allow construction of new, useful general-purpose types.

Category Symbols
Tuple isTuple Tuple tuple reverse
Flags BitFlags isBitFlagEnum Flag No Yes
Reference Counting borrow RefCountedAutoInitialize RefCounted refCounted SafeRefCounted safeRefCounted
Memory allocation scoped Unique
Code generation AutoImplement BlackHole generateAssertTrap generateEmptyFunction NotImplementedError WhiteHole
Nullable apply Nullable nullable NullableRef nullableRef
Proxies Proxy rebindable Rebindable unwrap wrap
Types alignForSize ReplaceType ReplaceTypeUnless Ternary Typedef TypedefType UnqualRef

Source

std/typecons.d

Examples

Value tuples

alias Coord = Tuple!(int, "x", int, "y", int, "z");
Coord c;
c[1] = 1;       // access by index
c.z = 1;        // access by given name
assert(c == Coord(0, 1, 1));

// names can be omitted, types can be mixed
alias DictEntry = Tuple!(string, int);
auto dict = DictEntry("seven", 7);

// element types can be inferred
assert(tuple(2, 3, 4)[1] == 3);
// type inference works with names too
auto tup = tuple!("x", "y", "z")(2, 3, 4);
assert(tup.y == 3);

Rebindable references to const and immutable objects

class Widget
{
    void foo() const @safe {}
}
const w1 = new Widget, w2 = new Widget;
w1.foo();
// w1 = w2 would not work; can't rebind const object

auto r = Rebindable!(const Widget)(w1);
// invoke method as if r were a Widget object
r.foo();
// rebind r to refer to another object
r = w2;
@copyrightCopyright the respective authors, 2008-@licenseBoost License 1.0.@authorsAndrei Alexandrescu, Bartosz Milewski, Don Clugston, Shin Fujishiro, Kenji Hara
typecons
:
(alias template) nullable = std.typecons.nullable(T)(T t)

Defines a value paired with a distinctive "null" state that denotes the absence of a value. If default constructed, a $(D Nullable!T) object starts in the null state. Assigning it renders it non-null. Calling nullify can nullify it again.

Practically Nullable!T stores a T and a bool.

See also: $(LREF apply), an alternative way to use the payload.

nullable
;
import
(package) sparkles
sparkles
.
(package) sparkles.test_runner
test_runner
.
(module) sparkles.test_runner.perf

Hardware performance counters via perf_event_open(2), in pure D.

One counter group (cycles leader; instructions, branches, branch-misses, cache-references, cache-misses, plus the page-fault software event) is opened once and reused: a benchmark's counting pass — separate from the wall-clock measurement — brackets only the timed body with PERF_EVENT_IOC_ENABLE/DISABLE, so the per-iteration ioctls never pollute the reported timings and any between() cleanup is never counted.

Counters answer why two implementations differ: IPC, cycles and instructions per iteration, branch/cache miss rates, and the page-fault (allocation) signature. On kernels that refuse perf_event_open (perf_event_paranoid, seccomp) — and on platforms with no backend at all — this degrades gracefully: PerfGroup.available is false and callers simply omit the counter columns.

The binding is pure D over druntime's core.sys.linux.perf_event (which carries the arch-specific syscall numbers, the perf_event_attr layout, and a perf_event_open wrapper) plus ioctl/read/close — no ImportC, so the module source-includes cleanly into every host package's test build.

On macOS the same PerfGroup surface is backed by proc_pid_rusage(RUSAGE_INFO_V4) — the unprivileged XNU fixed counters: true retired instructions and core cycles (process-wide, user+kernel, all threads), so --perf`` renders IPC and instr/iter with the other columns honestly absent. Everything richer is a capability ad, not a backend: kpc is root-or-blessed with the RESTRICT_TO_KNOWN allowlist, and sampling is Instruments/xctrace-brokered only.

perf
:
(struct) sparkles.test_runner.perf.PerfStats

Per-iteration counter averages of one counting pass. A field is nan when the event could not be opened on this machine (e.g. the LLC pair was dropped to avoid multiplexing, or the PMU exposes fewer events).

PerfStats
;
import
(package) sparkles
sparkles
.
(package) sparkles.test_runner
test_runner
.
(module) sparkles.test_runner.syscalls

In-process syscall counting via perf_event_open tracepoints, in pure D — strace -c without a subprocess or ptrace.

A counter group is opened over syscall tracepoints: raw_syscalls:sys_enter (the group leader) counts every syscall, and one ``syscalls:sys_enter_<name> counter per requested name gives the per-syscall breakdown. The tracepoint ids come from tracefs (/sys/kernel/tracing/events/<group>/<event>/id). Counting is kernel-side, so — like perf.d — a separate counting pass brackets each benchmark's timed body with ENABLE/DISABLE, and the ioctls never perturb the reported timings.

attr.inherit is set, so counters clone into every thread the process spawns after perf_event_open — and the group opens once at bench-mode start, before any case's setup runs, so worker pools created in untimed setup are followed too (their syscalls aggregate into the leader's group read). Only threads that already existed when the group opened are not followed — that needs per-TID attach (a later refinement) or the ptrace backend the roadmap prepares behind the same --syscalls`` flag.

Tracepoints need perf_event_paranoid <= 1; where they can't be opened — and everywhere off Linux — the group degrades to unavailable and the columns are simply omitted. Pure D over druntime's core.sys.linux.perf_event; no ImportC.

syscalls
:
(struct) sparkles.test_runner.syscalls.SyscallStats

Per-iteration syscall counts of one counting pass. total is every syscall (raw_syscalls:sys_enter); counts[i] is the per-iteration count of the tracepoint named named[i] (nan if that tracepoint could not be opened).

SyscallStats
;
(struct) sparkles.test_runner.workload.WorkloadWindow

One measured window. Deliberately NOT BenchStats: its per-iteration timing fields would misrepresent a single window — counter stats here are window totals (iters == 1).

WorkloadWindow
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
;
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) string sparkles.test_runner.workload.WorkloadWindow.name
name
= "ingest";
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) uint sparkles.test_runner.workload.WorkloadWindow.reps

times the window content ran inside this window

reps
= 2;
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) long sparkles.test_runner.workload.WallDecomposition.wallNs

the window's wall-clock duration

wallNs
= 41_235_678;
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) string sparkles.test_runner.workload.WallDecomposition.scope_

"thread" (Linux) or "process"

scope_
= "thread";
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) double sparkles.test_runner.workload.WallDecomposition.onCpuUserNs

rusage user time (µs resolution)

onCpuUserNs
= 31_000_000;
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) double sparkles.test_runner.workload.WallDecomposition.onCpuKernelNs

rusage system time

onCpuKernelNs
= 4_000_000;
// runqueue stays nan (schedstat-less host) → null in the document
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) double sparkles.test_runner.workload.WallDecomposition.offCpuOtherNs

clamped residual: locks, sleeps, the rest

offCpuOtherNs
= 6_235_678;
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) string sparkles.test_runner.workload.WallDecomposition.note

clamp/absence/cross-thread disclosures, "; "-joined

note
= "runqueue wait unattributed (schedstat unreadable) — included in other";
(struct) sparkles.test_runner.perf.PerfStats

Per-iteration counter averages of one counting pass. A field is nan when the event could not be opened on this machine (e.g. the LLC pair was dropped to avoid multiplexing, or the PMU exposes fewer events).

PerfStats
(local variable) sparkles.test_runner.perf.PerfStats p
p
;
(local variable) sparkles.test_runner.perf.PerfStats p
p
.
(field) ulong sparkles.test_runner.perf.PerfStats.iters

counting-pass iterations

iters
= 1;
(local variable) sparkles.test_runner.perf.PerfStats p
p
.
(field) double sparkles.test_runner.perf.PerfStats.instructions

retired instructions per iteration

instructions
= 2.41e9;
(local variable) sparkles.test_runner.perf.PerfStats p
p
.
(field) double sparkles.test_runner.perf.PerfStats.cycles

CPU cycles per iteration

cycles
= 3.1e9;
(local variable) sparkles.test_runner.perf.PerfStats p
p
.
(field) double sparkles.test_runner.perf.PerfStats.pageFaults

page faults per iteration

pageFaults
= 12;
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) std.typecons.Nullable!(PerfStats) sparkles.test_runner.workload.WorkloadWindow.perf
perf
=
std.typecons.Nullable!(PerfStats) std.typecons.nullable!(sparkles.test_runner.perf.PerfStats)(sparkles.test_runner.perf.PerfStats t) pure nothrow @nogc @safe

Defines a value paired with a distinctive "null" state that denotes the absence of a value. If default constructed, a Nullable!T object starts in the null state. Assigning it renders it non-null. Calling nullify can nullify it again.

Practically Nullable!T stores a T and a bool.

See also: apply, an alternative way to use the payload.

Examples

struct CustomerRecord
{
    string name;
    string address;
    int customerNum;
}

Nullable!CustomerRecord getByName(string name)
{
    //A bunch of hairy stuff

    return Nullable!CustomerRecord.init;
}

auto queryResult = getByName("Doe, John");
if (!queryResult.isNull)
{
    //Process Mr. Doe's customer record
    auto address = queryResult.get.address;
    auto customerNum = queryResult.get.customerNum;

    //Do some things with this customer's info
}
else
{
    //Add the customer to the database
}
import std.exception : assertThrown;

auto a = 42.nullable;
assert(!a.isNull);
assert(a.get == 42);

a.nullify();
assert(a.isNull);
assertThrown!Throwable(a.get);
import std.algorithm.iteration : each, joiner;
Nullable!int a = 42;
Nullable!int b;
// Add each value to an array
int[] arr;
a.each!((n) => arr ~= n);
assert(arr == [42]);
b.each!((n) => arr ~= n);
assert(arr == [42]);
// Take first value from an array of Nullables
Nullable!int[] c = new Nullable!int[](10);
c[7] = Nullable!int(42);
assert(c.joiner.front == 42);
nullable
(
(local variable) sparkles.test_runner.perf.PerfStats p
p
);
(struct) sparkles.test_runner.syscalls.SyscallStats

Per-iteration syscall counts of one counting pass. total is every syscall (raw_syscalls:sys_enter); counts[i] is the per-iteration count of the tracepoint named named[i] (nan if that tracepoint could not be opened).

SyscallStats
(local variable) sparkles.test_runner.syscalls.SyscallStats s
s
;
(local variable) sparkles.test_runner.syscalls.SyscallStats s
s
.
(field) ulong sparkles.test_runner.syscalls.SyscallStats.iters
iters
= 1;
(local variable) sparkles.test_runner.syscalls.SyscallStats s
s
.
(field) double sparkles.test_runner.syscalls.SyscallStats.total
total
= 1234;
(local variable) sparkles.test_runner.syscalls.SyscallStats s
s
.
(field) const(string)[] sparkles.test_runner.syscalls.SyscallStats.named
named
= ["read"];
(local variable) sparkles.test_runner.syscalls.SyscallStats s
s
.
(field) double[] sparkles.test_runner.syscalls.SyscallStats.counts
counts
= [600.0];
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) std.typecons.Nullable!(SyscallStats) sparkles.test_runner.workload.WorkloadWindow.syscalls
syscalls
=
std.typecons.Nullable!(SyscallStats) std.typecons.nullable!(sparkles.test_runner.syscalls.SyscallStats)(sparkles.test_runner.syscalls.SyscallStats t) pure nothrow @nogc @safe

Defines a value paired with a distinctive "null" state that denotes the absence of a value. If default constructed, a Nullable!T object starts in the null state. Assigning it renders it non-null. Calling nullify can nullify it again.

Practically Nullable!T stores a T and a bool.

See also: apply, an alternative way to use the payload.

Examples

struct CustomerRecord
{
    string name;
    string address;
    int customerNum;
}

Nullable!CustomerRecord getByName(string name)
{
    //A bunch of hairy stuff

    return Nullable!CustomerRecord.init;
}

auto queryResult = getByName("Doe, John");
if (!queryResult.isNull)
{
    //Process Mr. Doe's customer record
    auto address = queryResult.get.address;
    auto customerNum = queryResult.get.customerNum;

    //Do some things with this customer's info
}
else
{
    //Add the customer to the database
}
import std.exception : assertThrown;

auto a = 42.nullable;
assert(!a.isNull);
assert(a.get == 42);

a.nullify();
assert(a.isNull);
assertThrown!Throwable(a.get);
import std.algorithm.iteration : each, joiner;
Nullable!int a = 42;
Nullable!int b;
// Add each value to an array
int[] arr;
a.each!((n) => arr ~= n);
assert(arr == [42]);
b.each!((n) => arr ~= n);
assert(arr == [42]);
// Take first value from an array of Nullables
Nullable!int[] c = new Nullable!int[](10);
c[7] = Nullable!int(42);
assert(c.joiner.front == 42);
nullable
(
(local variable) sparkles.test_runner.syscalls.SyscallStats s
s
);
(struct) sparkles.test_runner.workload.WorkloadWindow

One measured window. Deliberately NOT BenchStats: its per-iteration timing fields would misrepresent a single window — counter stats here are window totals (iters == 1).

WorkloadWindow
(local variable) sparkles.test_runner.workload.WorkloadWindow err
err
;
(local variable) sparkles.test_runner.workload.WorkloadWindow err
err
.
(field) string sparkles.test_runner.workload.WorkloadWindow.name
name
= "bad";
(local variable) sparkles.test_runner.workload.WorkloadWindow err
err
.
(field) uint sparkles.test_runner.workload.WorkloadWindow.reps

times the window content ran inside this window

reps
= 1;
(local variable) sparkles.test_runner.workload.WorkloadWindow err
err
.
(field) string sparkles.test_runner.workload.WorkloadWindow.error

non-empty = error (or, with skipped, skip) row

error
= "object.Exception: boom";
(struct) sparkles.test_runner.workload.WorkloadWindow

One measured window. Deliberately NOT BenchStats: its per-iteration timing fields would misrepresent a single window — counter stats here are window totals (iters == 1).

WorkloadWindow
(local variable) sparkles.test_runner.workload.WorkloadWindow skipped
skipped
;
(local variable) sparkles.test_runner.workload.WorkloadWindow skipped
skipped
.
(field) string sparkles.test_runner.workload.WorkloadWindow.name
name
= "skippy";
(local variable) sparkles.test_runner.workload.WorkloadWindow skipped
skipped
.
(field) uint sparkles.test_runner.workload.WorkloadWindow.reps

times the window content ran inside this window

reps
= 1;
(local variable) sparkles.test_runner.workload.WorkloadWindow skipped
skipped
.
(field) string sparkles.test_runner.workload.WorkloadWindow.error

non-empty = error (or, with skipped, skip) row

error
= "no hardware";
(local variable) sparkles.test_runner.workload.WorkloadWindow skipped
skipped
.
(field) bool sparkles.test_runner.workload.WorkloadWindow.skipped
skipped
= true;
const
(local variable) const(std.json.JSONValue) doc
doc
=
std.json.JSONValue std.json.parseJSON!string(string json, int maxDepth = -1, std.json.JSONOptions options = JSONOptions.none) pure @safe

Parses a serialized string and returns a tree of JSON values.

@throwsJSONException if string does not follow the JSON grammar or the depth exceeds the max depth, ConvException if a number in the input cannot be represented by a native D type.@paramjson json-formatted string to parse@parammaxDepth maximum depth of nesting allowed, -1 disables depth checking@paramoptions enable decoding string representations of NaN/Inf as float values
parseJSON
(
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
(null,
(struct) sparkles.test_runner.bench_json.BenchMeta

Provenance and the effective measurement knobs stamped onto a report, so a committed baseline is self-describing (the budget it was measured under is part of the data, not tribal knowledge).

BenchMeta
(date: "2026-08-02"),
[
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
,
(local variable) sparkles.test_runner.workload.WorkloadWindow err
err
,
(local variable) sparkles.test_runner.workload.WorkloadWindow skipped
skipped
]));
assert(
(local variable) const(std.json.JSONValue) doc
doc
["schema"].
long std.json.JSONValue.integer() const pure @property @safe

Value getter/setter for JSONType.integer``.

@throwsJSONException for read access if type is not JSONType.integer``.
integer
== 2, "windows fold into unreleased schema 2");
const
(local variable) const(std.json.JSONValue) win
win
=
(local variable) const(std.json.JSONValue) doc
doc
["windows"][0];
assert(
(local variable) const(std.json.JSONValue) win
win
["name"].
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
== "ingest");
assert(
(local variable) const(std.json.JSONValue) win
win
["reps"].
long std.json.JSONValue.integer() const pure @property @safe

Value getter/setter for JSONType.integer``.

@throwsJSONException for read access if type is not JSONType.integer``.
integer
== 2);
assert(
(local variable) const(std.json.JSONValue) win
win
["wallNs"].
long std.json.JSONValue.integer() const pure @property @safe

Value getter/setter for JSONType.integer``.

@throwsJSONException for read access if type is not JSONType.integer``.
integer
== 41_235_678);
assert(
(local variable) const(std.json.JSONValue) win
win
["scope"].
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
== "thread");
assert(
(local variable) const(std.json.JSONValue) win
win
["onCpuUserNs"].
long std.json.JSONValue.integer() const pure @property @safe

Value getter/setter for JSONType.integer``.

@throwsJSONException for read access if type is not JSONType.integer``.
integer
== 31_000_000);
assert(
(local variable) const(std.json.JSONValue) win
win
["offCpuRunqueueNs"].
std.json.JSONType std.json.JSONValue.type() const pure nothrow @nogc @property @safe

Returns the JSONType of the value stored in this structure.

Examples

string s = "{ \"language\": \"D\" }";
JSONValue j = parseJSON(s);
assert(j.type == JSONType.object);
assert(j["language"].type == JSONType.string);
type
==
(enum) std.json.JSONType

Enumeration of JSON types

JSONType
.
(enum value) std.json.JSONType.null_ = cast(byte)0

Indicates the type of a JSONValue.

null_
,
"unattributable = null, exactly the table's em dash"); assert(
(local variable) const(std.json.JSONValue) win
win
["offCpuDiskNs"].
std.json.JSONType std.json.JSONValue.type() const pure nothrow @nogc @property @safe

Returns the JSONType of the value stored in this structure.

Examples

string s = "{ \"language\": \"D\" }";
JSONValue j = parseJSON(s);
assert(j.type == JSONType.object);
assert(j["language"].type == JSONType.string);
type
==
(enum) std.json.JSONType

Enumeration of JSON types

JSONType
.
(enum value) std.json.JSONType.null_ = cast(byte)0

Indicates the type of a JSONValue.

null_
,
"PSI is system-scoped; disk attribution lands with M8 cgroups"); assert(
(local variable) const(std.json.JSONValue) win
win
["perf"]["instructions"].
long std.json.JSONValue.integer() const pure @property @safe

Value getter/setter for JSONType.integer``.

@throwsJSONException for read access if type is not JSONType.integer``.
integer
== 2_410_000_000,
"integral totals render as JSON integers"); assert(
(local variable) const(std.json.JSONValue) win
win
["perf"]["scale"].
long std.json.JSONValue.integer() const pure @property @safe

Value getter/setter for JSONType.integer``.

@throwsJSONException for read access if type is not JSONType.integer``.
integer
== 1);
assert(
(local variable) const(std.json.JSONValue) win
win
["syscalls"]["total"].
long std.json.JSONValue.integer() const pure @property @safe

Value getter/setter for JSONType.integer``.

@throwsJSONException for read access if type is not JSONType.integer``.
integer
== 1234);
assert(
(local variable) const(std.json.JSONValue) win
win
["syscalls"]["named"]["read"].
long std.json.JSONValue.integer() const pure @property @safe

Value getter/setter for JSONType.integer``.

@throwsJSONException for read access if type is not JSONType.integer``.
integer
== 600);
assert("tier0" !in
(local variable) const(std.json.JSONValue) win
win
, "an absent source omits its key");
assert("raw" !in
(local variable) const(std.json.JSONValue) win
win
);
assert("psi" !in
(local variable) const(std.json.JSONValue) win
win
, "psi omits its key like every absent source");
assert(
(local variable) const(std.json.JSONValue) win
win
["note"].
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
.
(field) ulong string.length
length
> 0);
assert(
(local variable) const(std.json.JSONValue) win
win
["error"].
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
== "");
const
(local variable) const(std.json.JSONValue) bad
bad
=
(local variable) const(std.json.JSONValue) doc
doc
["windows"][1];
assert(
(local variable) const(std.json.JSONValue) bad
bad
["wallNs"].
std.json.JSONType std.json.JSONValue.type() const pure nothrow @nogc @property @safe

Returns the JSONType of the value stored in this structure.

Examples

string s = "{ \"language\": \"D\" }";
JSONValue j = parseJSON(s);
assert(j.type == JSONType.object);
assert(j["language"].type == JSONType.string);
type
==
(enum) std.json.JSONType

Enumeration of JSON types

JSONType
.
(enum value) std.json.JSONType.null_ = cast(byte)0

Indicates the type of a JSONValue.

null_
);
// The always-present keys mirror the error-row shape: null, not absent. assert(
(local variable) const(std.json.JSONValue) bad
bad
["scope"].
std.json.JSONType std.json.JSONValue.type() const pure nothrow @nogc @property @safe

Returns the JSONType of the value stored in this structure.

Examples

string s = "{ \"language\": \"D\" }";
JSONValue j = parseJSON(s);
assert(j.type == JSONType.object);
assert(j["language"].type == JSONType.string);
type
==
(enum) std.json.JSONType

Enumeration of JSON types

JSONType
.
(enum value) std.json.JSONType.null_ = cast(byte)0

Indicates the type of a JSONValue.

null_
);
assert(
(local variable) const(std.json.JSONValue) bad
bad
["onCpuUserNs"].
std.json.JSONType std.json.JSONValue.type() const pure nothrow @nogc @property @safe

Returns the JSONType of the value stored in this structure.

Examples

string s = "{ \"language\": \"D\" }";
JSONValue j = parseJSON(s);
assert(j.type == JSONType.object);
assert(j["language"].type == JSONType.string);
type
==
(enum) std.json.JSONType

Enumeration of JSON types

JSONType
.
(enum value) std.json.JSONType.null_ = cast(byte)0

Indicates the type of a JSONValue.

null_
);
assert(
(local variable) const(std.json.JSONValue) bad
bad
["offCpuOtherNs"].
std.json.JSONType std.json.JSONValue.type() const pure nothrow @nogc @property @safe

Returns the JSONType of the value stored in this structure.

Examples

string s = "{ \"language\": \"D\" }";
JSONValue j = parseJSON(s);
assert(j.type == JSONType.object);
assert(j["language"].type == JSONType.string);
type
==
(enum) std.json.JSONType

Enumeration of JSON types

JSONType
.
(enum value) std.json.JSONType.null_ = cast(byte)0

Indicates the type of a JSONValue.

null_
);
assert(
(local variable) const(std.json.JSONValue) bad
bad
["error"].
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
== "object.Exception: boom");
assert("skipped" !in
(local variable) const(std.json.JSONValue) bad
bad
);
assert(
(local variable) const(std.json.JSONValue) doc
doc
["windows"][2]["skipped"].
bool std.json.JSONValue.boolean() const pure @property @safe

Value getter/setter for boolean stored in JSON.

@throwsJSONException for read access if this.type is not JSONType.true_ or JSONType.false_.
boolean
);
} @("benchJson.windows.absentKeepsDocumentByteIdentical") @safe unittest { // A run without workloads must stay byte-identical to the pre-window // document — `windows` is a pure addition, not a schema perturbation.
(struct) sparkles.test_runner.bench.BenchStats

Summary statistics of one benchmark row, in nanoseconds per iteration. A row with a non-empty error is a failure row (its timing fields are unset).

BenchStats
(local variable) sparkles.test_runner.bench.BenchStats row
row
;
(local variable) sparkles.test_runner.bench.BenchStats row
row
.
(field) string sparkles.test_runner.bench.BenchStats.name
name
= "r";
(local variable) sparkles.test_runner.bench.BenchStats row
row
.
(field) ulong sparkles.test_runner.bench.BenchStats.iterations

iterations per sample

iterations
= 1;
const
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
=
(struct) sparkles.test_runner.bench_json.BenchMeta

Provenance and the effective measurement knobs stamped onto a report, so a committed baseline is self-describing (the budget it was measured under is part of the data, not tribal knowledge).

BenchMeta
(date: "2026-08-02");
assert(
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
([
(local variable) sparkles.test_runner.bench.BenchStats row
row
],
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
) ==
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
([
(local variable) sparkles.test_runner.bench.BenchStats row
row
],
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
, null));
assert(
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
(null,
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
) ==
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
(null,
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
, null));
// And a psi-less window (a CONFIG_PSI=n host) must omit the psi key — // asserted explicitly, not incidentally.
(struct) sparkles.test_runner.workload.WorkloadWindow

One measured window. Deliberately NOT BenchStats: its per-iteration timing fields would misrepresent a single window — counter stats here are window totals (iters == 1).

WorkloadWindow
(local variable) sparkles.test_runner.workload.WorkloadWindow noPsi
noPsi
;
(local variable) sparkles.test_runner.workload.WorkloadWindow noPsi
noPsi
.
(field) string sparkles.test_runner.workload.WorkloadWindow.name
name
= "w";
(local variable) sparkles.test_runner.workload.WorkloadWindow noPsi
noPsi
.
(field) uint sparkles.test_runner.workload.WorkloadWindow.reps

times the window content ran inside this window

reps
= 1;
(local variable) sparkles.test_runner.workload.WorkloadWindow noPsi
noPsi
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) long sparkles.test_runner.workload.WallDecomposition.wallNs

the window's wall-clock duration

wallNs
= 1;
(local variable) sparkles.test_runner.workload.WorkloadWindow noPsi
noPsi
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) string sparkles.test_runner.workload.WallDecomposition.scope_

"thread" (Linux) or "process"

scope_
= "thread";
import
(package) std
std
.
(package) std.algorithm
algorithm
.
(module) std.algorithm.searching

This is a submodule of std.algorithm. It contains generic searching algorithms.

Function Name Description
all all!"a > 0"([1, 2, 3, 4]) returns true because all elements are positive
any any!"a > 0"([1, 2, -3, -4]) returns true because at least one element is positive
balancedParens balancedParens("((1 + 1) / 2)", '(', ')') returns true because the string has balanced parentheses.
boyerMooreFinder find("hello world", boyerMooreFinder("or")) returns "orld" using the Boyer-Moore algorithm.
canFind canFind("hello world", "or") returns true.
count Counts all elements or elements matching a predicate, specific element or sub-range.

count([1, 2, 1]) returns 3, count([1, 2, 1], 1) returns 2 and count!"a < 0"([1, -3, 0]) returns 1. | | countUntil | countUntil(a, b) returns the number of steps taken in a to reach b; for example, countUntil("hello!", "o") returns 4. | | commonPrefix | commonPrefix("parakeet", "parachute") returns "para". | | endsWith | endsWith("rocks", "ks") returns true. | | extrema | extrema([2, 1, 3, 5, 4]) returns [1, 5]. | | find | find("hello world", "or") returns "orld" using linear search. (For binary search refer to SortedRange.) | | findAdjacent | findAdjacent([1, 2, 3, 3, 4]) returns the subrange starting with two equal adjacent elements, i.e. [3, 3, 4]. | | findAmong | findAmong("abcd", "qcx") returns "cd" because 'c' is among "qcx". | | findSkip | If a = "abcde", then findSkip(a, "x") returns false and leaves a unchanged, whereas findSkip(a, "c") advances a to "de" and returns true. | | findSplit | findSplit("abcdefg", "de") returns a tuple of three ranges "abc", "de", and "fg". | | findSplitAfter | findSplitAfter("abcdefg", "de") returns a tuple of two ranges "abcde" and "fg". | | findSplitBefore | findSplitBefore("abcdefg", "de") returns a tuple of two ranges "abc" and "defg". | | minCount | minCount([2, 1, 1, 4, 1]) returns tuple(1, 3). | | maxCount | maxCount([2, 4, 1, 4, 1]) returns tuple(4, 2). | | minElement | Selects the minimal element of a range. minElement([3, 4, 1, 2]) returns 1. | | maxElement | Selects the maximal element of a range. maxElement([3, 4, 1, 2]) returns 4. | | minIndex | Index of the minimal element of a range. minIndex([3, 4, 1, 2]) returns 2. | | maxIndex | Index of the maximal element of a range. maxIndex([3, 4, 1, 2]) returns 1. | | minPos | minPos([2, 3, 1, 3, 4, 1]) returns the subrange [1, 3, 4, 1], i.e., positions the range at the first occurrence of its minimal element. | | maxPos | maxPos([2, 3, 1, 3, 4, 1]) returns the subrange [4, 1], i.e., positions the range at the first occurrence of its maximal element. | | skipOver | Assume a = "blah". Then skipOver(a, "bi") leaves a unchanged and returns false, whereas skipOver(a, "bl") advances a to refer to "ah" and returns true. | | startsWith | startsWith("hello, world", "hello") returns true. | | until | Lazily iterates a range until a specific value is found. |

Source

std/algorithm/searching.d

@copyrightAndrei Alexandrescu 2008-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu
searching
:
(alias template) canFind = std.algorithm.searching.canFind(alias pred = "a == b")

Convenience function. Like find, but only returns whether or not the search was successful.

For more information about pred see $(LREF find).

See_Also: $(REF among, std,algorithm,comparison) for checking a value against multiple arguments.

canFind
;
assert(!
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
(null,
(local variable) const(sparkles.test_runner.bench_json.BenchMeta) meta
meta
, [
(local variable) sparkles.test_runner.workload.WorkloadWindow noPsi
noPsi
]).
bool std.algorithm.searching.canFind!().canFind!(string, string)(string haystack, scope string needle) pure nothrow @nogc @safe

Convenience function. Like find, but only returns whether or not the search was successful.

For more information about pred see find.

Examples

const arr = [0, 1, 2, 3];
assert(canFind(arr, 2));
assert(!canFind(arr, 4));

// find one of several needles
assert(arr.canFind(3, 2));
assert(arr.canFind(3, 2) == 2); // second needle found
assert(arr.canFind([1, 3], 2) == 2);

assert(canFind(arr, [1, 2], [2, 3]));
assert(canFind(arr, [1, 2], [2, 3]) == 1);
assert(canFind(arr, [1, 7], [2, 3]));
assert(canFind(arr, [1, 7], [2, 3]) == 2);
assert(!canFind(arr, [1, 3], [2, 4]));
assert(canFind(arr, [1, 3], [2, 4]) == 0);

Example using a custom predicate. Note that the needle appears as the second argument of the predicate.

auto words = [
    "apple",
    "beeswax",
    "cardboard"
];
assert(!canFind(words, "bees"));
assert( canFind!((string elem, string needle) => elem.startsWith(needle))(words, "bees"));

Search for multiple items in an array of items (search for needles in an array of haystacks)

string s1 = "aaa111aaa";
string s2 = "aaa222aaa";
string s3 = "aaa333aaa";
string s4 = "aaa444aaa";
const hay = [s1, s2, s3, s4];
assert(hay.canFind!(e => e.canFind("111", "222")));
@see

among for checking a value against multiple arguments.

Returns true if and only if needle can be found in range. Performs O(haystack.length) evaluations of pred.

canFind
("\"psi\""));
} @("benchJson.windows.psiObject") @system unittest { import
(package) std
std
.
(module) std.json

Implements functionality to read and write JavaScript Object Notation values.

JavaScript Object Notation is a lightweight data interchange format commonly used in web services and configuration files. It's easy for humans to read and write, and it's easy for machines to parse and generate.

Warning: While JSONValue is fine for small-scale use, at the range of hundreds of megabytes it is known to cause and exacerbate GC problems. If you encounter problems, try replacing it with a stream parser. See also https://forum.dlang.org/post/dzfyaxypmkdrpakmycjv@forum.dlang.org.

References

http://json.org/, https://seriot.ch/projects/parsing_json.html

Source

std/json.d

Examples

import std.conv : to;

// parse a file or string of json into a usable structure
string s = `{ "language": "D", "rating": 3.5, "code": "42" }`;
JSONValue j = parseJSON(s);
// j and j["language"] return JSONValue,
// j["language"].str returns a string
assert(j["language"].str == "D");
assert(j["rating"].floating == 3.5);

// check a type
long x;
if (const(JSONValue)* code = "code" in j)
{
    if (code.type() == JSONType.integer)
        x = code.integer;
    else
        x = to!int(code.str);
}

// create a json struct
JSONValue jj = [ "language": "D" ];
// rating doesnt exist yet, so use .object to assign
jj.object["rating"] = JSONValue(3.5);
// create an array to assign to list
jj.object["list"] = JSONValue( ["a", "b", "c"] );
// list already exists, so .object optional
jj["list"].array ~= JSONValue("D");

string jjStr = `{"language":"D","list":["a","b","c","D"],"rating":3.5}`;
assert(jj.toString == jjStr);
@copyrightCopyright Jeremie Pelletier 2008 - 2009.@licenseBoost License 1.0.@authorsJeremie Pelletier, David Herberth
json
:
(enum) std.json.JSONType

Enumeration of JSON types

JSONType
,
(alias template) parseJSON = std.json.parseJSON(T)(T json, int maxDepth = -1, JSONOptions options = JSONOptions.none) if (isSomeFiniteCharInputRange!T)

Parses a serialized string and returns a tree of JSON values. Throws: $(LREF JSONException) if string does not follow the JSON grammar or the depth exceeds the max depth, $(LREF ConvException) if a number in the input cannot be represented by a native D type. Params: json = json-formatted string to parse maxDepth = maximum depth of nesting allowed, -1 disables depth checking options = enable decoding string representations of NaN/Inf as float values

parseJSON
;
import
(package) std
std
.
(module) std.typecons

This module implements a variety of type constructors, i.e., templates that allow construction of new, useful general-purpose types.

Category Symbols
Tuple isTuple Tuple tuple reverse
Flags BitFlags isBitFlagEnum Flag No Yes
Reference Counting borrow RefCountedAutoInitialize RefCounted refCounted SafeRefCounted safeRefCounted
Memory allocation scoped Unique
Code generation AutoImplement BlackHole generateAssertTrap generateEmptyFunction NotImplementedError WhiteHole
Nullable apply Nullable nullable NullableRef nullableRef
Proxies Proxy rebindable Rebindable unwrap wrap
Types alignForSize ReplaceType ReplaceTypeUnless Ternary Typedef TypedefType UnqualRef

Source

std/typecons.d

Examples

Value tuples

alias Coord = Tuple!(int, "x", int, "y", int, "z");
Coord c;
c[1] = 1;       // access by index
c.z = 1;        // access by given name
assert(c == Coord(0, 1, 1));

// names can be omitted, types can be mixed
alias DictEntry = Tuple!(string, int);
auto dict = DictEntry("seven", 7);

// element types can be inferred
assert(tuple(2, 3, 4)[1] == 3);
// type inference works with names too
auto tup = tuple!("x", "y", "z")(2, 3, 4);
assert(tup.y == 3);

Rebindable references to const and immutable objects

class Widget
{
    void foo() const @safe {}
}
const w1 = new Widget, w2 = new Widget;
w1.foo();
// w1 = w2 would not work; can't rebind const object

auto r = Rebindable!(const Widget)(w1);
// invoke method as if r were a Widget object
r.foo();
// rebind r to refer to another object
r = w2;
@copyrightCopyright the respective authors, 2008-@licenseBoost License 1.0.@authorsAndrei Alexandrescu, Bartosz Milewski, Don Clugston, Shin Fujishiro, Kenji Hara
typecons
:
(alias template) nullable = std.typecons.nullable(T)(T t)

Defines a value paired with a distinctive "null" state that denotes the absence of a value. If default constructed, a $(D Nullable!T) object starts in the null state. Assigning it renders it non-null. Calling nullify can nullify it again.

Practically Nullable!T stores a T and a bool.

See also: $(LREF apply), an alternative way to use the payload.

nullable
;
import
(package) sparkles
sparkles
.
(package) sparkles.test_runner
test_runner
.
(module) sparkles.test_runner.workload

The @workload`` window measurement model: one window, counter deltas.

Where @benchmark runs a body many times and reports per-iteration statistics, a workload runs once (or a few reps) and reports what happened across the window: every open counter source's delta between two edge snapshots, plus a wall-clock decomposition into on-CPU time (rusage), runqueue wait (schedstat), and a clamped residual. Sources are read cumulatively at the edges (no per-iteration ioctl bracket, no RESET — see sparkles.test_runner.perf_group.GroupSnapshot), so the driver's whole-body candidate window and in-body workloadWindow calls overlap freely in a single pass — a workload body is never re-run for counting, because it may be expensive or non-idempotent.

Edge-snapshot nesting order (outer → inner): psi, wall clock, wall source (rusage/schedstat), syscalls, raw, tier-0, perf — so the cycle counters see only the body, and each tier's window contains at most the inner tiers' edge reads (a handful of syscalls per edge, negligible at window granularity and disclosed here rather than hidden). Psi sits outermost — outside even the wall clock and rusage windows — so its six file reads per edge (~20 µs) contribute zero apparatus anywhere in the decomposition; a system-wide µs-resolution integral's own window being a few µs wider than the wall clock is immaterial.

Decomposition honesty: only runqueue wait is a true per-cause duration today; everything else off-CPU — locks, sleeps, disk — lands in offCpuOtherNs, which clamps at zero and says so in note rather than fabricating a cause. PSI stall integrals ride alongside as system-wide diagnostics (WorkloadWindow.psi) — /proc/pressure cannot attribute to the measured thread, so disk attribution waits for M8's cgroup scoping. On Linux the decomposition is thread-scoped (RUSAGE_THREAD + /proc/thread-self/schedstat — the only scoping under which wall = onCpu + runqueue + other is arithmetically meaningful); the process-wide reading is captured too, purely to disclose CPU burned by other threads. Thread coverage caveats (counters follow clone inheritance, the decomposition follows the driving thread) match the bench modes.

workload
:
(struct) sparkles.test_runner.workload.PsiStats

A window's PSI stall-time deltas, in ns — system-wide diagnostics ("the system accumulated this much stall concurrently with the window"), never attribution to the measured thread (that lands with M8's cgroup-scoped PSI). nan = line absent, edges unreadable, or a backwards accumulator.

PsiStats
;
(struct) sparkles.test_runner.workload.WorkloadWindow

One measured window. Deliberately NOT BenchStats: its per-iteration timing fields would misrepresent a single window — counter stats here are window totals (iters == 1).

WorkloadWindow
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
;
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) string sparkles.test_runner.workload.WorkloadWindow.name
name
= "with-psi";
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) uint sparkles.test_runner.workload.WorkloadWindow.reps

times the window content ran inside this window

reps
= 1;
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) long sparkles.test_runner.workload.WallDecomposition.wallNs

the window's wall-clock duration

wallNs
= 10_000_000;
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) string sparkles.test_runner.workload.WallDecomposition.scope_

"thread" (Linux) or "process"

scope_
= "thread";
(struct) sparkles.test_runner.workload.PsiStats

A window's PSI stall-time deltas, in ns — system-wide diagnostics ("the system accumulated this much stall concurrently with the window"), never attribution to the measured thread (that lands with M8's cgroup-scoped PSI). nan = line absent, edges unreadable, or a backwards accumulator.

PsiStats
(local variable) sparkles.test_runner.workload.PsiStats p
p
;
(local variable) sparkles.test_runner.workload.PsiStats p
p
.
(field) double sparkles.test_runner.workload.PsiStats.ioSomeNs

≥ 1 task stalled on io

ioSomeNs
= 3_000_000;
(local variable) sparkles.test_runner.workload.PsiStats p
p
.
(field) double sparkles.test_runner.workload.PsiStats.ioFullNs

all non-idle tasks stalled on io

ioFullNs
= 200_000;
(local variable) sparkles.test_runner.workload.PsiStats p
p
.
(field) double sparkles.test_runner.workload.PsiStats.memSomeNs
memSomeNs
= 0;
// memFullNs stays nan (absent full line) → null
(local variable) sparkles.test_runner.workload.PsiStats p
p
.
(field) double sparkles.test_runner.workload.PsiStats.cpuSomeNs
cpuSomeNs
= 14_000;
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) std.typecons.Nullable!(PsiStats) sparkles.test_runner.workload.WorkloadWindow.psi

system-wide stall deltas — diagnostics, not attribution

psi
=
std.typecons.Nullable!(PsiStats) std.typecons.nullable!(sparkles.test_runner.workload.PsiStats)(sparkles.test_runner.workload.PsiStats t) pure nothrow @nogc @safe

Defines a value paired with a distinctive "null" state that denotes the absence of a value. If default constructed, a Nullable!T object starts in the null state. Assigning it renders it non-null. Calling nullify can nullify it again.

Practically Nullable!T stores a T and a bool.

See also: apply, an alternative way to use the payload.

Examples

struct CustomerRecord
{
    string name;
    string address;
    int customerNum;
}

Nullable!CustomerRecord getByName(string name)
{
    //A bunch of hairy stuff

    return Nullable!CustomerRecord.init;
}

auto queryResult = getByName("Doe, John");
if (!queryResult.isNull)
{
    //Process Mr. Doe's customer record
    auto address = queryResult.get.address;
    auto customerNum = queryResult.get.customerNum;

    //Do some things with this customer's info
}
else
{
    //Add the customer to the database
}
import std.exception : assertThrown;

auto a = 42.nullable;
assert(!a.isNull);
assert(a.get == 42);

a.nullify();
assert(a.isNull);
assertThrown!Throwable(a.get);
import std.algorithm.iteration : each, joiner;
Nullable!int a = 42;
Nullable!int b;
// Add each value to an array
int[] arr;
a.each!((n) => arr ~= n);
assert(arr == [42]);
b.each!((n) => arr ~= n);
assert(arr == [42]);
// Take first value from an array of Nullables
Nullable!int[] c = new Nullable!int[](10);
c[7] = Nullable!int(42);
assert(c.joiner.front == 42);
nullable
(
(local variable) sparkles.test_runner.workload.PsiStats p
p
);
const
(local variable) const(std.json.JSONValue) doc
doc
=
std.json.JSONValue std.json.parseJSON!string(string json, int maxDepth = -1, std.json.JSONOptions options = JSONOptions.none) pure @safe

Parses a serialized string and returns a tree of JSON values.

@throwsJSONException if string does not follow the JSON grammar or the depth exceeds the max depth, ConvException if a number in the input cannot be represented by a native D type.@paramjson json-formatted string to parse@parammaxDepth maximum depth of nesting allowed, -1 disables depth checking@paramoptions enable decoding string representations of NaN/Inf as float values
parseJSON
(
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
(null,
(struct) sparkles.test_runner.bench_json.BenchMeta

Provenance and the effective measurement knobs stamped onto a report, so a committed baseline is self-describing (the budget it was measured under is part of the data, not tribal knowledge).

BenchMeta
(date: "2026-08-03"), [
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
]));
const
(local variable) const(std.json.JSONValue) psi
psi
=
(local variable) const(std.json.JSONValue) doc
doc
["windows"][0]["psi"];
assert(
(local variable) const(std.json.JSONValue) psi
psi
["scope"].
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
== "system",
"the object self-describes its scope — M8's cgroup source will differ"); assert(
(local variable) const(std.json.JSONValue) psi
psi
["ioSomeNs"].
long std.json.JSONValue.integer() const pure @property @safe

Value getter/setter for JSONType.integer``.

@throwsJSONException for read access if type is not JSONType.integer``.
integer
== 3_000_000);
assert(
(local variable) const(std.json.JSONValue) psi
psi
["ioFullNs"].
long std.json.JSONValue.integer() const pure @property @safe

Value getter/setter for JSONType.integer``.

@throwsJSONException for read access if type is not JSONType.integer``.
integer
== 200_000);
assert(
(local variable) const(std.json.JSONValue) psi
psi
["memSomeNs"].
long std.json.JSONValue.integer() const pure @property @safe

Value getter/setter for JSONType.integer``.

@throwsJSONException for read access if type is not JSONType.integer``.
integer
== 0, "a zero system delta is a true statement");
assert(
(local variable) const(std.json.JSONValue) psi
psi
["memFullNs"].
std.json.JSONType std.json.JSONValue.type() const pure nothrow @nogc @property @safe

Returns the JSONType of the value stored in this structure.

Examples

string s = "{ \"language\": \"D\" }";
JSONValue j = parseJSON(s);
assert(j.type == JSONType.object);
assert(j["language"].type == JSONType.string);
type
==
(enum) std.json.JSONType

Enumeration of JSON types

JSONType
.
(enum value) std.json.JSONType.null_ = cast(byte)0

Indicates the type of a JSONValue.

null_
, "absent full line → null");
assert(
(local variable) const(std.json.JSONValue) psi
psi
["cpuSomeNs"].
long std.json.JSONValue.integer() const pure @property @safe

Value getter/setter for JSONType.integer``.

@throwsJSONException for read access if type is not JSONType.integer``.
integer
== 14_000);
assert("cpuFullNs" !in
(local variable) const(std.json.JSONValue) psi
psi
, "pinned-zero system cpu-full is not emitted");
// The decomposition slot stays honest: no attribution from system scope. assert(
(local variable) const(std.json.JSONValue) doc
doc
["windows"][0]["offCpuDiskNs"].
std.json.JSONType std.json.JSONValue.type() const pure nothrow @nogc @property @safe

Returns the JSONType of the value stored in this structure.

Examples

string s = "{ \"language\": \"D\" }";
JSONValue j = parseJSON(s);
assert(j.type == JSONType.object);
assert(j["language"].type == JSONType.string);
type
==
(enum) std.json.JSONType

Enumeration of JSON types

JSONType
.
(enum value) std.json.JSONType.null_ = cast(byte)0

Indicates the type of a JSONValue.

null_
);
} @("benchJson.windows.regimeObject") @system unittest { import
(package) std
std
.
(package) std.algorithm
algorithm
.
(module) std.algorithm.searching

This is a submodule of std.algorithm. It contains generic searching algorithms.

Function Name Description
all all!"a > 0"([1, 2, 3, 4]) returns true because all elements are positive
any any!"a > 0"([1, 2, -3, -4]) returns true because at least one element is positive
balancedParens balancedParens("((1 + 1) / 2)", '(', ')') returns true because the string has balanced parentheses.
boyerMooreFinder find("hello world", boyerMooreFinder("or")) returns "orld" using the Boyer-Moore algorithm.
canFind canFind("hello world", "or") returns true.
count Counts all elements or elements matching a predicate, specific element or sub-range.

count([1, 2, 1]) returns 3, count([1, 2, 1], 1) returns 2 and count!"a < 0"([1, -3, 0]) returns 1. | | countUntil | countUntil(a, b) returns the number of steps taken in a to reach b; for example, countUntil("hello!", "o") returns 4. | | commonPrefix | commonPrefix("parakeet", "parachute") returns "para". | | endsWith | endsWith("rocks", "ks") returns true. | | extrema | extrema([2, 1, 3, 5, 4]) returns [1, 5]. | | find | find("hello world", "or") returns "orld" using linear search. (For binary search refer to SortedRange.) | | findAdjacent | findAdjacent([1, 2, 3, 3, 4]) returns the subrange starting with two equal adjacent elements, i.e. [3, 3, 4]. | | findAmong | findAmong("abcd", "qcx") returns "cd" because 'c' is among "qcx". | | findSkip | If a = "abcde", then findSkip(a, "x") returns false and leaves a unchanged, whereas findSkip(a, "c") advances a to "de" and returns true. | | findSplit | findSplit("abcdefg", "de") returns a tuple of three ranges "abc", "de", and "fg". | | findSplitAfter | findSplitAfter("abcdefg", "de") returns a tuple of two ranges "abcde" and "fg". | | findSplitBefore | findSplitBefore("abcdefg", "de") returns a tuple of two ranges "abc" and "defg". | | minCount | minCount([2, 1, 1, 4, 1]) returns tuple(1, 3). | | maxCount | maxCount([2, 4, 1, 4, 1]) returns tuple(4, 2). | | minElement | Selects the minimal element of a range. minElement([3, 4, 1, 2]) returns 1. | | maxElement | Selects the maximal element of a range. maxElement([3, 4, 1, 2]) returns 4. | | minIndex | Index of the minimal element of a range. minIndex([3, 4, 1, 2]) returns 2. | | maxIndex | Index of the maximal element of a range. maxIndex([3, 4, 1, 2]) returns 1. | | minPos | minPos([2, 3, 1, 3, 4, 1]) returns the subrange [1, 3, 4, 1], i.e., positions the range at the first occurrence of its minimal element. | | maxPos | maxPos([2, 3, 1, 3, 4, 1]) returns the subrange [4, 1], i.e., positions the range at the first occurrence of its maximal element. | | skipOver | Assume a = "blah". Then skipOver(a, "bi") leaves a unchanged and returns false, whereas skipOver(a, "bl") advances a to refer to "ah" and returns true. | | startsWith | startsWith("hello, world", "hello") returns true. | | until | Lazily iterates a range until a specific value is found. |

Source

std/algorithm/searching.d

@copyrightAndrei Alexandrescu 2008-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu
searching
:
(alias template) canFind = std.algorithm.searching.canFind(alias pred = "a == b")

Convenience function. Like find, but only returns whether or not the search was successful.

For more information about pred see $(LREF find).

See_Also: $(REF among, std,algorithm,comparison) for checking a value against multiple arguments.

canFind
;
import
(package) std
std
.
(module) std.json

Implements functionality to read and write JavaScript Object Notation values.

JavaScript Object Notation is a lightweight data interchange format commonly used in web services and configuration files. It's easy for humans to read and write, and it's easy for machines to parse and generate.

Warning: While JSONValue is fine for small-scale use, at the range of hundreds of megabytes it is known to cause and exacerbate GC problems. If you encounter problems, try replacing it with a stream parser. See also https://forum.dlang.org/post/dzfyaxypmkdrpakmycjv@forum.dlang.org.

References

http://json.org/, https://seriot.ch/projects/parsing_json.html

Source

std/json.d

Examples

import std.conv : to;

// parse a file or string of json into a usable structure
string s = `{ "language": "D", "rating": 3.5, "code": "42" }`;
JSONValue j = parseJSON(s);
// j and j["language"] return JSONValue,
// j["language"].str returns a string
assert(j["language"].str == "D");
assert(j["rating"].floating == 3.5);

// check a type
long x;
if (const(JSONValue)* code = "code" in j)
{
    if (code.type() == JSONType.integer)
        x = code.integer;
    else
        x = to!int(code.str);
}

// create a json struct
JSONValue jj = [ "language": "D" ];
// rating doesnt exist yet, so use .object to assign
jj.object["rating"] = JSONValue(3.5);
// create an array to assign to list
jj.object["list"] = JSONValue( ["a", "b", "c"] );
// list already exists, so .object optional
jj["list"].array ~= JSONValue("D");

string jjStr = `{"language":"D","list":["a","b","c","D"],"rating":3.5}`;
assert(jj.toString == jjStr);
@copyrightCopyright Jeremie Pelletier 2008 - 2009.@licenseBoost License 1.0.@authorsJeremie Pelletier, David Herberth
json
:
(enum) std.json.JSONType

Enumeration of JSON types

JSONType
,
(alias template) parseJSON = std.json.parseJSON(T)(T json, int maxDepth = -1, JSONOptions options = JSONOptions.none) if (isSomeFiniteCharInputRange!T)

Parses a serialized string and returns a tree of JSON values. Throws: $(LREF JSONException) if string does not follow the JSON grammar or the depth exceeds the max depth, $(LREF ConvException) if a number in the input cannot be represented by a native D type. Params: json = json-formatted string to parse maxDepth = maximum depth of nesting allowed, -1 disables depth checking options = enable decoding string representations of NaN/Inf as float values

parseJSON
;
import
(package) std
std
.
(module) std.typecons

This module implements a variety of type constructors, i.e., templates that allow construction of new, useful general-purpose types.

Category Symbols
Tuple isTuple Tuple tuple reverse
Flags BitFlags isBitFlagEnum Flag No Yes
Reference Counting borrow RefCountedAutoInitialize RefCounted refCounted SafeRefCounted safeRefCounted
Memory allocation scoped Unique
Code generation AutoImplement BlackHole generateAssertTrap generateEmptyFunction NotImplementedError WhiteHole
Nullable apply Nullable nullable NullableRef nullableRef
Proxies Proxy rebindable Rebindable unwrap wrap
Types alignForSize ReplaceType ReplaceTypeUnless Ternary Typedef TypedefType UnqualRef

Source

std/typecons.d

Examples

Value tuples

alias Coord = Tuple!(int, "x", int, "y", int, "z");
Coord c;
c[1] = 1;       // access by index
c.z = 1;        // access by given name
assert(c == Coord(0, 1, 1));

// names can be omitted, types can be mixed
alias DictEntry = Tuple!(string, int);
auto dict = DictEntry("seven", 7);

// element types can be inferred
assert(tuple(2, 3, 4)[1] == 3);
// type inference works with names too
auto tup = tuple!("x", "y", "z")(2, 3, 4);
assert(tup.y == 3);

Rebindable references to const and immutable objects

class Widget
{
    void foo() const @safe {}
}
const w1 = new Widget, w2 = new Widget;
w1.foo();
// w1 = w2 would not work; can't rebind const object

auto r = Rebindable!(const Widget)(w1);
// invoke method as if r were a Widget object
r.foo();
// rebind r to refer to another object
r = w2;
@copyrightCopyright the respective authors, 2008-@licenseBoost License 1.0.@authorsAndrei Alexandrescu, Bartosz Milewski, Don Clugston, Shin Fujishiro, Kenji Hara
typecons
:
(alias template) nullable = std.typecons.nullable(T)(T t)

Defines a value paired with a distinctive "null" state that denotes the absence of a value. If default constructed, a $(D Nullable!T) object starts in the null state. Assigning it renders it non-null. Calling nullify can nullify it again.

Practically Nullable!T stores a T and a bool.

See also: $(LREF apply), an alternative way to use the payload.

nullable
;
import
(package) sparkles
sparkles
.
(package) sparkles.test_runner
test_runner
.
(module) sparkles.test_runner.attributes

User-defined attributes recognized by the sparkles:test-runner unittest runner.

Attach these to unittest blocks to opt into special handling:

import sparkles.test_runner.attributes : benchmark, betterC, ctfe;

@("SmallBuffer.append")
@betterC @safe pure nothrow @nogc
unittest { /+ also compiled & run with -betterC via `--better-c` +/ }

@("levenshtein.ctfe")
@ctfe @safe pure nothrow
unittest { /+ evaluated during compilation, not at runtime +/ }

@("SmallBuffer.append.bench")
@benchmark @safe
unittest { /+ timed with auto-scaling iterations via `--bench` +/ }

All attributes are plain marker types — the runner discovers them with hasUDA — so annotated tests remain ordinary unittest blocks for any other runner.

attributes
:
(enum) sparkles.test_runner.attributes.CacheRegime

The page-cache regime a @workload requests for the files it names via workloadFiles: leave the cache alone (steadyState), preload (warm), or evict (cold). The runner verifies the achieved regime (mmap + mincore residency) and stamps every measured window with requested vs effective — a regime that could not be established (tmpfs, no posix_fadvise, foreign mappings) degrades with a reason, never silently.

steadyState is first so .init (and a bare @workload) means "no cache manipulation".

CacheRegime
;
import
(package) sparkles
sparkles
.
(package) sparkles.test_runner
test_runner
.
(module) sparkles.test_runner.cache_regime

Page-cache regime control for @workload tests: establish a declared cache state — cold (evict), warm (preload), steadyState (leave alone) — for the files a workload names, and verify what was actually achieved instead of assuming it.

The mechanics: cold is posix_fadvise(POSIX_FADV_DONTNEED) per file (preceded by fdatasync — DONTNEED silently skips dirty pages); warm is an explicit read-through preload (never the async WILLNEED advice, which promises nothing); verification is mmap + mincore residency, strided by sysconf(_SC_PAGESIZE) (Apple Silicon's 16 KiB pages make hardcoded 4 KiB wrong). The pure resolveStamp policy turns requested + filesystem kind + measured residency into an honest CacheRegimeStamp: a regime that could not be established downgrades effective with a reason, and residency that cannot be trusted is noted, never converted into a confident number.

Filesystem honesty: on tmpfs the pages ARE the file — cold is impossible by construction. On ZFS, mincore is blind in both directions: reads are served from the ARC without populating the Linux page cache, so a warm-preloaded file can read 0 % resident while fully cached, and a fadvised file reads 0 % while the ARC still holds everything — the residency thresholds are suppressed there and the stamp says so. /proc/sys/vm/drop_caches is deliberately never used: it is a system-global, root-only sledgehammer that evicts every other process's state — the per-file fadvise + verify + downgrade-note contract is the honest scope (M8's cgroup memory.max is the scoped successor if stronger eviction is ever needed).

cache_regime
:
(struct) sparkles.test_runner.cache_regime.CacheRegimeStamp

What one workloadFiles call established, attached to every window measured after it. residentBefore/residentAfter are page-weighted fractions across the call's files (nan = unverifiable, which is a note, never a downgrade by itself).

CacheRegimeStamp
;
(struct) sparkles.test_runner.workload.WorkloadWindow

One measured window. Deliberately NOT BenchStats: its per-iteration timing fields would misrepresent a single window — counter stats here are window totals (iters == 1).

WorkloadWindow
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
;
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) string sparkles.test_runner.workload.WorkloadWindow.name
name
= "cold-run";
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) uint sparkles.test_runner.workload.WorkloadWindow.reps

times the window content ran inside this window

reps
= 1;
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) long sparkles.test_runner.workload.WallDecomposition.wallNs

the window's wall-clock duration

wallNs
= 5_000_000;
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) string sparkles.test_runner.workload.WallDecomposition.scope_

"thread" (Linux) or "process"

scope_
= "thread";
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
.
(field) std.typecons.Nullable!(CacheRegimeStamp) sparkles.test_runner.workload.WorkloadWindow.regime

what workloadFiles established for this window

regime
=
std.typecons.Nullable!(CacheRegimeStamp) std.typecons.nullable!(sparkles.test_runner.cache_regime.CacheRegimeStamp)(sparkles.test_runner.cache_regime.CacheRegimeStamp t) pure nothrow @nogc @safe

Defines a value paired with a distinctive "null" state that denotes the absence of a value. If default constructed, a Nullable!T object starts in the null state. Assigning it renders it non-null. Calling nullify can nullify it again.

Practically Nullable!T stores a T and a bool.

See also: apply, an alternative way to use the payload.

Examples

struct CustomerRecord
{
    string name;
    string address;
    int customerNum;
}

Nullable!CustomerRecord getByName(string name)
{
    //A bunch of hairy stuff

    return Nullable!CustomerRecord.init;
}

auto queryResult = getByName("Doe, John");
if (!queryResult.isNull)
{
    //Process Mr. Doe's customer record
    auto address = queryResult.get.address;
    auto customerNum = queryResult.get.customerNum;

    //Do some things with this customer's info
}
else
{
    //Add the customer to the database
}
import std.exception : assertThrown;

auto a = 42.nullable;
assert(!a.isNull);
assert(a.get == 42);

a.nullify();
assert(a.isNull);
assertThrown!Throwable(a.get);
import std.algorithm.iteration : each, joiner;
Nullable!int a = 42;
Nullable!int b;
// Add each value to an array
int[] arr;
a.each!((n) => arr ~= n);
assert(arr == [42]);
b.each!((n) => arr ~= n);
assert(arr == [42]);
// Take first value from an array of Nullables
Nullable!int[] c = new Nullable!int[](10);
c[7] = Nullable!int(42);
assert(c.joiner.front == 42);
nullable
(
(struct) sparkles.test_runner.cache_regime.CacheRegimeStamp

What one workloadFiles call established, attached to every window measured after it. residentBefore/residentAfter are page-weighted fractions across the call's files (nan = unverifiable, which is a note, never a downgrade by itself).

CacheRegimeStamp
(
requested:
(enum) sparkles.test_runner.attributes.CacheRegime

The page-cache regime a @workload requests for the files it names via workloadFiles: leave the cache alone (steadyState), preload (warm), or evict (cold). The runner verifies the achieved regime (mmap + mincore residency) and stamps every measured window with requested vs effective — a regime that could not be established (tmpfs, no posix_fadvise, foreign mappings) degrades with a reason, never silently.

steadyState is first so .init (and a bare @workload) means "no cache manipulation".

CacheRegime
.
(enum value) sparkles.test_runner.attributes.CacheRegime.cold = 2
cold
, effective:
(enum) sparkles.test_runner.attributes.CacheRegime

The page-cache regime a @workload requests for the files it names via workloadFiles: leave the cache alone (steadyState), preload (warm), or evict (cold). The runner verifies the achieved regime (mmap + mincore residency) and stamps every measured window with requested vs effective — a regime that could not be established (tmpfs, no posix_fadvise, foreign mappings) degrades with a reason, never silently.

steadyState is first so .init (and a bare @workload) means "no cache manipulation".

CacheRegime
.
(enum value) sparkles.test_runner.attributes.CacheRegime.steadyState = 0
steadyState
,
residentBefore: 1.0, residentAfter: double.
(constant) double double.nan = nan
nan
,
note: "cold impossible on tmpfs (the pages ARE the file) — ran steady-state")); const
(local variable) const(std.json.JSONValue) doc
doc
=
std.json.JSONValue std.json.parseJSON!string(string json, int maxDepth = -1, std.json.JSONOptions options = JSONOptions.none) pure @safe

Parses a serialized string and returns a tree of JSON values.

@throwsJSONException if string does not follow the JSON grammar or the depth exceeds the max depth, ConvException if a number in the input cannot be represented by a native D type.@paramjson json-formatted string to parse@parammaxDepth maximum depth of nesting allowed, -1 disables depth checking@paramoptions enable decoding string representations of NaN/Inf as float values
parseJSON
(
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
(null,
(struct) sparkles.test_runner.bench_json.BenchMeta

Provenance and the effective measurement knobs stamped onto a report, so a committed baseline is self-describing (the budget it was measured under is part of the data, not tribal knowledge).

BenchMeta
(date: "2026-08-05"), [
(local variable) sparkles.test_runner.workload.WorkloadWindow w
w
]));
const
(local variable) const(std.json.JSONValue) g
g
=
(local variable) const(std.json.JSONValue) doc
doc
["windows"][0]["regime"];
assert(
(local variable) const(std.json.JSONValue) g
g
["requested"].
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
== "cold");
assert(
(local variable) const(std.json.JSONValue) g
g
["effective"].
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
== "steadyState");
assert(
(local variable) const(std.json.JSONValue) g
g
["residentBefore"].
long std.json.JSONValue.integer() const pure @property @safe

Value getter/setter for JSONType.integer``.

@throwsJSONException for read access if type is not JSONType.integer``.
integer
== 1);
assert(
(local variable) const(std.json.JSONValue) g
g
["residentAfter"].
std.json.JSONType std.json.JSONValue.type() const pure nothrow @nogc @property @safe

Returns the JSONType of the value stored in this structure.

Examples

string s = "{ \"language\": \"D\" }";
JSONValue j = parseJSON(s);
assert(j.type == JSONType.object);
assert(j["language"].type == JSONType.string);
type
==
(enum) std.json.JSONType

Enumeration of JSON types

JSONType
.
(enum value) std.json.JSONType.null_ = cast(byte)0

Indicates the type of a JSONValue.

null_
, "nan fraction → null");
assert(
(local variable) const(std.json.JSONValue) g
g
["note"].
string std.json.JSONValue.str() const pure @property return scope @trusted

Value getter/setter for JSONType.string.

@throwsJSONException for read access if type is not JSONType.string.
str
.
bool std.algorithm.searching.canFind!().canFind!(string, string)(string haystack, scope string needle) pure nothrow @nogc @safe

Convenience function. Like find, but only returns whether or not the search was successful.

For more information about pred see find.

Examples

const arr = [0, 1, 2, 3];
assert(canFind(arr, 2));
assert(!canFind(arr, 4));

// find one of several needles
assert(arr.canFind(3, 2));
assert(arr.canFind(3, 2) == 2); // second needle found
assert(arr.canFind([1, 3], 2) == 2);

assert(canFind(arr, [1, 2], [2, 3]));
assert(canFind(arr, [1, 2], [2, 3]) == 1);
assert(canFind(arr, [1, 7], [2, 3]));
assert(canFind(arr, [1, 7], [2, 3]) == 2);
assert(!canFind(arr, [1, 3], [2, 4]));
assert(canFind(arr, [1, 3], [2, 4]) == 0);

Example using a custom predicate. Note that the needle appears as the second argument of the predicate.

auto words = [
    "apple",
    "beeswax",
    "cardboard"
];
assert(!canFind(words, "bees"));
assert( canFind!((string elem, string needle) => elem.startsWith(needle))(words, "bees"));

Search for multiple items in an array of items (search for needles in an array of haystacks)

string s1 = "aaa111aaa";
string s2 = "aaa222aaa";
string s3 = "aaa333aaa";
string s4 = "aaa444aaa";
const hay = [s1, s2, s3, s4];
assert(hay.canFind!(e => e.canFind("111", "222")));
@see

among for checking a value against multiple arguments.

Returns true if and only if needle can be found in range. Performs O(haystack.length) evaluations of pred.

canFind
("tmpfs"));
// Stampless windows omit the key — and the whole document stays free // of it (the byte-identity contract for regime-less runs).
(struct) sparkles.test_runner.workload.WorkloadWindow

One measured window. Deliberately NOT BenchStats: its per-iteration timing fields would misrepresent a single window — counter stats here are window totals (iters == 1).

WorkloadWindow
(local variable) sparkles.test_runner.workload.WorkloadWindow plain
plain
;
(local variable) sparkles.test_runner.workload.WorkloadWindow plain
plain
.
(field) string sparkles.test_runner.workload.WorkloadWindow.name
name
= "plain";
(local variable) sparkles.test_runner.workload.WorkloadWindow plain
plain
.
(field) uint sparkles.test_runner.workload.WorkloadWindow.reps

times the window content ran inside this window

reps
= 1;
(local variable) sparkles.test_runner.workload.WorkloadWindow plain
plain
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) long sparkles.test_runner.workload.WallDecomposition.wallNs

the window's wall-clock duration

wallNs
= 1;
(local variable) sparkles.test_runner.workload.WorkloadWindow plain
plain
.
(field) sparkles.test_runner.workload.WallDecomposition sparkles.test_runner.workload.WorkloadWindow.wall
wall
.
(field) string sparkles.test_runner.workload.WallDecomposition.scope_

"thread" (Linux) or "process"

scope_
= "thread";
assert(!
string sparkles.test_runner.bench_json.benchReportJson(in sparkles.test_runner.bench.BenchStats[] rows, in sparkles.test_runner.bench_json.BenchMeta meta, in sparkles.test_runner.workload.WorkloadWindow[] windows = null) @safe

The full report document: {schema, meta, columns, rows}, pretty-printed with 2-space indent. rows keep measurement order (grouping/sorting are presentation concerns; the group dimensions travel in each row's labels, whose keys are emitted sorted). columns describe the available catalog metrics for these rows, so metrics keys match --list-metrics names. Schema 2 adds the optional per-row estimatedMetrics array naming the metrics keys whose values are multiplex-scaled estimates (absent = every metric exact), and — when @workload tests ran — a windows sibling array of window objects: wall decomposition fields (null = unattributable on this host, exactly the table's em dash) and one nested per-source totals object per attached source. Window values are window TOTALS with their own field names, deliberately never the per-iteration metrics catalog keys — reusing those names would quietly overload their semantics. A run without workloads emits no windows key and is byte-identical to the pre-window document.

benchReportJson
(null,
(struct) sparkles.test_runner.bench_json.BenchMeta

Provenance and the effective measurement knobs stamped onto a report, so a committed baseline is self-describing (the budget it was measured under is part of the data, not tribal knowledge).

BenchMeta
(date: "2026-08-05"), [
(local variable) sparkles.test_runner.workload.WorkloadWindow plain
plain
])
.
bool std.algorithm.searching.canFind!().canFind!(string, string)(string haystack, scope string needle) pure nothrow @nogc @safe

Convenience function. Like find, but only returns whether or not the search was successful.

For more information about pred see find.

Examples

const arr = [0, 1, 2, 3];
assert(canFind(arr, 2));
assert(!canFind(arr, 4));

// find one of several needles
assert(arr.canFind(3, 2));
assert(arr.canFind(3, 2) == 2); // second needle found
assert(arr.canFind([1, 3], 2) == 2);

assert(canFind(arr, [1, 2], [2, 3]));
assert(canFind(arr, [1, 2], [2, 3]) == 1);
assert(canFind(arr, [1, 7], [2, 3]));
assert(canFind(arr, [1, 7], [2, 3]) == 2);
assert(!canFind(arr, [1, 3], [2, 4]));
assert(canFind(arr, [1, 3], [2, 4]) == 0);

Example using a custom predicate. Note that the needle appears as the second argument of the predicate.

auto words = [
    "apple",
    "beeswax",
    "cardboard"
];
assert(!canFind(words, "bees"));
assert( canFind!((string elem, string needle) => elem.startsWith(needle))(words, "bees"));

Search for multiple items in an array of items (search for needles in an array of haystacks)

string s1 = "aaa111aaa";
string s2 = "aaa222aaa";
string s3 = "aaa333aaa";
string s4 = "aaa444aaa";
const hay = [s1, s2, s3, s4];
assert(hay.canFind!(e => e.canFind("111", "222")));
@see

among for checking a value against multiple arguments.

Returns true if and only if needle can be found in range. Performs O(haystack.length) evaluations of pred.

canFind
("\"regime\""));
}