font-scan-timing.dhover×477all
#!/usr/bin/env dub
/+ dub.sdl:
    name "font_libraries_font_scan_timing"
    targetPath "build"
    buildType "checked" {
        buildOptions "optimize" "inline" "debugInfo"
    }
+/
/**
 * How long does describing every font on a machine take? For each file
 * (`.ttf`, `.otf`, and every face of a `.ttc`/`.otc` collection) this reads
 * what a font catalog records per face — the table directory, the family name
 * from `name`, the weight class from `OS/2`, and the code-point coverage of
 * the best Unicode `cmap` subtable as a range count — through `mmap`, so only
 * the pages those tables live on are touched.
 *
 * It times one serial pass, a second serial pass, and two passes over a
 * `std.parallelism` pool. The first pass is cold only for files no process has
 * read since boot: eviction needs root (and on ZFS the ARC ignores
 * `posix_fadvise`), so the program does not try.
 *
 * Spike S1 of docs/specs/font/PLAN.md; decision FTX8 in
 * docs/specs/font/decisions.md records the result.
 *
 * Run with: dub run --single font-scan-timing.d [-- list-of-paths.txt]
 *
 * Font resolution: the argument names a file with one font path per line;
 * without it the program asks `fc-list : file`. If neither yields a font, it
 * prints a `SKIP:` line and exits 0 so CI stays green.
 */
module 
(module) font_libraries_font_scan_timing

How long does describing every font on a machine take? For each file (.ttf, .otf, and every face of a .ttc/.otc collection) this reads what a font catalog records per face — the table directory, the family name from name, the weight class from OS/2, and the code-point coverage of the best Unicode cmap subtable as a range count — through mmap, so only the pages those tables live on are touched.

It times one serial pass, a second serial pass, and two passes over a std.parallelism pool. The first pass is cold only for files no process has read since boot: eviction needs root (and on ZFS the ARC ignores posix_fadvise), so the program does not try.

Spike S1 of docs/specs/font/PLAN.md; decision FTX8 in docs/specs/font/decisions.md records the result.

Run with: dub run --single font-scan-timing.d [-- list-of-paths.txt]

Font resolution: the argument names a file with one font path per line; without it the program asks fc-list : file. If neither yields a font, it prints a SKIP: line and exits 0 so CI stays green.

font_libraries_font_scan_timing
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(module) core.sys.posix.fcntl

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly, Alex Rønne Petersen@standardsThe Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
fcntl
: open,
(alias constant) font_libraries_font_scan_timing.O_RDONLY = int core.sys.posix.fcntl.O_RDONLY = 0
O_RDONLY
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(package) core.sys.posix.sys
sys
.
(module) core.sys.posix.sys.mman

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly, Alex Rønne Petersen@standardsThe Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
mman
:
(alias constant) font_libraries_font_scan_timing.MAP_FAILED = void* core.sys.posix.sys.mman.MAP_FAILED = cast(void*)cast(size_t)18446744073709551615LU
MAP_FAILED
,
(alias constant) font_libraries_font_scan_timing.MAP_PRIVATE = int core.sys.posix.sys.mman.MAP_PRIVATE = 2
MAP_PRIVATE
, mmap,
(alias) font_libraries_font_scan_timing.munmap = int core.sys.posix.sys.mman.munmap(void*, ulong) nothrow @nogc
munmap
,
(alias constant) font_libraries_font_scan_timing.PROT_READ = int core.sys.posix.sys.mman.PROT_READ = 1
PROT_READ
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(package) core.sys.posix.sys
sys
.
(module) core.sys.posix.sys.stat

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly, Alex Rønne Petersen@standardsThe Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
stat
: fstat,
(struct) core.sys.posix.sys.stat.stat_t
stat_t
;
import
(package) core
core
.
(package) core.sys
sys
.
(package) core.sys.posix
posix
.
(module) core.sys.posix.unistd

D header file for POSIX.

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseBoost License 1.0.@authorsSean Kelly@standardsThe Open Group Base Specifications Issue 8, IEEE Std 1003.1, 2024 Edition
unistd
:
(alias) font_libraries_font_scan_timing.close = int core.sys.posix.unistd.close(int) nothrow @nogc @trusted
close
;
import
(package) std
std
.
(module) std.algorithm

This 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

@copyrightAndrei Alexandrescu 2008-.@licenseBoost License 1.0.@authorsAndrei Alexandrescu
algorithm
:
(alias template) font_libraries_font_scan_timing.count = std.algorithm.searching.count(alias pred = "a == b", Range, E)(Range haystack, E needle) if (isInputRange!Range && !isInfinite!Range && is(typeof(binaryFun!pred(haystack.front, needle))))

Counts matches of needle in haystack.

The first overload counts each element e in haystack for which pred(e, needle) is true. pred defaults to equality. Performs O(haystack.length) evaluations of pred.

The second overload counts the number of times needle was matched in haystack. pred compares elements in each range. Throws an exception if needle.empty is true, as the count of the empty range in any range would be infinite. Overlapped counts are not considered, for example ``count("aaa", "aa") is 1, not 2.

Note

Regardless of the overload, count will not accept infinite ranges for haystack.

@parampred The predicate to compare elements.@paramhaystack The range to count.@paramneedle The element or sub-range to count in haystack.@returnsThe number of matches in haystack.
count
,
(alias template) font_libraries_font_scan_timing.endsWith = std.algorithm.searching.endsWith(alias pred = "a == b", Range, Needles...)(Range doesThisEnd, Needles withOneOfThese) if (isBidirectionalRange!Range && (Needles.length > 1) && allSatisfy!(canTestStartsWith!(pred, Range), Needles))

Checks if the given range ends with (one of) the given needle(s). The reciprocal of startsWith.

@parampred The predicate to use for comparing elements between the range and the needle(s).@paramdoesThisEnd The bidirectional range to check.@paramwithOneOfThese The needles to check against, which may be single elements, or bidirectional ranges of elements.@paramwithThis The single element to check.@returns

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

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

endsWith
,
(alias template) font_libraries_font_scan_timing.filter = std.algorithm.iteration.filter(alias predicate) if (is(typeof(unaryFun!predicate)))

``filter!(predicate)(range) returns a new range containing only elements x in range for which predicate(x) returns true.

The predicate is passed to unaryFun, and can be either a string, or any callable that can be executed via pred(element).

@parampredicate Function to apply to each element of range@returnsAn input range that contains the filtered elements. If range is at least a forward range, the return value of filter will also be a forward range.@seeFilter (higher-order function), filterBidirectional
filter
,
(alias template) font_libraries_font_scan_timing.joiner = std.algorithm.iteration.joiner(RoR, Separator)(RoR r, Separator sep)

Lazily joins a range of ranges with a separator. The separator itself is a range. If a separator is not provided, then the ranges are joined directly without anything in between them (often called flatten in other languages).

Note

When both outer and inner ranges of RoR are bidirectional and the joiner is iterated from the back to the front, the separator will still be consumed from front to back, even if it is a bidirectional range too.

@paramr An input range of input ranges to be joined.@paramsep A forward range of element(s) to serve as separators in the joined range.@returnsA range of elements in the joined range. This will be a bidirectional range if both outer and inner ranges of RoR are at least bidirectional ranges. Else if both outer and inner ranges of RoR are forward ranges, the returned range will be likewise. Otherwise it will be only an input range. The range bidirectionality is propagated if no separator is specified.@seechain, which chains a sequence of ranges with compatible elements into a single range.
joiner
,
(alias template) font_libraries_font_scan_timing.map = std.algorithm.iteration.map(fun...) if (fun.length >= 1)

Implements the homonym function (also known as transform) present in many languages of functional flavor. The call ``map!(fun)(range) returns a range of which elements are obtained by applying fun(a) left to right for all elements a in range. The original ranges are not changed. Evaluation is done lazily.

@paramfun one or more transformation functions@seeMap (higher-order function)
map
,
(alias template) font_libraries_font_scan_timing.sort = std.algorithm.sorting.sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range r)

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

Performs O(r.length * log(r.length)) evaluations of less. If less involves expensive computations on the sort key, it may be worthwhile to use schwartzSort instead.

Stable sorting requires hasAssignableElements!Range to be true.

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

Preconditions

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

Algorithms

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

@paramless The predicate to sort by.@paramss The swapping strategy to use.@paramr The range to sort.@returnsThe initial range wrapped as a SortedRange with the predicate binaryFun!less.@see

assumeSorted

SortedRange

SwapStrategy

binaryFun

sort
,
(alias template) font_libraries_font_scan_timing.sum = std.algorithm.iteration.sum(R)(R r) if (isInputRange!R && !isInfinite!R && is(typeof(r.front + r.front)))

Sums elements of r, which must be a finite input range. Although conceptually sum`(r)` is equivalent to `fold`!((a, b) => a + b)(r, 0), sum`` uses specialized algorithms to maximize accuracy, as follows.

  • If ElementType!R is a floating-point type and R is a random-access range with length and slicing, then sum uses the pairwise summation algorithm.

  • If ElementType!R is a floating-point type and R is a finite input range (but not a random-access range with slicing), then sum uses the Kahan summation algorithm.

  • In all other cases, a simple element by element addition is done.

