mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 14:40:30 +03:00
Merge pull request #4845 from MartinNowak/merge_stable
Merge remote-tracking branch 'upstream/stable' into merge_stable
This commit is contained in:
commit
df34e4266c
11 changed files with 108 additions and 554 deletions
494
changelog.dd
494
changelog.dd
|
@ -1,503 +1,13 @@
|
||||||
Ddoc
|
Ddoc
|
||||||
|
|
||||||
$(COMMENT Pending changelog for 2.072. This will get copied to dlang.org and
|
$(COMMENT Pending changelog for 2.073. This will get copied to dlang.org and
|
||||||
cleared when master gets merged into stable prior to 2.072.
|
cleared when master gets merged into stable.
|
||||||
)
|
)
|
||||||
|
|
||||||
$(BUGSTITLE Library Changes,
|
$(BUGSTITLE Library Changes,
|
||||||
$(LI $(RELATIVE_LINK2 std-digest-murmurhash, Implementation of MurmurHash
|
|
||||||
digest.))
|
|
||||||
$(LI $(RELATIVE_LINK2 process, Process creation in `std.process` was sped up
|
|
||||||
on Posix.))
|
|
||||||
$(LI $(RELATIVE_LINK2 std-algorithm-iteration-cumulativeFold,
|
|
||||||
`algorithm.iteration.cumulativeFold` was added.))
|
|
||||||
$(LI $(RELATIVE_LINK2 padLeft-padRight, `std.range.padLeft` and
|
|
||||||
`std.range.padRight` were added.))
|
|
||||||
$(LI $(RELATIVE_LINK2 regex-multiple-patterns, `std.regex.regex` now
|
|
||||||
supports matching multiple patterns in one go.))
|
|
||||||
$(LI $(RELATIVE_LINK2 regex-with-matches, `std.regex.splitter` now
|
|
||||||
supports keeping the pattern matches in the resulting range.))
|
|
||||||
$(LI $(RELATIVE_LINK2 optimization, `findLocalMin` was added to `std.numeric`.))
|
|
||||||
$(LI $(RELATIVE_LINK2 slice_ptr, `ptr` property and public constructor were
|
|
||||||
added to `std.experimental.ndslice.slice.Slice`.))
|
|
||||||
$(LI $(RELATIVE_LINK2 slice_toHash, `toHash` method was
|
|
||||||
added to `std.experimental.ndslice.slice.Slice`.))
|
|
||||||
$(LI $(RELATIVE_LINK2 slice_alloc, `slice`, `shape`, `ndarray`, and other
|
|
||||||
utilities were added to `std.experimental.ndslice.slice`.))
|
|
||||||
$(LI $(RELATIVE_LINK2 slice_as, `as` lazy tensor was added to
|
|
||||||
`std.experimental.ndslice.slice`.))
|
|
||||||
$(LI $(RELATIVE_LINK2 slice_iota, `iotaSlice` lazy tensor was added to
|
|
||||||
`std.experimental.ndslice.selection`.))
|
|
||||||
$(LI $(RELATIVE_LINK2 slice_index, `indexSlice` lazy tensor was added to
|
|
||||||
`std.experimental.ndslice.selection`.))
|
|
||||||
$(LI $(RELATIVE_LINK2 slice_repeat, `repeatSlice` lazy tensor was added to
|
|
||||||
`std.experimental.ndslice.selection`.))
|
|
||||||
$(LI $(RELATIVE_LINK2 slice_map, `mapSlice` lazy tensor was added to
|
|
||||||
`std.experimental.ndslice.selection`.))
|
|
||||||
$(LI $(RELATIVE_LINK2 slice_mio, partial support for Math Index Order
|
|
||||||
was added to `std.experimental.ndslice.slice.Slice`.))
|
|
||||||
$(LI $(RELATIVE_LINK2 mutation, `std.algorithm.mutation.swapAt` was
|
|
||||||
exposed))
|
|
||||||
$(LI $(RELATIVE_LINK2 iota-length-size_t, `std.range.iota's `.length`
|
|
||||||
property is fixed to `size_t` instead of the type being iterated))
|
|
||||||
$(LI $(REF isNumber, std,uni) and $(REF isPunctuation, std,uni) now use a separate,
|
|
||||||
optimized path for ASCII inputs.)
|
|
||||||
$(LI $(REF isAlphaNum, std,uni), which is analogous to $(REF isAlphaNum, std,ascii)
|
|
||||||
was added.)
|
|
||||||
$(LI $(REF regex, std,regex) now supports inline comments with (?#...) syntax.)
|
|
||||||
$(LI std.regex had numerous optimization applied, compile-time $(REF ctRegex, std,regex)
|
|
||||||
should now be generally faster then the run-time version.)
|
|
||||||
$(LI $(REF moveAt, std,range,primitives) accepts only `size_t` for its index
|
|
||||||
arguments.)
|
|
||||||
$(LI $(REF isStrictlyMonotonic, std,algorithm,sorting) which doesn't allow
|
|
||||||
equal values was added.)
|
|
||||||
$(LI $(REF readLink, std,file) and $(REF symlink, std,file) have been
|
|
||||||
rangified.)
|
|
||||||
$(LI All overloads of `std.conv.toImpl` has been made private. Please use
|
|
||||||
$(REF to, std,conv) instead.)
|
|
||||||
$(LI $(RELATIVE_LINK2 min-max-element,
|
|
||||||
`std.algorithm.searching.{min,max}Element` for ranges have been added.))
|
|
||||||
$(LI $(REF Ternary, std,typecons) was added to represent three valued
|
|
||||||
logic.)
|
|
||||||
$(LI $(RELATIVE_LINK2 quantize, Added `std.math.quantize`, for rounding to
|
|
||||||
the nearest multiple of some number.))
|
|
||||||
$(LI $(RELATIVE_LINK2 traits, Three new traits were added to `std.traits`.))
|
|
||||||
$(LI Wrong
|
|
||||||
$(LINK2 $(ROOT_DIR)spec/function.html#trusted-functions, `@trusted`)
|
|
||||||
attributes have been
|
|
||||||
removed from $(MREF etc,c,curl) functions
|
|
||||||
$(REF_ALTTEXT `curl_easy_escape`, curl_easy_escape, etc,c,curl),
|
|
||||||
$(REF_ALTTEXT `curl_escape`, curl_escape, etc,c,curl),
|
|
||||||
$(REF_ALTTEXT `curl_easy_unescape`, curl_easy_unescape, etc,c,curl), and
|
|
||||||
$(REF_ALTTEXT `curl_unescape`, curl_unescape, etc,c,curl).)
|
|
||||||
$(LI $(RELATIVE_LINK2 generate, `std.range.generate` fixed to be a proper
|
|
||||||
range.))
|
|
||||||
$(LI $(MREF std,numeric) no longer uses `enforce` for verifying
|
|
||||||
contract preconditions.)
|
|
||||||
$(LI $(RELATIVE_LINK2 headconst, `Final` was added to
|
|
||||||
`std.experimental.typecons`))
|
|
||||||
$(LI $(RELATIVE_LINK2 inner-class, `std.traits.isInnerClass` was added to
|
|
||||||
identify nested classes with an accessible `outer` pointer))
|
|
||||||
$(LI $(RELATIVE_LINK2 emplace-inner-class, `std.conv.emplace` no longer allows
|
|
||||||
to emplace classes directly nested inside other classes without specifying a
|
|
||||||
suitable `outer` pointer))
|
|
||||||
)
|
)
|
||||||
|
|
||||||
$(BUGSTITLE Library Changes,
|
$(BUGSTITLE Library Changes,
|
||||||
|
|
||||||
$(LI $(LNAME2 std-digest-murmurhash, Implementation of `std.digest.murmurhash`).
|
|
||||||
$(P $(MREF std,digest,murmurhash) has been added. MurmurHash is a
|
|
||||||
non-cryptographic hash function suitable for general hash-based lookup. It
|
|
||||||
is optimized for x86 architectures.
|
|
||||||
)
|
|
||||||
------
|
|
||||||
// Computing the 32-bits hash value of an int array using the convenient digest template.
|
|
||||||
import std.digest.murmurhash;
|
|
||||||
|
|
||||||
ubyte[4] hashed = digest!MurmurHash3_32_opt32([1, 2, 3, 4]);
|
|
||||||
------
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 process, Process creation in `std.process` was sped up on Posix.)
|
|
||||||
$(P Previously, Posix systems would attempt to close every file descriptor
|
|
||||||
from 3 to the maximum file descriptor number if `inheritFDs` was not
|
|
||||||
specified with `spawnProcess`, `pipeProcess`, etc.
|
|
||||||
$(MREF std,process) now uses `poll()` to determine which
|
|
||||||
descriptors need closing.
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 std-algorithm-iteration-cumulativeFold,
|
|
||||||
`algorithm.iteration.cumulativeFold` was added.)
|
|
||||||
|
|
||||||
$(P $(REF cumulativeFold, std,algorithm,iteration) returns the successive
|
|
||||||
reduced values of an input range.)
|
|
||||||
------
|
|
||||||
assert([1, 2, 3, 4, 5].cumulativeFold!((a, b) => a + b).array == [1, 3, 6, 10, 15]);
|
|
||||||
assert([1, 2, 3].cumulativeFold!((a, b) => a + b)(100).array == [101, 103, 106]);
|
|
||||||
------
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 padLeft-padRight, `std.range.padLeft` and `std.range.padRight`
|
|
||||||
were added.)
|
|
||||||
$(P $(REF padLeft, std,range) and $(REF padRight, std,range) are functions for
|
|
||||||
padding ranges to a specified length using the given element.
|
|
||||||
)
|
|
||||||
|
|
||||||
-------
|
|
||||||
import std.range;
|
|
||||||
import std.algorithm.comparison;
|
|
||||||
|
|
||||||
assert([1, 2, 3, 4, 5].padLeft(0, 7).equal([0, 0, 1, 2, 3, 4, 5]));
|
|
||||||
|
|
||||||
assert("Hello World!".padRight('!', 15).equal("Hello World!!!!"));
|
|
||||||
-------
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 regex-multiple-patterns, `std.regex.regex` now supports matching multiple patterns in one go.)
|
|
||||||
-------
|
|
||||||
import std.regex;
|
|
||||||
// multi-pattern regex
|
|
||||||
auto multi = regex([`\d+,\d+`,`(a-z]+):(\d+)`]);
|
|
||||||
auto m = "abc:43 12,34".matchAll(multi);
|
|
||||||
assert(m.front.whichPattern == 2);
|
|
||||||
assert(m.front[1] == "abc");
|
|
||||||
assert(m.front[2] == "43");
|
|
||||||
m.popFront();
|
|
||||||
assert(m.front.whichPattern == 1);
|
|
||||||
assert(m.front[1] == "12");
|
|
||||||
-------
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 regex-with-matches, `std.regex.splitter` now supports keeping the
|
|
||||||
pattern matches in the resulting range.)
|
|
||||||
-------
|
|
||||||
import std.regex;
|
|
||||||
import std.algorithm.comparison : equal;
|
|
||||||
|
|
||||||
auto pattern = regex(`([\.,])`);
|
|
||||||
assert("2003.04.05"
|
|
||||||
.splitter!(No.keepSeparators)(pattern)
|
|
||||||
.equal(["2003", "04", "05"]));
|
|
||||||
assert("2003.04.05"
|
|
||||||
.splitter!(Yes.keepSeparators)(pattern)
|
|
||||||
.equal(["2003", ".", "04", ".", "05"]));
|
|
||||||
-------
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 optimization, `findLocalMin` was added to `std.numeric`.)
|
|
||||||
$(P $(REF findLocalMin, std,numeric) finds a real minimum of a real function `f(x)` via bracketing.)
|
|
||||||
-------
|
|
||||||
import std.numeric, std.math;
|
|
||||||
|
|
||||||
auto ret = findLocalMin((double x) => (x-4)^^2, -1e7, 1e7);
|
|
||||||
|
|
||||||
assert(ret.x.approxEqual(4.0));
|
|
||||||
assert(ret.y.approxEqual(0.0));
|
|
||||||
-------
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 slice_ptr, `ptr` property and public constructor were added to
|
|
||||||
`std.experimental.ndslice.slice.Slice`.)
|
|
||||||
$(P `ptr` property allows to access `Slice`'s underlaying pointer or range.
|
|
||||||
Please refer to $(REF Slice, std,experimental,ndslice,slice)'s
|
|
||||||
internal binary epresentation before using the property.
|
|
||||||
`ptr` property is used in $(LINK2 https://github.com/libmir/mir, Mir)
|
|
||||||
for $(LINK2 http://docs.mir.dlang.io/latest/mir_sparse_package.html, sparse tensors).
|
|
||||||
`ndslice` developer mirror in Mir will be removed as
|
|
||||||
soon as LDC (LLVM D compiler) supports D version 2.072..
|
|
||||||
)
|
|
||||||
$(P Public constructor for `Slice` was added to support
|
|
||||||
$(MREF std,experimental,ndslice) integration
|
|
||||||
with other languages and libraries such as Julia language and NumPy library.
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 slice_toHash, $(P $(REF .Slice.toHash, std,experimental,ndslice,slice) method was added.)
|
|
||||||
---
|
|
||||||
import std.experimental.ndslice;
|
|
||||||
|
|
||||||
// hash is the same for allocated data and generated data
|
|
||||||
auto a = iotaSlice(3, 7);
|
|
||||||
auto b = iotaSlice(3, 7).slice;
|
|
||||||
|
|
||||||
assert(a.toHash == b.toHash);
|
|
||||||
---
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 slice_alloc, `slice`, `shape`, `ndarray`, and other utilities
|
|
||||||
were added to `std.experimental.ndslice.slice`.)
|
|
||||||
$(P These utility functions have been added to
|
|
||||||
$(MREF std,experimental,ndslice):)
|
|
||||||
$(UL
|
|
||||||
$(LI $(REF makeNdarray, std,experimental,ndslice,slice),)
|
|
||||||
$(LI $(REF makeSlice, std,experimental,ndslice,slice),)
|
|
||||||
$(LI $(REF makeUninitializedSlice, std,experimental,ndslice,slice),)
|
|
||||||
$(LI $(REF ndarray, std,experimental,ndslice,slice),)
|
|
||||||
$(LI $(REF shape, std,experimental,ndslice,slice),)
|
|
||||||
$(LI $(REF slice, std,experimental,ndslice,slice),)
|
|
||||||
$(LI $(REF uninitializedSlice, std,experimental,ndslice,slice).)
|
|
||||||
)
|
|
||||||
$(P Example: Transposing common 2D array using `ndslice`)
|
|
||||||
-----
|
|
||||||
import std.experimental.ndslice;
|
|
||||||
|
|
||||||
auto ar = [[0, 1, 2], [3, 4, 5]];
|
|
||||||
|
|
||||||
auto sh = ar.shape; // [2, 3] type of size_t[2]
|
|
||||||
auto sl = slice!int(sh); // allocates slice with corresponding shape
|
|
||||||
sl[] = ar; // fills sl with values from ar
|
|
||||||
ar = sl.transposed.ndarray; // allocates common 2D array
|
|
||||||
|
|
||||||
assert(ar == [[0, 3], [1, 4], [2, 5]]);
|
|
||||||
-----
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 slice_as, $(P $(REF as, std,experimental,ndslice,slice)
|
|
||||||
lazy tensor was added.)
|
|
||||||
---
|
|
||||||
import std.experimental.ndslice;
|
|
||||||
|
|
||||||
auto matrix = slice!double([2, 2], 0);
|
|
||||||
auto stringMatrixView = matrix.as!string;
|
|
||||||
assert(stringMatrixView ==
|
|
||||||
[["0", "0"],
|
|
||||||
["0", "0"]]);
|
|
||||||
|
|
||||||
matrix.diagonal[] = 1;
|
|
||||||
assert(stringMatrixView ==
|
|
||||||
[["1", "0"],
|
|
||||||
["0", "1"]]);
|
|
||||||
---
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 slice_iota, `iotaSlice` lazy tensor was added to `std.experimental.ndslice.selection`.)
|
|
||||||
$(P $(REF iotaSlice, std,experimental,ndslice,selection) is the fastest possible `Slice`.)
|
|
||||||
---
|
|
||||||
import std.experimental.ndslice;
|
|
||||||
|
|
||||||
auto sl = iotaSlice([2, 3], 10);
|
|
||||||
|
|
||||||
assert(sl.transposed == [[10, 13],
|
|
||||||
[11, 14],
|
|
||||||
[12, 15]]);
|
|
||||||
---
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 slice_index, $(P $(REF indexSlice, std,experimental,ndslice,selection)
|
|
||||||
lazy tensor was added.)
|
|
||||||
---
|
|
||||||
import std.experimental.ndslice;
|
|
||||||
|
|
||||||
auto slice = indexSlice(2, 3);
|
|
||||||
|
|
||||||
assert(slice == [[[0, 0], [0, 1], [0, 2]],
|
|
||||||
[[1, 0], [1, 1], [1, 2]]]);
|
|
||||||
---
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 slice_repeat, $(P $(REF repeatSlice, std,experimental,ndslice,selection)
|
|
||||||
lazy tensor was added.)
|
|
||||||
---
|
|
||||||
import std.experimental.ndslice;
|
|
||||||
|
|
||||||
auto sl = iotaSlice(3).repeatSlice(4);
|
|
||||||
assert(sl == [[0, 1, 2],
|
|
||||||
[0, 1, 2],
|
|
||||||
[0, 1, 2],
|
|
||||||
[0, 1, 2]]);
|
|
||||||
|
|
||||||
auto m = 4.repeatSlice(2, 3);
|
|
||||||
assert(m == [[4, 4, 4],
|
|
||||||
[4, 4, 4]]);
|
|
||||||
---
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 slice_map, $(P $(REF mapSlice, std,experimental,ndslice,selection)
|
|
||||||
lazy tensor was added.)
|
|
||||||
---
|
|
||||||
import std.experimental.ndslice;
|
|
||||||
|
|
||||||
auto s = iotaSlice(2, 3).mapSlice!(a => a * a);
|
|
||||||
assert(s == [[ 0, 1, 4],
|
|
||||||
[ 9, 16, 25]]);
|
|
||||||
---
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 slice_mio, partial support for Math Index Order was added to `std.experimental.ndslice.slice.Slice`.)
|
|
||||||
---
|
|
||||||
import std.experimental.ndslice;
|
|
||||||
|
|
||||||
auto sl = iotaSlice(3, 4);
|
|
||||||
|
|
||||||
assert(sl[2, 3] == 11); // D & C index order
|
|
||||||
assert(sl(3, 2) == 11); // Math & Fortran index order
|
|
||||||
---
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 mutation, `std.algorithm.mutation.swapAt` was exposed)
|
|
||||||
$(P $(REF swapAt, std,algorithm,mutation) allows to swap elements
|
|
||||||
of a RandomAccessRange by their indices.
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 iota-length-size_t, `std.range.iota's `.length` property is fixed
|
|
||||||
to `size_t` instead of the type being iterated)
|
|
||||||
$(P $(REF iota, std,range)'s `.length` property is now always returned as
|
|
||||||
`size_t`. This means if you are on a 32-bit CPU and you are using
|
|
||||||
iota to iterate 64-bit types, the length will be truncated to `size_t`.
|
|
||||||
In non-release mode, you will get an exception if the length exceeds
|
|
||||||
`size_t.max` in your call to `iota`.
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 min-max-element, `std.algorithm.searching.{min,max}Element`
|
|
||||||
have been added.)
|
|
||||||
$(P $(REF minElement, algorithm,searching) and $(REF maxElement,
|
|
||||||
algorithm,searching) are functions to search for the minimum and maximum
|
|
||||||
element in a range. They support a custom `map` accessor.
|
|
||||||
)
|
|
||||||
|
|
||||||
-------
|
|
||||||
import std.algorithm.searching;
|
|
||||||
import std.range;
|
|
||||||
import std.typecons;
|
|
||||||
assert([3, 1, 4].minElement == 1);
|
|
||||||
assert([4, 7, 5].enumerate.maxElement!`a.value` == tuple(1, 7));
|
|
||||||
-------
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 quantize, Added `std.math.quantize`.)
|
|
||||||
$(P $(REF quantize, std,math) rounds to the nearest multiple of some number.
|
|
||||||
Features:)
|
|
||||||
$(UL
|
|
||||||
$(LI The rounding method can be specified using the `rfunc` parameter. By
|
|
||||||
default, the current rounding mode will be used, which is typically
|
|
||||||
"banker's rounding".)
|
|
||||||
$(LI Overloads are included for the common case of rounding to the $(I Nth)
|
|
||||||
digit place in some base.)
|
|
||||||
$(LI If known at compile time, the base and exponent (digit place) can be
|
|
||||||
supplied as template parameters for better performance.)
|
|
||||||
)
|
|
||||||
---
|
|
||||||
import std.math;
|
|
||||||
|
|
||||||
assert(12345.6789L.quantize(20.0L) == 12340.0L);
|
|
||||||
assert(12345.6789L.quantize!(10, -2) == 12345.68L);
|
|
||||||
assert(12345.6789L.quantize!(10, floor)(-2) == 12345.67L);
|
|
||||||
---
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 traits, Three new traits were added to `std.traits`.)
|
|
||||||
$(P $(REF isType, std,traits), $(REF isFunction, std,traits), and
|
|
||||||
$(REF isFinal, std,traits) were added to `std.traits`.
|
|
||||||
)
|
|
||||||
|
|
||||||
-------
|
|
||||||
import std.traits;
|
|
||||||
|
|
||||||
static assert(isType!int);
|
|
||||||
|
|
||||||
struct S {}
|
|
||||||
class C {}
|
|
||||||
interface I {}
|
|
||||||
|
|
||||||
static assert(isType!S);
|
|
||||||
static assert(isType!C);
|
|
||||||
static assert(isType!I);
|
|
||||||
-------
|
|
||||||
|
|
||||||
-------
|
|
||||||
import std.traits;
|
|
||||||
|
|
||||||
void func(){}
|
|
||||||
struct S
|
|
||||||
{
|
|
||||||
@property int prop(){ return 0; }
|
|
||||||
}
|
|
||||||
|
|
||||||
static assert(isFunction!func);
|
|
||||||
static assert(isFunction!(S.prop));
|
|
||||||
|
|
||||||
// is a delegate type, not function type
|
|
||||||
static assert(!isFunction!(typeof(&S.prop)));
|
|
||||||
-------
|
|
||||||
|
|
||||||
-------
|
|
||||||
import std.traits;
|
|
||||||
|
|
||||||
class C
|
|
||||||
{
|
|
||||||
void nf() {}
|
|
||||||
final void ff() {}
|
|
||||||
}
|
|
||||||
final class FC {}
|
|
||||||
|
|
||||||
static assert(!isFinal!(C));
|
|
||||||
static assert( isFinal!(FC));
|
|
||||||
static assert(!isFinal!(C.nf));
|
|
||||||
static assert( isFinal!(C.ff));
|
|
||||||
-------
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 generate, `std.range.generate` fixed to be a proper range.)
|
|
||||||
$(P $(REF generate, std, range) was set up to return a different value on each
|
|
||||||
call to `front`. In addition, `popFront` did nothing. This means that
|
|
||||||
manipulation functions like $(REF drop, std, range) did nothing. The new
|
|
||||||
version uses a one-element cache to meet the expectations of the range
|
|
||||||
definition. It preserves the ref-ness of the generator as well.
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 headconst, `Final` was added to `std.experimental.typecons`.)
|
|
||||||
$(P $(REF Final, std, experimental, typecons) can't be mutated directly.
|
|
||||||
However references are typed with their original mutability. This is
|
|
||||||
equivalent to `final` in Java or `readonly` in C#.
|
|
||||||
)
|
|
||||||
-------
|
|
||||||
auto a = makeFinal([1, 2, 3]);
|
|
||||||
assert(a[0] == 1);
|
|
||||||
|
|
||||||
// a = [2, 3]; // Reassignment is illegal,
|
|
||||||
a[0] = 42; // Elements or fields are still mutable.
|
|
||||||
|
|
||||||
assert(a[0] == 42);
|
|
||||||
-------
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 inner-class, `std.traits.isInnerClass` was added to identify
|
|
||||||
nested classes with an accessible `outer` pointer)
|
|
||||||
$(P Classes, that are nested inside other classes (and not inside functions)
|
|
||||||
and that don't define any `outer` symbol, have an `outer` field which allows
|
|
||||||
to get and even set the instance of the outer class they are nested in.
|
|
||||||
$(REF isInnerClass, std, traits) allows to identify them. The types satisfying
|
|
||||||
`isInnerClass` are a subset of the ones satisfying `isNested`, as the latter
|
|
||||||
includes classes and structures nested inside functions or that redefine `outer`.
|
|
||||||
)
|
|
||||||
-------
|
|
||||||
class Outer
|
|
||||||
{
|
|
||||||
class Inner1 { }
|
|
||||||
class Inner2
|
|
||||||
{
|
|
||||||
int outer; // redefines outer, so the Outer instance is not accessible
|
|
||||||
}
|
|
||||||
static class Inner3 {} // static, thus not nested
|
|
||||||
}
|
|
||||||
static assert(isInnerClass!(Outer.Inner1));
|
|
||||||
static assert(!isInnerClass!(Outer.Inner2));
|
|
||||||
static assert(!isInnerClass!(Outer.Inner3));
|
|
||||||
-------
|
|
||||||
)
|
|
||||||
|
|
||||||
$(LI $(LNAME2 emplace-inner-class, `std.conv.emplace` no longer allows to emplace
|
|
||||||
classes nested directly inside other classes without specifying a suitable `outer`
|
|
||||||
pointer)
|
|
||||||
$(P If a class is nested within another class (there's a new trait
|
|
||||||
$(REF isInnerClass, std, traits) to check for this condition), `emplace` requires
|
|
||||||
now the outer class instance as additional mandatory parameter. Before this
|
|
||||||
change, emplacing did not require this parameter and access to variables of the
|
|
||||||
outer class resulted in segmentation faults.
|
|
||||||
)
|
|
||||||
-------
|
|
||||||
class Outer
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
class Inner
|
|
||||||
{
|
|
||||||
auto getX() { return x; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Outer outer = new Outer();
|
|
||||||
|
|
||||||
// auto inner = buf.emplace!(Outer.Inner)(); // this is no longer allowed
|
|
||||||
auto inner = buf.emplace!(Outer.Inner)(outer); // use this instead
|
|
||||||
|
|
||||||
auto x = inner.getX(); // this used to cause a segmentation fault;
|
|
||||||
// now it works as expected
|
|
||||||
-------
|
|
||||||
)
|
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
Macros:
|
Macros:
|
||||||
|
|
|
@ -216,7 +216,7 @@ EXTRA_MODULES_INTERNAL := $(addprefix \
|
||||||
std/internal/digest/, sha_SSSE3 ) $(addprefix \
|
std/internal/digest/, sha_SSSE3 ) $(addprefix \
|
||||||
std/internal/math/, biguintcore biguintnoasm biguintx86 \
|
std/internal/math/, biguintcore biguintnoasm biguintx86 \
|
||||||
gammafunction errorfunction) $(addprefix std/internal/, \
|
gammafunction errorfunction) $(addprefix std/internal/, \
|
||||||
cstring phobosinit unicode_tables scopebuffer\
|
cstring encodinginit processinit unicode_tables scopebuffer\
|
||||||
unicode_comp unicode_decomp unicode_grapheme unicode_norm) \
|
unicode_comp unicode_decomp unicode_grapheme unicode_norm) \
|
||||||
$(addprefix std/internal/test/, dummyrange) \
|
$(addprefix std/internal/test/, dummyrange) \
|
||||||
$(addprefix std/experimental/ndslice/, internal) \
|
$(addprefix std/experimental/ndslice/, internal) \
|
||||||
|
|
|
@ -3573,6 +3573,8 @@ if (is(typeof(binaryFun!pred(r.front, s)) : bool)
|
||||||
|
|
||||||
_separatorLength = codeLength!(ElementEncodingType!Range)(separator);
|
_separatorLength = codeLength!(ElementEncodingType!Range)(separator);
|
||||||
}
|
}
|
||||||
|
if (_input.empty)
|
||||||
|
_frontLength = _atEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static if (isInfinite!Range)
|
static if (isInfinite!Range)
|
||||||
|
@ -3704,7 +3706,6 @@ if (is(typeof(binaryFun!pred(r.front, s)) : bool)
|
||||||
|
|
||||||
debug(std_algorithm) scope(success)
|
debug(std_algorithm) scope(success)
|
||||||
writeln("unittest @", __FILE__, ":", __LINE__, " done.");
|
writeln("unittest @", __FILE__, ":", __LINE__, " done.");
|
||||||
assert(equal(splitter("", ' '), [ "" ]));
|
|
||||||
assert(equal(splitter("hello world", ' '), [ "hello", "", "world" ]));
|
assert(equal(splitter("hello world", ' '), [ "hello", "", "world" ]));
|
||||||
assert(equal(splitter("žlutoučkýřkůň", 'ř'), [ "žlutoučký", "kůň" ]));
|
assert(equal(splitter("žlutoučkýřkůň", 'ř'), [ "žlutoučký", "kůň" ]));
|
||||||
int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];
|
int[] a = [ 1, 2, 0, 0, 3, 0, 4, 5, 0 ];
|
||||||
|
@ -3717,7 +3718,7 @@ if (is(typeof(binaryFun!pred(r.front, s)) : bool)
|
||||||
// }
|
// }
|
||||||
assert(equal(splitter(a, 0), w));
|
assert(equal(splitter(a, 0), w));
|
||||||
a = null;
|
a = null;
|
||||||
assert(equal(splitter(a, 0), [ (int[]).init ][]));
|
assert(equal(splitter(a, 0), (int[][]).init));
|
||||||
a = [ 0 ];
|
a = [ 0 ];
|
||||||
assert(equal(splitter(a, 0), [ (int[]).init, (int[]).init ][]));
|
assert(equal(splitter(a, 0), [ (int[]).init, (int[]).init ][]));
|
||||||
a = [ 0, 1 ];
|
a = [ 0, 1 ];
|
||||||
|
@ -3821,17 +3822,17 @@ if (is(typeof(binaryFun!pred(r.front, s.front)) : bool)
|
||||||
private:
|
private:
|
||||||
Range _input;
|
Range _input;
|
||||||
Separator _separator;
|
Separator _separator;
|
||||||
enum size_t _unComputed = size_t.max - 1, _atEnd = size_t.max;
|
// _frontLength == size_t.max means empty
|
||||||
// _frontLength == _atEnd means empty
|
size_t _frontLength = size_t.max;
|
||||||
size_t _frontLength = _unComputed;
|
|
||||||
static if (isBidirectionalRange!Range)
|
static if (isBidirectionalRange!Range)
|
||||||
size_t _backLength = _unComputed;
|
size_t _backLength = size_t.max;
|
||||||
|
|
||||||
@property auto separatorLength() { return _separator.length; }
|
@property auto separatorLength() { return _separator.length; }
|
||||||
|
|
||||||
void ensureFrontLength()
|
void ensureFrontLength()
|
||||||
{
|
{
|
||||||
if (_frontLength != _unComputed) return;
|
if (_frontLength != _frontLength.max) return;
|
||||||
|
assert(!_input.empty);
|
||||||
// compute front length
|
// compute front length
|
||||||
_frontLength = (_separator.empty) ? 1 :
|
_frontLength = (_separator.empty) ? 1 :
|
||||||
_input.length - find!pred(_input, _separator).length;
|
_input.length - find!pred(_input, _separator).length;
|
||||||
|
@ -3842,7 +3843,8 @@ if (is(typeof(binaryFun!pred(r.front, s.front)) : bool)
|
||||||
void ensureBackLength()
|
void ensureBackLength()
|
||||||
{
|
{
|
||||||
static if (isBidirectionalRange!Range)
|
static if (isBidirectionalRange!Range)
|
||||||
if (_backLength != _unComputed) return;
|
if (_backLength != _backLength.max) return;
|
||||||
|
assert(!_input.empty);
|
||||||
// compute back length
|
// compute back length
|
||||||
static if (isBidirectionalRange!Range && isBidirectionalRange!Separator)
|
static if (isBidirectionalRange!Range && isBidirectionalRange!Separator)
|
||||||
{
|
{
|
||||||
|
@ -3874,7 +3876,7 @@ if (is(typeof(binaryFun!pred(r.front, s.front)) : bool)
|
||||||
{
|
{
|
||||||
@property bool empty()
|
@property bool empty()
|
||||||
{
|
{
|
||||||
return _frontLength == _atEnd;
|
return _frontLength == size_t.max && _input.empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3886,9 +3888,9 @@ if (is(typeof(binaryFun!pred(r.front, s.front)) : bool)
|
||||||
{
|
{
|
||||||
// done, there's no separator in sight
|
// done, there's no separator in sight
|
||||||
_input = _input[_frontLength .. _frontLength];
|
_input = _input[_frontLength .. _frontLength];
|
||||||
_frontLength = _atEnd;
|
_frontLength = _frontLength.max;
|
||||||
static if (isBidirectionalRange!Range)
|
static if (isBidirectionalRange!Range)
|
||||||
_backLength = _atEnd;
|
_backLength = _backLength.max;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_frontLength + separatorLength == _input.length)
|
if (_frontLength + separatorLength == _input.length)
|
||||||
|
@ -3905,7 +3907,7 @@ if (is(typeof(binaryFun!pred(r.front, s.front)) : bool)
|
||||||
// reading the next item
|
// reading the next item
|
||||||
_input = _input[_frontLength + separatorLength .. _input.length];
|
_input = _input[_frontLength + separatorLength .. _input.length];
|
||||||
// mark _frontLength as uninitialized
|
// mark _frontLength as uninitialized
|
||||||
_frontLength = _unComputed;
|
_frontLength = _frontLength.max;
|
||||||
}
|
}
|
||||||
|
|
||||||
static if (isForwardRange!Range)
|
static if (isForwardRange!Range)
|
||||||
|
@ -3955,8 +3957,6 @@ if (is(typeof(binaryFun!pred(r.front, s.front)) : bool)
|
||||||
|
|
||||||
debug(std_algorithm) scope(success)
|
debug(std_algorithm) scope(success)
|
||||||
writeln("unittest @", __FILE__, ":", __LINE__, " done.");
|
writeln("unittest @", __FILE__, ":", __LINE__, " done.");
|
||||||
assert(equal(splitter("", " "), [ "" ]));
|
|
||||||
|
|
||||||
auto s = ",abc, de, fg,hi,";
|
auto s = ",abc, de, fg,hi,";
|
||||||
auto sp0 = splitter(s, ',');
|
auto sp0 = splitter(s, ',');
|
||||||
// //foreach (e; sp0) writeln("[", e, "]");
|
// //foreach (e; sp0) writeln("[", e, "]");
|
||||||
|
@ -4131,7 +4131,10 @@ private struct SplitterResult(alias isTerminator, Range)
|
||||||
static if (!fullSlicing)
|
static if (!fullSlicing)
|
||||||
_next = _input.save;
|
_next = _input.save;
|
||||||
|
|
||||||
findTerminator();
|
if (!_input.empty)
|
||||||
|
findTerminator();
|
||||||
|
else
|
||||||
|
_end = size_t.max;
|
||||||
}
|
}
|
||||||
|
|
||||||
static if (isInfinite!Range)
|
static if (isInfinite!Range)
|
||||||
|
@ -4240,7 +4243,7 @@ private struct SplitterResult(alias isTerminator, Range)
|
||||||
["Mary", "", "has", "a", "little", "lamb.", "", "", ""]);
|
["Mary", "", "has", "a", "little", "lamb.", "", "", ""]);
|
||||||
compare("Mary has a little lamb.",
|
compare("Mary has a little lamb.",
|
||||||
["Mary", "", "has", "a", "little", "lamb."]);
|
["Mary", "", "has", "a", "little", "lamb."]);
|
||||||
compare("", [""]);
|
compare("", (string[]).init);
|
||||||
compare(" ", ["", ""]);
|
compare(" ", ["", ""]);
|
||||||
|
|
||||||
static assert(isForwardRange!(typeof(splitter!"a == ' '"("ABC"))));
|
static assert(isForwardRange!(typeof(splitter!"a == ' '"("ABC"))));
|
||||||
|
@ -4270,7 +4273,7 @@ private struct SplitterResult(alias isTerminator, Range)
|
||||||
int[][] result;
|
int[][] result;
|
||||||
}
|
}
|
||||||
Entry[] entries = [
|
Entry[] entries = [
|
||||||
Entry(0, 0, [[]]),
|
Entry(0, 0, []),
|
||||||
Entry(0, 1, [[0]]),
|
Entry(0, 1, [[0]]),
|
||||||
Entry(1, 2, [[], []]),
|
Entry(1, 2, [[], []]),
|
||||||
Entry(2, 7, [[2], [4], [6]]),
|
Entry(2, 7, [[2], [4], [6]]),
|
||||||
|
|
|
@ -55,6 +55,7 @@ module std.encoding;
|
||||||
import std.traits;
|
import std.traits;
|
||||||
import std.typecons;
|
import std.typecons;
|
||||||
import std.range.primitives;
|
import std.range.primitives;
|
||||||
|
import std.internal.encodinginit;
|
||||||
|
|
||||||
@system unittest
|
@system unittest
|
||||||
{
|
{
|
||||||
|
@ -2360,17 +2361,30 @@ abstract class EncodingScheme
|
||||||
* This function allows user-defined subclasses of EncodingScheme to
|
* This function allows user-defined subclasses of EncodingScheme to
|
||||||
* be declared in other modules.
|
* be declared in other modules.
|
||||||
*
|
*
|
||||||
|
* Params:
|
||||||
|
* Klass = The subclass of EncodingScheme to register.
|
||||||
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* ----------------------------------------------
|
* ----------------------------------------------
|
||||||
* class Amiga1251 : EncodingScheme
|
* class Amiga1251 : EncodingScheme
|
||||||
* {
|
* {
|
||||||
* shared static this()
|
* shared static this()
|
||||||
* {
|
* {
|
||||||
* EncodingScheme.register("path.to.Amiga1251");
|
* EncodingScheme.register!Amiga1251;
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* ----------------------------------------------
|
* ----------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
static void register(Klass:EncodingScheme)()
|
||||||
|
{
|
||||||
|
scope scheme = new Klass();
|
||||||
|
foreach (encodingName;scheme.names())
|
||||||
|
{
|
||||||
|
supported[toLower(encodingName)] = () => new Klass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated("Please pass the EncodingScheme subclass as template argument instead.")
|
||||||
static void register(string className)
|
static void register(string className)
|
||||||
{
|
{
|
||||||
auto scheme = cast(EncodingScheme)ClassInfo.find(className).create();
|
auto scheme = cast(EncodingScheme)ClassInfo.find(className).create();
|
||||||
|
@ -2378,7 +2392,7 @@ abstract class EncodingScheme
|
||||||
throw new EncodingException("Unable to create class "~className);
|
throw new EncodingException("Unable to create class "~className);
|
||||||
foreach (encodingName;scheme.names())
|
foreach (encodingName;scheme.names())
|
||||||
{
|
{
|
||||||
supported[toLower(encodingName)] = className;
|
supportedFactories[toLower(encodingName)] = className;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2396,7 +2410,12 @@ abstract class EncodingScheme
|
||||||
*/
|
*/
|
||||||
static EncodingScheme create(string encodingName)
|
static EncodingScheme create(string encodingName)
|
||||||
{
|
{
|
||||||
auto p = toLower(encodingName) in supported;
|
encodingName = toLower(encodingName);
|
||||||
|
|
||||||
|
if (auto p = encodingName in supported)
|
||||||
|
return (*p)();
|
||||||
|
|
||||||
|
auto p = encodingName in supportedFactories;
|
||||||
if (p is null)
|
if (p is null)
|
||||||
throw new EncodingException("Unrecognized Encoding: "~encodingName);
|
throw new EncodingException("Unrecognized Encoding: "~encodingName);
|
||||||
string className = *p;
|
string className = *p;
|
||||||
|
@ -2650,7 +2669,8 @@ abstract class EncodingScheme
|
||||||
return t.length - s.length;
|
return t.length - s.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
__gshared string[string] supported;
|
__gshared EncodingScheme function()[string] supported;
|
||||||
|
__gshared string[string] supportedFactories;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3297,6 +3317,20 @@ class EncodingSchemeUtf32Native : EncodingScheme
|
||||||
assert(ub.length == 8);
|
assert(ub.length == 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// shared static this() called from encodinginit to break ctor cycle
|
||||||
|
extern(C) void std_encoding_shared_static_this()
|
||||||
|
{
|
||||||
|
EncodingScheme.register!EncodingSchemeASCII;
|
||||||
|
EncodingScheme.register!EncodingSchemeLatin1;
|
||||||
|
EncodingScheme.register!EncodingSchemeLatin2;
|
||||||
|
EncodingScheme.register!EncodingSchemeWindows1250;
|
||||||
|
EncodingScheme.register!EncodingSchemeWindows1252;
|
||||||
|
EncodingScheme.register!EncodingSchemeUtf8;
|
||||||
|
EncodingScheme.register!EncodingSchemeUtf16Native;
|
||||||
|
EncodingScheme.register!EncodingSchemeUtf32Native;
|
||||||
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
|
19
std/internal/encodinginit.d
Normal file
19
std/internal/encodinginit.d
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Written in the D programming language.
|
||||||
|
|
||||||
|
/++
|
||||||
|
The purpose of this module is to perform static construction away from the
|
||||||
|
normal modules to eliminate cyclic construction errors.
|
||||||
|
|
||||||
|
Copyright: Copyright 2011 - 2016
|
||||||
|
License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
|
||||||
|
Authors: Martin Nowak, Steven Schveighoffer
|
||||||
|
Source: $(PHOBOSSRC std/internal/_encodinginit.d)
|
||||||
|
+/
|
||||||
|
module std.internal.encodinginit;
|
||||||
|
|
||||||
|
extern(C) void std_encoding_shared_static_this();
|
||||||
|
|
||||||
|
shared static this()
|
||||||
|
{
|
||||||
|
std_encoding_shared_static_this();
|
||||||
|
}
|
|
@ -1,35 +0,0 @@
|
||||||
// Written in the D programming language.
|
|
||||||
|
|
||||||
/++
|
|
||||||
The purpose of this module is to perform static construction away from the
|
|
||||||
normal modules to eliminate cyclic construction errors.
|
|
||||||
|
|
||||||
Copyright: Copyright 2011 - 2016
|
|
||||||
License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
|
|
||||||
Authors: Jonathan M Davis, Kato Shoichi, Steven Schveighoffer
|
|
||||||
Source: $(PHOBOSSRC std/internal/_phobosinit.d)
|
|
||||||
+/
|
|
||||||
module std.internal.phobosinit;
|
|
||||||
|
|
||||||
version(OSX)
|
|
||||||
{
|
|
||||||
extern(C) void std_process_shared_static_this();
|
|
||||||
|
|
||||||
shared static this()
|
|
||||||
{
|
|
||||||
std_process_shared_static_this();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shared static this()
|
|
||||||
{
|
|
||||||
import std.encoding : EncodingScheme;
|
|
||||||
EncodingScheme.register("std.encoding.EncodingSchemeASCII");
|
|
||||||
EncodingScheme.register("std.encoding.EncodingSchemeLatin1");
|
|
||||||
EncodingScheme.register("std.encoding.EncodingSchemeLatin2");
|
|
||||||
EncodingScheme.register("std.encoding.EncodingSchemeWindows1250");
|
|
||||||
EncodingScheme.register("std.encoding.EncodingSchemeWindows1252");
|
|
||||||
EncodingScheme.register("std.encoding.EncodingSchemeUtf8");
|
|
||||||
EncodingScheme.register("std.encoding.EncodingSchemeUtf16Native");
|
|
||||||
EncodingScheme.register("std.encoding.EncodingSchemeUtf32Native");
|
|
||||||
}
|
|
22
std/internal/processinit.d
Normal file
22
std/internal/processinit.d
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Written in the D programming language.
|
||||||
|
|
||||||
|
/++
|
||||||
|
The only purpose of this module is to do the static construction for
|
||||||
|
std.process in order to eliminate cyclic construction errors.
|
||||||
|
|
||||||
|
Copyright: Copyright 2011 -
|
||||||
|
License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
|
||||||
|
Authors: Jonathan M Davis and Kato Shoichi
|
||||||
|
Source: $(PHOBOSSRC std/internal/_processinit.d)
|
||||||
|
+/
|
||||||
|
module std.internal.processinit;
|
||||||
|
|
||||||
|
version(OSX)
|
||||||
|
{
|
||||||
|
extern(C) void std_process_shared_static_this();
|
||||||
|
|
||||||
|
shared static this()
|
||||||
|
{
|
||||||
|
std_process_shared_static_this();
|
||||||
|
}
|
||||||
|
}
|
|
@ -976,9 +976,7 @@ private final class ParallelismThread : Thread
|
||||||
// Kill daemon threads.
|
// Kill daemon threads.
|
||||||
shared static ~this()
|
shared static ~this()
|
||||||
{
|
{
|
||||||
auto allThreads = Thread.getAll();
|
foreach (ref thread; Thread)
|
||||||
|
|
||||||
foreach (thread; allThreads)
|
|
||||||
{
|
{
|
||||||
auto pthread = cast(ParallelismThread) thread;
|
auto pthread = cast(ParallelismThread) thread;
|
||||||
if (pthread is null) continue;
|
if (pthread is null) continue;
|
||||||
|
|
|
@ -100,6 +100,7 @@ version (Windows)
|
||||||
|
|
||||||
import std.range.primitives;
|
import std.range.primitives;
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
|
import std.internal.processinit;
|
||||||
import std.internal.cstring;
|
import std.internal.cstring;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -274,7 +274,8 @@ SRC_STD_C_FREEBSD= \
|
||||||
|
|
||||||
SRC_STD_INTERNAL= \
|
SRC_STD_INTERNAL= \
|
||||||
std\internal\cstring.d \
|
std\internal\cstring.d \
|
||||||
std\internal\phobosinit.d \
|
std\internal\encodinginit.d \
|
||||||
|
std\internal\processinit.d \
|
||||||
std\internal\unicode_tables.d \
|
std\internal\unicode_tables.d \
|
||||||
std\internal\unicode_comp.d \
|
std\internal\unicode_comp.d \
|
||||||
std\internal\unicode_decomp.d \
|
std\internal\unicode_decomp.d \
|
||||||
|
|
|
@ -293,7 +293,8 @@ SRC_STD_C_FREEBSD= \
|
||||||
|
|
||||||
SRC_STD_INTERNAL= \
|
SRC_STD_INTERNAL= \
|
||||||
std\internal\cstring.d \
|
std\internal\cstring.d \
|
||||||
std\internal\phobosinit.d \
|
std\internal\encodinginit.d \
|
||||||
|
std\internal\processinit.d \
|
||||||
std\internal\unicode_tables.d \
|
std\internal\unicode_tables.d \
|
||||||
std\internal\unicode_comp.d \
|
std\internal\unicode_comp.d \
|
||||||
std\internal\unicode_decomp.d \
|
std\internal\unicode_decomp.d \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue