gen-wired-inline.dhover×257all
#!/usr/bin/env dub
/+ dub.sdl:
    name "gen-wired-inline"
+/
/**
Generates the `wired-inline` bench engine's single-translation-unit copy of
the native JSON reader.

The wired-native hot path is built from templates (`parseJsonDocument` →
`parseInto` → `scanNumber`), so it is code-generated in whichever package
*instantiates* it — here the benchmark package, which cannot enable
`-enable-cross-module-inlining` (it would propagate to mir-ion and cull a
template-nested symbol). The consequence is visible in the disassembly: even
`doubleToBits`, a single `movq`, is emitted as a `call` into `sparkles:base`.

This tool splices the six modules that make up that path into one module, so
every seam is intra-module and LDC's inliner sees the whole kernel at once.
That isolates the value of inlining from the build-system variables
(cross-module inlining, ThinLTO, PGO) that could not be evaluated cleanly.

Nothing under `libs/base` or `libs/wired` is modified — this is a copy, and
the copy is what the `wired-inline` engine measures. Re-run after changing any
source module so the two engines stay comparable:

    dub run --single tools/gen-wired-inline.d
*/
module 
(module) gen_wired_inline

Generates the wired-inline bench engine's single-translation-unit copy of the native JSON reader.

The wired-native hot path is built from templates (parseJsonDocumentparseIntoscanNumber), so it is code-generated in whichever package instantiates* it — here the benchmark package, which cannot enable -enable-cross-module-inlining (it would propagate to mir-ion and cull a template-nested symbol). The consequence is visible in the disassembly: even doubleToBits, a single movq, is emitted as a call into sparkles:base.

This tool splices the six modules that make up that path into one module, so every seam is intra-module and LDC's inliner sees the whole kernel at once. That isolates the value of inlining from the build-system variables (cross-module inlining, ThinLTO, PGO) that could not be evaluated cleanly.

Nothing under libs/base or libs/wired is modified — this is a copy, and the copy is what the wired-inline engine measures. Re-run after changing any source module so the two engines stay comparable:

dub run --single tools/gen-wired-inline.d

gen_wired_inline
;
import
(package) std
std
.
(package) std.algorithm
algorithm
.
(module) std.algorithm.searching

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

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

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

Source

std/algorithm/searching.d

@copyrightAndrei Alexandrescu 2008-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu
searching
:
(alias template) gen_wired_inline.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.

@seeamong for checking a value against multiple arguments.
canFind
,
(alias template) gen_wired_inline.startsWith = std.algorithm.searching.startsWith(alias pred = (a, b) => a == b, Range, Needles...)(Range doesThisStart, Needles withOneOfThese) if (isInputRange!Range && (Needles.length > 1) && allSatisfy!(canTestStartsWith!(pred, Range), Needles))

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

For more information about pred see find.

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

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

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

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

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

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

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

Function Name Description

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

Source

std/array.d

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

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

appender
,
(alias template) gen_wired_inline.join = std.array.join(RoR, R)(RoR ror, R sep) if (isInputRange!RoR && isInputRange!(Unqual!(ElementType!RoR)) && isInputRange!R && (is(immutable(ElementType!(ElementType!RoR)) == immutable(ElementType!R)) || isSomeChar!(ElementType!(ElementType!RoR)) && isSomeChar!(ElementType!R)))

Eagerly concatenates all of the ranges in ror together (with the GC) into one array using sep as the separator if present.

@paramror An input range of input ranges@paramsep An input range, or a single element, to join the ranges on@returnsAn array of elements@seeFor a lazy version, see joiner
join
;
import
(package) std
std
.
(module) std.file

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

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

Source

std/file.d

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

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

@paramS the string type of the file@paramname string or range of characters representing the file name@returnsArray of characters read.@throwsFileException if there is an error reading the file, UTFException on UTF decoding error.@seeread for reading a binary file.
readText
,
(alias template) gen_wired_inline.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.

@paramname string or range of characters representing the file name@parambuffer data to be written to file@throwsFileException on error.@seetoFile
write
;
import
(package) std
std
.
(module) std.path

This 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

@authorsLars Tandle Kyllingstad, Walter Bright, Grzegorz Adam Hankiewicz, Thomas Khne, Andrei Alexandrescu@copyrightCopyright (c) 2000-2014, the authors. All rights reserved.@licenseBoost License 1.0
path
:
(alias template) gen_wired_inline.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.

@paramsegments An input range of segments to assemble the path from.@returnsThe assembled path.
buildPath
,
(alias template) gen_wired_inline.dirName = std.path.dirName(R)(return scope R path) if (isRandomAccessRange!R && hasSlicing!R && hasLength!R && isSomeChar!(ElementType!R) && !isSomeString!R)

Returns the parent directory of path. On Windows, this includes the drive letter if present. If path is a relative path and the parent directory is the current working directory, returns ".".