For floating point inputs, calculations are made in spec/type, Types, real precision for real inputs and in double precision otherwise (Note this is a special case that deviates from fold's behavior, which would have kept float precision for a float range). For all other types, the calculations are done in the same type obtained from from adding two elements of the range, which may be a different type from the elements themselves (for example, in case of integral promotion).

A seed may be passed to sum. Not only will this seed be used as an initial value, but its type will override all the above, and determine the algorithm and precision used for summation. If a seed is not passed, one is created with the value of typeof(r.front + r.front)(0), or typeof(r.front + r.front).zero if no constructor exists that takes an int.

Note that these specialized summing algorithms execute more primitive operations than vanilla summation. Therefore, if in certain cases maximum speed is required at expense of precision, one can use fold!((a, b) => a + b)(r, 0), which is not specialized for summation.

@paramseed the initial value of the summation@paramr a finite input range@returnsThe sum of all the elements in the range r.
sum
,
(alias template) font_libraries_font_scan_timing.uniq = std.algorithm.iteration.uniq(alias pred = "a == b", Range)(Range r) if (isInputRange!Range && is(typeof(binaryFun!pred(r.front, r.front)) == bool))

Lazily iterates unique consecutive elements of the given range, which is assumed to be sorted (functionality akin to the uniq system utility). Equivalence of elements is assessed by using the predicate pred, by default "a == b". The predicate is passed to binaryFun, and can either accept a string, or any callable that can be executed via pred(element, element). If the given range is bidirectional, uniq also yields a bidirectional range.

@parampred Predicate for determining equivalence between range elements.@paramr An input range of elements to filter.@returnsAn input range of consecutively unique elements in the original range. If r is also a forward range or bidirectional range, the returned range will be likewise.
uniq
;
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) font_libraries_font_scan_timing.array = std.array.array(Range)(Range r) if (isIterable!Range && !isAutodecodableString!Range && !isInfinite!Range)

Allocates an array and initializes it with copies of the elements of range r.

Narrow strings are handled as follows:

  • If autodecoding is turned on (default), then they are handled as a separate overload.

  • If autodecoding is turned off, then this is equivalent to duplicating the array.

@paramr range (or aggregate with opApply function) whose elements are copied into the allocated array@returnsallocated and initialized array
array
,
(alias template) font_libraries_font_scan_timing.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.

@params the string to split by word if no separator is given@paramrange the range to split@paramsep a value of the same type as the elements of range or another@paramisTerminator a predicate that splits the range when it returns true.@returnsAn array containing the divided parts of range (or the words of s).@see

splitter for a lazy version without allocating memory.

splitter for a version that splits using a regular expression defined separator.

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

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

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

Source

std/conv.d

@copyrightCopyright The D Language Foundation 2007-.@licenseBoost License 1.0.@authorsWalter Bright, Andrei Alexandrescu, Shin Fujishiro, Adam D. Ruppe, Kenji Hara
conv
:
(alias template) font_libraries_font_scan_timing.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
;
import
(package) std
std
.
(package) std.datetime
datetime
.
(module) std.datetime.stopwatch

Module containing some basic benchmarking and timing functionality.

For convenience, this module publicly imports core.time.

Category Functions
Main functionality StopWatch benchmark
Flags AutoStart

Unlike the other modules in std.datetime, this module is not currently publicly imported in std.datetime.package, because the old versions of this functionality which use TickDuration are in std.datetime.package and would conflict with the symbols in this module. After the old symbols have gone through the deprecation cycle and have been fully removed, then this module will be publicly imported in std.datetime.package. The old, deprecated symbols has been removed from the documentation in December 2019 and currently scheduled to be fully removed from Phobos after 2.094.

So, for now, when using std.datetime.stopwatch, if other modules from std.datetime are needed, then either import them individually rather than importing std.datetime, or use selective or static imports to import std.datetime.stopwatch. e.g.

import std.datetime;
import std.datetime.stopwatch : benchmark, StopWatch;

The compiler will then know to use the symbols from std.datetime.stopwatch rather than the deprecated ones from std.datetime.package.

Source

std/datetime/stopwatch.d

@licenseBoost License 1.0.@authorsJonathan M Davis and Kato Shoichi
stopwatch
:
(enum) std.typecons.Flag!"autoStart"

Examples

Flag!"abc" flag;

assert(flag == Flag!"abc".no);
assert(flag == No.abc);
assert(!flag);
if (flag) assert(0);
auto flag = Yes.abc;

assert(flag);
assert(flag == Yes.abc);
if (!flag) assert(0);
if (flag) {} else assert(0);
AutoStart
,
(struct) std.datetime.stopwatch.StopWatch

StopWatch is used to measure time just like one would do with a physical stopwatch, including stopping, restarting, and/or resetting it.

MonoTime is used to hold the time, and it uses the system's monotonic clock, which is high precision and never counts backwards (unlike the wall clock time, which can count backwards, which is why SysTime should not be used for timing).

Note that the precision of StopWatch differs from system to system. It is impossible for it to be the same for all systems, since the precision of the system clock and other system-dependent and situation-dependent factors (such as the overhead of a context switch between threads) varies from system to system and can affect StopWatch's accuracy.

Examples

Measure a time in milliseconds, microseconds, or nanoseconds

auto sw = StopWatch(AutoStart.no);
sw.start();
// ... Insert operations to be timed here ...
sw.stop();

long msecs = sw.peek.total!"msecs";
long usecs = sw.peek.total!"usecs";
long nsecs = sw.peek.total!"nsecs";

assert(usecs >= msecs * 1000);
assert(nsecs >= usecs * 1000);
import core.thread : Thread;

auto sw = StopWatch(AutoStart.yes);

Duration t1 = sw.peek();
Thread.sleep(usecs(1));
Duration t2 = sw.peek();
assert(t2 > t1);

Thread.sleep(usecs(1));
sw.stop();

Duration t3 = sw.peek();
assert(t3 > t2);
Duration t4 = sw.peek();
assert(t3 == t4);

sw.start();
Thread.sleep(usecs(1));

Duration t5 = sw.peek();
assert(t5 > t4);

// If stopping or resetting the StopWatch is not required, then
// MonoTime can easily be used by itself without StopWatch.
auto before = MonoTime.currTime;
// do stuff...
auto timeElapsed = MonoTime.currTime - before;
StopWatch
;
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) font_libraries_font_scan_timing.exists = std.file.exists(R)(R name) if (isSomeFiniteCharInputRange!R && !isConvertibleToString!R)

Determine whether the given file (or directory) exists.

@paramname string or range of characters representing the file name@returnstrue if the file name specified as input exists
exists
,
(alias template) font_libraries_font_scan_timing.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
;
import
(package) std
std
.
(module) std.parallelism

std.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

@copyrightCopyright (c) 2009-2011, David Simcha.@licenseBoost License 1.0
parallelism
:
(alias template) font_libraries_font_scan_timing.parallel = std.parallelism.parallel(R)(R range)

Convenience functions that forwards to taskPool.parallel``. The purpose of these is to make parallel foreach less verbose and more readable.

Example

// Find the logarithm of every number from
// 1 to 1_000_000 in parallel, using the
// default TaskPool instance.
auto logs = new double[1_000_000];

foreach (i, ref elem; parallel(logs))
{
    elem = log(i + 1.0);
}
parallel
;
import
(package) std
std
.
(module) std.process

Functions 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.

@authorsLars Tandle Kyllingstad, Steven Schveighoffer, Vladimir Panteleev@copyrightCopyright (c) 2013, the authors. All rights reserved.@licenseBoost License 1.0.
process
:
(alias) font_libraries_font_scan_timing.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) @safe

Executes 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.)

@paramargs An array which contains the program name as the zeroth element and any command-line arguments in the following elements. (See spawnProcess for details.)@paramprogram The program name, without command-line arguments. (See spawnProcess for details.)@paramcommand A shell command which is passed verbatim to the command interpreter. (See spawnShell for details.)@paramenv Additional environment variables for the child process. (See spawnProcess for details.)@paramconfig Flags that control process creation. See Config for an overview of available flags, and note that the retainStd... flags have no effect in this function.@parammaxOutput The maximum number of bytes of output that should be captured.@paramworkDir The working directory for the new process. By default the child process inherits the parent's working directory.@paramshellPath The path to the shell to use to run the specified program. By default this is nativeShell.@returnsAn std.typecons.Tuple!(int, "status", string, "output").@throws

ProcessException on failure to start the process.

StdioException on failure to capture output.

execute
;
import
(package) std
std
.
(module) std.range

This module defines the notion of a range. Ranges generalize the concept of arrays, lists, or anything that involves sequential access. This abstraction enables the same set of algorithms (see std.algorithm) to be used with a vast variety of different concrete types. For example, a linear search algorithm such as find works not just for arrays, but for linked-lists, input files, incoming network data, etc.

Guides

There are many articles available that can bolster understanding ranges:

Submodules

This module has two submodules:

The std.range.primitives submodule provides basic range functionality. It defines several templates for testing whether a given object is a range, what kind of range it is, and provides some common range operations.

The std.range.interfaces submodule provides object-based interfaces for working with ranges via runtime polymorphism.

The remainder of this module provides a rich set of range creation and composition templates that let you construct new ranges out of existing ranges:

| chain | Concatenates several ranges into a single range. | | choose | Chooses one of two ranges at runtime based on a boolean condition. | | chooseAmong | Chooses one of several ranges at runtime based on an index. | | chunks | Creates a range that returns fixed-size chunks of the original range. | | cycle | Creates an infinite range that repeats the given forward range indefinitely. Good for implementing circular buffers. | | drop | Creates the range that results from discarding the first n elements from the given range. | | dropBack | Creates the range that results from discarding the last n elements from the given range. | | dropExactly | Creates the range that results from discarding exactly n of the first elements from the given range. | | dropBackExactly | Creates the range that results from discarding exactly n of the last elements from the given range. | | dropOne | Creates the range that results from discarding the first element from the given range. | | dropBackOne | Creates the range that results from discarding the last element from the given range. | | enumerate | Iterates a range with an attached index variable. | | evenChunks | Creates a range that returns a number of chunks of approximately equal length from the original range. | | frontTransversal | Creates a range that iterates over the first elements of the given ranges. | | generate | Creates a range by successive calls to a given function. This allows to create ranges as a single delegate. | | indexed | Creates a range that offers a view of a given range as though its elements were reordered according to a given range of indices. | | iota | Creates a range consisting of numbers between a starting point and ending point, spaced apart by a given interval. | | lockstep | Iterates n ranges in lockstep, for use in a foreach loop. Similar to zip, except that lockstep is designed especially for foreach loops. | | nullSink | An output range that discards the data it receives. | | only | Creates a range that iterates over the given arguments. | | padLeft | Pads a range to a specified length by adding a given element to the front of the range. Is lazy if the range has a known length. | | padRight | Lazily pads a range to a specified length by adding a given element to the back of the range. | | radial | Given a random-access range and a starting point, creates a range that alternately returns the next left and next right element to the starting point. | | recurrence | Creates a forward range whose values are defined by a mathematical recurrence relation. | | refRange | Pass a range by reference. Both the original range and the RefRange will always have the exact same elements. Any operation done on one will affect the other. | | repeat | Creates a range that consists of a single element repeated n times, or an infinite range repeating that element indefinitely. | | retro | Iterates a bidirectional range backwards. | | roundRobin | Given n ranges, creates a new range that return the n first elements of each range, in turn, then the second element of each range, and so on, in a round-robin fashion. | | sequence | Similar to recurrence, except that a random-access range is created. | | slide | Creates a range that returns a fixed-size sliding window over the original range. Unlike chunks, it advances a configurable number of items at a time, not one chunk at a time. | | stride | Iterates a range with stride n. | | tail | Return a range advanced to within n elements of the end of the given range. | | take | Creates a sub-range consisting of only up to the first n elements of the given range. | | takeExactly | Like take, but assumes the given range actually has n elements, and therefore also defines the length property. | | takeNone | Creates a random-access range consisting of zero elements of the given range. | | takeOne | Creates a random-access range consisting of exactly the first element of the given range. | | tee | Creates a range that wraps a given range, forwarding along its elements while also calling a provided function with each element. | | transposed | Transposes a range of ranges. | | transversal | Creates a range that iterates over the n'th elements of the given random-access ranges. | | zip | Given n ranges, creates a range that successively returns a tuple of all the first elements, a tuple of all the second elements, etc. |

Sortedness

Ranges whose elements are sorted afford better efficiency with certain operations. For this, the assumeSorted function can be used to construct a SortedRange from a pre-sorted range. The sort function also conveniently returns a SortedRange. SortedRange objects provide some additional range operations that take advantage of the fact that the range is sorted.

Source

std/range/package.d

@licenseBoost License 1.0.@authorsAndrei Alexandrescu, David Simcha, Jonathan M Davis, and Jack Stouffer. Credit for some of the ideas in building this module goes to Leonardo Maffi.
range
:
(alias template) font_libraries_font_scan_timing.walkLength = std.range.primitives.walkLength(Range)(Range range) if (isInputRange!Range && !isInfinite!Range)

This is a best-effort implementation of length for any kind of range.

If hasLength!Range, simply returns range.length without checking upTo (when specified).

Otherwise, walks the range through its length and returns the number of elements seen. Performes O(n) evaluations of range.empty and range.popFront(), where n is the effective length of range.

The upTo parameter is useful to "cut the losses" in case the interest is in seeing whether the range has at least some number of elements. If the parameter upTo is specified, stops if upTo steps have been taken and returns upTo.

Infinite ranges are compatible, provided the parameter upTo is specified, in which case the implementation simply returns upTo.

walkLength
;
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) font_libraries_font_scan_timing.writefln = std.stdio.writefln(alias fmt, A...)(A args) if (isSomeString!(typeof(fmt)))

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

writefln
,
(alias template) font_libraries_font_scan_timing.writeln = std.stdio.writeln(T...)(T args)

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

Example

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

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
;
import
(package) 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) font_libraries_font_scan_timing.lineSplitter = std.string.lineSplitter(Flag keepTerm = No.keepTerminator, Range)(Range r) if (hasSlicing!Range && hasLength!Range && isSomeChar!(ElementType!Range) && !isSomeString!Range)

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

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

Adheres to Unicode 7.0.

Does not allocate memory.

@paramr array of chars, wchars, or dchars or a slicable range@paramkeepTerm whether delimiter is included or not in the results@returnsrange of slices of the input range r@seesplitLines splitter splitter
lineSplitter
,
(alias template) font_libraries_font_scan_timing.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) font_libraries_font_scan_timing.toStringz = immutable(char)* std.string.toStringz(scope const(char)[] s) pure nothrow @trusted
@params A D-style string.@returns

A C-style null-terminated string equivalent to s. s must not contain embedded '\0''s as any C function will treat the first '\0' that it sees as the end of the string. If s.empty is true, then a string containing only '\0' is returned.

Important Note: When passing a char* to a C function, and the C function keeps it around for any reason, make sure that you keep a reference to it in your D code. Otherwise, it may become invalid during a garbage collection cycle and cause a nasty bug when the C code tries to use it.

toStringz
;
/// What a catalog keeps per face. struct
(struct) font_libraries_font_scan_timing.FaceRecord

What a catalog keeps per face.

