#!/usr/bin/env dub
/+ dub.sdl:
name "android-dev-env-probe"
platforms "linux" "osx"
dependency "sparkles:core-cli" path="../../../../.."
targetPath "build"
buildType "checked" {
buildOptions "optimize" "inline" "debugInfo"
}
+/
/**
* Host-side, read-only AVF/NNS evidence collector.
* See ../contributing.md for the evidence limits and contributor agent prompt.
* No arguments: portable CI skip, without contacting ADB.
*/
module (module) contributor_probeHost-side, read-only AVF/NNS evidence collector.
See ../contributing.md for the evidence limits and contributor agent prompt.
No arguments: portable CI skip, without contacting ADB.
contributor_probe;
import (package) stdstd.(module) std.algorithmThis package implements generic algorithms oriented towards the processing of
sequences. Sequences processed by these functions define range-based
interfaces. See also Reference on ranges and
tutorial on ranges.
Algorithms are categorized into the following submodules:
Submodule Functions
| Searching |
all
any
balancedParens
boyerMooreFinder
canFind
commonPrefix
count
countUntil
endsWith
find
findAdjacent
findAmong
findSkip
findSplit
findSplitAfter
findSplitBefore
minCount
maxCount
minElement
maxElement
minIndex
maxIndex
minPos
maxPos
skipOver
startsWith
until
|
| Comparison |
among
castSwitch
clamp
cmp
either
equal
isPermutation
isSameLength
levenshteinDistance
levenshteinDistanceAndPath
max
min
mismatch
predSwitch
|
| Iteration |
cache
cacheBidirectional
chunkBy
cumulativeFold
each
filter
filterBidirectional
fold
group
joiner
map
mean
permutations
reduce
splitWhen
splitter
substitute
sum
uniq
|
| Sorting |
completeSort
isPartitioned
isSorted
isStrictlyMonotonic
ordered
strictlyOrdered
makeIndex
merge
multiSort
nextEvenPermutation
nextPermutation
nthPermutation
partialSort
partition
partition3
schwartzSort
sort
topN
topNCopy
topNIndex
|
| Set operations (setops) |
cartesianProduct
largestPartialIntersection
largestPartialIntersectionWeighted
multiwayMerge
multiwayUnion
setDifference
setIntersection
setSymmetricDifference
|
| Mutation |
bringToFront
copy
fill
initializeAll
move
moveAll
moveSome
moveEmplace
moveEmplaceAll
moveEmplaceSome
remove
reverse
strip
stripLeft
stripRight
swap
swapRanges
uninitializedFill
|
Many functions in this package are parameterized with a predicate.
The predicate may be any suitable callable type
(a function, a delegate, a functor, or a lambda), or a
compile-time string. The string may consist of any legal D
expression that uses the symbol a (for unary functions) or the
symbols a and b (for binary functions). These names will NOT
interfere with other homonym symbols in user code because they are
evaluated in a different context. The default for all binary
comparison predicates is "a == b" for unordered operations and
"a < b" for ordered operations.
Example
int[] a = ...;
static bool greater(int a, int b)
{
return a > b;
}
sort!greater(a); // predicate as alias
sort!((a, b) => a > b)(a); // predicate as a lambda.
sort!"a > b"(a); // predicate as string
// (no ambiguity with array name)
sort(a); // no predicate, "a < b" is implicit
Source
std/algorithm/package.d
algorithm : (alias template) contributor_probe.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 find.
canFind;
import (package) stdstd.(module) std.arrayFunctions 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
array : (alias template) contributor_probe.split = std.array.split(S)(S s) if (isSomeString!S)Eagerly splits range into an array, using sep as the delimiter.
When no delimiter is provided, strings are split into an array of words,
using whitespace as delimiter.
Runs of whitespace are merged together (no empty words are produced).
The range must be a forward range.
The separator can be a value of the same type as the elements in range
or it can be another forward range.
split, (alias template) contributor_probe.replace = std.array.replace(E, R1, R2)(E[] subject, R1 from, R2 to) if (isForwardRange!R1 && isForwardRange!R2 && (hasLength!R2 || isSomeString!R2) || is(Unqual!E : Unqual!R1))Replace occurrences of from with to in subject in a new array.
replace;
import (package) stdstd.(module) std.convA 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
conv : (alias template) contributor_probe.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:
Integer:
Sign UnsignedInteger
UnsignedInteger
Sign:
+
-
For conversion to unsigned types, the grammar recognized is:
UnsignedInteger:
DecimalDigit
DecimalDigit UnsignedInteger
to, (alias template) contributor_probe.octal = std.conv.octal(string num) if (isOctalLiteral(num))The octal facility provides a means to declare a number in base 8.
Using octal`!177` or octal!"177" for 127 represented in octal
(same as 0177 in C).
The rules for strings are the usual for literals: If it can fit in an
int, it is an int. Otherwise, it is a long. But, if the
user specifically asks for a long with the L suffix, always
give the long. Give an unsigned iff it is asked for with the U or u suffix. Octals created from integers preserve the type
of the passed-in integral.
octal;
import (package) stdstd.(package) std.datetimedatetime.(module) std.datetime.systimeCategory 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.ClockEffectively 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) stdstd.(module) std.exceptionThis module defines functions related to exceptions and general error
handling. It also defines functions intended to aid in unit testing.
Category Functions Assumptions assertNotThrown assertThrown assumeUnique assumeWontThrow mayPointTo Enforce doesPointTo enforce errnoEnforce Handlers collectException collectExceptionMsg ifThrown handle Other basicExceptionCtors emptyExceptionMsg ErrnoException RangePrimitive
Source
std/exception.d
Examples
Synopis
import core.stdc.stdlib : malloc, free;
import std.algorithm.comparison : equal;
import std.algorithm.iteration : map, splitter;
import std.algorithm.searching : endsWith;
import std.conv : ConvException, to;
import std.range : front, retro;
// use enforce like assert
int a = 3;
enforce(a > 2, "a needs to be higher than 2.");
// enforce can throw a custom exception
enforce!ConvException(a > 2, "a needs to be higher than 2.");
// enforce will return it's input
enum size = 42;
auto memory = enforce(malloc(size), "malloc failed")[0 .. size];
scope(exit) free(memory.ptr);
// collectException can be used to test for exceptions
Exception e = collectException("abc".to!int);
assert(e.file.endsWith("conv.d"));
// and just for the exception message
string msg = collectExceptionMsg("abc".to!int);
assert(msg == "Unexpected 'a' when converting from type string to type int");
// assertThrown can be used to assert that an exception is thrown
assertThrown!ConvException("abc".to!int);
// ifThrown can be used to provide a default value if an exception is thrown
assert("x".to!int().ifThrown(0) == 0);
// handle is a more advanced version of ifThrown for ranges
auto r = "12,1337z32,54".splitter(',').map!(a => to!int(a));
auto h = r.handle!(ConvException, RangePrimitive.front, (e, r) => 0);
assert(h.equal([12, 0, 54]));
assertThrown!ConvException(h.retro.equal([54, 0, 12]));
// basicExceptionCtors avoids the boilerplate when creating custom exceptions
static class MeaCulpa : Exception
{
mixin basicExceptionCtors;
}
e = collectException((){throw new MeaCulpa("diagnostic message");}());
assert(e.msg == "diagnostic message");
assert(e.file == __FILE__);
assert(e.line == __LINE__ - 3);
// assumeWontThrow can be used to cast throwing code into `nothrow`
void exceptionFreeCode() nothrow
{
// auto-decoding only throws if an invalid UTF char is given
assumeWontThrow("abc".front);
}
// assumeUnique can be used to cast mutable instance to an `immutable` one
// use with care
char[] str = " mutable".dup;
str[0 .. 2] = "im";
immutable res = assumeUnique(str);
assert(res == "immutable");
exception : (alias template) contributor_probe.enforce = std.exception.enforce(E : Throwable = Exception) if (is(typeof(new E("", string.init, size_t.init)) : Throwable) || is(typeof(new E(string.init, size_t.init)) : Throwable))Enforces that the given value is true.
If the given value is false, an exception is thrown.
The
msg - error message as a string
dg - custom delegate that return a string and is only called if an exception occurred
ex - custom exception to be thrown. It is lazy and is only created if an exception occurred
enforce;
import (package) stdstd.(module) std.fileUtilities 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
file : (alias template) contributor_probe.exists = std.file.exists(R)(R name) if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)Determine whether the given file (or directory) exists.
exists, (alias) contributor_probe.mkdirRecurse = void std.file.mkdirRecurse(scope const(char)[] pathname) @safeMake directory and all parent directories as needed.
Does nothing if the directory specified by
pathname already exists.
mkdirRecurse, (alias template) contributor_probe.write = std.file.write(R)(R name, const void[] buffer) if ((isSomeFiniteCharInputRange!R || isSomeString!R) && !isConvertibleToString!R)Write buffer to file name.
Creates the file if it does not already exist.
write;
import (package) stdstd.(module) std.jsonImplements 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);
json : (struct) std.json.JSONValueJSON value node
JSONValue;
import (package) stdstd.(module) std.pathThis module is used to manipulate path strings.
All functions, with the exception of expandTilde (and in some
cases absolutePath and relativePath), are pure
string manipulation functions; they don't depend on any state outside
the program, nor do they perform any actual file system actions.
This has the consequence that the module does not make any distinction
between a path that points to a directory and a path that points to a
file, and it does not know whether or not the object pointed to by the
path actually exists in the file system.
To differentiate between these cases, use isDir and
exists.
Note that on Windows, both the backslash (\) and the slash (/)
are in principle valid directory separators. This module treats them
both on equal footing, but in cases where a new separator is
added, a backslash will be used. Furthermore, the buildNormalizedPath
function will replace all slashes with backslashes on that platform.
In general, the functions in this module assume that the input paths
are well-formed. (That is, they should not contain invalid characters,
they should follow the file system's path format, etc.) The result
of calling a function on an ill-formed path is undefined. When there
is a chance that a path or a file name is invalid (for instance, when it
has been input by the user), it may sometimes be desirable to use the
isValidFilename and isValidPath functions to check
this.
Most functions do not perform any memory allocations, and if a string is
returned, it is usually a slice of an input string. If a function
allocates, this is explicitly mentioned in the documentation.
Category Functions Normalization absolutePath asAbsolutePath asNormalizedPath asRelativePath buildNormalizedPath buildPath chainPath expandTilde Partitioning baseName dirName dirSeparator driveName pathSeparator pathSplitter relativePath rootName stripDrive Validation isAbsolute isDirSeparator isRooted isValidFilename isValidPath Extension defaultExtension extension setExtension stripExtension withDefaultExtension withExtension Other filenameCharCmp filenameCmp globMatch CaseSensitive
Source
std/path.d
path : (alias template) contributor_probe.buildPath = std.path.buildPath(Range)(scope Range segments) if (isInputRange!Range && !isInfinite!Range && isSomeString!(ElementType!Range))Combines one or more path segments.
This function takes a set of path segments, given as an input
range of string elements or as a set of string arguments,
and concatenates them with each other. Directory separators
are inserted between segments if necessary. If any of the
path segments are absolute (as defined by isAbsolute), the
preceding segments will be dropped.
On Windows, if one of the path segments are rooted, but not absolute
(e.g. \foo), all preceding path segments down to the previous
root will be dropped. (See below for an example.)
This function always allocates memory to hold the resulting path.
The variadic overload is guaranteed to only perform a single
allocation, as is the range version if paths is a forward
range.
buildPath;
import (package) stdstd.(module) std.processFunctions for starting and interacting with other processes, and for
working with the current process' execution environment.
Process handling
`spawnProcess` spawns a new `process`, optionally assigning it an
arbitrary set of standard input, output, and error streams.
The function returns immediately, leaving the child process to execute
in parallel with its parent. All other functions in this module that
spawn processes are built around spawnProcess.
`wait` makes the parent `process` wait for a child `process` to
terminate. In general one should always do this, to avoid
child processes becoming "zombies" when the parent process exits.
Scope guards are perfect for this – see the spawnProcess
documentation for examples. tryWait is similar to wait,
but does not block if the process has not yet terminated.
`pipeProcess` also spawns a child `process` which runs
in parallel with its parent. However, instead of taking
arbitrary streams, it automatically creates a set of
pipes that allow the parent to communicate with the child
through the child's standard input, output, and/or error streams.
This function corresponds roughly to C's popen function.
`execute` starts a new `process` and waits for it
to complete before returning. Additionally, it captures
the process' standard output and error streams and returns
the output of these as a string.
`spawnShell`, `pipeShell` and `executeShell` work like
spawnProcess, pipeProcess and execute, respectively,
except that they take a single command string and run it through
the current user's default command interpreter.
executeShell corresponds roughly to C's system function.
`kill` attempts to terminate a running `process`.
The following table compactly summarises the different process creation
functions and how they relate to each other:
Runs program directly
Runs shell command Low-level process creation spawnProcess spawnShell Automatic input/output redirection using pipes pipeProcess pipeShell Execute and wait for completion, collect output execute executeShell
Other functionality
`pipe` is used to create unidirectional pipes.
`environment` is an interface through which the current `process`'
environment variables can be read and manipulated.
`escapeShellCommand` and `escapeShellFileName` are useful
for constructing shell command lines in a portable way.
Source
std/process.d
Note
Most of the functionality in this module is not available on iOS, tvOS
and watchOS. The only functions available on those platforms are:
environment, thisProcessID and thisThreadID.
process : (alias) contributor_probe.execute = std.typecons.Tuple!(int, "status", string, "output") std.process.execute(scope const(char[])[] args, const(string[string]) env = cast(const(string[string]))null, std.process.Config config = Config(Flags.none, null, null), ulong maxOutput = 18446744073709551615LU, scope const(char)[] workDir = null) @safeExecutes the given program or shell command and returns its exit
code and output.
execute and executeShell start a new process using
spawnProcess and spawnShell, respectively, and wait
for the process to complete before returning. The functions capture
what the child process prints to both its standard output and
standard error streams, and return this together with its exit code.
auto dmd = execute(["dmd", "myapp.d"]);
if (dmd.status != 0) writeln("Compilation failed:\n", dmd.output);
auto ls = executeShell("ls -l");
if (ls.status != 0) writeln("Failed to retrieve file listing");
else writeln(ls.output);
The args/program/command, env and config
parameters are forwarded straight to the underlying spawn functions,
and we refer to their documentation for details.
POSIX specific
If the process is terminated by a signal, the status field of
the return value will contain a negative number whose absolute
value is the signal number. (See wait for details.)
execute, (struct) std.process.ConfigOptions that control the behaviour of process creation functions in this
module. Most options only apply to spawnProcess and
spawnShell.
Example
auto logFile = File("myapp_error.log", "w");
// Start program, suppressing the console window (Windows only),
// redirect its error stream to logFile, and leave logFile open
// in the parent process as well.
auto pid = spawnProcess("myapp", stdin, stdout, logFile,
Config.retainStderr | Config.suppressConsole);
scope(exit)
{
auto exitCode = wait(pid);
logFile.writeln("myapp exited with code ", exitCode);
logFile.close();
}
Config;
import (package) stdstd.(module) std.stdioCategory Symbols File handles _popen File isFileHandle openNetwork stderr stdin stdout Reading chunks lines readf readfln readln Writing toFile write writef writefln writeln Misc KeepTerminator LockType StdioException
Standard I/O functions that extend core.stdc.stdio. core.stdc.stdio
is publically imported when importing std.stdio.
There are three layers of I/O:
The lowest layer is the operating system layer. The two main schemes are Windows and Posix.
C's stdio.h which unifies the two operating system schemes.
std.stdio, this module, unifies the various stdio.h implementations into
a high level package for D programs.
Source
std/stdio.d
stdio : stderr, (alias template) contributor_probe.writeln = std.stdio.writeln(T...)(T args)Equivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln;
import (package) stdstd.(module) std.stringString 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
string : (alias template) contributor_probe.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
isWhite) or as specified in the second argument.
strip, (alias template) contributor_probe.splitLines = std.string.splitLines(C)(C[] s, KeepTerminator keepTerm = No.keepTerminator) if (isSomeChar!C)Split s into an array of lines according to the unicode standard using
'\r', '\n', "\r\n", lineSep,
paraSep, U+0085 (NEL), '\v' and '\f'
as delimiters. If keepTerm is set to KeepTerminator.yes, then the
delimiter is included in the strings returned.
Does not throw on invalid UTF; such is simply passed unchanged
to the output.
Allocates memory; use lineSplitter for an alternative that
does not.
Adheres to Unicode 7.0.
splitLines, (alias) contributor_probe.toStringz = immutable(char)* std.string.toStringz(scope const(char)[] s) pure nothrow @trustedtoStringz;
import (package) stdstd.(module) std.parallelismstd.parallelism implements high-level primitives for SMP `parallelism`.
These include parallel foreach, parallel reduce, parallel eager map, pipelining
and future/promise `parallelism`. `std.`parallelism is recommended when the
same operation is to be executed in parallel on different data, or when a
function is to be executed in a background thread and its result returned to a
well-defined main thread. For communication between arbitrary threads, see
std.concurrency.
std.parallelism`` is based on the concept of a Task. A Task is an
object that represents the fundamental unit of work in this library and may be
executed in parallel with any other Task. Using Task
directly allows programming with a future/promise paradigm. All other
supported parallelism paradigms (parallel foreach, map, reduce, pipelining)
represent an additional level of abstraction over Task. They
automatically create one or more Task objects, or closely related types
that are conceptually identical but not part of the public API.
After creation, a Task may be executed in a new thread, or submitted
to a TaskPool for execution. A TaskPool encapsulates a task queue
and its worker threads. Its purpose is to efficiently map a large
number of Tasks onto a smaller number of threads. A task queue is a
FIFO queue of Task objects that have been submitted to the
TaskPool and are awaiting execution. A worker thread is a thread that
is associated with exactly one task queue. It executes the Task at the
front of its queue when the queue has work available, or sleeps when
no work is available. Each task queue is associated with zero or
more worker threads. If the result of a Task is needed before execution
by a worker thread has begun, the Task can be removed from the task queue
and executed immediately in the thread where the result is needed.
Warning
Unless marked as @trusted or @safe, artifacts in
this module allow implicit data sharing between threads and cannot
guarantee that client code is free from low level data races.
Source
std/parallelism.d
Author
David Simcha
parallelism : (alias template) contributor_probe.task = std.parallelism.task(alias fun, Args...)(Args args)Creates a Task on the GC heap that calls an alias. This may be executed
via Task.executeInNewThread or by submitting to a
TaskPool. A globally accessible instance of
TaskPool is provided by taskPool.
Example
// Read two files into memory at the same time.
import std.file;
void main()
{
// Create and execute a Task for reading
// foo.txt.
auto file1Task = task!read("foo.txt");
file1Task.executeInNewThread();
// Read bar.txt in parallel.
auto file2Data = read("bar.txt");
// Get the results of reading foo.txt.
auto file1Data = file1Task.yieldForce;
}
// Sorts an array using a parallel quick sort algorithm.
// The first partition is done serially. Both recursion
// branches are then executed in parallel.
//
// Timings for sorting an array of 1,000,000 doubles on
// an Athlon 64 X2 dual core machine:
//
// This implementation: 176 milliseconds.
// Equivalent serial implementation: 280 milliseconds
void parallelSort(T)(T[] data)
{
// Sort small subarrays serially.
if (data.length < 100)
{
std.algorithm.sort(data);
return;
}
// Partition the array.
swap(data[$ / 2], data[$ - 1]);
auto pivot = data[$ - 1];
bool lessThanPivot(T elem) { return elem < pivot; }
auto greaterEqual = partition!lessThanPivot(data[0..$ - 1]);
swap(data[$ - greaterEqual.length - 1], data[$ - 1]);
auto less = data[0..$ - greaterEqual.length - 1];
greaterEqual = data[$ - greaterEqual.length..$];
// Execute both recursion branches in parallel.
auto recurseTask = task!parallelSort(greaterEqual);
taskPool.put(recurseTask);
parallelSort(less);
recurseTask.yieldForce;
}
task;
import (package) corecore.(module) core.threadThe thread module provides support for thread creation and management.
Source
core/thread/package.d
thread : (class) core.thread.osthread.ThreadThis class encapsulates all threading functionality for the D
programming language. As thread manipulation is a required facility
for garbage collection, all user threads should derive from this
class, and instances of this class should never be explicitly deleted.
A new thread may be created using either derivation or composition, as
in the following example.
Thread;
import (package) corecore.(module) core.timeModule 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 days hours
minutes seconds msecs
usecs hnsecs 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
time : msecs;
import (package) corecore.(package) core.syssys.(package) core.sys.posixposix.(package) core.sys.posix.syssys.(module) core.sys.posix.sys.statD header file for POSIX.
stat : (alias) contributor_probe.chmod = int core.sys.posix.sys.stat.chmod(scope const(char*), uint) nothrow @nogcchmod;
import (package) sparklessparkles.(package) sparkles.core_clicore_cli.(module) sparkles.core_cli.argsargs : (struct) sparkles.core_cli.args.uda.CommandCommand, (struct) sparkles.core_cli.args.uda.OptionOption, (alias template) contributor_probe.parseCli = sparkles.core_cli.args.internal.parseCli(Cli)(string[] argv, HelpInfo helpInfo = HelpInfo.init)parseCli, (alias template) contributor_probe.runParsedCli = sparkles.core_cli.args.internal.runParsedCli(Cli)(ref Cli cli)runParsedCli, (alias) contributor_probe.reportCliError = int sparkles.core_cli.args.internal.reportCliError(in sparkles.core_cli.args.error.CliError e)Reports a failed parse and returns the exit code the program should use.
A help request is a failure in the Expected sense but a success to the
user, and carries exitCode == 0 to say so — returning this value is what
keeps --help from looking like an error to a shell.
For a program whose commands have run methods, prefer runCli,
which calls this. This is the entry point for a program that parses into a
struct and then does its own work.
reportCliError;
import (package) sparklessparkles.(package) sparkles.core_clicore_cli.(module) sparkles.core_cli.term_unstyleterm_unstyle : (alias) contributor_probe.unstyle = string sparkles.core_cli.term_unstyle.unstyle(in char[] s) pure nothrow @safeReturns s with every ANSI/VT escape sequence removed (CSI/SGR, OSC
including OSC 8 hyperlinks, DCS/SOS/PM/APC, …). Built on the shared escape
scanner in sparkles.base.text.ansi, so stripping and width measurement
always agree (the old regex only matched CSI + OSC 8).
unstyle;
import (package) sparklessparkles.(package) sparkles.basebase.(module) sparkles.base.term_capsTerminal capability probing: the synchronous size query (terminalSize),
tty and color detection (detectTermCaps), and resize notifications
(setTermWindowSizeHandler).
This is the single place the "what can this terminal do" decision is made;
renderers stay pure producers that take explicit widths/flags. It lives in
sparkles:base rather than a UI package because it is an environment query,
not a presentation concern — a logger, a CLI tool and a full-screen UI all need
it, and none of them should pull in a UI stack to ask.
TermSize is deliberately a plain POD rather than a
Vector specialization: base sits below
sparkles:math, and a capability snapshot never does vector arithmetic. The
terminal's geometry types — positions you add offsets to — live in
sparkles:tui (TermPosition), which is free to specialize Vector.
term_caps : (alias) contributor_probe.detectTermCaps = sparkles.base.term_caps.TermCaps sparkles.base.term_caps.detectTermCaps(bool noColors = false) @safeDetects capabilities and prepares the console.
Colors are on only when stdout is a terminal and neither noColors,
$NO_COLOR, nor TERM=dumb disables them; a non-empty, non-"0"
$CLICOLOR_FORCE forces them on for a non-tty (but never overrides an
explicit disable). colorDepth is the tier
(classifyColorDepth over $COLORTERM/$TERM)
when colors are on, else none. On Windows this additionally sets the output code page to
UTF-8 (so ✓ ✗ ⚙ render even without colors) and enables virtual-terminal
processing (so ANSI escapes are interpreted rather than printed literally);
colors stay off when stdout is redirected or VT can't be enabled.
detectTermCaps, (alias) contributor_probe.isTerminal = bool sparkles.base.term_caps.isTerminal(sparkles.base.term_caps.StdStream stream = StdStream.stdout) nothrow @nogc @trustedIs stream attached to a terminal? POSIX: isatty; Windows: GetConsoleMode
succeeds (it fails when the handle is redirected — the non-tty check).
isTerminal, (enum) sparkles.base.term_caps.StdStreamA standard stream, for tty queries.
StdStream;
import (package) sparklessparkles.(package) sparkles.core_clicore_cli.(module) sparkles.core_cli.promptsBlocking, line-based interactive prompts: a numbered select, a yes/no
confirm, and a validated free-text textInput.
Every prompt takes a PromptPolicy so non-interactive callers (--auto
flags, piped stdin) are handled uniformly instead of per call site: interactive
asks (re-prompting on invalid input), takeDefault resolves silently to the
default, and fail returns an error. I/O goes through an injectable
PromptIo pair, so prompts are unit-testable with canned input; EOF on
stdin is an error, never an accidental default.
Line-based by default (works over any pipe/ssh, and is what confirm/
textInput always use); select additionally layers a cursor-driven
mode on top when PromptIo.beginKeySession is available (a real terminal —
see stdioKeySession), falling back to the
numbered flow otherwise.
prompts : (alias) contributor_probe.select = expected.Expected!(ulong, string, Abort) sparkles.core_cli.prompts.select(string question, const(sparkles.core_cli.prompts.SelectOption)[] options, ulong defaultIndex, sparkles.core_cli.prompts.PromptPolicy policy, sparkles.core_cli.prompts.PromptIo io, const(sparkles.ui.components.theme.Theme) theme = Theme(false, true, BorderStyle.rounded, StatusGlyphs("\xe2\x9c\x94", "\xe2\x9c\x96", "\xe2\x9a\xa0", "\xe2\x80\xa2", "\xe2\x97\x8b", "\xe2\x97\x90", "\xe2\x94\x84", "\xe2\x80\xa6")), bool wrapAround = true)Ask the user to pick one of options by number. Renders the list (default
marked and painted accent), then loops until a valid number or an empty line
(= the default). Returns the chosen index; errors on EOF or a non-
interactive fail policy.
When io.beginKeySession is available (a real terminal), arrow keys move
the highlighted row instead: Up/Down move, Enter confirms, Esc/Ctrl+C/
Ctrl+D cancel. wrapAround (on by default) makes Up from the first row
jump to the last (and Down from the last jump to the first); pass false
to clamp at the ends instead.
select, (struct) sparkles.core_cli.prompts.SelectOptionOne choice of a select.
SelectOption, (enum) sparkles.core_cli.prompts.PromptPolicyHow a prompt resolves when it cannot, or should not, actually ask.
PromptPolicy, (alias) contributor_probe.stdioPromptIo = sparkles.core_cli.prompts.PromptIo sparkles.core_cli.prompts.stdioPromptIo()The real stdin/stdout PromptIo.
stdioPromptIo;
import (package) sparklessparkles.(package) sparkles.uiui.(package) sparkles.ui.componentscomponents.(module) sparkles.ui.components.liveA live region: a block of lines at the bottom of the normal scrollback flow that
is repainted in place (no alternate screen), with a static channel for lines
that graduate into scrollback above it — the log-update pattern (Ink/Bubble
Tea/Mosaic) per docs/specs/core-cli/tui-components §5.
Every repaint is framed in DEC 2026 synchronized-output markers (no tearing),
each frame line is truncated to the terminal width (a wrapped line would break
the cursor-up arithmetic), and the region re-reads the width every update so
resizes are picked up. On a non-interactive sink (piped output) update is a
no-op and printAbove degrades to plain appended lines, so redirected runs see
only the permanent output.
The region writes through an injected sink (testable without a terminal); use
stdoutLiveRegion for the real thing, and scope (exit) region.finish();
so a thrown exception never leaves the cursor hidden.
live : (alias) contributor_probe.stdoutLiveRegion = sparkles.ui.components.live.LiveRegion sparkles.ui.components.live.stdoutLiveRegion()A LiveRegion on stdout: interactive iff stdout is a terminal (each write is
flushed so frames appear atomically), width from terminalSize() per repaint.
stdoutLiveRegion;
import (package) sparklessparkles.(package) sparkles.uiui.(package) sparkles.ui.componentscomponents.(module) sparkles.ui.components.tasklistA checklist of tasks driven through a LiveRegion:
pending/running items are repainted in place, and each task that reaches a
terminal state (ok / failed / skipped) graduates as a permanent line into the
scrollback above — so on a tty the block shrinks as work completes, and on
piped output only the completed-task transitions appear, one line each.
renderTaskLine/renderTaskList are pure producers (unit-testable, theme-
driven); TaskReporter is the stateful driver the apps use.
tasklist : (struct) sparkles.ui.components.tasklist.TaskReporterThe stateful checklist driver. Owns the item states; each transition
repaints the live block and graduates finished tasks into the scrollback.
The LiveRegion stays owned by the caller (scope (exit) region.finish();).
TaskReporter;
import (package) sparklessparkles.(package) sparkles.uiui.(package) sparkles.ui.componentscomponents.(module) sparkles.ui.components.themeTheme layer: one border-charset selector shared by every framed component
(drawBox / drawHeader / drawTable), the status-glyph vocabulary with ASCII
fallbacks, semantic styles, and a Theme snapshot derived from
TermCaps.
Components stay pure producers — the theme only selects glyphs/styles once at
the edge (typically makeTheme(detectTermCaps()) at app startup); callers thread
the resulting values through the existing BoxProps/TableProps/colored
parameters.
theme : (alias) contributor_probe.makeTheme = sparkles.ui.components.theme.Theme sparkles.ui.components.theme.makeTheme(in sparkles.base.term_caps.OutputCapabilities caps) pure nothrow @nogc @safeThe theme for a target's output affordances: ASCII borders + fallback
glyphs without Unicode, colors per the color tier. A TermCaps converts
implicitly (its output is alias this), so ``makeTheme(detectTermCaps())
reads as before; a GUI target passes its own declaration.
makeTheme;
import (package) sparklessparkles.(package) sparkles.uiui.(package) sparkles.ui.componentscomponents.(module) sparkles.ui.components.headerSection header rendering utilities.
Provides functions to draw styled section headers in terminal applications,
supporting divider and banner styles.
header : (alias) contributor_probe.drawHeader = string sparkles.ui.components.header.drawHeader(string title, sparkles.ui.components.header.HeaderProps props = HeaderProps(HeaderStyle.divider, '\u2500', '\u2550', 0LU, 1LU)) @safeDraw a section header.
Examples
// Simple divider
"Section".drawHeader.writeln;
// Output: ── Section ──
// Banner style
"Main Title".drawHeader(HeaderProps(style: HeaderStyle.banner, width: 40)).writeln;
drawHeader, (struct) sparkles.ui.components.header.HeaderPropsConfiguration options for header rendering.
HeaderProps, (enum) sparkles.ui.components.header.HeaderStyleHeader display style.
HeaderStyle;
(alias) object.string = stringstring string contributor_probe.quote(string value)quote((alias) object.string = stringstring (parameter) string valuevalue)
{
return "'" ~ (parameter) string valuevalue.string std.array.replace!(immutable(char), string, string)(string subject, string from, string to) pure nothrow @safeReplace occurrences of from with to in subject in a new array.
Examples
assert("Hello Wörld".replace("o Wö", "o Wo") == "Hello World");
assert("Hello Wörld".replace("l", "h") == "Hehho Wörhd");
replace("'", "'\\''") ~ "'";
}
bool bool contributor_probe.identifier(string value, bool packageName = false)identifier((alias) object.string = stringstring (parameter) string valuevalue, bool (parameter) bool packageNamepackageName = false)
{
if (!(parameter) string valuevalue.(field) ulong string.lengthlength) return false;
foreach ((parameter) immutable(char) cc; (parameter) string valuevalue)
if (!((local variable) immutable(char) cc >= '0' && (local variable) immutable(char) cc <= '9') && !((parameter) bool packageNamepackageName &&
(((local variable) immutable(char) cc >= 'a' && (local variable) immutable(char) cc <= 'z') || ((local variable) immutable(char) cc >= 'A' && (local variable) immutable(char) cc <= 'Z') || (local variable) immutable(char) cc == '.' || (local variable) immutable(char) cc == '_')))
return false;
return true;
}
struct (struct) contributor_probe.CollectorCollector
{
(alias) object.string = stringstring (field) string contributor_probe.Collector.adbadb, (field) string contributor_probe.Collector.serialserial, (field) string contributor_probe.Collector.directorydirectory;
(struct) std.json.JSONValueJSON value node
JSONValue[] (field) std.json.JSONValue[] contributor_probe.Collector.recordsrecords;
(alias) object.string = stringstring (field) string contributor_probe.Collector.reportreport;
(alias) object.size_t = ulongsize_t (field) ulong contributor_probe.Collector.failuresfailures;
(struct) sparkles.ui.components.tasklist.TaskReporterThe stateful checklist driver. Owns the item states; each transition
repaints the live block and graduates finished tasks into the scrollback.
The LiveRegion stays owned by the caller (scope (exit) region.finish();).
TaskReporter* (field) sparkles.ui.components.tasklist.TaskReporter* contributor_probe.Collector.taskstasks;
auto std.typecons.Tuple!(int, "status", string, "output") contributor_probe.Collector.host(string[] arguments) @safehost((alias) object.string = stringstring[] (parameter) string[] argumentsarguments)
{
// GNU timeout is supplied by the flake on both Linux and macOS.
return std.typecons.Tuple!(int, "status", string, "output") std.process.execute(scope const(char[])[] args, const(string[string]) env = cast(const(string[string]))null, std.process.Config config = Config(Flags.none, null, null), ulong maxOutput = 18446744073709551615LU, scope const(char)[] workDir = null) @safeExecutes the given program or shell command and returns its exit
code and output.
execute and executeShell start a new process using
spawnProcess and spawnShell, respectively, and wait
for the process to complete before returning. The functions capture
what the child process prints to both its standard output and
standard error streams, and return this together with its exit code.
auto dmd = execute(["dmd", "myapp.d"]);
if (dmd.status != 0) writeln("Compilation failed:\n", dmd.output);
auto ls = executeShell("ls -l");
if (ls.status != 0) writeln("Failed to retrieve file listing");
else writeln(ls.output);
The args/program/command, env and config
parameters are forwarded straight to the underlying spawn functions,
and we refer to their documentation for details.
POSIX specific
If the process is terminated by a signal, the status field of
the return value will contain a negative number whose absolute
value is the signal number. (See wait for details.)
execute(["timeout", "--signal=TERM", "--kill-after=2s", "25s", (field) string contributor_probe.Collector.adbadb] ~ (parameter) string[] argumentsarguments,
null, (struct) std.process.ConfigOptions that control the behaviour of process creation functions in this
module. Most options only apply to spawnProcess and
spawnShell.
Example
auto logFile = File("myapp_error.log", "w");
// Start program, suppressing the console window (Windows only),
// redirect its error stream to logFile, and leave logFile open
// in the parent process as well.
auto pid = spawnProcess("myapp", stdin, stdout, logFile,
Config.retainStderr | Config.suppressConsole);
scope(exit)
{
auto exitCode = wait(pid);
logFile.writeln("myapp exited with code ", exitCode);
logFile.close();
}
Config.(constant) std.process.Config std.process.Config.none = Config(Flags.none, null, null)For backwards compatibility, and cases when only flags need to
be specified in the Config, these allow building Config
instances using flag names only.
none, 2 * 1024 * 1024);
}
(alias) object.string = stringstring string contributor_probe.Collector.collect(string name, string command)collect((alias) object.string = stringstring (parameter) string namename, (alias) object.string = stringstring (parameter) string commandcommand)
{
const (local variable) const(ulong) taskIdtaskId = (field) sparkles.ui.components.tasklist.TaskReporter* contributor_probe.Collector.taskstasks.ulong sparkles.ui.components.tasklist.TaskReporter.add(string label, ulong indent = 0LU)Register a task (pending) and return its handle.
add((parameter) string namename);
(field) sparkles.ui.components.tasklist.TaskReporter* contributor_probe.Collector.taskstasks.void sparkles.ui.components.tasklist.TaskReporter.start(ulong id)Mark id running (starts its clock) and repaint.
start((local variable) const(ulong) taskIdtaskId);
int (local variable) int statusstatus = -1;
(alias) object.string = stringstring (local variable) string outputoutput;
try
{
auto (local variable) std.parallelism.Task!(run, Tuple!(int, "status", string, "output") delegate() @safe)* workwork = std.parallelism.Task!(run, Tuple!(int, "status", string, "output") delegate() @safe)* std.parallelism.task!(std.typecons.Tuple!(int, "status", string, "output") delegate() @safe)(std.typecons.Tuple!(int, "status", string, "output") delegate() @safe delegateOrFp) pure nothrow @safeCreates a Task on the GC heap that calls a function pointer, delegate, or
class/struct with overloaded opCall.
Example
// Read two files in at the same time again,
// but this time use a function pointer instead
// of an alias to represent std.file.read.
import std.file;
void main()
{
// Create and execute a Task for reading
// foo.txt.
auto file1Task = task(&read!string, "foo.txt", size_t.max);
file1Task.executeInNewThread();
// Read bar.txt in parallel.
auto file2Data = read("bar.txt");
// Get the results of reading foo.txt.
auto file1Data = file1Task.yieldForce;
}
Notes
This function takes a non-scope delegate, meaning it can be
used with closures. If you can't allocate a closure due to objects
on the stack that have scoped destruction, see scopedTask, which
takes a scope delegate.
task(() => std.typecons.Tuple!(int, "status", string, "output") contributor_probe.Collector.host(string[] arguments) @safehost(["-s", (field) string contributor_probe.Collector.serialserial, "shell", (parameter) string commandcommand]));
(local variable) std.parallelism.Task!(run, Tuple!(int, "status", string, "output") delegate() @safe)* workwork.void std.parallelism.Task!(run, std.typecons.Tuple!(int, "status", string, "output") delegate() @safe).executeInNewThread() @trustedCreate a new thread for executing this Task, execute it in the
newly created thread, then terminate the thread. This can be used for
future/promise parallelism. An explicit priority may be given
to the Task. If one is provided, its value is forwarded to
core.thread.Thread.priority. See task for
usage example.
executeInNewThread();
while (!(local variable) std.parallelism.Task!(run, Tuple!(int, "status", string, "output") delegate() @safe)* workwork.bool std.parallelism.Task!(run, std.typecons.Tuple!(int, "status", string, "output") delegate() @safe).done() @property @trustedReturns true if the Task is finished executing.
done)
{
(field) sparkles.ui.components.tasklist.TaskReporter* contributor_probe.Collector.taskstasks.void sparkles.ui.components.tasklist.TaskReporter.tick()Advance the spinner (call from a periodic tick when one is available).
tick();
(class) core.thread.osthread.ThreadThis class encapsulates all threading functionality for the D
programming language. As thread manipulation is a required facility
for garbage collection, all user threads should derive from this
class, and instances of this class should never be explicitly deleted.
A new thread may be created using either derivation or composition, as
in the following example.
Thread.void core.thread.osthread.Thread.sleep(core.time.Duration val) nothrow @nogc @trustedSuspends the calling thread for at least the supplied period. This may
result in multiple OS calls if period is greater than the maximum sleep
duration supported by the operating system.
In
period must be non-negative.
Example
Thread.sleep( dur!("msecs")( 50 ) ); // sleep for 50 milliseconds
Thread.sleep( dur!("seconds")( 5 ) ); // sleep for 5 seconds
sleep(80.msecs);
}
const (local variable) const(std.typecons.Tuple!(int, "status", string, "output")) resultresult = (local variable) std.parallelism.Task!(run, Tuple!(int, "status", string, "output") delegate() @safe)* workwork.std.typecons.Tuple!(int, "status", string, "output") std.parallelism.Task!(run, std.typecons.Tuple!(int, "status", string, "output") delegate() @safe).yieldForce() @property ref @trustedIf the Task isn't started yet, execute it in the current thread.
If it's done, return its return value, if any. If it's in progress,
wait on a condition variable. If it threw an exception, rethrow that
exception.
This function should be used for expensive functions, as waiting on a
condition variable introduces latency, but avoids wasted CPU cycles.
yieldForce;
(local variable) int statusstatus = (local variable) const(std.typecons.Tuple!(int, "status", string, "output")) resultresult.(field) int std.typecons.Tuple!(int, "status", string, "output").__expand_field_0status;
(local variable) string outputoutput = (local variable) const(std.typecons.Tuple!(int, "status", string, "output")) resultresult.(field) string std.typecons.Tuple!(int, "status", string, "output").__expand_field_1output;
}
catch ((class) object.ExceptionThe 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 (local variable) object.Exception ee) { (local variable) string outputoutput = "collector error: " ~ (local variable) object.Exception ee.(field) string object.Throwable.msgA message describing the error.
msg ~ "\n"; }
const (local variable) const(bool) boundedbounded = (local variable) string outputoutput.(field) ulong string.lengthlength >= 2 * 1024 * 1024;
// Android proc labels can end in NUL; ADB commonly returns CRLF.
(local variable) string outputoutput = (local variable) string outputoutput.string std.array.replace!(immutable(char), string, string)(string subject, string from, string to) pure nothrow @safeReplace occurrences of from with to in subject in a new array.
Examples
assert("Hello Wörld".replace("o Wö", "o Wo") == "Hello World");
assert("Hello Wörld".replace("l", "h") == "Hehho Wörhd");
replace("\r", "").string std.array.replace!(immutable(char), string, string)(string subject, string from, string to) pure nothrow @safeReplace occurrences of from with to in subject in a new array.
Examples
assert("Hello Wörld".replace("o Wö", "o Wo") == "Hello World");
assert("Hello Wörld".replace("l", "h") == "Hehho Wörhd");
replace("\0", "\n");
const (local variable) const(string) filenamefilename = (parameter) string namename ~ ".txt";
void std.file.write!string(string name, const(void[]) buffer) @safeWrite buffer to file name.
Creates the file if it does not already exist.
Examples
scope(exit)
{
assert(exists(deleteme));
remove(deleteme);
}
int[] a = [ 0, 1, 1, 2, 3, 5, 8 ];
write(deleteme, a); // deleteme is the name of a temporary file
const bytes = read(deleteme);
const fileInts = () @trusted { return cast(int[]) bytes; }();
assert(fileInts == a);
write(string std.path.buildPath!char(const(char)[][] paths...) pure nothrow @safeCombines one or more path segments.
This function takes a set of path segments, given as an input
range of string elements or as a set of string arguments,
and concatenates them with each other. Directory separators
are inserted between segments if necessary. If any of the
path segments are absolute (as defined by isAbsolute), the
preceding segments will be dropped.
On Windows, if one of the path segments are rooted, but not absolute
(e.g. \foo), all preceding path segments down to the previous
root will be dropped. (See below for an example.)
This function always allocates memory to hold the resulting path.
The variadic overload is guaranteed to only perform a single
allocation, as is the range version if paths is a forward
range.
Examples
version (Posix)
{
assert(buildPath("foo", "bar", "baz") == "foo/bar/baz");
assert(buildPath("/foo/", "bar/baz") == "/foo/bar/baz");
assert(buildPath("/foo", "/bar") == "/bar");
}
version (Windows)
{
assert(buildPath("foo", "bar", "baz") == `foo\bar\baz`);
assert(buildPath(`c:\foo`, `bar\baz`) == `c:\foo\bar\baz`);
assert(buildPath("foo", `d:\bar`) == `d:\bar`);
assert(buildPath("foo", `\bar`) == `\bar`);
assert(buildPath(`c:\foo`, `\bar`) == `c:\bar`);
}
buildPath((field) string contributor_probe.Collector.directorydirectory, (local variable) const(string) filenamefilename), "command: " ~ (parameter) string commandcommand ~ "\nexit: " ~
(local variable) int statusstatus.string std.conv.to!string.to!int(int __param_0) pure nothrow @safeThe 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 = stringstring ~ "\noutput_limit_reached: " ~ (local variable) const(bool) boundedbounded.string std.conv.to!string.to!(const(bool))(const(bool) __param_0) pure @safeThe 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 = stringstring ~ "\n\n" ~ (local variable) string outputoutput);
(struct) std.json.JSONValueJSON value node
JSONValue[(alias) object.string = stringstring] (local variable) std.json.JSONValue[string] recordrecord;
std.json.JSONValue* core.internal.newaa._d_aaGetY!(string, std.json.JSONValue, std.json.JSONValue[string], string, std.json.JSONValue, string)(ref scope std.json.JSONValue[string] aa, string key, out bool found) pure nothrow @safeLookup key in aa.
Called only from implementation of (aa[`key`]) expressions when value is mutable.
record["name"] = (struct) std.json.JSONValueJSON value node
JSONValue(std.json.JSONValue std.json.JSONValue.this!string(string arg) pure nothrow @nogc ref @safeConstructor for JSONValue. If arg is a JSONValue
its value and type will be copied to the new JSONValue.
Note that this is a shallow copy: if type is JSONType.object
or JSONType.array then only the reference to the data will
be copied.
Otherwise, arg must be implicitly convertible to one of the
following types: typeof(null), string, ulong,
long, double, an associative array V[K] for any V
and K i.e. a JSON object, any array or bool. The type will
be set accordingly.
name);
std.json.JSONValue* core.internal.newaa._d_aaGetY!(string, std.json.JSONValue, std.json.JSONValue[string], string, std.json.JSONValue, string)(ref scope std.json.JSONValue[string] aa, string key, out bool found) pure nothrow @safeLookup key in aa.
Called only from implementation of (aa[`key`]) expressions when value is mutable.
record["command"] = (struct) std.json.JSONValueJSON value node
JSONValue(std.json.JSONValue std.json.JSONValue.this!string(string arg) pure nothrow @nogc ref @safeConstructor for JSONValue. If arg is a JSONValue
its value and type will be copied to the new JSONValue.
Note that this is a shallow copy: if type is JSONType.object
or JSONType.array then only the reference to the data will
be copied.
Otherwise, arg must be implicitly convertible to one of the
following types: typeof(null), string, ulong,
long, double, an associative array V[K] for any V
and K i.e. a JSON object, any array or bool. The type will
be set accordingly.
command);
std.json.JSONValue* core.internal.newaa._d_aaGetY!(string, std.json.JSONValue, std.json.JSONValue[string], string, std.json.JSONValue, string)(ref scope std.json.JSONValue[string] aa, string key, out bool found) pure nothrow @safeLookup key in aa.
Called only from implementation of (aa[`key`]) expressions when value is mutable.
record["exit"] = (struct) std.json.JSONValueJSON value node
JSONValue(std.json.JSONValue std.json.JSONValue.this!int(int arg) pure nothrow @nogc ref @safeConstructor for JSONValue. If arg is a JSONValue
its value and type will be copied to the new JSONValue.
Note that this is a shallow copy: if type is JSONType.object
or JSONType.array then only the reference to the data will
be copied.
Otherwise, arg must be implicitly convertible to one of the
following types: typeof(null), string, ulong,
long, double, an associative array V[K] for any V
and K i.e. a JSON object, any array or bool. The type will
be set accordingly.
status);
std.json.JSONValue* core.internal.newaa._d_aaGetY!(string, std.json.JSONValue, std.json.JSONValue[string], string, std.json.JSONValue, string)(ref scope std.json.JSONValue[string] aa, string key, out bool found) pure nothrow @safeLookup key in aa.
Called only from implementation of (aa[`key`]) expressions when value is mutable.
record["output_limit_reached"] = (struct) std.json.JSONValueJSON value node
JSONValue(std.json.JSONValue std.json.JSONValue.this!(const(bool))(const(bool) arg) pure nothrow @nogc ref @safeConstructor for JSONValue. If arg is a JSONValue
its value and type will be copied to the new JSONValue.
Note that this is a shallow copy: if type is JSONType.object
or JSONType.array then only the reference to the data will
be copied.
Otherwise, arg must be implicitly convertible to one of the
following types: typeof(null), string, ulong,
long, double, an associative array V[K] for any V
and K i.e. a JSON object, any array or bool. The type will
be set accordingly.
bounded);
std.json.JSONValue* core.internal.newaa._d_aaGetY!(string, std.json.JSONValue, std.json.JSONValue[string], string, std.json.JSONValue, string)(ref scope std.json.JSONValue[string] aa, string key, out bool found) pure nothrow @safeLookup key in aa.
Called only from implementation of (aa[`key`]) expressions when value is mutable.
record["file"] = (struct) std.json.JSONValueJSON value node
JSONValue(std.json.JSONValue std.json.JSONValue.this!string(string arg) pure nothrow @nogc ref @safeConstructor for JSONValue. If arg is a JSONValue
its value and type will be copied to the new JSONValue.
Note that this is a shallow copy: if type is JSONType.object
or JSONType.array then only the reference to the data will
be copied.
Otherwise, arg must be implicitly convertible to one of the
following types: typeof(null), string, ulong,
long, double, an associative array V[K] for any V
and K i.e. a JSON object, any array or bool. The type will
be set accordingly.
filename);
(field) std.json.JSONValue[] contributor_probe.Collector.recordsrecords ~= (struct) std.json.JSONValueJSON value node
JSONValue(std.json.JSONValue std.json.JSONValue.this!(std.json.JSONValue[string])(std.json.JSONValue[string] arg) pure nothrow @nogc ref @safeConstructor for JSONValue. If arg is a JSONValue
its value and type will be copied to the new JSONValue.
Note that this is a shallow copy: if type is JSONType.object
or JSONType.array then only the reference to the data will
be copied.
Otherwise, arg must be implicitly convertible to one of the
following types: typeof(null), string, ulong,
long, double, an associative array V[K] for any V
and K i.e. a JSON object, any array or bool. The type will
be set accordingly.
record);
(field) string contributor_probe.Collector.reportreport ~= "| " ~ (parameter) string namename ~ " | " ~ (local variable) int statusstatus.string std.conv.to!string.to!int(int __param_0) pure nothrow @safeThe 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 = stringstring ~ " | [output](./" ~ (local variable) const(string) filenamefilename ~ ") |\n";
if ((local variable) int statusstatus || (local variable) const(bool) boundedbounded) (field) ulong contributor_probe.Collector.failuresfailures++;
if ((local variable) int statusstatus == 124 || (local variable) int statusstatus == 137 || (local variable) const(bool) boundedbounded || (local variable) int statusstatus < 0)
(field) sparkles.ui.components.tasklist.TaskReporter* contributor_probe.Collector.taskstasks.void sparkles.ui.components.tasklist.TaskReporter.fail(ulong id, string detail = null)Terminal transitions: the task's line graduates into the scrollback.
A multi-line detail puts the first line on the task row and the rest
as indented follow-up lines (e.g. a failure's output tail).
fail((local variable) const(ulong) taskIdtaskId, "exit " ~ (local variable) int statusstatus.string std.conv.to!string.to!int(int __param_0) pure nothrow @safeThe 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 = stringstring ~ ((local variable) const(bool) boundedbounded ? "; output bounded" : ""));
else if ((local variable) int statusstatus)
(field) sparkles.ui.components.tasklist.TaskReporter* contributor_probe.Collector.taskstasks.void sparkles.ui.components.tasklist.TaskReporter.skip(ulong id, string detail = null)Terminal transitions: the task's line graduates into the scrollback.
A multi-line detail puts the first line on the task row and the rest
as indented follow-up lines (e.g. a failure's output tail).
skip((local variable) const(ulong) taskIdtaskId, "unavailable/denied; exit " ~ (local variable) int statusstatus.string std.conv.to!string.to!int(int __param_0) pure nothrow @safeThe 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 = stringstring ~ "; evidence saved");
else
(field) sparkles.ui.components.tasklist.TaskReporter* contributor_probe.Collector.taskstasks.void sparkles.ui.components.tasklist.TaskReporter.succeed(ulong id, string detail = null)Terminal transitions: the task's line graduates into the scrollback.
A multi-line detail puts the first line on the task row and the rest
as indented follow-up lines (e.g. a failure's output tail).
succeed((local variable) const(ulong) taskIdtaskId, "evidence saved");
return (local variable) string outputoutput;
}
}
int int D main(string[] args)main((alias) object.string = stringstring[] (parameter) string[] argsargs)
{
if ((parameter) string[] argsargs.(field) ulong string[].lengthlength == 1)
{
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("SKIP: explicit --serial required; no Android device contacted");
(parameter) string[] argsargs ~= "--help";
}
try
{
auto (local variable) expected.Expected!(ProbeOptions, CliError, Abort) parsedparsed = expected.Expected!(ProbeOptions, CliError, Abort) sparkles.core_cli.args.internal.parseCli!(contributor_probe.ProbeOptions)(string[] argv, sparkles.core_cli.help_formatting.HelpInfo helpInfo = HelpInfo(null, null, null)) @systemparseCli!(struct) contributor_probe.ProbeOptionsProbeOptions((parameter) string[] argsargs);
if (!(local variable) expected.Expected!(ProbeOptions, CliError, Abort) parsedparsed)
{
auto (local variable) sparkles.core_cli.args.error.CliError errorerror = (local variable) expected.Expected!(ProbeOptions, CliError, Abort) parsedparsed.inout(sparkles.core_cli.args.error.CliError) expected.Expected!(contributor_probe.ProbeOptions, sparkles.core_cli.args.error.CliError, expected.Abort).error() inout nothrow @nogc @property ref @safeReturns the error value. May only be called when hasValue returns false.
If there is no error value, it calls hook's onAccessEmptyError.
It returns E.init when hook doesn't provide onAccessEmptyError.
error;
if (!bool sparkles.base.term_caps.isTerminal(sparkles.base.term_caps.StdStream stream = StdStream.stdout) nothrow @nogc @trustedIs stream attached to a terminal? POSIX: isatty; Windows: GetConsoleMode
succeeds (it fails when the handle is redirected — the non-tty check).
Examples
The query never throws and is @nogc; the value is environment-dependent.
cast(void) isTerminal();
cast(void) isTerminal(StdStream.stderr);
isTerminal((enum) sparkles.base.term_caps.StdStreamA standard stream, for tty queries.
StdStream.(enum value) sparkles.base.term_caps.StdStream.stdout = 1stdout)) (local variable) sparkles.core_cli.args.error.CliError errorerror.(field) string sparkles.core_cli.args.error.CliError.helphelp = (local variable) sparkles.core_cli.args.error.CliError errorerror.(field) string sparkles.core_cli.args.error.CliError.helphelp.string sparkles.core_cli.term_unstyle.unstyle(in char[] s) pure nothrow @safeReturns s with every ANSI/VT escape sequence removed (CSI/SGR, OSC
including OSC 8 hyperlinks, DCS/SOS/PM/APC, …). Built on the shared escape
scanner in sparkles.base.text.ansi, so stripping and width measurement
always agree (the old regex only matched CSI + OSC 8).
unstyle;
return int sparkles.core_cli.args.internal.reportCliError(in sparkles.core_cli.args.error.CliError e)Reports a failed parse and returns the exit code the program should use.
A help request is a failure in the Expected sense but a success to the
user, and carries exitCode == 0 to say so — returning this value is what
keeps --help from looking like an error to a shell.
For a program whose commands have run methods, prefer runCli,
which calls this. This is the entry point for a program that parses into a
struct and then does its own work.
reportCliError((local variable) sparkles.core_cli.args.error.CliError errorerror);
}
auto (local variable) contributor_probe.ProbeOptions optionsoptions = (local variable) expected.Expected!(ProbeOptions, CliError, Abort) parsedparsed.inout(contributor_probe.ProbeOptions) expected.Expected!(contributor_probe.ProbeOptions, sparkles.core_cli.args.error.CliError, expected.Abort).value!()() inout pure nothrow @nogc @property ref @safeReturns the expected value if there is one.
With default Abort hook, it asserts when there is no value.
It calls hook's onAccessEmptyValue otherwise.
It returns T.init when hook doesn't provide onAccessEmptyValue.
value;
return int sparkles.core_cli.args.internal.runParsedCli!(contributor_probe.ProbeOptions)(ref contributor_probe.ProbeOptions cli) @systemrunParsedCli((local variable) contributor_probe.ProbeOptions optionsoptions);
}
catch ((class) object.ExceptionThe 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 (local variable) object.Exception ee) { stderr.std.stdio.File std.stdio.makeGlobal!"core.stdc.stdio.stderr"() nothrow @nogc @property ref @systemwriteln("probe: ", (local variable) object.Exception ee.(field) string object.Throwable.msgA message describing the error.
msg); return 1; }
}
@((struct) sparkles.core_cli.args.uda.CommandCommand("android-dev-env-probe",
shortDescription: "Collect Android AVF and NNS evidence through read-only ADB"))
struct (struct) contributor_probe.ProbeOptionsProbeOptions
{
@((struct) sparkles.core_cli.args.uda.OptionOption("serial", description: "Explicit authorized device serial; required for collection"))
(alias) object.string = stringstring (field) string contributor_probe.ProbeOptions.serialserial;
@((struct) sparkles.core_cli.args.uda.OptionOption("out", description: "New local report directory (must not already exist)"))
(alias) object.string = stringstring (field) string contributor_probe.ProbeOptions.directorydirectory;
@((struct) sparkles.core_cli.args.uda.OptionOption("adb", description: "ADB executable override"))
(alias) object.string = stringstring (field) string contributor_probe.ProbeOptions.adbadb = "adb";
@((struct) sparkles.core_cli.args.uda.OptionOption("list", description: "List devices without collecting a report"))
bool (field) bool contributor_probe.ProbeOptions.listlist;
@((struct) sparkles.core_cli.args.uda.OptionOption("choose", description: "Choose an online device interactively"))
bool (field) bool contributor_probe.ProbeOptions.choosechoose;
@((struct) sparkles.core_cli.args.uda.OptionOption("pid", description: "Inspect this active process (repeatable; maximum 32)"))
(alias) object.string = stringstring[] (field) string[] contributor_probe.ProbeOptions.pidspids;
@((struct) sparkles.core_cli.args.uda.OptionOption("package", description: "Inspect this terminal package (repeatable; maximum 16)"))
(alias) object.string = stringstring[] (field) string[] contributor_probe.ProbeOptions.packagespackages;
int int contributor_probe.ProbeOptions.run()run() { return int contributor_probe.collectDevice(contributor_probe.ProbeOptions options)collectDevice(this); }
}
int int contributor_probe.collectDevice(contributor_probe.ProbeOptions options)collectDevice((struct) contributor_probe.ProbeOptionsProbeOptions (parameter) contributor_probe.ProbeOptions optionsoptions)
{
(struct) contributor_probe.CollectorCollector (local variable) contributor_probe.Collector collectorcollector;
(local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.adbadb = (parameter) contributor_probe.ProbeOptions optionsoptions.(field) string contributor_probe.ProbeOptions.adbadb;
(local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.serialserial = (parameter) contributor_probe.ProbeOptions optionsoptions.(field) string contributor_probe.ProbeOptions.serialserial;
(local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.directorydirectory = (parameter) contributor_probe.ProbeOptions optionsoptions.(field) string contributor_probe.ProbeOptions.directorydirectory;
auto (local variable) string[] pidspids = (parameter) contributor_probe.ProbeOptions optionsoptions.(field) string[] contributor_probe.ProbeOptions.pidspids;
auto (local variable) string[] packagespackages = (parameter) contributor_probe.ProbeOptions optionsoptions.(field) string[] contributor_probe.ProbeOptions.packagespackages;
foreach ((parameter) string pidpid; (local variable) string[] pidspids) bool std.exception.enforce!().enforce!bool(bool value, lazy const(char)[] msg = null, string file = __FILE__, ulong line = cast(ulong)__LINE__) pure @safeEnforces that the given value is true.
If the given value is false, an exception is thrown.
The
msg - error message as a string
dg - custom delegate that return a string and is only called if an exception occurred
ex - custom exception to be thrown. It is lazy and is only created if an exception occurred
enforce(bool contributor_probe.identifier(string value, bool packageName = false)identifier((local variable) string pidpid) && (local variable) string pidpid.ulong std.conv.to!ulong.to!string(string __param_0) pure @safeThe 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!ulong > 0, "invalid PID");
foreach ((local variable) string packageNamepackageName; (local variable) string[] packagespackages) bool std.exception.enforce!().enforce!bool(bool value, lazy const(char)[] msg = null, string file = __FILE__, ulong line = cast(ulong)__LINE__) pure @safeEnforces that the given value is true.
If the given value is false, an exception is thrown.
The
msg - error message as a string
dg - custom delegate that return a string and is only called if an exception occurred
ex - custom exception to be thrown. It is lazy and is only created if an exception occurred
enforce(bool contributor_probe.identifier(string value, bool packageName = false)identifier((local variable) string packageNamepackageName, true), "invalid package name");
bool std.exception.enforce!().enforce!bool(bool value, lazy const(char)[] msg = null, string file = __FILE__, ulong line = cast(ulong)__LINE__) pure @safeEnforces that the given value is true.
If the given value is false, an exception is thrown.
The
msg - error message as a string
dg - custom delegate that return a string and is only called if an exception occurred
ex - custom exception to be thrown. It is lazy and is only created if an exception occurred
enforce((local variable) string[] pidspids.(field) ulong string[].lengthlength <= 32 && (local variable) string[] packagespackages.(field) ulong string[].lengthlength <= 16, "too many process/package selectors");
if ((parameter) contributor_probe.ProbeOptions optionsoptions.(field) bool contributor_probe.ProbeOptions.choosechoose)
{
bool std.exception.enforce!().enforce!bool(bool value, lazy const(char)[] msg = null, string file = __FILE__, ulong line = cast(ulong)__LINE__) pure @safeEnforces that the given value is true.
If the given value is false, an exception is thrown.
The
msg - error message as a string
dg - custom delegate that return a string and is only called if an exception occurred
ex - custom exception to be thrown. It is lazy and is only created if an exception occurred
enforce(!(parameter) contributor_probe.ProbeOptions optionsoptions.(field) bool contributor_probe.ProbeOptions.listlist && !(local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.serialserial.(field) ulong string.lengthlength, "--choose cannot be combined with --list or --serial");
bool std.exception.enforce!().enforce!bool(bool value, lazy const(char)[] msg = null, string file = __FILE__, ulong line = cast(ulong)__LINE__) pure @safeEnforces that the given value is true.
If the given value is false, an exception is thrown.
The
msg - error message as a string
dg - custom delegate that return a string and is only called if an exception occurred
ex - custom exception to be thrown. It is lazy and is only created if an exception occurred
enforce(bool sparkles.base.term_caps.isTerminal(sparkles.base.term_caps.StdStream stream = StdStream.stdout) nothrow @nogc @trustedIs stream attached to a terminal? POSIX: isatty; Windows: GetConsoleMode
succeeds (it fails when the handle is redirected — the non-tty check).
Examples
The query never throws and is @nogc; the value is environment-dependent.
cast(void) isTerminal();
cast(void) isTerminal(StdStream.stderr);
isTerminal((enum) sparkles.base.term_caps.StdStreamA standard stream, for tty queries.
StdStream.(enum value) sparkles.base.term_caps.StdStream.stdin = 0stdin), "--choose needs a terminal; use explicit --serial for automation");
const (local variable) const(std.typecons.Tuple!(int, "status", string, "output")) devicesdevices = (local variable) contributor_probe.Collector collectorcollector.std.typecons.Tuple!(int, "status", string, "output") contributor_probe.Collector.host(string[] arguments) @safehost(["devices", "-l"]);
bool std.exception.enforce!().enforce!bool(bool value, lazy const(char)[] msg = null, string file = __FILE__, ulong line = cast(ulong)__LINE__) pure @safeEnforces that the given value is true.
If the given value is false, an exception is thrown.
The
msg - error message as a string
dg - custom delegate that return a string and is only called if an exception occurred
ex - custom exception to be thrown. It is lazy and is only created if an exception occurred
enforce((local variable) const(std.typecons.Tuple!(int, "status", string, "output")) devicesdevices.(field) int std.typecons.Tuple!(int, "status", string, "output").__expand_field_0status == 0, (field) int std.typecons.Tuple!(int, "status", string, "output").__expand_field_0devices.(field) string std.typecons.Tuple!(int, "status", string, "output").__expand_field_1output);
(alias) object.string = stringstring[] (local variable) string[] serialsserials;
(struct) sparkles.core_cli.prompts.SelectOptionOne choice of a select.
SelectOption[] (local variable) sparkles.core_cli.prompts.SelectOption[] choiceschoices;
foreach ((parameter) string lineline; (local variable) const(std.typecons.Tuple!(int, "status", string, "output")) devicesdevices.(field) string std.typecons.Tuple!(int, "status", string, "output").__expand_field_1output.string[] std.string.splitLines!(immutable(char))(string s, std.typecons.Flag!"keepTerminator" keepTerm = Flag.no) pure nothrow @safeSplit s into an array of lines according to the unicode standard using
'\r', '\n', "\r\n", lineSep,
paraSep, U+0085 (NEL), '\v' and '\f'
as delimiters. If keepTerm is set to KeepTerminator.yes, then the
delimiter is included in the strings returned.
Does not throw on invalid UTF; such is simply passed unchanged
to the output.
Allocates memory; use lineSplitter for an alternative that
does not.
Adheres to Unicode 7.0.
Examples
string s = "Hello\nmy\rname\nis";
assert(splitLines(s) == ["Hello", "my", "name", "is"]);
splitLines)
{
const (local variable) const(string[]) fieldsfields = (local variable) string lineline.string[] std.array.split!string(string s) pure @safeEagerly splits range into an array, using sep as the delimiter.
When no delimiter is provided, strings are split into an array of words,
using whitespace as delimiter.
Runs of whitespace are merged together (no empty words are produced).
The range must be a forward range.
The separator can be a value of the same type as the elements in range
or it can be another forward range.
Examples
import std.uni : isWhite;
assert("Learning,D,is,fun".split(",") == ["Learning", "D", "is", "fun"]);
assert("Learning D is fun".split!isWhite == ["Learning", "D", "is", "fun"]);
assert("Learning D is fun".split(" D ") == ["Learning", "is fun"]);
string str = "Hello World!";
assert(str.split == ["Hello", "World!"]);
string str2 = "Hello\t\tWorld\t!";
assert(str2.split == ["Hello", "World", "!"]);
assert(split("hello world") == ["hello","world"]);
assert(split("192.168.0.1", ".") == ["192", "168", "0", "1"]);
auto a = split([1, 2, 3, 4, 5, 1, 2, 3, 4, 5], [2, 3]);
assert(a == [[1], [4, 5, 1], [4, 5]]);
split;
if ((local variable) const(string[]) fieldsfields.(field) ulong const(string[]).lengthlength < 2 || (local variable) const(string[]) fieldsfields[1] != "device") continue;
(local variable) string[] serialsserials ~= (local variable) const(string[]) fieldsfields[0];
(local variable) sparkles.core_cli.prompts.SelectOption[] choiceschoices ~= (struct) sparkles.core_cli.prompts.SelectOptionOne choice of a select.
SelectOption((local variable) const(string[]) fieldsfields[0], (local variable) string lineline);
}
ulong std.exception.enforce!().enforce!ulong(ulong value, lazy const(char)[] msg = null, string file = __FILE__, ulong line = cast(ulong)__LINE__) pure @safeEnforces that the given value is true.
If the given value is false, an exception is thrown.
The
msg - error message as a string
dg - custom delegate that return a string and is only called if an exception occurred
ex - custom exception to be thrown. It is lazy and is only created if an exception occurred
enforce((local variable) string[] serialsserials.(field) ulong string[].lengthlength, "no authorized online devices; enable USB debugging and authorize this computer");
auto (local variable) sparkles.core_cli.prompts.PromptIo ioio = sparkles.core_cli.prompts.PromptIo sparkles.core_cli.prompts.stdioPromptIo()The real stdin/stdout PromptIo.
stdioPromptIo();
const (local variable) const(expected.Expected!(ulong, string, Abort)) pickedpicked = expected.Expected!(ulong, string, Abort) sparkles.core_cli.prompts.select(string question, const(sparkles.core_cli.prompts.SelectOption)[] options, ulong defaultIndex, sparkles.core_cli.prompts.PromptPolicy policy, sparkles.core_cli.prompts.PromptIo io, const(sparkles.ui.components.theme.Theme) theme = Theme(false, true, BorderStyle.rounded, StatusGlyphs("\xe2\x9c\x94", "\xe2\x9c\x96", "\xe2\x9a\xa0", "\xe2\x80\xa2", "\xe2\x97\x8b", "\xe2\x97\x90", "\xe2\x94\x84", "\xe2\x80\xa6")), bool wrapAround = true)Ask the user to pick one of options by number. Renders the list (default
marked and painted accent), then loops until a valid number or an empty line
(= the default). Returns the chosen index; errors on EOF or a non-
interactive fail policy.
When io`.beginKeySession` is available (a real terminal), arrow keys move
the highlighted row instead: Up/Down move, Enter confirms, Esc/Ctrl+C/
Ctrl+D cancel. wrapAround`` (on by default) makes Up from the first row
jump to the last (and Down from the last jump to the first); pass false
to clamp at the ends instead.
select("Device for AVF + NNS research", (local variable) sparkles.core_cli.prompts.SelectOption[] choiceschoices, 0,
(enum) sparkles.core_cli.prompts.PromptPolicyHow a prompt resolves when it cannot, or should not, actually ask.
PromptPolicy.(enum value) sparkles.core_cli.prompts.PromptPolicy.interactive = 0Ask on the terminal, re-prompting on invalid input.
interactive, (local variable) sparkles.core_cli.prompts.PromptIo ioio, sparkles.ui.components.theme.Theme sparkles.ui.components.theme.makeTheme(in sparkles.base.term_caps.OutputCapabilities caps) pure nothrow @nogc @safeThe theme for a target's output affordances: ASCII borders + fallback
glyphs without Unicode, colors per the color tier. A TermCaps converts
implicitly (its output is alias this), so ``makeTheme(detectTermCaps())
reads as before; a GUI target passes its own declaration.
makeTheme(sparkles.base.term_caps.TermCaps sparkles.base.term_caps.detectTermCaps(bool noColors = false) @safeDetects capabilities and prepares the console.
Colors are on only when stdout is a terminal and neither noColors,
$NO_COLOR, nor TERM=dumb disables them; a non-empty, non-"0"
$CLICOLOR_FORCE forces them on for a non-tty (but never overrides an
explicit disable). colorDepth is the tier
(classifyColorDepth over $COLORTERM/$TERM)
when colors are on, else none. On Windows this additionally sets the output code page to
UTF-8 (so ✓ ✗ ⚙ render even without colors) and enables virtual-terminal
processing (so ANSI escapes are interpreted rather than printed literally);
colors stay off when stdout is redirected or VT can't be enabled.
detectTermCaps()));
bool std.exception.enforce!().enforce!bool(bool value, lazy const(char)[] msg = null, string file = __FILE__, ulong line = cast(ulong)__LINE__) pure @safeEnforces that the given value is true.
If the given value is false, an exception is thrown.
The
msg - error message as a string
dg - custom delegate that return a string and is only called if an exception occurred
ex - custom exception to be thrown. It is lazy and is only created if an exception occurred
enforce(!(local variable) const(expected.Expected!(ulong, string, Abort)) pickedpicked.bool expected.Expected!(ulong, string, expected.Abort).hasError!()() const pure nothrow @nogc @property @safeChecks if Expected has error
hasError, (local variable) const(expected.Expected!(ulong, string, Abort)) pickedpicked.bool expected.Expected!(ulong, string, expected.Abort).hasError!()() const pure nothrow @nogc @property @safeChecks if Expected has error
hasError ? (local variable) const(expected.Expected!(ulong, string, Abort)) pickedpicked.inout(string) expected.Expected!(ulong, string, expected.Abort).error() inout nothrow @nogc @property ref @safeReturns the error value. May only be called when hasValue returns false.
If there is no error value, it calls hook's onAccessEmptyError.
It returns E.init when hook doesn't provide onAccessEmptyError.
error : "");
(local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.serialserial = (local variable) string[] serialsserials[(local variable) const(expected.Expected!(ulong, string, Abort)) pickedpicked.inout(ulong) expected.Expected!(ulong, string, expected.Abort).value!()() inout pure nothrow @nogc @property ref @safeReturns the expected value if there is one.
With default Abort hook, it asserts when there is no value.
It calls hook's onAccessEmptyValue otherwise.
It returns T.init when hook doesn't provide onAccessEmptyValue.
value];
}
if ((parameter) contributor_probe.ProbeOptions optionsoptions.(field) bool contributor_probe.ProbeOptions.listlist)
{
bool std.exception.enforce!().enforce!bool(bool value, lazy const(char)[] msg = null, string file = __FILE__, ulong line = cast(ulong)__LINE__) pure @safeEnforces that the given value is true.
If the given value is false, an exception is thrown.
The
msg - error message as a string
dg - custom delegate that return a string and is only called if an exception occurred
ex - custom exception to be thrown. It is lazy and is only created if an exception occurred
enforce(!(local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.serialserial.(field) ulong string.lengthlength, "use --list separately from --serial");
const (local variable) const(std.typecons.Tuple!(int, "status", string, "output")) resultresult = (local variable) contributor_probe.Collector collectorcollector.std.typecons.Tuple!(int, "status", string, "output") contributor_probe.Collector.host(string[] arguments) @safehost(["devices", "-l"]);
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln((local variable) const(std.typecons.Tuple!(int, "status", string, "output")) resultresult.(field) string std.typecons.Tuple!(int, "status", string, "output").__expand_field_1output);
return (local variable) const(std.typecons.Tuple!(int, "status", string, "output")) resultresult.(field) int std.typecons.Tuple!(int, "status", string, "output").__expand_field_0status;
}
bool std.exception.enforce!().enforce!bool(bool value, lazy const(char)[] msg = null, string file = __FILE__, ulong line = cast(ulong)__LINE__) pure @safeEnforces that the given value is true.
If the given value is false, an exception is thrown.
The
msg - error message as a string
dg - custom delegate that return a string and is only called if an exception occurred
ex - custom exception to be thrown. It is lazy and is only created if an exception occurred
enforce((local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.serialserial.(field) ulong string.lengthlength && !(local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.serialserial.bool std.algorithm.searching.canFind!().canFind!(string, char)(string haystack, scope char needle) pure @safeConvenience 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")));
canFind('\n') &&
!(local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.serialserial.bool std.algorithm.searching.canFind!().canFind!(string, char)(string haystack, scope char needle) pure @safeConvenience 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")));
canFind('\r'), "explicit --serial required");
const (local variable) const(std.typecons.Tuple!(int, "status", string, "output")) statestate = (local variable) contributor_probe.Collector collectorcollector.std.typecons.Tuple!(int, "status", string, "output") contributor_probe.Collector.host(string[] arguments) @safehost(["-s", (local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.serialserial, "get-state"]);
bool std.exception.enforce!().enforce!bool(bool value, lazy const(char)[] msg = null, string file = __FILE__, ulong line = cast(ulong)__LINE__) pure @safeEnforces that the given value is true.
If the given value is false, an exception is thrown.
The
msg - error message as a string
dg - custom delegate that return a string and is only called if an exception occurred
ex - custom exception to be thrown. It is lazy and is only created if an exception occurred
enforce((local variable) const(std.typecons.Tuple!(int, "status", string, "output")) statestate.(field) int std.typecons.Tuple!(int, "status", string, "output").__expand_field_0status == 0 && (field) int std.typecons.Tuple!(int, "status", string, "output").__expand_field_0state.(field) string std.typecons.Tuple!(int, "status", string, "output").__expand_field_1output.string std.string.strip!string(string str) pure nothrow @nogc @safeStrips 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");
strip == "device", "device is not authorized/online: " ~ (local variable) const(std.typecons.Tuple!(int, "status", string, "output")) statestate.(field) string std.typecons.Tuple!(int, "status", string, "output").__expand_field_1output);
if (!(local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.directorydirectory.(field) ulong string.lengthlength)
(local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.directorydirectory = "android-dev-env-report-" ~ (class) std.datetime.systime.ClockEffectively 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 @safeReturns the current time in the given time zone.
currTime.long std.datetime.systime.SysTime.toUnixTime!long() const pure nothrow @nogc scope @safeConverts this SysTime to unix time (i.e. seconds from midnight,
January 1st, 1970 in UTC).
The C standard does not specify the representation of time_t, so it is
implementation defined. On POSIX systems, unix time is equivalent to
time_t, but that's not necessarily true on other systems (e.g. it is
not true for the Digital Mars C runtime). So, be careful when using unix
time with C functions on non-POSIX systems.
By default, the return type is time_t (which is normally an alias for
int on 32-bit systems and long on 64-bit systems), but if a different
size is required than either int or long can be passed as a template
argument to get the desired size.
If the return type is int, and the result can't fit in an int, then the
closest value that can be held in 32 bits will be used (so int.max
if it goes over and int.min if it goes under). However, no attempt
is made to deal with integer overflow if the return type is long.
Examples
import core.time : hours;
import std.datetime.date : DateTime;
import std.datetime.timezone : SimpleTimeZone, UTC;
assert(SysTime(DateTime(1970, 1, 1), UTC()).toUnixTime() == 0);
auto pst = new immutable SimpleTimeZone(hours(-8));
assert(SysTime(DateTime(1970, 1, 1), pst).toUnixTime() == 28800);
auto utc = SysTime(DateTime(2007, 12, 22, 8, 14, 45), UTC());
assert(utc.toUnixTime() == 1_198_311_285);
auto ca = SysTime(DateTime(2007, 12, 22, 8, 14, 45), pst);
assert(ca.toUnixTime() == 1_198_340_085);
static void testScope(scope ref SysTime st) @safe
{
auto result = st.toUnixTime();
}
toUnixTime.string std.conv.to!string.to!long(long __param_0) pure nothrow @safeThe 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 = stringstring;
bool std.exception.enforce!().enforce!bool(bool value, lazy const(char)[] msg = null, string file = __FILE__, ulong line = cast(ulong)__LINE__) pure @safeEnforces that the given value is true.
If the given value is false, an exception is thrown.
The
msg - error message as a string
dg - custom delegate that return a string and is only called if an exception occurred
ex - custom exception to be thrown. It is lazy and is only created if an exception occurred
enforce(!bool std.file.exists!string(string name) nothrow @nogc @safeDetermine whether the given file (or directory) exists.
exists((local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.directorydirectory), "output directory already exists; choose a new --out directory");
void std.file.mkdirRecurse(scope const(char)[] pathname) @safeMake directory and all parent directories as needed.
Does nothing if the directory specified by
pathname already exists.
Examples
import std.path : buildPath;
auto dir = deleteme ~ "dir";
scope(exit) dir.rmdirRecurse;
dir.mkdir;
assert(dir.exists);
dir.mkdirRecurse; // does nothing
// creates all parent directories as needed
auto nested = dir.buildPath("a", "b", "c");
nested.mkdirRecurse;
assert(nested.exists);
import std.exception : assertThrown;
scope(exit) deleteme.remove;
deleteme.write("a");
// cannot make directory as it's already a file
assertThrown!FileException(deleteme.mkdirRecurse);
mkdirRecurse((local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.directorydirectory);
bool std.exception.enforce!().enforce!bool(bool value, lazy const(char)[] msg = null, string file = __FILE__, ulong line = cast(ulong)__LINE__) pure @safeEnforces that the given value is true.
If the given value is false, an exception is thrown.
The
msg - error message as a string
dg - custom delegate that return a string and is only called if an exception occurred
ex - custom exception to be thrown. It is lazy and is only created if an exception occurred
enforce(int core.sys.posix.sys.stat.chmod(scope const(char*), uint) nothrow @nogcchmod((local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.directorydirectory.immutable(char)* std.string.toStringz(scope const(char)[] s) pure nothrow @trustedExamples
import core.stdc.string : strlen;
import std.conv : to;
auto p = toStringz("foo");
assert(strlen(p) == 3);
const(char)[] foo = "abbzxyzzy";
p = toStringz(foo[3 .. 5]);
assert(strlen(p) == 2);
string test = "";
p = toStringz(test);
assert(*p == 0);
test = "\0";
p = toStringz(test);
assert(*p == 0);
test = "foo\0";
p = toStringz(test);
assert(p[0] == 'f' && p[1] == 'o' && p[2] == 'o' && p[3] == 0);
const string test2 = "";
p = toStringz(test2);
assert(*p == 0);
assert(toStringz([]) is toStringz(""));
toStringz, (template instance) std.conv.octal!"700"octal!"700") == 0, "cannot make report directory private");
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("Android AVF + NNS research".string sparkles.ui.components.header.drawHeader(string title, sparkles.ui.components.header.HeaderProps props = HeaderProps(HeaderStyle.divider, '\u2500', '\u2550', 0LU, 1LU)) @safeDraw a section header.
Examples
// Simple divider
"Section".drawHeader.writeln;
// Output: ── Section ──
// Banner style
"Main Title".drawHeader(HeaderProps(style: HeaderStyle.banner, width: 40)).writeln;
Examples
Default divider style
assert("Title".drawHeader == "── Title ──");
Custom line character
assert("Test".drawHeader(HeaderProps(lineChar: '═')) == "══ Test ══");
Banner style with fixed width
const result = "Demo".drawHeader(HeaderProps(style: HeaderStyle.banner, width: 20));
assert(result == "════════════════════\n Demo \n════════════════════");
Fixed width divider
const result = "X".drawHeader(HeaderProps(width: 11));
assert(result == "──── X ────");
A title wider than width is wrapped to fit (a single unbreakable token is
hard-broken), so a banner never exceeds width: every line is exactly that
wide. (This also guards the pad arithmetic, which would otherwise underflow
size_t and try to allocate a near-infinite line.)
import std.string : splitLines;
const title = "a-very-long-title-that-exceeds-the-requested-banner-width";
const result = title.drawHeader(HeaderProps(style: HeaderStyle.banner, width: 20));
const lines = result.splitLines;
assert(lines.length >= 4); // top rule + >=2 wrapped title rows + bottom rule
foreach (line; lines)
assert(line.visibleWidth == 20);
The same hard cap for the divider style: every wrapped row is width wide.
import std.string : splitLines;
const title = "a-very-long-title-that-exceeds-the-requested-divider-width";
const result = title.drawHeader(HeaderProps(width: 10));
foreach (line; result.splitLines)
assert(line.visibleWidth == 10);
width breaks a long banner title across lines instead of widening past it;
every line (rules and title rows) is exactly width, and the words survive.
import std.string : splitLines;
import std.algorithm.searching : canFind;
const title = "alpha beta gamma delta epsilon zeta";
const result = title.drawHeader(HeaderProps(style: HeaderStyle.banner, width: 20));
const lines = result.splitLines;
assert(lines.length >= 4); // top rule + >=2 title rows + bottom rule
foreach (line; lines)
assert(line.visibleWidth == 20);
assert(result.canFind("alpha") && result.canFind("zeta"));
The same for the divider style: each wrapped row is a full width-wide line.
import std.string : splitLines;
const title = "alpha beta gamma delta epsilon zeta";
const result = title.drawHeader(HeaderProps(width: 20));
const lines = result.splitLines;
assert(lines.length >= 2);
foreach (line; lines)
assert(line.visibleWidth == 20);
drawHeader((struct) sparkles.ui.components.header.HeaderPropsConfiguration options for header rendering.
HeaderProps(style: (enum) sparkles.ui.components.header.HeaderStyleHeader display style.
HeaderStyle.(enum value) sparkles.ui.components.header.HeaderStyle.banner = 1banner)));
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("Read-only collection · no guest boot or policy changes · local report\n");
auto (local variable) sparkles.ui.components.live.LiveRegion regionregion = sparkles.ui.components.live.LiveRegion sparkles.ui.components.live.stdoutLiveRegion()A LiveRegion on stdout: interactive iff stdout is a terminal (each write is
flushed so frames appear atomically), width from terminalSize() per repaint.
stdoutLiveRegion();
scope (exit) (local variable) sparkles.ui.components.live.LiveRegion regionregion.void sparkles.ui.components.live.LiveRegion.finish(bool keepFrame = true)End the region: restore the cursor and either keep the last frame as
permanent output (default) or erase it. Idempotent; call it from a
scope (exit) so exceptions can't leave the cursor hidden.
finish();
auto (local variable) sparkles.ui.components.tasklist.TaskReporter taskstasks = (struct) sparkles.ui.components.tasklist.TaskReporterThe stateful checklist driver. Owns the item states; each transition
repaints the live block and graduates finished tasks into the scrollback.
The LiveRegion stays owned by the caller (scope (exit) region.finish();).
TaskReporter(&sparkles.ui.components.tasklist.TaskReporter sparkles.ui.components.tasklist.TaskReporter.this(sparkles.ui.components.live.LiveRegion* region, sparkles.ui.components.theme.Theme theme) refregion, sparkles.ui.components.theme.Theme sparkles.ui.components.theme.makeTheme(in sparkles.base.term_caps.OutputCapabilities caps) pure nothrow @nogc @safeThe theme for a target's output affordances: ASCII borders + fallback
glyphs without Unicode, colors per the color tier. A TermCaps converts
implicitly (its output is alias this), so ``makeTheme(detectTermCaps())
reads as before; a GUI target passes its own declaration.
makeTheme(sparkles.base.term_caps.TermCaps sparkles.base.term_caps.detectTermCaps(bool noColors = false) @safeDetects capabilities and prepares the console.
Colors are on only when stdout is a terminal and neither noColors,
$NO_COLOR, nor TERM=dumb disables them; a non-empty, non-"0"
$CLICOLOR_FORCE forces them on for a non-tty (but never overrides an
explicit disable). colorDepth is the tier
(classifyColorDepth over $COLORTERM/$TERM)
when colors are on, else none. On Windows this additionally sets the output code page to
UTF-8 (so ✓ ✗ ⚙ render even without colors) and enables virtual-terminal
processing (so ANSI escapes are interpreted rather than printed literally);
colors stay off when stdout is redirected or VT can't be enabled.
detectTermCaps()));
(local variable) contributor_probe.Collector collectorcollector.(field) sparkles.ui.components.tasklist.TaskReporter* contributor_probe.Collector.taskstasks = &(local variable) sparkles.ui.components.tasklist.TaskReporter taskstasks;
(local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.reportreport = "# Android development environment probe\n\nCollected: " ~
(class) std.datetime.systime.ClockEffectively 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 @safeReturns the current time in the given time zone.
currTime.string std.datetime.systime.SysTime.toISOExtString(int prec = -1) const nothrow scope @safeConverts this SysTime to a string with the format
YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ
is the time zone).
Default behaviour:
Note that the number of digits in the fractional seconds varies with the
number of fractional seconds. It's a maximum of 7 (which would be
hnsecs), but only has as many as are necessary to hold the correct value
(so no trailing zeroes), and if there are no fractional seconds, then
there is no decimal point.
The optional parameter "prec" allows to change the default behavior by
specifying the precision of the fractional seconds. The accepted values
are in the range [-1, 7], where -1 represents the default behavior.
If this SysTime's time zone is
LocalTime, then TZ is empty. If its time
zone is UTC, then it is "Z". Otherwise, it is the offset from UTC
(e.g. +01:00 or -07:00). Note that the offset from UTC is not
enough to uniquely identify the time zone.
Time zone offsets will be in the form +HH:MM or -HH:MM.
toISOExtString ~ "\n\n" ~
"Read-only root/shell ADB observations. No guests started, no permissions granted, " ~
"no NNS launcher executed. ADB serial is deliberately omitted from report metadata. " ~
"Outputs normalize CRLF to LF and NUL terminators to newlines; all other output is retained. " ~
"Process observations describe existing contexts; they do not prove that an ordinary app " ~
"can create them. Missing files, denied reads, failed commands and timeouts remain evidence.\n\n" ~
"| Probe | Exit | Evidence |\n| --- | --- | --- |\n";
(local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("identity", "for k in ro.product.model ro.product.device ro.soc.model " ~
"ro.product.cpu.abilist ro.build.version.release ro.build.version.sdk ro.build.fingerprint " ~
"ro.build.type ro.boot.verifiedbootstate ro.boot.flash.locked; do echo $k=$(getprop $k); done; uname -a; getconf PAGE_SIZE");
const (local variable) const(string) securitysecurity = (local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("security", "id; getenforce; cat /proc/self/attr/current; " ~
"grep -E '^(Uid|Gid|Cap|NoNewPrivs|Seccomp)' /proc/self/status");
(local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("resources", "grep -E 'MemTotal:|MemAvailable:' /proc/meminfo; " ~
"df -h /data; dumpsys battery | grep -E 'level:|temperature:|status:'");
(local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("avf-features", "pm list features | grep -E 'virtualization|hypervisor'; " ~
"for p in /dev/kvm /dev/gunyah /dev/gzvm /apex/com.android.virt/bin/vm " ~
"/apex/com.android.virt/etc/fs/microdroid_kernel /apex/com.android.virt/etc/microdroid_initrd_debuggable.img; " ~
"do ls -ldZ $p; done");
(local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("avf-info", "/apex/com.android.virt/bin/vm info");
(local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("avf-list", "/apex/com.android.virt/bin/vm list");
(local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("avf-cli", "/apex/com.android.virt/bin/vm --help");
(local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("avf-artifacts", "ls -lZ /apex/com.android.virt/etc/; sha256sum " ~
"/apex/com.android.virt/etc/fs/microdroid_kernel " ~
"/apex/com.android.virt/etc/microdroid_initrd_debuggable.img " ~
"/apex/com.android.virt/etc/microdroid_initrd_normal.img");
(local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("avf-permissions", "pm list permissions -f | grep -A 4 -E " ~
"'MANAGE_VIRTUAL_MACHINE|USE_CUSTOM_VIRTUAL_MACHINE|USE_PROTECTED_VM'; " ~
"getprop | grep -E '^\\[(ro\\.boot\\.hypervisor|ro\\.boot\\.avf|ro\\.boot\\.pvmfw|ro\\.boot\\.protected_vm|hypervisor\\.)'");
(local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("kernel-config", "zcat /proc/config.gz | grep -E " ~
"'CONFIG_(USER_NS|NAMESPACES|SECCOMP|CGROUP|FUSE|VIRTIO|KVM|GUNYAH|PROTECTED|EXT4|F2FS|OVERLAY|NET_NS|PID_NS)'");
(local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("namespace-policy", "for p in /proc/sys/kernel/seccomp_bypass_paths " ~
"/proc/sys/user/max_user_namespaces /proc/sys/user/max_mnt_namespaces; do echo $p; cat $p; done");
(local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("nns-layout", "for p in /data/adb/modules/nix/module.prop " ~
"/data/nix /data/nix/store /data/nix/bin/nix-enter /data/adb/modules/nix/bin/nix-enter " ~
"/data/nix/lib /data/nix/etc/nix/nix.conf /data/nix/var/nix/daemon.pid " ~
"/data/nix/var/nix/daemon-socket/socket /data/nix/var/nix/profiles/profile " ~
"/data/nix/var/nns/runsvdir.pid /data/ve/etc; do ls -ldZ $p; done; " ~
"cat /data/adb/modules/nix/module.prop; cat /data/nix/var/nix/daemon.pid; " ~
"sha256sum /data/nix/bin/nix-enter /data/adb/modules/nix/bin/nix-enter");
(local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("nns-config", "grep -E '^[[:space:]]*(sandbox|build-users-group|experimental-features|store)[[:space:]]*=' " ~
"/data/nix/etc/nix/nix.conf; ls -lZ /data/nix/lib/libnns* /data/nix/bin/nns-resolver");
const (local variable) const(string) mountsmounts = "grep -E ' / |/nix|/data/ve|/data/adb/modules/nix' ";
(local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("adb-mounts", (local variable) const(string) mountsmounts ~ "/proc/self/mountinfo; " ~
"for n in mnt user pid net; do readlink /proc/self/ns/$n; done");
const (local variable) const(string) processesprocesses = (local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("processes", "ps -A -o PID,UID,NAME | " ~
"grep -E 'PID|nix|proot|virtmgr|crosvm|microdroid|runsv|sparkles|termux|shizuku'");
foreach ((parameter) string lineline; (local variable) const(string) processesprocesses.string[] std.string.splitLines!(immutable(char))(string s, std.typecons.Flag!"keepTerminator" keepTerm = Flag.no) pure nothrow @safeSplit s into an array of lines according to the unicode standard using
'\r', '\n', "\r\n", lineSep,
paraSep, U+0085 (NEL), '\v' and '\f'
as delimiters. If keepTerm is set to KeepTerminator.yes, then the
delimiter is included in the strings returned.
Does not throw on invalid UTF; such is simply passed unchanged
to the output.
Allocates memory; use lineSplitter for an alternative that
does not.
Adheres to Unicode 7.0.
Examples
string s = "Hello\nmy\rname\nis";
assert(splitLines(s) == ["Hello", "my", "name", "is"]);
splitLines)
{
const (local variable) const(string[]) fieldsfields = (local variable) string lineline.string[] std.array.split!string(string s) pure @safeEagerly splits range into an array, using sep as the delimiter.
When no delimiter is provided, strings are split into an array of words,
using whitespace as delimiter.
Runs of whitespace are merged together (no empty words are produced).
The range must be a forward range.
The separator can be a value of the same type as the elements in range
or it can be another forward range.
Examples
import std.uni : isWhite;
assert("Learning,D,is,fun".split(",") == ["Learning", "D", "is", "fun"]);
assert("Learning D is fun".split!isWhite == ["Learning", "D", "is", "fun"]);
assert("Learning D is fun".split(" D ") == ["Learning", "is fun"]);
string str = "Hello World!";
assert(str.split == ["Hello", "World!"]);
string str2 = "Hello\t\tWorld\t!";
assert(str2.split == ["Hello", "World", "!"]);
assert(split("hello world") == ["hello","world"]);
assert(split("192.168.0.1", ".") == ["192", "168", "0", "1"]);
auto a = split([1, 2, 3, 4, 5, 1, 2, 3, 4, 5], [2, 3]);
assert(a == [[1], [4, 5, 1], [4, 5]]);
split;
if ((local variable) const(string[]) fieldsfields.(field) ulong const(string[]).lengthlength >= 3 && bool contributor_probe.identifier(string value, bool packageName = false)identifier((local variable) const(string[]) fieldsfields[0]) && !(local variable) string[] pidspids.bool std.algorithm.searching.canFind!().canFind!(string[], string)(string[] haystack, scope string needle) pure nothrow @nogc @safeConvenience 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")));
canFind((local variable) const(string[]) fieldsfields[0]) && (local variable) string[] pidspids.(field) ulong string[].lengthlength < 32)
(local variable) string[] pidspids ~= (local variable) const(string[]) fieldsfields[0];
}
foreach ((local variable) string packageNamepackageName; (local variable) string[] packagespackages)
{
(local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("package-" ~ (local variable) string packageNamepackageName, "dumpsys package " ~ string contributor_probe.quote(string value)quote((local variable) string packageNamepackageName) ~
" | grep -E 'versionCode=|versionName=|userId=|targetSdk=|MANAGE_VIRTUAL_MACHINE|USE_CUSTOM_VIRTUAL_MACHINE|USE_PROTECTED_VM'");
const (local variable) const(string) runningrunning = (local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("package-pids-" ~ (local variable) string packageNamepackageName, "pidof " ~ string contributor_probe.quote(string value)quote((local variable) string packageNamepackageName));
foreach ((parameter) string pidpid; (local variable) const(string) runningrunning.string[] std.array.split!string(string s) pure @safeEagerly splits range into an array, using sep as the delimiter.
When no delimiter is provided, strings are split into an array of words,
using whitespace as delimiter.
Runs of whitespace are merged together (no empty words are produced).
The range must be a forward range.
The separator can be a value of the same type as the elements in range
or it can be another forward range.
Examples
import std.uni : isWhite;
assert("Learning,D,is,fun".split(",") == ["Learning", "D", "is", "fun"]);
assert("Learning D is fun".split!isWhite == ["Learning", "D", "is", "fun"]);
assert("Learning D is fun".split(" D ") == ["Learning", "is fun"]);
string str = "Hello World!";
assert(str.split == ["Hello", "World!"]);
string str2 = "Hello\t\tWorld\t!";
assert(str2.split == ["Hello", "World", "!"]);
assert(split("hello world") == ["hello","world"]);
assert(split("192.168.0.1", ".") == ["192", "168", "0", "1"]);
auto a = split([1, 2, 3, 4, 5, 1, 2, 3, 4, 5], [2, 3]);
assert(a == [[1], [4, 5, 1], [4, 5]]);
split)
if (bool contributor_probe.identifier(string value, bool packageName = false)identifier((local variable) string pidpid) && !(local variable) string[] pidspids.bool std.algorithm.searching.canFind!().canFind!(string[], string)(string[] haystack, scope string needle) pure nothrow @nogc @safeConvenience 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")));
canFind((local variable) string pidpid) && (local variable) string[] pidspids.(field) ulong string[].lengthlength < 32) (local variable) string[] pidspids ~= (local variable) string pidpid;
}
foreach ((parameter) string pidpid; (local variable) string[] pidspids)
{
const (local variable) const(string) basebase = "/proc/" ~ (local variable) string pidpid;
(local variable) contributor_probe.Collector collectorcollector.string contributor_probe.Collector.collect(string name, string command)collect("pid-" ~ (local variable) string pidpid, "cat " ~ (local variable) const(string) basebase ~ "/comm; readlink " ~ (local variable) const(string) basebase ~ "/exe; cat " ~
(local variable) const(string) basebase ~ "/attr/current; grep -E '^(Name|Uid|Gid|Cap|NoNewPrivs|Seccomp)' " ~ (local variable) const(string) basebase ~
"/status; for n in mnt user pid net; do readlink " ~ (local variable) const(string) basebase ~ "/ns/$n; done; " ~
"cat " ~ (local variable) const(string) basebase ~ "/uid_map " ~ (local variable) const(string) basebase ~ "/gid_map " ~ (local variable) const(string) basebase ~ "/cgroup; " ~
(local variable) const(string) mountsmounts ~ (local variable) const(string) basebase ~ "/mountinfo; ls -ldZ " ~ (local variable) const(string) basebase ~ "/root/nix/store " ~
(local variable) const(string) basebase ~ "/root/nix/var/nix/daemon-socket/socket");
}
(local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.reportreport ~= "\nRoot ADB detected: **" ~ (local variable) const(string) securitysecurity.bool std.algorithm.searching.canFind!().canFind!(string, string)(string haystack, scope string needle) pure nothrow @nogc @safeConvenience 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")));
canFind("uid=0(").string std.conv.to!string.to!bool(bool __param_0) pure nothrow @nogc @safeThe 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 = stringstring ~
"**. Commands with nonzero status or capped output: **" ~ (local variable) contributor_probe.Collector collectorcollector.(field) ulong contributor_probe.Collector.failuresfailures.string std.conv.to!string.to!ulong(ulong __param_0) pure nothrow @safeThe 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 = stringstring ~
"**. Pipelines and compound commands can contain earlier failed subcommands even when their " ~
"final exit is zero; read the evidence files.\n\n" ~
"Before publishing: inspect model/build strings, process names, mount paths and module metadata. " ~
"No complete environment, command lines, package inventory or Nix credentials were requested. " ~
"Mount paths may still identify applications or local directories. See the contributor guide " ~
"for application-context tests, source provenance and the PR workflow.\n";
void std.file.write!string(string name, const(void[]) buffer) @safeWrite buffer to file name.
Creates the file if it does not already exist.
Examples
scope(exit)
{
assert(exists(deleteme));
remove(deleteme);
}
int[] a = [ 0, 1, 1, 2, 3, 5, 8 ];
write(deleteme, a); // deleteme is the name of a temporary file
const bytes = read(deleteme);
const fileInts = () @trusted { return cast(int[]) bytes; }();
assert(fileInts == a);
write(string std.path.buildPath!char(const(char)[][] paths...) pure nothrow @safeCombines one or more path segments.
This function takes a set of path segments, given as an input
range of string elements or as a set of string arguments,
and concatenates them with each other. Directory separators
are inserted between segments if necessary. If any of the
path segments are absolute (as defined by isAbsolute), the
preceding segments will be dropped.
On Windows, if one of the path segments are rooted, but not absolute
(e.g. \foo), all preceding path segments down to the previous
root will be dropped. (See below for an example.)
This function always allocates memory to hold the resulting path.
The variadic overload is guaranteed to only perform a single
allocation, as is the range version if paths is a forward
range.
Examples
version (Posix)
{
assert(buildPath("foo", "bar", "baz") == "foo/bar/baz");
assert(buildPath("/foo/", "bar/baz") == "/foo/bar/baz");
assert(buildPath("/foo", "/bar") == "/bar");
}
version (Windows)
{
assert(buildPath("foo", "bar", "baz") == `foo\bar\baz`);
assert(buildPath(`c:\foo`, `bar\baz`) == `c:\foo\bar\baz`);
assert(buildPath("foo", `d:\bar`) == `d:\bar`);
assert(buildPath("foo", `\bar`) == `\bar`);
assert(buildPath(`c:\foo`, `\bar`) == `c:\bar`);
}
buildPath((local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.directorydirectory, "report.md"), (local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.reportreport);
(struct) std.json.JSONValueJSON value node
JSONValue[(alias) object.string = stringstring] (local variable) std.json.JSONValue[string] manifestmanifest;
std.json.JSONValue* core.internal.newaa._d_aaGetY!(string, std.json.JSONValue, std.json.JSONValue[string], string, std.json.JSONValue, string)(ref scope std.json.JSONValue[string] aa, string key, out bool found) pure nothrow @safeLookup key in aa.
Called only from implementation of (aa[`key`]) expressions when value is mutable.
manifest["schema_version"] = (struct) std.json.JSONValueJSON value node
JSONValue(1);
std.json.JSONValue* core.internal.newaa._d_aaGetY!(string, std.json.JSONValue, std.json.JSONValue[string], string, std.json.JSONValue, string)(ref scope std.json.JSONValue[string] aa, string key, out bool found) pure nothrow @safeLookup key in aa.
Called only from implementation of (aa[`key`]) expressions when value is mutable.
manifest["read_only"] = (struct) std.json.JSONValueJSON value node
JSONValue(true);
std.json.JSONValue* core.internal.newaa._d_aaGetY!(string, std.json.JSONValue, std.json.JSONValue[string], string, std.json.JSONValue, string)(ref scope std.json.JSONValue[string] aa, string key, out bool found) pure nothrow @safeLookup key in aa.
Called only from implementation of (aa[`key`]) expressions when value is mutable.
manifest["root_adb_detected"] = (struct) std.json.JSONValueJSON value node
JSONValue(std.json.JSONValue std.json.JSONValue.this!bool(bool arg) pure nothrow @nogc ref @safeConstructor for JSONValue. If arg is a JSONValue
its value and type will be copied to the new JSONValue.
Note that this is a shallow copy: if type is JSONType.object
or JSONType.array then only the reference to the data will
be copied.
Otherwise, arg must be implicitly convertible to one of the
following types: typeof(null), string, ulong,
long, double, an associative array V[K] for any V
and K i.e. a JSON object, any array or bool. The type will
be set accordingly.
security.bool std.algorithm.searching.canFind!().canFind!(string, string)(string haystack, scope string needle) pure nothrow @nogc @safeConvenience 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")));
canFind("uid=0("));
std.json.JSONValue* core.internal.newaa._d_aaGetY!(string, std.json.JSONValue, std.json.JSONValue[string], string, std.json.JSONValue, string)(ref scope std.json.JSONValue[string] aa, string key, out bool found) pure nothrow @safeLookup key in aa.
Called only from implementation of (aa[`key`]) expressions when value is mutable.
manifest["probes"] = (struct) std.json.JSONValueJSON value node
JSONValue(std.json.JSONValue std.json.JSONValue.this!(std.json.JSONValue[])(std.json.JSONValue[] arg) pure nothrow @nogc ref @safeConstructor for JSONValue. If arg is a JSONValue
its value and type will be copied to the new JSONValue.
Note that this is a shallow copy: if type is JSONType.object
or JSONType.array then only the reference to the data will
be copied.
Otherwise, arg must be implicitly convertible to one of the
following types: typeof(null), string, ulong,
long, double, an associative array V[K] for any V
and K i.e. a JSON object, any array or bool. The type will
be set accordingly.
collector.(field) std.json.JSONValue[] contributor_probe.Collector.recordsrecords);
void std.file.write!string(string name, const(void[]) buffer) @safeWrite buffer to file name.
Creates the file if it does not already exist.
Examples
scope(exit)
{
assert(exists(deleteme));
remove(deleteme);
}
int[] a = [ 0, 1, 1, 2, 3, 5, 8 ];
write(deleteme, a); // deleteme is the name of a temporary file
const bytes = read(deleteme);
const fileInts = () @trusted { return cast(int[]) bytes; }();
assert(fileInts == a);
write(string std.path.buildPath!char(const(char)[][] paths...) pure nothrow @safeCombines one or more path segments.
This function takes a set of path segments, given as an input
range of string elements or as a set of string arguments,
and concatenates them with each other. Directory separators
are inserted between segments if necessary. If any of the
path segments are absolute (as defined by isAbsolute), the
preceding segments will be dropped.
On Windows, if one of the path segments are rooted, but not absolute
(e.g. \foo), all preceding path segments down to the previous
root will be dropped. (See below for an example.)
This function always allocates memory to hold the resulting path.
The variadic overload is guaranteed to only perform a single
allocation, as is the range version if paths is a forward
range.
Examples
version (Posix)
{
assert(buildPath("foo", "bar", "baz") == "foo/bar/baz");
assert(buildPath("/foo/", "bar/baz") == "/foo/bar/baz");
assert(buildPath("/foo", "/bar") == "/bar");
}
version (Windows)
{
assert(buildPath("foo", "bar", "baz") == `foo\bar\baz`);
assert(buildPath(`c:\foo`, `bar\baz`) == `c:\foo\bar\baz`);
assert(buildPath("foo", `d:\bar`) == `d:\bar`);
assert(buildPath("foo", `\bar`) == `\bar`);
assert(buildPath(`c:\foo`, `\bar`) == `c:\bar`);
}
buildPath((local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.directorydirectory, "manifest.json"), (struct) std.json.JSONValueJSON value node
JSONValue(std.json.JSONValue std.json.JSONValue.this!(std.json.JSONValue[string])(std.json.JSONValue[string] arg) pure nothrow @nogc ref @safeConstructor for JSONValue. If arg is a JSONValue
its value and type will be copied to the new JSONValue.
Note that this is a shallow copy: if type is JSONType.object
or JSONType.array then only the reference to the data will
be copied.
Otherwise, arg must be implicitly convertible to one of the
following types: typeof(null), string, ulong,
long, double, an associative array V[K] for any V
and K i.e. a JSON object, any array or bool. The type will
be set accordingly.
manifest).string std.json.JSONValue.toPrettyString(in std.json.JSONOptions options = JSONOptions.none) const @safeImplicitly calls toJSON on this JSONValue, like toString, but
also passes true as pretty argument.
options can be used to tweak the conversion behavior
toPrettyString ~ "\n");
(local variable) sparkles.ui.components.live.LiveRegion regionregion.void sparkles.ui.components.live.LiveRegion.finish(bool keepFrame = true)End the region: restore the cursor and either keep the last frame as
permanent output (default) or erase it. Idempotent; call it from a
scope (exit) so exceptions can't leave the cursor hidden.
finish();
void std.stdio.writeln!(string, string)(string __param_0, string __param_1) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("Report: ", string std.path.buildPath!char(const(char)[][] paths...) pure nothrow @safeCombines one or more path segments.
This function takes a set of path segments, given as an input
range of string elements or as a set of string arguments,
and concatenates them with each other. Directory separators
are inserted between segments if necessary. If any of the
path segments are absolute (as defined by isAbsolute), the
preceding segments will be dropped.
On Windows, if one of the path segments are rooted, but not absolute
(e.g. \foo), all preceding path segments down to the previous
root will be dropped. (See below for an example.)
This function always allocates memory to hold the resulting path.
The variadic overload is guaranteed to only perform a single
allocation, as is the range version if paths is a forward
range.
Examples
version (Posix)
{
assert(buildPath("foo", "bar", "baz") == "foo/bar/baz");
assert(buildPath("/foo/", "bar/baz") == "/foo/bar/baz");
assert(buildPath("/foo", "/bar") == "/bar");
}
version (Windows)
{
assert(buildPath("foo", "bar", "baz") == `foo\bar\baz`);
assert(buildPath(`c:\foo`, `bar\baz`) == `c:\foo\bar\baz`);
assert(buildPath("foo", `d:\bar`) == `d:\bar`);
assert(buildPath("foo", `\bar`) == `\bar`);
assert(buildPath(`c:\foo`, `\bar`) == `c:\bar`);
}
buildPath((local variable) contributor_probe.Collector collectorcollector.(field) string contributor_probe.Collector.directorydirectory, "report.md"));
void std.stdio.writeln!string(string __param_0) @safeEquivalent to write(args, '\n'). Calling writeln without
arguments is valid and just prints a newline to the standard
output.
Example
Reads stdin and writes it to stdout with an argument
counter.
import std.stdio;
void main()
{
string line;
for (size_t count = 0; (line = readln) !is null; count++)
{
writeln("Input ", count, ": ", line);
}
}
writeln("Partial/unavailable probes are preserved; review before publishing.");
return 0;
}