@parampath A path name.@returnsA slice of path or ".".@standardsThis function complies with the POSIX requirements for the 'dirname' shell utility (with suitable adaptations for Windows paths).
dirName
;
import
(package) std
std
.
(module) std.stdio
Category Symbols
File handles _popen File isFileHandle openNetwork stderr stdin stdout
Reading chunks lines readf readfln readln
Writing toFile write writef writefln writeln
Misc KeepTerminator LockType StdioException

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

There are three layers of I/O:

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

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

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

Source

std/stdio.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Alex Rønne Petersen
stdio
:
(alias template) gen_wired_inline.writefln = std.stdio.writefln(alias fmt, A...)(A args) if (isSomeString!(typeof(fmt)))

Equivalent to writef(fmt, args, '\n').

writefln
;
import
(package) std
std
.
(module) std.string

String handling functions.

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

The following functions are publicly imported:

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

Source

std/string.d

@seestd.algorithm and std.range for generic range algorithms , std.ascii for functions that work with ASCII strings , std.uni for functions that work with unicode strings@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Jonathan M Davis, and David L. 'SpottedTiger' Davis
string
:
(alias template) gen_wired_inline.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.

@paramstr string or random access range of characters@paramchars string of characters to be stripped@paramleftChars string of leading characters to be stripped@paramrightChars string of trailing characters to be stripped@returnsslice of str stripped of leading and trailing whitespace or characters as specified in the second argument.@seeGeneric stripping on ranges: strip
strip
,
(alias template) gen_wired_inline.stripRight = std.string.stripRight(Range)(Range str) if (isSomeString!Range || isRandomAccessRange!Range && hasLength!Range && hasSlicing!Range && !isConvertibleToString!Range && isSomeChar!(ElementEncodingType!Range))

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

@paramstr string or random access range of characters@paramchars string of characters to be stripped@returnsslice of str stripped of trailing whitespace or characters specified in the second argument.@seeGeneric stripping on ranges: stripRight
stripRight
;
/// One source module folded into the generated unit. Order is cosmetic — /// D module-scope declarations are order-independent — but it keeps the /// generated file readable bottom-up: primitives first, grammar last. private struct
(struct) gen_wired_inline.Source

One source module folded into the generated unit. Order is cosmetic — D module-scope declarations are order-independent — but it keeps the generated file readable bottom-up: primitives first, grammar last.

Source
{
(alias) object.string = string
string
(field) string gen_wired_inline.Source.path

repo-relative

path
; /// repo-relative
(alias) object.string = string
string
(field) string gen_wired_inline.Source.moduleName

the module being absorbed (its imports drop out)

moduleName
; /// the module being absorbed (its imports drop out)
} private immutable
(struct) gen_wired_inline.Source

One source module folded into the generated unit. Order is cosmetic — D module-scope declarations are order-independent — but it keeps the generated file readable bottom-up: primitives first, grammar last.