FaceRecord
{
(alias) object.string = string
string
(field) string font_libraries_font_scan_timing.FaceRecord.family
family
;
uint
(field) uint font_libraries_font_scan_timing.FaceRecord.weightClass
weightClass
;
uint
(field) uint font_libraries_font_scan_timing.FaceRecord.codepoints
codepoints
,
(field) uint font_libraries_font_scan_timing.FaceRecord.ranges
ranges
;
bool
(field) bool font_libraries_font_scan_timing.FaceRecord.hasCmap
hasCmap
;
} uint
uint font_libraries_font_scan_timing.u16(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u16
(const(ubyte)[]
(parameter) const(ubyte)[] d
d
,
(alias) object.size_t = ulong
size_t
(parameter) ulong o
o
) @safe pure nothrow @nogc
=>
(parameter) ulong o
o
+ 2 <=
(parameter) const(ubyte)[] d
d
.
(field) ulong const(ubyte)[].length
length
? (
(parameter) const(ubyte)[] d
d
[
(parameter) ulong o
o
] << 8) |
(parameter) const(ubyte)[] d
d
[
(parameter) ulong o
o
+ 1] : 0;
uint
uint font_libraries_font_scan_timing.u32(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u32
(const(ubyte)[]
(parameter) const(ubyte)[] d
d
,
(alias) object.size_t = ulong
size_t
(parameter) ulong o
o
) @safe pure nothrow @nogc
=>
(parameter) ulong o
o
+ 4 <=
(parameter) const(ubyte)[] d
d
.
(field) ulong const(ubyte)[].length
length
? (uint(
(parameter) const(ubyte)[] d
d
[
(parameter) ulong o
o
]) << 24) | (
(parameter) const(ubyte)[] d
d
[
(parameter) ulong o
o
+ 1] << 16) | (
(parameter) const(ubyte)[] d
d
[
(parameter) ulong o
o
+ 2] << 8) |
(parameter) const(ubyte)[] d
d
[
(parameter) ulong o
o
+ 3] : 0;
/// The table `tag` of the face whose directory starts at `dir`, or `null`. const(ubyte)[]
const(ubyte)[] font_libraries_font_scan_timing.table(const(ubyte)[] d, ulong dir, string tag) pure nothrow @nogc @safe

The table tag of the face whose directory starts at dir, or null.

table
(const(ubyte)[]
(parameter) const(ubyte)[] d
d
,
(alias) object.size_t = ulong
size_t
(parameter) ulong dir
dir
,
(alias) object.string = string
string
(parameter) string tag
tag
) @safe pure nothrow @nogc
{ const
(local variable) const(uint) t
t
= (uint(
(parameter) string tag
tag
[0]) << 24) | (
(parameter) string tag
tag
[1] << 16) | (
(parameter) string tag
tag
[2] << 8) |
(parameter) string tag
tag
[3];
foreach (
(local variable) uint i
i
; 0 ..
uint font_libraries_font_scan_timing.u16(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u16
(
(parameter) const(ubyte)[] d
d
,
(parameter) ulong dir
dir
+ 4))
{ const
(local variable) const(ulong) r
r
=
(parameter) ulong dir
dir
+ 12 +
(local variable) uint i
i
* 16;
if (
uint font_libraries_font_scan_timing.u32(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u32
(
(parameter) const(ubyte)[] d
d
,
(local variable) const(ulong) r
r
) !=
(local variable) const(uint) t
t
)
continue; const
(local variable) const(ulong) off
off
=
(ulong) ulong
size_t
(
uint font_libraries_font_scan_timing.u32(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u32
(
(parameter) const(ubyte)[] d
d
,
(local variable) const(ulong) r
r
+ 8)),
(local variable) const(ulong) len
len
=
(ulong) ulong
size_t
(
uint font_libraries_font_scan_timing.u32(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u32
(
(parameter) const(ubyte)[] d
d
,
(local variable) const(ulong) r
r
+ 12));
return
(local variable) const(ulong) off
off
+
(local variable) const(ulong) len
len
<=
(parameter) const(ubyte)[] d
d
.
(field) ulong const(ubyte)[].length
length
?
(parameter) const(ubyte)[] d
d
[
(local variable) const(ulong) off
off
..
(local variable) const(ulong) off
off
+
(local variable) const(ulong) len
len
] : null;
} return null; } /// Counts the code points and ranges of the best Unicode subtable: /// format 12 (full repertoire) over format 4 (BMP). void
void font_libraries_font_scan_timing.readCoverage(const(ubyte)[] cmap, ref font_libraries_font_scan_timing.FaceRecord rec) pure nothrow @nogc @safe

Counts the code points and ranges of the best Unicode subtable: format 12 (full repertoire) over format 4 (BMP).

readCoverage
(const(ubyte)[]
(parameter) const(ubyte)[] cmap
cmap
, ref
(struct) font_libraries_font_scan_timing.FaceRecord

What a catalog keeps per face.

FaceRecord
(parameter) font_libraries_font_scan_timing.FaceRecord rec
rec
) @safe pure nothrow @nogc
{
(alias) object.size_t = ulong
size_t
(local variable) ulong best
best
;
int
(local variable) int bestScore
bestScore
;
foreach (
(local variable) uint i
i
; 0 ..
uint font_libraries_font_scan_timing.u16(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u16
(
(parameter) const(ubyte)[] cmap
cmap
, 2))
{ const
(local variable) const(uint) platform
platform
=
uint font_libraries_font_scan_timing.u16(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u16
(
(parameter) const(ubyte)[] cmap
cmap
, 4 +
(local variable) uint i
i
* 8),
(local variable) const(uint) encoding
encoding
=
uint font_libraries_font_scan_timing.u16(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u16
(
(parameter) const(ubyte)[] cmap
cmap
, 6 +
(local variable) uint i
i
* 8);
const
(local variable) const(uint) off
off
=
uint font_libraries_font_scan_timing.u32(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u32
(
(parameter) const(ubyte)[] cmap
cmap
, 8 +
(local variable) uint i
i
* 8),
(local variable) const(uint) format
format
=
uint font_libraries_font_scan_timing.u16(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u16
(
(parameter) const(ubyte)[] cmap
cmap
,
(local variable) const(uint) off
off
);
const
(local variable) const(bool) unicode
unicode
=
(local variable) const(uint) platform
platform
== 0 || (
(local variable) const(uint) platform
platform
== 3 && (
(local variable) const(uint) encoding
encoding
== 1 ||
(local variable) const(uint) encoding
encoding
== 10));
const
(local variable) const(int) score
score
= !
(local variable) const(bool) unicode
unicode
? 0 :
(local variable) const(uint) format
format
== 12 ? 2 :
(local variable) const(uint) format
format
== 4 ? 1 : 0;
if (
(local variable) const(int) score
score
>
(local variable) int bestScore
bestScore
)
{
(local variable) int bestScore
bestScore
=
(local variable) const(int) score
score
;
(local variable) ulong best
best
=
(local variable) const(uint) off
off
;
} }
(parameter) font_libraries_font_scan_timing.FaceRecord rec
rec
.
(field) bool font_libraries_font_scan_timing.FaceRecord.hasCmap
hasCmap
=
(local variable) int bestScore
bestScore
> 0;
uint
(local variable) uint next
next
= uint.
(constant) uint uint.max = 4294967295u
max
;
void
void font_libraries_font_scan_timing.readCoverage.add(uint lo, uint hi) pure nothrow @nogc @safe
add
(uint
(parameter) uint lo
lo
, uint
(parameter) uint hi
hi
)
{
(parameter) font_libraries_font_scan_timing.FaceRecord rec
rec
.
(field) uint font_libraries_font_scan_timing.FaceRecord.codepoints
codepoints
+=
(parameter) uint hi
hi
-
(parameter) uint lo
lo
+ 1;
if (
(parameter) uint lo
lo
!=
(local variable) uint next
next
)
++
(parameter) font_libraries_font_scan_timing.FaceRecord rec
rec
.
(field) uint font_libraries_font_scan_timing.FaceRecord.ranges
ranges
;
(local variable) uint next
next
=
(parameter) uint hi
hi
+ 1;
} if (
(local variable) int bestScore
bestScore
== 1)
{ const
(local variable) const(uint) segX2
segX2
=
uint font_libraries_font_scan_timing.u16(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u16
(
(parameter) const(ubyte)[] cmap
cmap
,
(local variable) ulong best
best
+ 6);
foreach (
(local variable) uint s
s
; 0 ..
(local variable) const(uint) segX2
segX2
/ 2)
{ const
(local variable) const(uint) end
end
=
uint font_libraries_font_scan_timing.u16(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u16
(
(parameter) const(ubyte)[] cmap
cmap
,
(local variable) ulong best
best
+ 14 +
(local variable) uint s
s
* 2),
(local variable) const(uint) start
start
=
uint font_libraries_font_scan_timing.u16(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u16
(
(parameter) const(ubyte)[] cmap
cmap
,
(local variable) ulong best
best
+ 16 +
(local variable) const(uint) segX2
segX2
+
(local variable) uint s
s
* 2);
if (
(local variable) const(uint) start
start
<=
(local variable) const(uint) end
end
&&
(local variable) const(uint) start
start
!= 0xFFFF)
void font_libraries_font_scan_timing.readCoverage.add(uint lo, uint hi) pure nothrow @nogc @safe
add
(
(local variable) const(uint) start
start
,
(local variable) const(uint) end
end
);
} } else if (
(local variable) int bestScore
bestScore
== 2)
foreach (
(local variable) uint g
g
; 0 ..
uint font_libraries_font_scan_timing.u32(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u32
(
(parameter) const(ubyte)[] cmap
cmap
,
(local variable) ulong best
best
+ 12))
{ const
(local variable) const(uint) lo
lo
=
uint font_libraries_font_scan_timing.u32(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u32
(
(parameter) const(ubyte)[] cmap
cmap
,
(local variable) ulong best
best
+ 16 +
(local variable) uint g
g
* 12),
(local variable) const(uint) hi
hi
=
uint font_libraries_font_scan_timing.u32(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u32
(
(parameter) const(ubyte)[] cmap
cmap
,
(local variable) ulong best
best
+ 20 +
(local variable) uint g
g
* 12);
if (
(local variable) const(uint) lo
lo
<=
(local variable) const(uint) hi
hi
&&
(local variable) const(uint) hi
hi
<= 0x10FFFF)
void font_libraries_font_scan_timing.readCoverage.add(uint lo, uint hi) pure nothrow @nogc @safe
add
(
(local variable) const(uint) lo
lo
,
(local variable) const(uint) hi
hi
);
} } /// The typographic family (name ID 16), else the family (ID 1), Windows platform.
(alias) object.string = string
string
string font_libraries_font_scan_timing.familyName(const(ubyte)[] name) pure @safe

The typographic family (name ID 16), else the family (ID 1), Windows platform.

familyName
(const(ubyte)[]
(parameter) const(ubyte)[] name
name
) @safe pure
{ const
(local variable) const(uint) strings
strings
=
uint font_libraries_font_scan_timing.u16(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u16
(
(parameter) const(ubyte)[] name
name
, 4);
(alias) object.string = string
string
(local variable) string found
found
;
foreach (
(local variable) uint i
i
; 0 ..
uint font_libraries_font_scan_timing.u16(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u16
(
(parameter) const(ubyte)[] name
name
, 2))
{ const
(local variable) const(uint) r
r
= 6 +
(local variable) uint i
i
* 12,
(local variable) const(uint) id
id
=
uint font_libraries_font_scan_timing.u16(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u16
(
(parameter) const(ubyte)[] name
name
,
(local variable) const(uint) r
r
+ 6);
if (
uint font_libraries_font_scan_timing.u16(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u16
(
(parameter) const(ubyte)[] name
name
,
(local variable) const(uint) r
r
) != 3 || (
(local variable) const(uint) id
id
!= 1 &&
(local variable) const(uint) id
id
!= 16))
continue; const
(local variable) const(uint) start
start
=
(local variable) const(uint) strings
strings
+
uint font_libraries_font_scan_timing.u16(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u16
(
(parameter) const(ubyte)[] name
name
,
(local variable) const(uint) r
r
+ 10),
(local variable) const(uint) len
len
=
uint font_libraries_font_scan_timing.u16(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u16
(
(parameter) const(ubyte)[] name
name
,
(local variable) const(uint) r
r
+ 8);
if (
(local variable) const(uint) start
start
+
(local variable) const(uint) len
len
>
(parameter) const(ubyte)[] name
name
.
(field) ulong const(ubyte)[].length
length
)
continue; wchar[]
(local variable) wchar[] utf16
utf16
;
foreach (
(local variable) uint k
k
; 0 ..
(local variable) const(uint) len
len
/ 2)
(local variable) wchar[] utf16
utf16
~= cast(wchar)
uint font_libraries_font_scan_timing.u16(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u16
(
(parameter) const(ubyte)[] name
name
,
(local variable) const(uint) start
start
+
(local variable) uint k
k
* 2);
(local variable) string found
found
=
(local variable) wchar[] utf16
utf16
.
string std.conv.to!string.to!(wchar[])(wchar[] __param_0) pure @safe

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

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

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

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

Examples

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

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

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

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

import std.exception : assertThrown;

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

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

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

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

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

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

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

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

import std.exception : assertThrown;

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

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

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

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

import std.string : split;

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

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

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

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

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

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

Stringize conversion from all types is supported.

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

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

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

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

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

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

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

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

  • char, wchar, dchar to a string type.

  • Unsigned or signed integers to strings.

    [special case]

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

  • All floating point types to all string types.

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

See formatValue on how toString should be defined.

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

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

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

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

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

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

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

import std.exception : assertThrown;

enum E { a, b, c }
assert(to!E("a") == E.a);
assert(to!E("b") == E.b);
assertThrown!ConvException(to!E("A"));
to
!
(alias) object.string = string
string
;
if (
(local variable) const(uint) id
id
== 16)
break; } return
(local variable) string found
found
;
}
(struct) font_libraries_font_scan_timing.FaceRecord

What a catalog keeps per face.

FaceRecord
[]
font_libraries_font_scan_timing.FaceRecord[] font_libraries_font_scan_timing.describe(const(ubyte)[] d) pure @safe
describe
(const(ubyte)[]
(parameter) const(ubyte)[] d
d
) @safe pure
{
(alias) object.size_t = ulong
size_t
[]
(local variable) ulong[] dirs
dirs
=
uint font_libraries_font_scan_timing.u32(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u32
(
(parameter) const(ubyte)[] d
d
, 0) == 0x74746366 // 'ttcf'
? (
(alias) object.size_t = ulong
size_t
(parameter) ulong n
n
) {
(alias) object.size_t = ulong
size_t
[]
(local variable) ulong[] r
r
; foreach (
(local variable) ulong i
i
; 0 ..
(parameter) ulong n
n
)
(local variable) ulong[] r
r
~=
uint font_libraries_font_scan_timing.u32(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u32
(
(parameter) const(ubyte)[] d
d
, 12 +
(local variable) ulong i
i
* 4); return
(local variable) ulong[] r
r
; }(
uint font_libraries_font_scan_timing.u32(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u32
(
(parameter) const(ubyte)[] d
d
, 8))
: [
(ulong) ulong
size_t
(0)];
(struct) font_libraries_font_scan_timing.FaceRecord

What a catalog keeps per face.

FaceRecord
[]
(local variable) font_libraries_font_scan_timing.FaceRecord[] faces
faces
;
foreach (
(parameter) ulong dir
dir
;
(local variable) ulong[] dirs
dirs
)
{
(struct) font_libraries_font_scan_timing.FaceRecord

What a catalog keeps per face.

FaceRecord
(local variable) font_libraries_font_scan_timing.FaceRecord rec
rec
;
void font_libraries_font_scan_timing.readCoverage(const(ubyte)[] cmap, ref font_libraries_font_scan_timing.FaceRecord rec) pure nothrow @nogc @safe

Counts the code points and ranges of the best Unicode subtable: format 12 (full repertoire) over format 4 (BMP).

readCoverage
(
const(ubyte)[] font_libraries_font_scan_timing.table(const(ubyte)[] d, ulong dir, string tag) pure nothrow @nogc @safe

The table tag of the face whose directory starts at dir, or null.

table
(
(parameter) const(ubyte)[] d
d
,
(local variable) ulong dir
dir
, "cmap"),
(local variable) font_libraries_font_scan_timing.FaceRecord rec
rec
);
(local variable) font_libraries_font_scan_timing.FaceRecord rec
rec
.
(field) string font_libraries_font_scan_timing.FaceRecord.family
family
=
string font_libraries_font_scan_timing.familyName(const(ubyte)[] name) pure @safe

The typographic family (name ID 16), else the family (ID 1), Windows platform.

familyName
(
const(ubyte)[] font_libraries_font_scan_timing.table(const(ubyte)[] d, ulong dir, string tag) pure nothrow @nogc @safe

The table tag of the face whose directory starts at dir, or null.

table
(
(parameter) const(ubyte)[] d
d
,
(local variable) ulong dir
dir
, "name"));
(local variable) font_libraries_font_scan_timing.FaceRecord rec
rec
.
(field) uint font_libraries_font_scan_timing.FaceRecord.weightClass
weightClass
=
uint font_libraries_font_scan_timing.u16(const(ubyte)[] d, ulong o) pure nothrow @nogc @safe
u16
(
const(ubyte)[] font_libraries_font_scan_timing.table(const(ubyte)[] d, ulong dir, string tag) pure nothrow @nogc @safe

The table tag of the face whose directory starts at dir, or null.

table
(
(parameter) const(ubyte)[] d
d
,
(local variable) ulong dir
dir
, "OS/2"), 4);
(local variable) font_libraries_font_scan_timing.FaceRecord[] faces
faces
~=
(local variable) font_libraries_font_scan_timing.FaceRecord rec
rec
;
} return
(local variable) font_libraries_font_scan_timing.FaceRecord[] faces
faces
;
}
(struct) font_libraries_font_scan_timing.FaceRecord

What a catalog keeps per face.

FaceRecord
[]
font_libraries_font_scan_timing.FaceRecord[] font_libraries_font_scan_timing.scanFile(string path) @trusted
scanFile
(
(alias) object.string = string
string
(parameter) string path
path
) @trusted
{ const
(local variable) const(int) fd
fd
= open(
int core.sys.posix.fcntl.open64(scope const(char*), int, ...) nothrow @nogc
path
.
immutable(char)* std.string.toStringz(scope const(char)[] s) pure nothrow @trusted

Examples

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(""));
@params A D-style string.@returns

A C-style null-terminated string equivalent to s. s must not contain embedded '\0''s as any C function will treat the first '\0' that it sees as the end of the string. If ``s.empty is true, then a string containing only '\0' is returned.

Important Note: When passing a char* to a C function, and the C function keeps it around for any reason, make sure that you keep a reference to it in your D code. Otherwise, it may become invalid during a garbage collection cycle and cause a nasty bug when the C code tries to use it.

toStringz
,
(constant) int core.sys.posix.fcntl.O_RDONLY = 0
O_RDONLY
);
if (
(local variable) const(int) fd
fd
< 0)
return null; scope (exit)
int core.sys.posix.unistd.close(int) nothrow @nogc @trusted
close
(
(local variable) const(int) fd
fd
);
(struct) core.sys.posix.sys.stat.stat_t
stat_t
(local variable) core.sys.posix.sys.stat.stat_t st
st
;
if (fstat(
int core.sys.posix.sys.stat.fstat64(int, core.sys.posix.sys.stat.stat_t*) nothrow @nogc @trusted
fd
, &
(local variable) core.sys.posix.sys.stat.stat_t st
st
) != 0 ||
(local variable) core.sys.posix.sys.stat.stat_t st
st
.
(field) long core.sys.posix.sys.stat.stat_t.st_size
st_size
< 12)
return null; auto
(local variable) void* p
p
= mmap(null,
(local variable) core.sys.posix.sys.stat.stat_t st
st
.
(field) long core.sys.posix.sys.stat.stat_t.st_size
st_size
,
(constant) int core.sys.posix.sys.mman.PROT_READ = 1
PROT_READ
,
(constant) int core.sys.posix.sys.mman.MAP_PRIVATE = 2
MAP_PRIVATE
,
(local variable) const(int) fd
fd
, 0);
if (
(local variable) void* p
p
==
(constant) void* core.sys.posix.sys.mman.MAP_FAILED = cast(void*)cast(size_t)18446744073709551615LU
MAP_FAILED
)
return null; scope (exit)
int core.sys.posix.sys.mman.munmap(void*, ulong) nothrow @nogc
munmap
(
(local variable) void* p
p
,
(local variable) core.sys.posix.sys.stat.stat_t st
st
.
(field) long core.sys.posix.sys.stat.stat_t.st_size
st_size
);
return
font_libraries_font_scan_timing.FaceRecord[] font_libraries_font_scan_timing.describe(const(ubyte)[] d) pure @safe
describe
((cast(const(ubyte)*)
(local variable) void* p
p
)[0 ..
(local variable) core.sys.posix.sys.stat.stat_t st
st
.
(field) long core.sys.posix.sys.stat.stat_t.st_size
st_size
]);
} void
void font_libraries_font_scan_timing.pass(string label, string[] paths, bool pooled)
pass
(
(alias) object.string = string
string
(parameter) string label
label
,
(alias) object.string = string
string
[]
(parameter) string[] paths
paths
, bool
(parameter) bool pooled
pooled
)
{ auto
(local variable) font_libraries_font_scan_timing.FaceRecord[][] records
records
= new
(struct) font_libraries_font_scan_timing.FaceRecord

What a catalog keeps per face.

FaceRecord
[][](
(parameter) string[] paths
paths
.
(field) ulong string[].length
length
);
auto
(local variable) std.datetime.stopwatch.StopWatch sw
sw
=
(struct) std.datetime.stopwatch.StopWatch

StopWatch is used to measure time just like one would do with a physical stopwatch, including stopping, restarting, and/or resetting it.

MonoTime is used to hold the time, and it uses the system's monotonic clock, which is high precision and never counts backwards (unlike the wall clock time, which can count backwards, which is why SysTime should not be used for timing).

Note that the precision of StopWatch differs from system to system. It is impossible for it to be the same for all systems, since the precision of the system clock and other system-dependent and situation-dependent factors (such as the overhead of a context switch between threads) varies from system to system and can affect StopWatch's accuracy.

Examples

Measure a time in milliseconds, microseconds, or nanoseconds

auto sw = StopWatch(AutoStart.no);
sw.start();
// ... Insert operations to be timed here ...
sw.stop();

long msecs = sw.peek.total!"msecs";
long usecs = sw.peek.total!"usecs";
long nsecs = sw.peek.total!"nsecs";

assert(usecs >= msecs * 1000);
assert(nsecs >= usecs * 1000);
import core.thread : Thread;

auto sw = StopWatch(AutoStart.yes);

Duration t1 = sw.peek();
Thread.sleep(usecs(1));
Duration t2 = sw.peek();
assert(t2 > t1);

Thread.sleep(usecs(1));
sw.stop();

Duration t3 = sw.peek();
assert(t3 > t2);
Duration t4 = sw.peek();
assert(t3 == t4);

sw.start();
Thread.sleep(usecs(1));

Duration t5 = sw.peek();
assert(t5 > t4);

// If stopping or resetting the StopWatch is not required, then
// MonoTime can easily be used by itself without StopWatch.
auto before = MonoTime.currTime;
// do stuff...
auto timeElapsed = MonoTime.currTime - before;
StopWatch
(
std.datetime.stopwatch.StopWatch std.datetime.stopwatch.StopWatch.this(std.typecons.Flag!"autoStart" autostart) nothrow @nogc ref @safe

Constructs a StopWatch. Whether it starts immediately depends on the AutoStart argument.

If StopWatch.init is used, then the constructed StopWatch isn't running (and can't be, since no constructor ran).

Examples

import core.thread : Thread;

{
    auto sw = StopWatch(AutoStart.yes);
    assert(sw.running);
    Thread.sleep(usecs(1));
    assert(sw.peek() > Duration.zero);
}
{
    auto sw = StopWatch(AutoStart.no);
    assert(!sw.running);
    Thread.sleep(usecs(1));
    assert(sw.peek() == Duration.zero);
}
{
    StopWatch sw;
    assert(!sw.running);
    Thread.sleep(usecs(1));
    assert(sw.peek() == Duration.zero);
}

assert(StopWatch.init == StopWatch(AutoStart.no));
assert(StopWatch.init != StopWatch(AutoStart.yes));
AutoStart
.
(enum value) std.typecons.Flag!"autoStart".yes = true
yes
);
if (
(parameter) bool pooled
pooled
)
foreach (
(foreach variable) ulong i
i
,
(parameter) string path
path
;
(parameter) string[] paths
paths
.
std.parallelism.ParallelForeach!(string[]) std.parallelism.parallel!(string[])(string[] range, ulong workUnitSize) @safe

Convenience functions that forwards to taskPool.parallel``. The purpose of these is to make parallel foreach less verbose and more readable.

Example

// Find the logarithm of every number from
// 1 to 1_000_000 in parallel, using the
// default TaskPool instance.
auto logs = new double[1_000_000];

foreach (i, ref elem; parallel(logs))
{
    elem = log(i + 1.0);
}
parallel
(4))
(local variable) font_libraries_font_scan_timing.FaceRecord[][] records
records
[
(foreach variable) ulong i
i
] =
font_libraries_font_scan_timing.FaceRecord[] font_libraries_font_scan_timing.scanFile(string path) @trusted
scanFile
(
(local variable) string path
path
);
else foreach (
(parameter) ulong i
i
,
(parameter) string path
path
;
(parameter) string[] paths
paths
)
(local variable) font_libraries_font_scan_timing.FaceRecord[][] records
records
[
(local variable) ulong i
i
] =
font_libraries_font_scan_timing.FaceRecord[] font_libraries_font_scan_timing.scanFile(string path) @trusted
scanFile
(
(local variable) string path
path
);
const
(local variable) const(double) ms
ms
=
(local variable) std.datetime.stopwatch.StopWatch sw
sw
.
core.time.Duration std.datetime.stopwatch.StopWatch.peek() const nothrow @nogc @safe

Peek at the amount of time that the StopWatch has been running.

This does not include any time during which the StopWatch was stopped but does include all of the time that it was running and not just the time since it was started last.

Calling reset will reset this to Duration.zero.

Examples

import core.thread : Thread;

auto sw = StopWatch(AutoStart.no);
assert(sw.peek() == Duration.zero);
sw.start();

Thread.sleep(usecs(1));
assert(sw.peek() >= usecs(1));

Thread.sleep(usecs(1));
assert(sw.peek() >= usecs(2));

sw.stop();
immutable stopped = sw.peek();
Thread.sleep(usecs(1));
assert(sw.peek() == stopped);

sw.start();
Thread.sleep(usecs(1));
assert(sw.peek() > stopped);
peek
.
long core.time.Duration.total!"usecs"() const pure nothrow @nogc @property @safe

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

Examples

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

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

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

assert(dur!"nsecs"(2007).total!"hnsecs" == 20);
assert(dur!"nsecs"(2007).total!"nsecs" == 2000);
total
!"usecs" / 1000.0;
auto
(local variable) font_libraries_font_scan_timing.FaceRecord[] faces
faces
=
(local variable) font_libraries_font_scan_timing.FaceRecord[][] records
records
.
std.algorithm.iteration.joiner!(FaceRecord[][]).Result std.algorithm.iteration.joiner!(font_libraries_font_scan_timing.FaceRecord[][])(font_libraries_font_scan_timing.FaceRecord[][] r) pure nothrow @nogc @safe

Examples

import std.algorithm.comparison : equal;
import std.range : repeat;

assert([""].joiner.equal(""));
assert(["", ""].joiner.equal(""));
assert(["", "abc"].joiner.equal("abc"));
assert(["abc", ""].joiner.equal("abc"));
assert(["abc", "def"].joiner.equal("abcdef"));
assert(["Mary", "has", "a", "little", "lamb"].joiner.equal("Maryhasalittlelamb"));
assert("abc".repeat(3).joiner.equal("abcabcabc"));

joiner allows in-place mutation!

import std.algorithm.comparison : equal;
auto a = [ [1, 2, 3], [42, 43] ];
auto j = joiner(a);
j.front = 44;
assert(a == [ [44, 2, 3], [42, 43] ]);
assert(equal(j, [44, 2, 3, 42, 43]));

insert characters fully lazily into a string

import std.algorithm.comparison : equal;
import std.range : chain, cycle, iota, only, retro, take, zip;
import std.format : format;

static immutable number = "12345678";
static immutable delimiter = ",";
auto formatted = number.retro
    .zip(3.iota.cycle.take(number.length))
    .map!(z => chain(z[0].only, z[1] == 2 ? delimiter : null))
    .joiner
    .retro;
static immutable expected = "12,345,678";
assert(formatted.equal(expected));

joiner can be bidirectional

import std.algorithm.comparison : equal;
import std.range : retro;

auto a = [[1, 2, 3], [4, 5]];
auto j = a.joiner;
j.back = 44;
assert(a == [[1, 2, 3], [4, 44]]);
assert(equal(j.retro, [44, 4, 3, 2, 1]));
joiner
.
font_libraries_font_scan_timing.FaceRecord[] std.array.array!(std.algorithm.iteration.joiner!(FaceRecord[][]).Result)(std.algorithm.iteration.joiner!(FaceRecord[][]).Result r) pure nothrow @safe

Allocates an array and initializes it with copies of the elements of range r.

Narrow strings are handled as follows:

  • If autodecoding is turned on (default), then they are handled as a separate overload.

  • If autodecoding is turned off, then this is equivalent to duplicating the array.

@paramr range (or aggregate with opApply function) whose elements are copied into the allocated array@returnsallocated and initialized array
array
;
void std.stdio.writefln!(char, string, ulong, ulong, const(double), double, ulong, ulong)(in char[] fmt, string __param_1, ulong __param_2, ulong __param_3, const(double) __param_4, double __param_5, ulong __param_6, ulong __param_7) @safe

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

writefln
("%-16s %5d files %5d faces %8.1f ms %6.1f us/file %4d families %d code points",
(parameter) string label
label
,
(parameter) string[] paths
paths
.
(field) ulong string[].length
length
,
(local variable) font_libraries_font_scan_timing.FaceRecord[] faces
faces
.
(field) ulong font_libraries_font_scan_timing.FaceRecord[].length
length
,
(local variable) const(double) ms
ms
,
(local variable) const(double) ms
ms
* 1000 /
(parameter) string[] paths
paths
.
(field) ulong string[].length
length
,
(local variable) font_libraries_font_scan_timing.FaceRecord[] faces
faces
.
font_libraries_font_scan_timing.pass.MapResult!(__lambda_L195_C20, FaceRecord[]) font_libraries_font_scan_timing.pass.map!(font_libraries_font_scan_timing.FaceRecord[])(font_libraries_font_scan_timing.FaceRecord[] r) pure nothrow @nogc @safe

Implements the homonym function (also known as transform) present in many languages of functional flavor. The call ``map!(fun)(range) returns a range of which elements are obtained by applying fun(a) left to right for all elements a in range. The original ranges are not changed. Evaluation is done lazily.

Examples

import std.algorithm.comparison : equal;
import std.range : chain, only;
auto squares =
    chain(only(1, 2, 3, 4), only(5, 6)).map!(a => a * a);
assert(equal(squares, only(1, 4, 9, 16, 25, 36)));

Multiple functions can be passed to map. In that case, the element type of map is a tuple containing one element for each function.

auto sums = [2, 4, 6, 8];
auto products = [1, 4, 9, 16];

size_t i = 0;
foreach (result; [ 1, 2, 3, 4 ].map!("a + a", "a * a"))
{
    assert(result[0] == sums[i]);
    assert(result[1] == products[i]);
    ++i;
}

You may alias map with some function(s) to a symbol and use it separately:

import std.algorithm.comparison : equal;
import std.conv : to;

alias stringize = map!(to!string);
assert(equal(stringize([ 1, 2, 3, 4 ]), [ "1", "2", "3", "4" ]));
@paramfun one or more transformation functions@seeMap (higher-order function)@paramr an input range@returnsA range with each fun applied to all the elements. If there is more than one fun, the element type will be Tuple containing one element for each fun.
map
!(f => f.family).
string[] std.array.array!(font_libraries_font_scan_timing.pass.MapResult!(__lambda_L195_C20, FaceRecord[]))(font_libraries_font_scan_timing.pass.MapResult!(__lambda_L195_C20, FaceRecord[]) r) pure @safe

Allocates an array and initializes it with copies of the elements of range r.

Narrow strings are handled as follows:

  • If autodecoding is turned on (default), then they are handled as a separate overload.

  • If autodecoding is turned off, then this is equivalent to duplicating the array.

@paramr range (or aggregate with opApply function) whose elements are copied into the allocated array@returnsallocated and initialized array
array
.
std.range.SortedRange!(string[], "a < b", SortedRangeOptions.assumeSorted) std.algorithm.sorting.sort!("a < b", SwapStrategy.unstable, string[])(string[] r) pure nothrow @nogc @safe

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

Performs O(r.length * log(r.length)) evaluations of less. If less involves expensive computations on the sort key, it may be worthwhile to use schwartzSort instead.

Stable sorting requires hasAssignableElements!Range to be true.

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

Preconditions

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

Algorithms

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

Examples

int[] array = [ 1, 2, 3, 4 ];

// sort in descending order
array.sort!("a > b");
assert(array == [ 4, 3, 2, 1 ]);

// sort in ascending order
array.sort();
assert(array == [ 1, 2, 3, 4 ]);

// sort with reusable comparator and chain
alias myComp = (x, y) => x > y;
assert(array.sort!(myComp).release == [ 4, 3, 2, 1 ]);
// Showcase stable sorting
import std.algorithm.mutation : SwapStrategy;
string[] words = [ "aBc", "a", "abc", "b", "ABC", "c" ];
sort!("toUpper(a) < toUpper(b)", SwapStrategy.stable)(words);
assert(words == [ "a", "aBc", "abc", "ABC", "b", "c" ]);
// Sorting floating-point numbers in presence of NaN
double[] numbers = [-0.0, 3.0, -2.0, double.nan, 0.0, -double.nan];

import std.algorithm.comparison : equal;
import std.math.operations : cmp;
import std.math.traits : isIdentical;

sort!((a, b) => cmp(a, b) < 0)(numbers);

double[] sorted = [-double.nan, -2.0, -0.0, 0.0, 3.0, double.nan];
assert(numbers.equal!isIdentical(sorted));
@paramless The predicate to sort by.@paramss The swapping strategy to use.@paramr The range to sort.@returnsThe initial range wrapped as a SortedRange with the predicate binaryFun!less.@see

assumeSorted

SortedRange

SwapStrategy

binaryFun

sort
.
std.algorithm.iteration.UniqResult!(binaryFun, SortedRange!(string[], "a < b", SortedRangeOptions.assumeSorted)) std.algorithm.iteration.uniq!("a == b", std.range.SortedRange!(string[], "a < b", SortedRangeOptions.assumeSorted))(std.range.SortedRange!(string[], "a < b", SortedRangeOptions.assumeSorted) r) pure nothrow @nogc @safe

Lazily iterates unique consecutive elements of the given range, which is assumed to be sorted (functionality akin to the uniq system utility). Equivalence of elements is assessed by using the predicate pred, by default "a == b". The predicate is passed to binaryFun, and can either accept a string, or any callable that can be executed via pred(element, element). If the given range is bidirectional, uniq also yields a bidirectional range.

Examples

import std.algorithm.comparison : equal;
import std.algorithm.mutation : copy;

int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ];
assert(equal(uniq(arr), [ 1, 2, 3, 4, 5 ][]));

// Filter duplicates in-place using copy
arr.length -= arr.uniq().copy(arr).length;
assert(arr == [ 1, 2, 3, 4, 5 ]);

// Note that uniqueness is only determined consecutively; duplicated
// elements separated by an intervening different element will not be
// eliminated:
assert(equal(uniq([ 1, 1, 2, 1, 1, 3, 1]), [1, 2, 1, 3, 1]));
@parampred Predicate for determining equivalence between range elements.@paramr An input range of elements to filter.@returnsAn input range of consecutively unique elements in the original range. If r is also a forward range or bidirectional range, the returned range will be likewise.
uniq
.
ulong std.range.primitives.walkLength!(std.algorithm.iteration.UniqResult!(binaryFun, SortedRange!(string[], "a < b", SortedRangeOptions.assumeSorted)))(std.algorithm.iteration.UniqResult!(binaryFun, SortedRange!(string[], "a < b", SortedRangeOptions.assumeSorted)) range) pure nothrow @nogc @safe

This is a best-effort implementation of length for any kind of range.

If hasLength!Range, simply returns ``range.length without checking upTo (when specified).

Otherwise, walks the range through its length and returns the number of elements seen. Performes O(n) evaluations of range`.empty` and range.popFront(), where n is the effective length of range.

The upTo parameter is useful to "cut the losses" in case the interest is in seeing whether the range has at least some number of elements. If the parameter upTo is specified, stops if upTo steps have been taken and returns upTo.

Infinite ranges are compatible, provided the parameter upTo is specified, in which case the implementation simply returns upTo.

walkLength
,
(local variable) font_libraries_font_scan_timing.FaceRecord[] faces
faces
.
font_libraries_font_scan_timing.pass.MapResult!(__lambda_L196_C20, FaceRecord[]) font_libraries_font_scan_timing.pass.map!(font_libraries_font_scan_timing.FaceRecord[])(font_libraries_font_scan_timing.FaceRecord[] r) pure nothrow @nogc @safe

Implements the homonym function (also known as transform) present in many languages of functional flavor. The call ``map!(fun)(range) returns a range of which elements are obtained by applying fun(a) left to right for all elements a in range. The original ranges are not changed. Evaluation is done lazily.

Examples

import std.algorithm.comparison : equal;
import std.range : chain, only;
auto squares =
    chain(only(1, 2, 3, 4), only(5, 6)).map!(a => a * a);
assert(equal(squares, only(1, 4, 9, 16, 25, 36)));

Multiple functions can be passed to map. In that case, the element type of map is a tuple containing one element for each function.

auto sums = [2, 4, 6, 8];
auto products = [1, 4, 9, 16];

size_t i = 0;
foreach (result; [ 1, 2, 3, 4 ].map!("a + a", "a * a"))
{
    assert(result[0] == sums[i]);
    assert(result[1] == products[i]);
    ++i;
}

You may alias map with some function(s) to a symbol and use it separately:

import std.algorithm.comparison : equal;
import std.conv : to;

alias stringize = map!(to!string);
assert(equal(stringize([ 1, 2, 3, 4 ]), [ "1", "2", "3", "4" ]));
@paramfun one or more transformation functions@seeMap (higher-order function)@paramr an input range@returnsA range with each fun applied to all the elements. If there is more than one fun, the element type will be Tuple containing one element for each fun.
map
!(f => ulong(f.codepoints)).
ulong std.algorithm.iteration.sum!(font_libraries_font_scan_timing.pass.MapResult!(__lambda_L196_C20, FaceRecord[]))(font_libraries_font_scan_timing.pass.MapResult!(__lambda_L196_C20, FaceRecord[]) r) pure nothrow @nogc @safe

Sums elements of r, which must be a finite input range. Although conceptually sum`(`r`)` is equivalent to `fold`!((a, b) => a + b)(`r`, 0), sum`` uses specialized algorithms to maximize accuracy, as follows.

  • If ElementType!R is a floating-point type and R is a random-access range with length and slicing, then sum uses the pairwise summation algorithm.

  • If ElementType!R is a floating-point type and R is a finite input range (but not a random-access range with slicing), then sum uses the Kahan summation algorithm.

  • In all other cases, a simple element by element addition is done.

For floating point inputs, calculations are made in spec/type, Types, real precision for real inputs and in double precision otherwise (Note this is a special case that deviates from fold's behavior, which would have kept float precision for a float range). For all other types, the calculations are done in the same type obtained from from adding two elements of the range, which may be a different type from the elements themselves (for example, in case of integral promotion).

A seed may be passed to sum. Not only will this seed be used as an initial value, but its type will override all the above, and determine the algorithm and precision used for summation. If a seed is not passed, one is created with the value of typeof(r.front + r.front)(0), or typeof(r.front + r.front).zero if no constructor exists that takes an int.

Note that these specialized summing algorithms execute more primitive operations than vanilla summation. Therefore, if in certain cases maximum speed is required at expense of precision, one can use fold!((a, b) => a + b)(r, 0), which is not specialized for summation.

@paramseed the initial value of the summation@paramr a finite input range@returnsThe sum of all the elements in the range r.
sum
);
}
(alias) object.string = string
string
[]
string[] font_libraries_font_scan_timing.fontPaths(string[] args)
fontPaths
(
(alias) object.string = string
string
[]
(parameter) string[] args
args
)
{
(alias) object.string = string
string
(local variable) string listing
listing
;
if (
(parameter) string[] args
args
.
(field) ulong string[].length
length
> 1 &&
bool std.file.exists!string(string name) nothrow @nogc @safe

Determine whether the given file (or directory) exists.

@paramname string or range of characters representing the file name@returnstrue if the file name specified as input exists
exists
(
(parameter) string[] args
args
[1]))
(local variable) string listing
listing
=
string std.file.readText!(string, string)(ref 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
(
(parameter) string[] args
args
[1]);
else try { auto
(local variable) std.typecons.Tuple!(int, "status", string, "output") r
r
=
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) @safe

Executes 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.)

@paramargs An array which contains the program name as the zeroth element and any command-line arguments in the following elements. (See spawnProcess for details.)@paramprogram The program name, without command-line arguments. (See spawnProcess for details.)@paramcommand A shell command which is passed verbatim to the command interpreter. (See spawnShell for details.)@paramenv Additional environment variables for the child process. (See spawnProcess for details.)@paramconfig Flags that control process creation. See Config for an overview of available flags, and note that the retainStd... flags have no effect in this function.@parammaxOutput The maximum number of bytes of output that should be captured.@paramworkDir The working directory for the new process. By default the child process inherits the parent's working directory.@paramshellPath The path to the shell to use to run the specified program. By default this is nativeShell.@returnsAn std.typecons.Tuple!(int, "status", string, "output").@throws

ProcessException on failure to start the process.

StdioException on failure to capture output.

execute
(["fc-list", ":", "file"]);
if (
(local variable) std.typecons.Tuple!(int, "status", string, "output") r
r
.status == 0)
(local variable) string listing
listing
=
(local variable) std.typecons.Tuple!(int, "status", string, "output") r
r
.output;
} catch (
(class) object.Exception

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

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

Examples

bool gotCaught;
try
{
    throw new Exception("msg");
}
catch (Exception e)
{
    gotCaught = true;
    assert(e.msg == "msg");
}
assert(gotCaught);
Exception
) {}
return
(local variable) string listing
listing
.
std.string.LineSplitter!(Flag.no, string) std.string.lineSplitter!(Flag.no, immutable(char))(string r) pure nothrow @nogc @safe

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

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

Adheres to Unicode 7.0.

Does not allocate memory.

Examples

import std.array : array;

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

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

Implements the homonym function (also known as transform) present in many languages of functional flavor. The call ``map!(fun)(range) returns a range of which elements are obtained by applying fun(a) left to right for all elements a in range. The original ranges are not changed. Evaluation is done lazily.

Examples

import std.algorithm.comparison : equal;
import std.range : chain, only;
auto squares =
    chain(only(1, 2, 3, 4), only(5, 6)).map!(a => a * a);
assert(equal(squares, only(1, 4, 9, 16, 25, 36)));

Multiple functions can be passed to map. In that case, the element type of map is a tuple containing one element for each function.

auto sums = [2, 4, 6, 8];
auto products = [1, 4, 9, 16];

size_t i = 0;
foreach (result; [ 1, 2, 3, 4 ].map!("a + a", "a * a"))
{
    assert(result[0] == sums[i]);
    assert(result[1] == products[i]);
    ++i;
}

You may alias map with some function(s) to a symbol and use it separately:

import std.algorithm.comparison : equal;
import std.conv : to;

alias stringize = map!(to!string);
assert(equal(stringize([ 1, 2, 3, 4 ]), [ "1", "2", "3", "4" ]));
@paramfun one or more transformation functions@seeMap (higher-order function)@paramr an input range@returnsA range with each fun applied to all the elements. If there is more than one fun, the element type will be Tuple containing one element for each fun.
map
!(l => l.split(":")[0].strip)
.
font_libraries_font_scan_timing.fontPaths.FilterResult!(__lambda_L214_C18, MapResult!(__lambda_L213_C15, LineSplitter!(Flag.no, string))) font_libraries_font_scan_timing.fontPaths.filter!(font_libraries_font_scan_timing.fontPaths.MapResult!(__lambda_L213_C15, LineSplitter!(Flag.no, string)))(font_libraries_font_scan_timing.fontPaths.MapResult!(__lambda_L213_C15, LineSplitter!(Flag.no, string)) range) pure nothrow @nogc @safe

filter`!(predicate)(`range`)` returns a new `range` containing only elements `x` in range`` for which predicate(x) returns true.

The predicate is passed to unaryFun, and can be either a string, or any callable that can be executed via pred(element).

Examples

import std.algorithm.comparison : equal;
import std.math.operations : isClose;
import std.range;

int[] arr = [ 1, 2, 3, 4, 5 ];

// Filter below 3
auto small = filter!(a => a < 3)(arr);
assert(equal(small, [ 1, 2 ]));

// Filter again, but with Uniform Function Call Syntax (UFCS)
auto sum = arr.filter!(a => a < 3);
assert(equal(sum, [ 1, 2 ]));

// In combination with chain() to span multiple ranges
int[] a = [ 3, -2, 400 ];
int[] b = [ 100, -101, 102 ];
auto r = chain(a, b).filter!(a => a > 0);
assert(equal(r, [ 3, 400, 100, 102 ]));

// Mixing convertible types is fair game, too
double[] c = [ 2.5, 3.0 ];
auto r1 = chain(c, a, b).filter!(a => cast(int) a != a);
assert(isClose(r1, [ 2.5 ]));
@parampredicate Function to apply to each element of range@returnsAn input range that contains the filtered elements. If range is at least a forward range, the return value of filter will also be a forward range.@seeFilter (higher-order function), filterBidirectional@paramrange An input range of elements@returnsA range containing only elements x in range for which predicate(x) returns true.
filter
!(p => p.endsWith(".ttf", ".otf", ".ttc", ".otc") && exists(p))
.
string[] std.array.array!(font_libraries_font_scan_timing.fontPaths.FilterResult!(__lambda_L214_C18, MapResult!(__lambda_L213_C15, LineSplitter!(Flag.no, string))))(font_libraries_font_scan_timing.fontPaths.FilterResult!(__lambda_L214_C18, MapResult!(__lambda_L213_C15, LineSplitter!(Flag.no, string))) r) @safe

Allocates an array and initializes it with copies of the elements of range r.

Narrow strings are handled as follows:

  • If autodecoding is turned on (default), then they are handled as a separate overload.

  • If autodecoding is turned off, then this is equivalent to duplicating the array.

@paramr range (or aggregate with opApply function) whose elements are copied into the allocated array@returnsallocated and initialized array
array
.
std.range.SortedRange!(string[], "a < b", SortedRangeOptions.assumeSorted) std.algorithm.sorting.sort!("a < b", SwapStrategy.unstable, string[])(string[] r) pure nothrow @nogc @safe

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

Performs O(r.length * log(r.length)) evaluations of less. If less involves expensive computations on the sort key, it may be worthwhile to use schwartzSort instead.

Stable sorting requires hasAssignableElements!Range to be true.

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

Preconditions

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

Algorithms

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

Examples

int[] array = [ 1, 2, 3, 4 ];

// sort in descending order
array.sort!("a > b");
assert(array == [ 4, 3, 2, 1 ]);

// sort in ascending order
array.sort();
assert(array == [ 1, 2, 3, 4 ]);

// sort with reusable comparator and chain
alias myComp = (x, y) => x > y;
assert(array.sort!(myComp).release == [ 4, 3, 2, 1 ]);
// Showcase stable sorting
import std.algorithm.mutation : SwapStrategy;
string[] words = [ "aBc", "a", "abc", "b", "ABC", "c" ];
sort!("toUpper(a) < toUpper(b)", SwapStrategy.stable)(words);
assert(words == [ "a", "aBc", "abc", "ABC", "b", "c" ]);
// Sorting floating-point numbers in presence of NaN
double[] numbers = [-0.0, 3.0, -2.0, double.nan, 0.0, -double.nan];

import std.algorithm.comparison : equal;
import std.math.operations : cmp;
import std.math.traits : isIdentical;

sort!((a, b) => cmp(a, b) < 0)(numbers);

double[] sorted = [-double.nan, -2.0, -0.0, 0.0, 3.0, double.nan];
assert(numbers.equal!isIdentical(sorted));
@paramless The predicate to sort by.@paramss The swapping strategy to use.@paramr The range to sort.@returnsThe initial range wrapped as a SortedRange with the predicate binaryFun!less.@see

assumeSorted

SortedRange

SwapStrategy

binaryFun

sort
.
std.algorithm.iteration.UniqResult!(binaryFun, SortedRange!(string[], "a < b", SortedRangeOptions.assumeSorted)) std.algorithm.iteration.uniq!("a == b", std.range.SortedRange!(string[], "a < b", SortedRangeOptions.assumeSorted))(std.range.SortedRange!(string[], "a < b", SortedRangeOptions.assumeSorted) r) pure nothrow @nogc @safe

Lazily iterates unique consecutive elements of the given range, which is assumed to be sorted (functionality akin to the uniq system utility). Equivalence of elements is assessed by using the predicate pred, by default "a == b". The predicate is passed to binaryFun, and can either accept a string, or any callable that can be executed via pred(element, element). If the given range is bidirectional, uniq also yields a bidirectional range.

Examples

import std.algorithm.comparison : equal;
import std.algorithm.mutation : copy;

int[] arr = [ 1, 2, 2, 2, 2, 3, 4, 4, 4, 5 ];
assert(equal(uniq(arr), [ 1, 2, 3, 4, 5 ][]));

// Filter duplicates in-place using copy
arr.length -= arr.uniq().copy(arr).length;
assert(arr == [ 1, 2, 3, 4, 5 ]);

// Note that uniqueness is only determined consecutively; duplicated
// elements separated by an intervening different element will not be
// eliminated:
assert(equal(uniq([ 1, 1, 2, 1, 1, 3, 1]), [1, 2, 1, 3, 1]));
@parampred Predicate for determining equivalence between range elements.@paramr An input range of elements to filter.@returnsAn input range of consecutively unique elements in the original range. If r is also a forward range or bidirectional range, the returned range will be likewise.
uniq
.
string[] std.array.array!(std.algorithm.iteration.UniqResult!(binaryFun, SortedRange!(string[], "a < b", SortedRangeOptions.assumeSorted)))(std.algorithm.iteration.UniqResult!(binaryFun, SortedRange!(string[], "a < b", SortedRangeOptions.assumeSorted)) r) pure nothrow @safe

Allocates an array and initializes it with copies of the elements of range r.

Narrow strings are handled as follows:

  • If autodecoding is turned on (default), then they are handled as a separate overload.

  • If autodecoding is turned off, then this is equivalent to duplicating the array.

@paramr range (or aggregate with opApply function) whose elements are copied into the allocated array@returnsallocated and initialized array
array
;
} int
int D main(string[] args)
main
(
(alias) object.string = string
string
[]
(parameter) string[] args
args
)
{ auto
(local variable) string[] paths
paths
=
string[] font_libraries_font_scan_timing.fontPaths(string[] args)
fontPaths
(
(parameter) string[] args
args
);
if (!
(local variable) string[] paths
paths
.
(field) ulong string[].length
length
)
{
void std.stdio.writeln!string(string __param_0) @safe

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

Example

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

import std.stdio;

void main()
{
    string line;

    for (size_t count = 0; (line = readln) !is null; count++)
    {
         writeln("Input ", count, ": ", line);
    }
}
@paramargs the items to write to stdout@throwsIn case of an I/O error, throws an StdioException.
writeln
("SKIP: no font files found (pass a list, or install fontconfig)");
return 0; }
void font_libraries_font_scan_timing.pass(string label, string[] paths, bool pooled)
pass
("first, serial",
(local variable) string[] paths
paths
, false);
void font_libraries_font_scan_timing.pass(string label, string[] paths, bool pooled)
pass
("warm, serial",
(local variable) string[] paths
paths
, false);
void font_libraries_font_scan_timing.pass(string label, string[] paths, bool pooled)
pass
("warm, 4 workers",
(local variable) string[] paths
paths
, true);
void font_libraries_font_scan_timing.pass(string label, string[] paths, bool pooled)
pass
("warm, 4 workers",
(local variable) string[] paths
paths
, true);
return 0; }