Source
[]
(immutable global) immutable(gen_wired_inline.Source[]) gen_wired_inline.sources
sources
= [
(struct) gen_wired_inline.Source

One source module folded into the generated unit. Order is cosmetic — D module-scope declarations are order-independent — but it keeps the generated file readable bottom-up: primitives first, grammar last.

Source
("libs/base/src/sparkles/base/text/errors.d", "sparkles.base.text.errors"),
(struct) gen_wired_inline.Source

One source module folded into the generated unit. Order is cosmetic — D module-scope declarations are order-independent — but it keeps the generated file readable bottom-up: primitives first, grammar last.

Source
("libs/base/src/sparkles/base/text/float_conv.d", "sparkles.base.text.float_conv"),
(struct) gen_wired_inline.Source

One source module folded into the generated unit. Order is cosmetic — D module-scope declarations are order-independent — but it keeps the generated file readable bottom-up: primitives first, grammar last.

Source
("libs/base/src/sparkles/base/text/utf8.d", "sparkles.base.text.utf8"),
(struct) gen_wired_inline.Source

One source module folded into the generated unit. Order is cosmetic — D module-scope declarations are order-independent — but it keeps the generated file readable bottom-up: primitives first, grammar last.

Source
("libs/wired/src/sparkles/wired/json/document.d", "sparkles.wired.json.document"),
(struct) gen_wired_inline.Source

One source module folded into the generated unit. Order is cosmetic — D module-scope declarations are order-independent — but it keeps the generated file readable bottom-up: primitives first, grammar last.

Source
("libs/wired/src/sparkles/wired/json/scan.d", "sparkles.wired.json.scan"),
(struct) gen_wired_inline.Source

One source module folded into the generated unit. Order is cosmetic — D module-scope declarations are order-independent — but it keeps the generated file readable bottom-up: primitives first, grammar last.

Source
("libs/wired/src/sparkles/wired/json/reader.d", "sparkles.wired.json.reader"),
]; private enum
(constant) string gen_wired_inline.outRelative = "libs/wired/bench/runtime/src/sparkles/wired_bench/engines/wired_inline_impl.d"
outRelative
= "libs/wired/bench/runtime/src/sparkles/wired_bench/engines/"
~ "wired_inline_impl.d"; void
void D main(string[] args)
main
(
(alias) object.string = string
string
[]
(parameter) string[] args
args
)
{ // The tool lives at <repo>/libs/wired/bench/runtime/tools/. const
(local variable) const(string) repo
repo
=
(parameter) string[] args
args
[0].
string std.path.dirName!(immutable(char))(return scope string path) pure nothrow @nogc @safe

Returns the parent directory of path. On Windows, this includes the drive letter if present. If path is a relative path and the parent directory is the current working directory, returns ".".

Examples

assert(dirName("") == ".");
assert(dirName("file"w) == ".");
assert(dirName("dir/"d) == ".");
assert(dirName("dir///") == ".");
assert(dirName("dir/file"w.dup) == "dir");
assert(dirName("dir///file"d.dup) == "dir");
assert(dirName("dir/subdir/") == "dir");
assert(dirName("/dir/file"w) == "/dir");
assert(dirName("/file"d) == "/");
assert(dirName("/") == "/");
assert(dirName("///") == "/");

version (Windows)
{
    assert(dirName(`dir\`) == `.`);
    assert(dirName(`dir\\\`) == `.`);
    assert(dirName(`dir\file`) == `dir`);
    assert(dirName(`dir\\\file`) == `dir`);
    assert(dirName(`dir\subdir\`) == `dir`);
    assert(dirName(`\dir\file`) == `\dir`);
    assert(dirName(`\file`) == `\`);
    assert(dirName(`\`) == `\`);
    assert(dirName(`\\\`) == `\`);
    assert(dirName(`d:`) == `d:`);
    assert(dirName(`d:file`) == `d:`);
    assert(dirName(`d:\`) == `d:\`);
    assert(dirName(`d:\file`) == `d:\`);
    assert(dirName(`d:\dir\file`) == `d:\dir`);
    assert(dirName(`\\server\share\dir\file`) == `\\server\share\dir`);
    assert(dirName(`\\server\share\file`) == `\\server\share`);
    assert(dirName(`\\server\share\`) == `\\server\share`);
    assert(dirName(`\\server\share`) == `\\server\share`);
}
@parampath A path name.@returnsA slice of path or ".".@standardsThis function complies with the POSIX requirements for the 'dirname' shell utility (with suitable adaptations for Windows paths).
dirName
.
string std.path.buildPath!char(const(char)[][] paths...) pure nothrow @safe

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.

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`);
}
@paramsegments An input range of segments to assemble the path from.@returnsThe assembled path.
buildPath
("..", "..", "..", "..", "..");
auto
(local variable) std.array.Appender!string body_
body_
=
std.array.Appender!string std.array.appender!string() pure nothrow @safe

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

appender
!
(alias) object.string = string
string
;
(alias) object.string = string
string
[]
(local variable) string[] carriedImports
carriedImports
;
foreach (
(parameter) immutable(gen_wired_inline.Source) src
src
;
(immutable global) immutable(gen_wired_inline.Source[]) gen_wired_inline.sources
sources
)
{ auto
(local variable) gen_wired_inline.Absorbed r
r
=
gen_wired_inline.Absorbed gen_wired_inline.absorb(string text, string moduleName)

Strips text down to the declarations worth copying: drops the module header, the top-level imports of modules that are themselves being absorbed (they would be self-imports), the test section, and any stray named unittest block. Top-level imports of outside modules are lifted out and returned so the generated file can carry them once.

absorb
(
string std.file.readText!(string, string)(string name) @safe

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

Examples

Read file with UTF-8 text.

write(deleteme, "abc"); // deleteme is the name of a temporary file
scope(exit) remove(deleteme);
string content = readText(deleteme);
assert(content == "abc");
@paramS the string type of the file@paramname string or range of characters representing the file name@returnsArray of characters read.@throwsFileException if there is an error reading the file, UTFException on UTF decoding error.@seeread for reading a binary file.
readText
(
(local variable) const(string) repo
repo
.
string std.path.buildPath!char(const(char)[][] paths...) pure nothrow @safe

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.

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`);
}
@paramsegments An input range of segments to assemble the path from.@returnsThe assembled path.
buildPath
(
(local variable) immutable(gen_wired_inline.Source) src
src
.
(field) string gen_wired_inline.Source.path

repo-relative

path
)),
(local variable) immutable(gen_wired_inline.Source) src
src
.
(field) string gen_wired_inline.Source.moduleName

the module being absorbed (its imports drop out)

moduleName
);
foreach (
(parameter) string imp
imp
;
(local variable) gen_wired_inline.Absorbed r
r
.
(field) string[] gen_wired_inline.Absorbed.imports

top-level imports of modules NOT being absorbed

imports
)
if (!
(local variable) string[] carriedImports
carriedImports
.
bool std.algorithm.searching.canFind!().canFind!(string[], string)(string[] haystack, scope string needle) pure nothrow @nogc @safe

Convenience function. Like find, but only returns whether or not the search was successful.

For more information about pred see find.

Examples

const arr = [0, 1, 2, 3];
assert(canFind(arr, 2));
assert(!canFind(arr, 4));

// find one of several needles
assert(arr.canFind(3, 2));
assert(arr.canFind(3, 2) == 2); // second needle found
assert(arr.canFind([1, 3], 2) == 2);

assert(canFind(arr, [1, 2], [2, 3]));
assert(canFind(arr, [1, 2], [2, 3]) == 1);
assert(canFind(arr, [1, 7], [2, 3]));
assert(canFind(arr, [1, 7], [2, 3]) == 2);
assert(!canFind(arr, [1, 3], [2, 4]));
assert(canFind(arr, [1, 3], [2, 4]) == 0);

Example using a custom predicate. Note that the needle appears as the second argument of the predicate.

auto words = [
    "apple",
    "beeswax",
    "cardboard"
];
assert(!canFind(words, "bees"));
assert( canFind!((string elem, string needle) => elem.startsWith(needle))(words, "bees"));

Search for multiple items in an array of items (search for needles in an array of haystacks)

string s1 = "aaa111aaa";
string s2 = "aaa222aaa";
string s3 = "aaa333aaa";
string s4 = "aaa444aaa";
const hay = [s1, s2, s3, s4];
assert(hay.canFind!(e => e.canFind("111", "222")));
@see

among for checking a value against multiple arguments.

Returns true if and only if needle can be found in range. Performs O(haystack.length) evaluations of pred.

canFind
(
(local variable) string imp
imp
))
(local variable) string[] carriedImports
carriedImports
~=
(local variable) string imp
imp
;
(local variable) std.array.Appender!string body_
body_
~= "// ═══════════════════════════════════════════════════════"
~ "══════════════════\n";
(local variable) std.array.Appender!string body_
body_
~= "// From " ~
(local variable) immutable(gen_wired_inline.Source) src
src
.
(field) string gen_wired_inline.Source.path

repo-relative

path
~ "\n";
(local variable) std.array.Appender!string body_
body_
~= "// ═══════════════════════════════════════════════════════"
~ "══════════════════\n\n";
(local variable) std.array.Appender!string body_
body_
~=
(local variable) gen_wired_inline.Absorbed r
r
.
(field) string gen_wired_inline.Absorbed.code
code
;
(local variable) std.array.Appender!string body_
body_
~= "\n";
} const
(local variable) const(string) outPath
outPath
=
(local variable) const(string) repo
repo
.
string std.path.buildPath!char(const(char)[][] paths...) pure nothrow @safe

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.

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`);
}
@paramsegments An input range of segments to assemble the path from.@returnsThe assembled path.
buildPath
(
(constant) string gen_wired_inline.outRelative = "libs/wired/bench/runtime/src/sparkles/wired_bench/engines/wired_inline_impl.d"
outRelative
);
// Exactly one trailing newline — the end-of-file-fixer hook rewrites the // file otherwise, and a hook-edited generated file no longer matches what // the generator produces.
void std.file.write!string(string name, const(void[]) buffer) @safe

Write 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);
@paramname string or range of characters representing the file name@parambuffer data to be written to file@throwsFileException on error.@seetoFile
write
(
(local variable) const(string) outPath
outPath
, (
string gen_wired_inline.header(string[] imports)
header
(
(local variable) string[] carriedImports
carriedImports
) ~
(local variable) std.array.Appender!string body_
body_
[]).
string std.string.stripRight!string(string str) pure nothrow @nogc @safe

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

Examples

import std.uni : lineSep, paraSep;
assert(stripRight("     hello world     ") ==
       "     hello world");
assert(stripRight("\n\t\v\rhello world\n\t\v\r") ==
       "\n\t\v\rhello world");
assert(stripRight("hello world") ==
       "hello world");
assert(stripRight([lineSep] ~ "hello world" ~ lineSep) ==
       [lineSep] ~ "hello world");
assert(stripRight([paraSep] ~ "hello world" ~ paraSep) ==
       [paraSep] ~ "hello world");
@paramstr string or random access range of characters@paramchars string of characters to be stripped@returnsslice of str stripped of trailing whitespace or characters specified in the second argument.@seeGeneric stripping on ranges: stripRight
stripRight
~ "\n");
void std.stdio.writefln!(char, string, ulong, ulong)(in char[] fmt, string __param_1, ulong __param_2, ulong __param_3) @safe

Equivalent to writef(fmt, args, '\n').

writefln
("wrote %s (%s lines, %s carried imports)",
(constant) string gen_wired_inline.outRelative = "libs/wired/bench/runtime/src/sparkles/wired_bench/engines/wired_inline_impl.d"
outRelative
,
(local variable) std.array.Appender!string body_
body_
[].
ulong gen_wired_inline.countLines(string s)
countLines
,
(local variable) string[] carriedImports
carriedImports
.
(field) ulong string[].length
length
);
} private
(alias) object.size_t = ulong
size_t
ulong gen_wired_inline.countLines(string s)
countLines
(
(alias) object.string = string
string
(parameter) string s
s
)
{
(alias) object.size_t = ulong
size_t
(local variable) ulong n
n
= 1;
foreach (
(parameter) immutable(char) c
c
;
(parameter) string s
s
)
if (
(local variable) immutable(char) c
c
== '\n')
(local variable) ulong n
n
++;
return
(local variable) ulong n
n
;
} private
(alias) object.string = string
string
string gen_wired_inline.header(string[] imports)
header
(
(alias) object.string = string
string
[]
(parameter) string[] imports
imports
)
{ return "// GENERATED FILE — DO NOT EDIT.\n" ~ "// Regenerate with: dub run --single tools/gen-wired-inline.d\n" ~ "//\n" ~ "// A single-translation-unit copy of the `sparkles:wired` native JSON\n" ~ "// reader and the `sparkles:base` primitives it calls, spliced together\n" ~ "// so every seam is intra-module and LDC's inliner sees the whole kernel\n" ~ "// at once. Backs the `wired-inline` bench engine, whose only difference\n" ~ "// from `wired-native` is that this code is all in one module — the A/B\n" ~ "// that isolates inlining from cross-module-inlining, LTO and PGO.\n" ~ "//\n" ~ "// Sources are copied verbatim (module headers, imports of the absorbed\n" ~ "// modules, and unittest blocks removed). Edit the originals, not this.\n" ~ "module sparkles.wired_bench.engines.wired_inline_impl;\n\n" ~
(parameter) string[] imports
imports
.
string std.array.join!(string[], string)(string[] ror, string sep) pure nothrow @safe

Eagerly concatenates all of the ranges in ror together (with the GC) into one array using sep as the separator if present.

@paramror An input range of input ranges@paramsep An input range, or a single element, to join the ranges on@returnsAn array of elements@seeFor a lazy version, see joiner
join
("\n") ~ "\n\n";
} private struct
(struct) gen_wired_inline.Absorbed
Absorbed
{
(alias) object.string = string
string
(field) string gen_wired_inline.Absorbed.code
code
;
(alias) object.string = string
string
[]
(field) string[] gen_wired_inline.Absorbed.imports

top-level imports of modules NOT being absorbed

imports
; /// top-level imports of modules NOT being absorbed
} /** Strips `text` down to the declarations worth copying: drops the module header, the top-level imports of modules that are themselves being absorbed (they would be self-imports), the test section, and any stray named unittest block. Top-level imports of *outside* modules are lifted out and returned so the generated file can carry them once. */ private
(struct) gen_wired_inline.Absorbed
Absorbed
gen_wired_inline.Absorbed gen_wired_inline.absorb(string text, string moduleName)

Strips text down to the declarations worth copying: drops the module header, the top-level imports of modules that are themselves being absorbed (they would be self-imports), the test section, and any stray named unittest block. Top-level imports of outside modules are lifted out and returned so the generated file can carry them once.

absorb
(
(alias) object.string = string
string
(parameter) string text
text
,
(alias) object.string = string
string
(parameter) string moduleName
moduleName
)
{ import
(package) std
std
.
(module) std.string

String handling functions.

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

The following functions are publicly imported:

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

Source

std/string.d

@seestd.algorithm and std.range for generic range algorithms , std.ascii for functions that work with ASCII strings , std.uni for functions that work with unicode strings@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Jonathan M Davis, and David L. 'SpottedTiger' Davis
string
:
(alias template) 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", $(REF lineSep, std,uni), $(REF paraSep, std,uni), 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 $(LREF lineSplitter) for an alternative that
    does not.

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

Params: s = a string of chars, wchars, or dchars, or any custom type that casts to a string type keepTerm = whether delimiter is included or not in the results Returns: array of strings, each element is a line that is a slice of s See_Also: $(LREF lineSplitter) $(REF splitter, std,algorithm) $(REF splitter, std,regex)

splitLines
;
auto
(local variable) string[] lines
lines
=
(parameter) string text
text
.
string[] std.string.splitLines!(immutable(char))(string s, std.typecons.Flag!"keepTerminator" keepTerm = Flag.no) pure nothrow @safe

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.

Examples

string s = "Hello\nmy\rname\nis";
assert(splitLines(s) == ["Hello", "my", "name", "is"]);
@params a string of chars, wchars, or dchars, or any custom type that casts to a string type@paramkeepTerm whether delimiter is included or not in the results@returnsarray of strings, each element is a line that is a slice of s@seelineSplitter splitter splitter
splitLines
;
auto
(local variable) std.array.Appender!string code
code
=
std.array.Appender!string std.array.appender!string() pure nothrow @safe

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

appender
!
(alias) object.string = string
string
;
(alias) object.string = string
string
[]
(local variable) string[] imports
imports
;
(alias) object.size_t = ulong
size_t
(local variable) ulong i
i
= 0;
// 1. Skip the module's DDoc banner and `module x.y.z;` line. foreach (
(parameter) ulong j
j
,
(parameter) string line
line
;
(local variable) string[] lines
lines
)
if (
(local variable) string line
line
.
string std.string.strip!string(string str) pure nothrow @nogc @safe

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

Examples

import std.uni : lineSep, paraSep;
assert(strip("     hello world     ") ==
       "hello world");
assert(strip("\n\t\v\rhello world\n\t\v\r") ==
       "hello world");
assert(strip("hello world") ==
       "hello world");
assert(strip([lineSep] ~ "hello world" ~ [lineSep]) ==
       "hello world");
assert(strip([paraSep] ~ "hello world" ~ [paraSep]) ==
       "hello world");
@paramstr string or random access range of characters@paramchars string of characters to be stripped@paramleftChars string of leading characters to be stripped@paramrightChars string of trailing characters to be stripped@returnsslice of str stripped of leading and trailing whitespace or characters as specified in the second argument.@seeGeneric stripping on ranges: strip
strip
.
bool std.algorithm.searching.startsWith!("a == b", string, string)(string doesThisStart, string withThis) pure nothrow @nogc @safe

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

For more information about pred see find.

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

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

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

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

startsWith
("module "))
{
(local variable) ulong i
i
=
(local variable) ulong j
j
+ 1;
break; } // The absorbed set — an import of any of these becomes a self-import. static immutable
(immutable global) immutable(string[]) gen_wired_inline.absorb.absorbedModules
absorbedModules
= [
"sparkles.base.text.errors", "sparkles.base.text.float_conv", "sparkles.base.text.utf8", "sparkles.wired.json.document", "sparkles.wired.json.scan", "sparkles.wired.json.reader", ]; for (; i < lines.length; i++) { const
(local variable) const(string) line
line
=
(local variable) string[] lines
lines
[
(local variable) ulong i
i
];
// 2. The test section — every module in this repo separates it with a // box-drawing banner whose next line reads `// Tests…`. if (
(local variable) const(string) line
line
.
bool std.algorithm.searching.startsWith!("a == b", string, string)(string doesThisStart, string withThis) pure nothrow @nogc @safe

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

For more information about pred see find.

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

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

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

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

startsWith
("// ─────") &&
(local variable) ulong i
i
+ 1 <
(local variable) string[] lines
lines
.
(field) ulong string[].length
length
&&
(local variable) string[] lines
lines
[
(local variable) ulong i
i
+ 1].
string std.string.strip!string(string str) pure nothrow @nogc @safe

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

Examples

import std.uni : lineSep, paraSep;
assert(strip("     hello world     ") ==
       "hello world");
assert(strip("\n\t\v\rhello world\n\t\v\r") ==
       "hello world");
assert(strip("hello world") ==
       "hello world");
assert(strip([lineSep] ~ "hello world" ~ [lineSep]) ==
       "hello world");
assert(strip([paraSep] ~ "hello world" ~ [paraSep]) ==
       "hello world");
@paramstr string or random access range of characters@paramchars string of characters to be stripped@paramleftChars string of leading characters to be stripped@paramrightChars string of trailing characters to be stripped@returnsslice of str stripped of leading and trailing whitespace or characters as specified in the second argument.@seeGeneric stripping on ranges: strip
strip
.
bool std.algorithm.searching.startsWith!("a == b", string, string)(string doesThisStart, string withThis) pure nothrow @nogc @safe

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

For more information about pred see find.

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

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

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

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

startsWith
("// Tests"))
break; // 3. A named unittest block (`@("name")` … through the closing brace // in column 0). Covers modules whose tests sit between // declarations rather than in a trailing section. if (
(local variable) const(string) line
line
.
bool std.algorithm.searching.startsWith!("a == b", string, string)(string doesThisStart, string withThis) pure nothrow @nogc @safe

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

For more information about pred see find.

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

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

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

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

startsWith
("@(\""))
{ while (
(local variable) ulong i
i
<
(local variable) string[] lines
lines
.
(field) ulong string[].length
length
&&
(local variable) string[] lines
lines
[
(local variable) ulong i
i
] != "}")
(local variable) ulong i
i
++;
continue; } // 4. A top-level import: drop it if self-referential, otherwise carry // it up to the generated file's header. Selective imports wrap, so // consume through the terminating semicolon. if (
(local variable) const(string) line
line
.
bool std.algorithm.searching.startsWith!("a == b", string, string)(string doesThisStart, string withThis) pure nothrow @nogc @safe

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

For more information about pred see find.

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

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

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

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

startsWith
("import "))
{
(alias) object.string = string
string
(local variable) string stmt
stmt
=
(local variable) const(string) line
line
;
while (!
(local variable) string stmt
stmt
.
string std.string.stripRight!string(string str) pure nothrow @nogc @safe

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

Examples

import std.uni : lineSep, paraSep;
assert(stripRight("     hello world     ") ==
       "     hello world");
assert(stripRight("\n\t\v\rhello world\n\t\v\r") ==
       "\n\t\v\rhello world");
assert(stripRight("hello world") ==
       "hello world");
assert(stripRight([lineSep] ~ "hello world" ~ lineSep) ==
       [lineSep] ~ "hello world");
assert(stripRight([paraSep] ~ "hello world" ~ paraSep) ==
       [paraSep] ~ "hello world");
@paramstr string or random access range of characters@paramchars string of characters to be stripped@returnsslice of str stripped of trailing whitespace or characters specified in the second argument.@seeGeneric stripping on ranges: stripRight
stripRight
.
bool gen_wired_inline.endsWith(string s, string suffix)
endsWith
(";") &&
(local variable) ulong i
i
+ 1 <
(local variable) string[] lines
lines
.
(field) ulong string[].length
length
)
(local variable) string stmt
stmt
~= "\n" ~
(local variable) string[] lines
lines
[++
(local variable) ulong i
i
];
if (!
(immutable global) immutable(string[]) gen_wired_inline.absorb.absorbedModules
absorbedModules
.
bool std.algorithm.searching.canFind!().canFind!(immutable(string)[], string)(immutable(string)[] haystack, scope string needle) pure nothrow @nogc @safe

Convenience function. Like find, but only returns whether or not the search was successful.

For more information about pred see find.

Examples

const arr = [0, 1, 2, 3];
assert(canFind(arr, 2));
assert(!canFind(arr, 4));

// find one of several needles
assert(arr.canFind(3, 2));
assert(arr.canFind(3, 2) == 2); // second needle found
assert(arr.canFind([1, 3], 2) == 2);

assert(canFind(arr, [1, 2], [2, 3]));
assert(canFind(arr, [1, 2], [2, 3]) == 1);
assert(canFind(arr, [1, 7], [2, 3]));
assert(canFind(arr, [1, 7], [2, 3]) == 2);
assert(!canFind(arr, [1, 3], [2, 4]));
assert(canFind(arr, [1, 3], [2, 4]) == 0);

Example using a custom predicate. Note that the needle appears as the second argument of the predicate.

auto words = [
    "apple",
    "beeswax",
    "cardboard"
];
assert(!canFind(words, "bees"));
assert( canFind!((string elem, string needle) => elem.startsWith(needle))(words, "bees"));

Search for multiple items in an array of items (search for needles in an array of haystacks)

string s1 = "aaa111aaa";
string s2 = "aaa222aaa";
string s3 = "aaa333aaa";
string s4 = "aaa444aaa";
const hay = [s1, s2, s3, s4];
assert(hay.canFind!(e => e.canFind("111", "222")));
@see

among for checking a value against multiple arguments.

Returns true if and only if needle can be found in range. Performs O(haystack.length) evaluations of pred.

canFind
(
string gen_wired_inline.importedModule(string stmt)

import a.b.c : x, y;a.b.c

importedModule
(
(local variable) string stmt
stmt
)))
(local variable) string[] imports
imports
~=
(local variable) string stmt
stmt
;
continue; } // 5. A module-scope attribute *block* (`@safe … package:`) would leak // its attributes across every later splice, so brace it instead. if (
(local variable) const(string) line
line
.
(field) ulong const(string).length
length
&&
(local variable) const(string) line
line
[0] == '@' &&
(local variable) const(string) line
line
.
string std.string.stripRight!string(string str) pure nothrow @nogc @safe

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

Examples

import std.uni : lineSep, paraSep;
assert(stripRight("     hello world     ") ==
       "     hello world");
assert(stripRight("\n\t\v\rhello world\n\t\v\r") ==
       "\n\t\v\rhello world");
assert(stripRight("hello world") ==
       "hello world");
assert(stripRight([lineSep] ~ "hello world" ~ lineSep) ==
       [lineSep] ~ "hello world");
assert(stripRight([paraSep] ~ "hello world" ~ paraSep) ==
       [paraSep] ~ "hello world");
@paramstr string or random access range of characters@paramchars string of characters to be stripped@returnsslice of str stripped of trailing whitespace or characters specified in the second argument.@seeGeneric stripping on ranges: stripRight
stripRight
.
bool gen_wired_inline.endsWith(string s, string suffix)
endsWith
(":"))
{ const
(local variable) const(string) attrs
attrs
=
(local variable) const(string) line
line
.
string std.string.stripRight!string(string str) pure nothrow @nogc @safe

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

Examples

import std.uni : lineSep, paraSep;
assert(stripRight("     hello world     ") ==
       "     hello world");
assert(stripRight("\n\t\v\rhello world\n\t\v\r") ==
       "\n\t\v\rhello world");
assert(stripRight("hello world") ==
       "hello world");
assert(stripRight([lineSep] ~ "hello world" ~ lineSep) ==
       [lineSep] ~ "hello world");
assert(stripRight([paraSep] ~ "hello world" ~ paraSep) ==
       [paraSep] ~ "hello world");
@paramstr string or random access range of characters@paramchars string of characters to be stripped@returnsslice of str stripped of trailing whitespace or characters specified in the second argument.@seeGeneric stripping on ranges: stripRight
stripRight
[0 .. $ - 1];
(local variable) std.array.Appender!string code
code
~=
(local variable) const(string) attrs
attrs
~ "\n{\n";
for (
(local variable) ulong i
i
++; i < lines.length; i++)
{ if (
(local variable) string[] lines
lines
[
(local variable) ulong i
i
].
bool std.algorithm.searching.startsWith!("a == b", string, string)(string doesThisStart, string withThis) pure nothrow @nogc @safe

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

For more information about pred see find.

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

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

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

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

startsWith
("// ─────") &&
(local variable) ulong i
i
+ 1 <
(local variable) string[] lines
lines
.
(field) ulong string[].length
length
&&
(local variable) string[] lines
lines
[
(local variable) ulong i
i
+ 1].
string std.string.strip!string(string str) pure nothrow @nogc @safe

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

Examples

import std.uni : lineSep, paraSep;
assert(strip("     hello world     ") ==
       "hello world");
assert(strip("\n\t\v\rhello world\n\t\v\r") ==
       "hello world");
assert(strip("hello world") ==
       "hello world");
assert(strip([lineSep] ~ "hello world" ~ [lineSep]) ==
       "hello world");
assert(strip([paraSep] ~ "hello world" ~ [paraSep]) ==
       "hello world");
@paramstr string or random access range of characters@paramchars string of characters to be stripped@paramleftChars string of leading characters to be stripped@paramrightChars string of trailing characters to be stripped@returnsslice of str stripped of leading and trailing whitespace or characters as specified in the second argument.@seeGeneric stripping on ranges: strip
strip
.
bool std.algorithm.searching.startsWith!("a == b", string, string)(string doesThisStart, string withThis) pure nothrow @nogc @safe

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

For more information about pred see find.

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

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

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

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

startsWith
("// Tests"))
break; if (
(local variable) string[] lines
lines
[
(local variable) ulong i
i
].
bool std.algorithm.searching.startsWith!("a == b", string, string)(string doesThisStart, string withThis) pure nothrow @nogc @safe

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

For more information about pred see find.

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

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

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

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

startsWith
("@(\""))
{ while (
(local variable) ulong i
i
<
(local variable) string[] lines
lines
.
(field) ulong string[].length
length
&&
(local variable) string[] lines
lines
[
(local variable) ulong i
i
] != "}")
(local variable) ulong i
i
++;
continue; }
(local variable) std.array.Appender!string code
code
~=
(local variable) string[] lines
lines
[
(local variable) ulong i
i
] ~ "\n";
}
(local variable) std.array.Appender!string code
code
~= "}\n";
break; }
(local variable) std.array.Appender!string code
code
~=
(local variable) const(string) line
line
~ "\n";
} return
(struct) gen_wired_inline.Absorbed
Absorbed
(
(local variable) std.array.Appender!string code
code
[],
(local variable) string[] imports
imports
);
} private bool
bool gen_wired_inline.endsWith(string s, string suffix)
endsWith
(
(alias) object.string = string
string
(parameter) string s
s
,
(alias) object.string = string
string
(parameter) string suffix
suffix
)
=>
(parameter) string s
s
.
(field) ulong string.length
length
>=
(parameter) string suffix
suffix
.
(field) ulong string.length
length
&&
(parameter) string s
s
[$ -
(parameter) string suffix
suffix
.
(field) ulong string.length
length
.. $] ==
(parameter) string suffix
suffix
;
/// `import a.b.c : x, y;` → `a.b.c` private
(alias) object.string = string
string
string gen_wired_inline.importedModule(string stmt)

import a.b.c : x, y;a.b.c

importedModule
(
(alias) object.string = string
string
(parameter) string stmt
stmt
)
{ auto
(local variable) string rest
rest
=
(parameter) string stmt
stmt
["import ".
(constant) ulong "import ".length = 7LU
length
.. $].
string std.string.strip!string(string str) pure nothrow @nogc @safe

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

Examples

import std.uni : lineSep, paraSep;
assert(strip("     hello world     ") ==
       "hello world");
assert(strip("\n\t\v\rhello world\n\t\v\r") ==
       "hello world");
assert(strip("hello world") ==
       "hello world");
assert(strip([lineSep] ~ "hello world" ~ [lineSep]) ==
       "hello world");
assert(strip([paraSep] ~ "hello world" ~ [paraSep]) ==
       "hello world");
@paramstr string or random access range of characters@paramchars string of characters to be stripped@paramleftChars string of leading characters to be stripped@paramrightChars string of trailing characters to be stripped@returnsslice of str stripped of leading and trailing whitespace or characters as specified in the second argument.@seeGeneric stripping on ranges: strip
strip
;
foreach (
(parameter) ulong k
k
,
(parameter) immutable(char) c
c
;
(local variable) string rest
rest
)
if (
(local variable) immutable(char) c
c
== ':' ||
(local variable) immutable(char) c
c
== ';' ||
(local variable) immutable(char) c
c
== ' ' ||
(local variable) immutable(char) c
c
== ',')
return
(local variable) string rest
rest
[0 ..
(local variable) ulong k
k
].
string std.string.strip!string(string str) pure nothrow @nogc @safe

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

Examples

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