mirror of
https://github.com/dlang/phobos.git
synced 2025-04-29 14:40:30 +03:00
One pass through std.range and friends
* Made emplace faster and replaced calls to it to also make them faster. * Replaced phobos.d in posix.mak with index.d. * Added version=StdDdoc to documentation build in posix.mak, and replaced uses of D_Ddoc with it. * Improved documentation target in posix.mak (target dir automatically created). * Added nice documentation table and cheat sheet at the top of std.algorithm. * Replaced a few helper structs in std.range and std.algorithm with local structs, which simplify matters a fair amount. * Added more constraints to functions in std.algorithm (still work in progress). * Improved error message in std.algorithm.sort in case of failure to sort. * std.random.dice(1, 10) now works (no need for array notation std.random.dice([1, 10])). * Fixed documentation bugs and insufficiencies in std.range (still more to do). * Improved speed of walkLength. * Simplified retro. * Simplified and optimized stride. Also folded stride(stride(r, a), b) into stride(r, a * b). * Added roundRobin to std.range, which as a perk simplified radial. * Added takeOne and takeNone to std.range. * Added unsigned to std.traits.
This commit is contained in:
parent
69d8b2e514
commit
1083bd4e7b
13 changed files with 2861 additions and 2420 deletions
15
posix.mak
15
posix.mak
|
@ -53,9 +53,9 @@ ROOT = $(ROOT_OF_THEM_ALL)/$(OS)/$(BUILD)/$(MODEL)
|
||||||
DOCSRC = ../d-programming-language.org
|
DOCSRC = ../d-programming-language.org
|
||||||
WEBSITE_DIR = ../web
|
WEBSITE_DIR = ../web
|
||||||
DOC_OUTPUT_DIR = $(WEBSITE_DIR)/phobos-prerelease
|
DOC_OUTPUT_DIR = $(WEBSITE_DIR)/phobos-prerelease
|
||||||
SRC_DOCUMENTABLES = phobos.d $(addsuffix .d,$(STD_MODULES))
|
SRC_DOCUMENTABLES = index.d $(addsuffix .d,$(STD_MODULES))
|
||||||
STDDOC = $(DOCSRC)/std.ddoc
|
STDDOC = $(DOCSRC)/std.ddoc
|
||||||
DDOCFLAGS=-m$(MODEL) -d -c -o- $(STDDOC) -I$(DRUNTIME_PATH)/import $(DMDEXTRAFLAGS)
|
DDOCFLAGS=-m$(MODEL) -d -c -o- -version=StdDdoc $(STDDOC) -I$(DRUNTIME_PATH)/import $(DMDEXTRAFLAGS)
|
||||||
|
|
||||||
# Variable defined in an OS-dependent manner (see below)
|
# Variable defined in an OS-dependent manner (see below)
|
||||||
CC =
|
CC =
|
||||||
|
@ -248,7 +248,7 @@ DISABLED_TESTS += std/math
|
||||||
DISABLED_TESTS += std/random
|
DISABLED_TESTS += std/random
|
||||||
DISABLED_TESTS += std/internal/math/biguintnoasm
|
DISABLED_TESTS += std/internal/math/biguintnoasm
|
||||||
|
|
||||||
$(addprefix $(ROOT)/unittest/,$(DISABLED_TESTS)) :
|
$(addprefix $(ROOT)/unittest/,$(DISABLED_TESTS)) :
|
||||||
@echo Testing $@ - disabled
|
@echo Testing $@ - disabled
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -288,8 +288,8 @@ $(DRUNTIME) :
|
||||||
###########################################################
|
###########################################################
|
||||||
# html documentation
|
# html documentation
|
||||||
|
|
||||||
$(DOC_OUTPUT_DIR)/%.html : %.d $(STDDOC)
|
$(DOC_OUTPUT_DIR)/. :
|
||||||
$(DDOC) $(DDOCFLAGS) -Df$@ $<
|
mkdir -p $@
|
||||||
|
|
||||||
$(DOC_OUTPUT_DIR)/std_%.html : std/%.d $(STDDOC)
|
$(DOC_OUTPUT_DIR)/std_%.html : std/%.d $(STDDOC)
|
||||||
$(DDOC) $(DDOCFLAGS) -Df$@ $<
|
$(DDOC) $(DDOCFLAGS) -Df$@ $<
|
||||||
|
@ -300,7 +300,10 @@ $(DOC_OUTPUT_DIR)/std_c_%.html : std/c/%.d $(STDDOC)
|
||||||
$(DOC_OUTPUT_DIR)/std_c_linux_%.html : std/c/linux/%.d $(STDDOC)
|
$(DOC_OUTPUT_DIR)/std_c_linux_%.html : std/c/linux/%.d $(STDDOC)
|
||||||
$(DDOC) $(DDOCFLAGS) -Df$@ $<
|
$(DDOC) $(DDOCFLAGS) -Df$@ $<
|
||||||
|
|
||||||
html : $(addprefix $(DOC_OUTPUT_DIR)/, $(subst /,_,$(subst .d,.html, \
|
$(DOC_OUTPUT_DIR)/%.html : %.d $(STDDOC)
|
||||||
|
$(DDOC) $(DDOCFLAGS) -Df$@ $<
|
||||||
|
|
||||||
|
html : $(DOC_OUTPUT_DIR)/. $(addprefix $(DOC_OUTPUT_DIR)/, $(subst /,_,$(subst .d,.html, \
|
||||||
$(SRC_DOCUMENTABLES)))) $(STYLECSS_TGT)
|
$(SRC_DOCUMENTABLES)))) $(STYLECSS_TGT)
|
||||||
# @$(MAKE) -f $(DOCSRC)/linux.mak -C $(DOCSRC) --no-print-directory
|
# @$(MAKE) -f $(DOCSRC)/linux.mak -C $(DOCSRC) --no-print-directory
|
||||||
|
|
||||||
|
|
1353
std/algorithm.d
1353
std/algorithm.d
File diff suppressed because it is too large
Load diff
|
@ -54,8 +54,7 @@ if (isIterable!Range && !isNarrowString!Range)
|
||||||
static if (is(typeof(e.opAssign(e))))
|
static if (is(typeof(e.opAssign(e))))
|
||||||
{
|
{
|
||||||
// this should be in-place construction
|
// this should be in-place construction
|
||||||
auto voidArr = (cast(void*) (result.ptr + i))[0..E.sizeof];
|
emplace!E(result.ptr + i, e);
|
||||||
emplace!E(voidArr, e);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,7 +7,6 @@ Source: $(PHOBOSSRC std/_container.d)
|
||||||
Macros:
|
Macros:
|
||||||
WIKI = Phobos/StdContainer
|
WIKI = Phobos/StdContainer
|
||||||
TEXTWITHCOMMAS = $0
|
TEXTWITHCOMMAS = $0
|
||||||
LEADINGROW = <tr style=leadingrow bgcolor=#E4E9EF><td colspan=3><b><em>$0</em></b></td></tr>
|
|
||||||
|
|
||||||
Copyright: Red-black tree code copyright (C) 2008- by Steven Schveighoffer. Other code
|
Copyright: Red-black tree code copyright (C) 2008- by Steven Schveighoffer. Other code
|
||||||
copyright 2010- Andrei Alexandrescu. All rights reserved by the respective holders.
|
copyright 2010- Andrei Alexandrescu. All rights reserved by the respective holders.
|
||||||
|
@ -1234,7 +1233,7 @@ $(D r) and $(D m) is the length of $(D stuff).
|
||||||
*/
|
*/
|
||||||
size_t insertAfter(Stuff)(Take!Range r, Stuff stuff)
|
size_t insertAfter(Stuff)(Take!Range r, Stuff stuff)
|
||||||
{
|
{
|
||||||
auto orig = r.original;
|
auto orig = r.source;
|
||||||
if (!orig._head)
|
if (!orig._head)
|
||||||
{
|
{
|
||||||
// Inserting after a null range counts as insertion to the
|
// Inserting after a null range counts as insertion to the
|
||||||
|
@ -1287,7 +1286,7 @@ Complexity: $(BIGOH n)
|
||||||
*/
|
*/
|
||||||
Range linearRemove(Take!Range r)
|
Range linearRemove(Take!Range r)
|
||||||
{
|
{
|
||||||
auto orig = r.original;
|
auto orig = r.source;
|
||||||
// We have something to remove here
|
// We have something to remove here
|
||||||
if (orig._head == _root)
|
if (orig._head == _root)
|
||||||
{
|
{
|
||||||
|
@ -1571,9 +1570,7 @@ struct Array(T) if (!is(T : const(bool)))
|
||||||
reserve(1 + capacity * 3 / 2);
|
reserve(1 + capacity * 3 / 2);
|
||||||
}
|
}
|
||||||
assert(capacity > length && _payload.ptr);
|
assert(capacity > length && _payload.ptr);
|
||||||
emplace!T((cast(void*) (_payload.ptr + _payload.length))
|
emplace(_payload.ptr + _payload.length, stuff);
|
||||||
[0 .. T.sizeof],
|
|
||||||
stuff);
|
|
||||||
_payload = _payload.ptr[0 .. _payload.length + 1];
|
_payload = _payload.ptr[0 .. _payload.length + 1];
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1605,17 +1602,17 @@ struct Array(T) if (!is(T : const(bool)))
|
||||||
|
|
||||||
this(U)(U[] values...) if (isImplicitlyConvertible!(U, T))
|
this(U)(U[] values...) if (isImplicitlyConvertible!(U, T))
|
||||||
{
|
{
|
||||||
auto p = malloc(T.sizeof * values.length);
|
auto p = cast(T*) malloc(T.sizeof * values.length);
|
||||||
if (hasIndirections!T && p)
|
if (hasIndirections!T && p)
|
||||||
{
|
{
|
||||||
GC.addRange(p, T.sizeof * values.length);
|
GC.addRange(p, T.sizeof * values.length);
|
||||||
}
|
}
|
||||||
foreach (i, e; values)
|
foreach (i, e; values)
|
||||||
{
|
{
|
||||||
emplace!T(p[i * T.sizeof .. (i + 1) * T.sizeof], e);
|
emplace(p + i, e);
|
||||||
assert((cast(T*) p)[i] == e);
|
assert(p[i] == e);
|
||||||
}
|
}
|
||||||
_data.RefCounted.initialize((cast(T*) p)[0 .. values.length]);
|
_data.RefCounted.initialize(p[0 .. values.length]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2089,8 +2086,7 @@ Complexity: $(BIGOH n + m), where $(D m) is the length of $(D stuff)
|
||||||
memmove(_data._payload.ptr + r._a + 1,
|
memmove(_data._payload.ptr + r._a + 1,
|
||||||
_data._payload.ptr + r._a,
|
_data._payload.ptr + r._a,
|
||||||
T.sizeof * (length - r._a));
|
T.sizeof * (length - r._a));
|
||||||
emplace!T((cast(void*) (_data._payload.ptr + r._a))[0 .. T.sizeof],
|
emplace(_data._payload.ptr + r._a, stuff);
|
||||||
stuff);
|
|
||||||
_data._payload = _data._payload.ptr[0 .. _data._payload.length + 1];
|
_data._payload = _data._payload.ptr[0 .. _data._payload.length + 1];
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -2114,7 +2110,7 @@ Complexity: $(BIGOH n + m), where $(D m) is the length of $(D stuff)
|
||||||
foreach (p; _data._payload.ptr + r._a ..
|
foreach (p; _data._payload.ptr + r._a ..
|
||||||
_data._payload.ptr + r._a + extra)
|
_data._payload.ptr + r._a + extra)
|
||||||
{
|
{
|
||||||
emplace!T((cast(void*) p)[0 .. T.sizeof], stuff.front);
|
emplace(p, stuff.front);
|
||||||
stuff.popFront();
|
stuff.popFront();
|
||||||
}
|
}
|
||||||
_data._payload =
|
_data._payload =
|
||||||
|
|
191
std/conv.d
191
std/conv.d
|
@ -3048,7 +3048,6 @@ version (none)
|
||||||
assert(to!string(cr) == to!string(creal.nan));
|
assert(to!string(cr) == to!string(creal.nan));
|
||||||
assert(feq(cr, creal.nan));
|
assert(feq(cr, creal.nan));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* **************************************************************
|
/* **************************************************************
|
||||||
|
@ -3956,7 +3955,8 @@ template octal(alias s) if (isIntegral!(typeof(s))) {
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
|
debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__,
|
||||||
|
" succeeded.");
|
||||||
// ensure that you get the right types, even with embedded underscores
|
// ensure that you get the right types, even with embedded underscores
|
||||||
auto w = octal!"100_000_000_000";
|
auto w = octal!"100_000_000_000";
|
||||||
static assert(!is(typeof(w) == int));
|
static assert(!is(typeof(w) == int));
|
||||||
|
@ -4022,114 +4022,86 @@ T toImpl(T, S)(S src) if (is(T == struct) && is(typeof(T(src))))
|
||||||
// Bugzilla 3961
|
// Bugzilla 3961
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
|
debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__,
|
||||||
|
" succeeded.");
|
||||||
struct Int { int x; }
|
struct Int { int x; }
|
||||||
Int i = to!Int(1);
|
Int i = to!Int(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// emplace
|
// emplace
|
||||||
/**
|
/**
|
||||||
Given a raw memory area $(D chunk), constructs an object of non-$(D
|
Given a pointer $(D chunk) to uninitialized memory (but already typed
|
||||||
class) type $(D T) at that address. The constructor is passed the
|
as $(D T)), constructs an object of non-$(D class) type $(D T) at that
|
||||||
arguments $(D Args). The $(D chunk) must be as least as large as $(D
|
address.
|
||||||
T) needs and should have an alignment multiple of $(D T)'s alignment.
|
|
||||||
|
|
||||||
This function can be $(D @trusted) if the corresponding constructor of
|
This function can be $(D @trusted) if the corresponding constructor of
|
||||||
$(D T) is $(D @safe).
|
$(D T) is $(D @safe).
|
||||||
|
|
||||||
Returns: A pointer to the newly constructed object.
|
Returns: A pointer to the newly constructed object (which is the same
|
||||||
|
as $(D chunk)).
|
||||||
*/
|
*/
|
||||||
T* emplace(T, Args...)(void[] chunk, Args args) if (!is(T == class))
|
T* emplace(T)(T* chunk)
|
||||||
|
if (!is(T == class))
|
||||||
{
|
{
|
||||||
enforce(chunk.length >= T.sizeof,
|
auto result = cast(typeof(return)) chunk;
|
||||||
new ConvException("emplace: target size too small"));
|
static T i;
|
||||||
auto a = cast(size_t) chunk.ptr;
|
memcpy(result, &i, T.sizeof);
|
||||||
version (OSX) // for some reason, breaks on other platforms
|
return result;
|
||||||
enforce(a % T.alignof == 0, new ConvException("misalignment"));
|
}
|
||||||
auto result = cast(typeof(return)) chunk.ptr;
|
|
||||||
|
/**
|
||||||
|
Given a pointer $(D chunk) to uninitialized memory (but already typed
|
||||||
|
as a non-class type $(D T)), constructs an object of type $(D T) at
|
||||||
|
that address from arguments $(D args).
|
||||||
|
|
||||||
|
This function can be $(D @trusted) if the corresponding constructor of
|
||||||
|
$(D T) is $(D @safe).
|
||||||
|
|
||||||
|
Returns: A pointer to the newly constructed object (which is the same
|
||||||
|
as $(D chunk)).
|
||||||
|
*/
|
||||||
|
T* emplace(T, Args...)(T* chunk, Args args)
|
||||||
|
if (!is(T == class) && !is(T == struct) && Args.length == 1)
|
||||||
|
{
|
||||||
|
*chunk = args[0];
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specialization for struct
|
||||||
|
T* emplace(T, Args...)(T* chunk, Args args)
|
||||||
|
if (is(T == struct))
|
||||||
|
{
|
||||||
|
auto result = cast(typeof(return)) chunk;
|
||||||
|
|
||||||
void initialize()
|
void initialize()
|
||||||
{
|
{
|
||||||
static T i;
|
static T i;
|
||||||
memcpy(chunk.ptr, &i, T.sizeof);
|
memcpy(chunk, &i, T.sizeof);
|
||||||
}
|
}
|
||||||
|
|
||||||
static if (Args.length == 0)
|
static if (is(typeof(result.__ctor(args))))
|
||||||
{
|
{
|
||||||
// Just initialize the thing
|
// T defines a genuine constructor accepting args
|
||||||
|
// Go the classic route: write .init first, then call ctor
|
||||||
initialize();
|
initialize();
|
||||||
|
result.__ctor(args);
|
||||||
}
|
}
|
||||||
else static if (is(T == struct))
|
else static if (is(typeof(T(args))))
|
||||||
{
|
{
|
||||||
static if (is(typeof(result.__ctor(args))))
|
// Struct without constructor that has one matching field for
|
||||||
{
|
// each argument
|
||||||
// T defines a genuine constructor accepting args
|
*result = T(args);
|
||||||
// Go the classic route: write .init first, then call ctor
|
|
||||||
initialize();
|
|
||||||
result.__ctor(args);
|
|
||||||
}
|
|
||||||
else static if (is(typeof(T(args))))
|
|
||||||
{
|
|
||||||
// Struct without constructor that has one matching field for
|
|
||||||
// each argument
|
|
||||||
initialize();
|
|
||||||
*result = T(args);
|
|
||||||
}
|
|
||||||
else static if (Args.length == 1 && is(Args[0] : T))
|
|
||||||
{
|
|
||||||
initialize();
|
|
||||||
*result = args[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else static if (Args.length == 1 && is(Args[0] : T))
|
else //static if (Args.length == 1 && is(Args[0] : T))
|
||||||
{
|
{
|
||||||
// Primitive type. Assignment is fine for initialization.
|
static assert(Args.length == 1);
|
||||||
|
//static assert(0, T.stringof ~ " " ~ Args.stringof);
|
||||||
|
// initialize();
|
||||||
*result = args[0];
|
*result = args[0];
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
static assert(false, "Don't know how to initialize an object of type "
|
|
||||||
~ T.stringof ~ " with arguments " ~ Args.stringof);
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
|
||||||
{
|
|
||||||
debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
|
|
||||||
int a;
|
|
||||||
int b = 42;
|
|
||||||
assert(*emplace!int((cast(void*) &a)[0 .. int.sizeof], b) == 42);
|
|
||||||
|
|
||||||
struct S
|
|
||||||
{
|
|
||||||
double x = 5, y = 6;
|
|
||||||
this(int a, int b) { assert(x == 5 && y == 6); x = a; y = b; }
|
|
||||||
}
|
|
||||||
|
|
||||||
auto s1 = new void[S.sizeof];
|
|
||||||
auto s2 = S(42, 43);
|
|
||||||
assert(*emplace!S(s1, s2) == s2);
|
|
||||||
assert(*emplace!S(s1, 44, 45) == S(44, 45));
|
|
||||||
}
|
|
||||||
|
|
||||||
// emplace
|
|
||||||
/**
|
|
||||||
Similar to $(D emplace) above, except it receives a pointer to an
|
|
||||||
uninitialized object of type $(D T). This overload is useful for
|
|
||||||
e.g. initializing member variables or stack variables defined with $(D
|
|
||||||
T variable = void).
|
|
||||||
|
|
||||||
Returns: A pointer to the newly constructed object.
|
|
||||||
*/
|
|
||||||
T* emplace(T, Args...)(T* chunk, Args args) if (!is(T == class))
|
|
||||||
{
|
|
||||||
// Since we're treating the memory pointed to by chunk as a raw memory
|
|
||||||
// block, we need to cast away any qualifiers.
|
|
||||||
return cast(T*) emplace!(Unqual!T)((cast(void*) chunk)[0 .. T.sizeof], args);
|
|
||||||
}
|
|
||||||
|
|
||||||
// emplace
|
|
||||||
/**
|
/**
|
||||||
Given a raw memory area $(D chunk), constructs an object of $(D class)
|
Given a raw memory area $(D chunk), constructs an object of $(D class)
|
||||||
type $(D T) at that address. The constructor is passed the arguments
|
type $(D T) at that address. The constructor is passed the arguments
|
||||||
|
@ -4170,6 +4142,60 @@ T emplace(T, Args...)(void[] chunk, Args args) if (is(T == class))
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Given a raw memory area $(D chunk), constructs an object of non-$(D
|
||||||
|
class) type $(D T) at that address. The constructor is passed the
|
||||||
|
arguments $(D args), if any. The $(D chunk) must be as least as large
|
||||||
|
as $(D T) needs and should have an alignment multiple of $(D T)'s
|
||||||
|
alignment.
|
||||||
|
|
||||||
|
This function can be $(D @trusted) if the corresponding constructor of
|
||||||
|
$(D T) is $(D @safe).
|
||||||
|
|
||||||
|
Returns: A pointer to the newly constructed object.
|
||||||
|
*/
|
||||||
|
T* emplace(T, Args...)(void[] chunk, Args args)
|
||||||
|
if (!is(T == class))
|
||||||
|
{
|
||||||
|
enforce(chunk.length >= T.sizeof,
|
||||||
|
new ConvException("emplace: chunk size too small"));
|
||||||
|
auto a = cast(size_t) chunk.ptr;
|
||||||
|
enforce(a % T.alignof == 0, text(a, " vs. ", T.alignof));
|
||||||
|
auto result = cast(typeof(return)) chunk.ptr;
|
||||||
|
return emplace(result, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
struct S { int a, b; }
|
||||||
|
auto p = new void[S.sizeof];
|
||||||
|
S s;
|
||||||
|
s.a = 42;
|
||||||
|
s.b = 43;
|
||||||
|
auto s1 = emplace!S(p, s);
|
||||||
|
assert(s1.a == 42 && s1.b == 43);
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__,
|
||||||
|
" succeeded.");
|
||||||
|
int a;
|
||||||
|
int b = 42;
|
||||||
|
assert(*emplace!int(&a, b) == 42);
|
||||||
|
|
||||||
|
struct S
|
||||||
|
{
|
||||||
|
double x = 5, y = 6;
|
||||||
|
this(int a, int b) { assert(x == 5 && y == 6); x = a; y = b; }
|
||||||
|
}
|
||||||
|
|
||||||
|
auto s1 = new void[S.sizeof];
|
||||||
|
auto s2 = S(42, 43);
|
||||||
|
assert(*emplace!S(cast(S*) s1.ptr, s2) == s2);
|
||||||
|
assert(*emplace!S(cast(S*) s1, 44, 45) == S(44, 45));
|
||||||
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
|
debug(conv) scope(success) writeln("unittest @", __FILE__, ":", __LINE__, " succeeded.");
|
||||||
|
@ -4200,7 +4226,6 @@ unittest
|
||||||
}
|
}
|
||||||
|
|
||||||
Foo foo;
|
Foo foo;
|
||||||
auto voidArr = (cast(void*) &foo)[0..Foo.sizeof];
|
emplace!Foo(&foo, 2U);
|
||||||
emplace!Foo(voidArr, 2U);
|
|
||||||
assert(foo.num == 2);
|
assert(foo.num == 2);
|
||||||
}
|
}
|
||||||
|
|
103
std/datetime.d
103
std/datetime.d
|
@ -28496,7 +28496,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
version(D_Ddoc)
|
version(StdDdoc)
|
||||||
{
|
{
|
||||||
/++
|
/++
|
||||||
The name of the time zone per the TZ Database. This is the name used to
|
The name of the time zone per the TZ Database. This is the name used to
|
||||||
|
@ -30587,7 +30587,7 @@ private:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
version(D_Ddoc)
|
version(StdDdoc)
|
||||||
{
|
{
|
||||||
|
|
||||||
/++
|
/++
|
||||||
|
@ -31119,7 +31119,7 @@ else version(Windows)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
version(D_Ddoc)
|
version(StdDdoc)
|
||||||
{
|
{
|
||||||
/++
|
/++
|
||||||
$(BLUE This function is Posix-Only.)
|
$(BLUE This function is Posix-Only.)
|
||||||
|
@ -32189,7 +32189,7 @@ unittest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
version(D_Ddoc)
|
version(StdDdoc)
|
||||||
{
|
{
|
||||||
version(Windows) {}
|
version(Windows) {}
|
||||||
else
|
else
|
||||||
|
@ -32982,76 +32982,61 @@ unittest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/++
|
||||||
|
Function for starting to a stop watch time when the function is called
|
||||||
|
and stopping it when its return value goes out of scope and is
|
||||||
|
destroyed.
|
||||||
|
|
||||||
version(D_Ddoc)
|
When the value that is returned by this function is destroyed, $(D
|
||||||
{
|
func) will run. $(D func) is a unary function that takes a $(D
|
||||||
/++
|
TickDuration).
|
||||||
Function for starting to a stop watch time when the function is called
|
|
||||||
and stopping it when its return value goes out of scope and is destroyed.
|
|
||||||
|
|
||||||
When the value that is returned by this function is destroyed,
|
Examples:
|
||||||
$(D func) will run. $(D func) is a unary function that takes a
|
|
||||||
$(D TickDuration).
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
--------------------
|
--------------------
|
||||||
writeln("benchmark start!");
|
writeln("benchmark start!");
|
||||||
{
|
{
|
||||||
auto mt = measureTime!((a){assert(a.seconds);});
|
auto mt = measureTime!((a){assert(a.seconds);});
|
||||||
doSomething();
|
doSomething();
|
||||||
}
|
}
|
||||||
writeln("benchmark end!");
|
writeln("benchmark end!");
|
||||||
--------------------
|
--------------------
|
||||||
+/
|
+/
|
||||||
auto measureTime(alias func)();
|
@safe auto measureTime(alias func)()
|
||||||
}
|
if(isSafe!func)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
@safe
|
struct Result
|
||||||
{
|
{
|
||||||
auto measureTime(alias func)()
|
private StopWatch sw = void;
|
||||||
if(isSafe!func)
|
this(StopWatch.AutoStart as)
|
||||||
{
|
{
|
||||||
struct TMP
|
sw = StopWatch(as);
|
||||||
{
|
}
|
||||||
private StopWatch sw = void;
|
~this()
|
||||||
this(StopWatch.AutoStart as)
|
{
|
||||||
{
|
unaryFun!(func)(sw.peek());
|
||||||
sw = StopWatch(as);
|
|
||||||
}
|
|
||||||
~this()
|
|
||||||
{
|
|
||||||
unaryFun!(func)(sw.peek());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TMP(autoStart);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@system
|
|
||||||
{
|
|
||||||
auto measureTime(alias func)()
|
|
||||||
if (!isSafe!func)
|
|
||||||
{
|
|
||||||
struct TMP
|
|
||||||
{
|
|
||||||
private StopWatch sw = void;
|
|
||||||
this(AutoStart as)
|
|
||||||
{
|
|
||||||
sw = StopWatch(as);
|
|
||||||
}
|
|
||||||
~this()
|
|
||||||
{
|
|
||||||
unaryFun!(func)(sw.peek());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TMP(autoStart);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return Result(autoStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@system
|
@system auto measureTime(alias func)() if (!isSafe!func)
|
||||||
unittest
|
{
|
||||||
|
struct TMP
|
||||||
|
{
|
||||||
|
private StopWatch sw = void;
|
||||||
|
this(AutoStart as)
|
||||||
|
{
|
||||||
|
sw = StopWatch(as);
|
||||||
|
}
|
||||||
|
~this()
|
||||||
|
{
|
||||||
|
unaryFun!(func)(sw.peek());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TMP(autoStart);
|
||||||
|
}
|
||||||
|
|
||||||
|
@system unittest
|
||||||
{
|
{
|
||||||
version(testStdDateTime)
|
version(testStdDateTime)
|
||||||
{
|
{
|
||||||
|
|
16
std/file.d
16
std/file.d
|
@ -601,7 +601,7 @@ unittest
|
||||||
* $(RED Scheduled for deprecation. Please use getTimesWin (for Windows)
|
* $(RED Scheduled for deprecation. Please use getTimesWin (for Windows)
|
||||||
* or getTimesPosix (for Posix) instead.)
|
* or getTimesPosix (for Posix) instead.)
|
||||||
*/
|
*/
|
||||||
version(D_Ddoc)
|
version(StdDdoc)
|
||||||
{
|
{
|
||||||
void getTimes(in char[] name,
|
void getTimes(in char[] name,
|
||||||
out d_time ftc,
|
out d_time ftc,
|
||||||
|
@ -668,7 +668,7 @@ else
|
||||||
static assert(0, "Unsupported/Unknown OS");
|
static assert(0, "Unsupported/Unknown OS");
|
||||||
|
|
||||||
|
|
||||||
version(D_Ddoc)
|
version(StdDdoc)
|
||||||
{
|
{
|
||||||
/++
|
/++
|
||||||
$(BLUE This function is Windows-Only.)
|
$(BLUE This function is Windows-Only.)
|
||||||
|
@ -877,7 +877,7 @@ else
|
||||||
static assert(0, "Unsupported/Unknown OS");
|
static assert(0, "Unsupported/Unknown OS");
|
||||||
|
|
||||||
|
|
||||||
version(D_Ddoc)
|
version(StdDdoc)
|
||||||
{
|
{
|
||||||
/++
|
/++
|
||||||
$(RED Scheduled for deprecation. Please use
|
$(RED Scheduled for deprecation. Please use
|
||||||
|
@ -911,7 +911,7 @@ else
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
version(D_Ddoc)
|
version(StdDdoc)
|
||||||
{
|
{
|
||||||
/++
|
/++
|
||||||
$(RED Scheduled for deprecation. Please use timeLastModified instead.)
|
$(RED Scheduled for deprecation. Please use timeLastModified instead.)
|
||||||
|
@ -1138,7 +1138,7 @@ uint getAttributes(in char[] name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
version(D_Ddoc)
|
version(StdDdoc)
|
||||||
{
|
{
|
||||||
/++
|
/++
|
||||||
If the given file is a symbolic link, then this returns the attributes of the
|
If the given file is a symbolic link, then this returns the attributes of the
|
||||||
|
@ -1724,7 +1724,7 @@ unittest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
version(D_Ddoc)
|
version(StdDdoc)
|
||||||
{
|
{
|
||||||
/++
|
/++
|
||||||
Info on a file, similar to what you'd get from stat on a Posix system.
|
Info on a file, similar to what you'd get from stat on a Posix system.
|
||||||
|
@ -2497,7 +2497,7 @@ version(Posix) void copy(in char[] from, in char[] to)
|
||||||
cenforce(utime(toz, &utim) != -1, from);
|
cenforce(utime(toz, &utim) != -1, from);
|
||||||
}
|
}
|
||||||
|
|
||||||
version(D_Ddoc)
|
version(StdDdoc)
|
||||||
{
|
{
|
||||||
/++
|
/++
|
||||||
$(RED Scheduled for deprecation. Please use the version which takes
|
$(RED Scheduled for deprecation. Please use the version which takes
|
||||||
|
@ -2553,7 +2553,7 @@ else
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
version(D_Ddoc)
|
version(StdDdoc)
|
||||||
{
|
{
|
||||||
/++
|
/++
|
||||||
Set access/modified times of file $(D name).
|
Set access/modified times of file $(D name).
|
||||||
|
|
|
@ -498,7 +498,7 @@ struct FormatSpec(Char)
|
||||||
$(D ubyte.max). ($(D 0) means not used).
|
$(D ubyte.max). ($(D 0) means not used).
|
||||||
*/
|
*/
|
||||||
ubyte index;
|
ubyte index;
|
||||||
version(D_Ddoc) {
|
version(StdDdoc) {
|
||||||
/**
|
/**
|
||||||
The format specifier contained a $(D '-') ($(D printf)
|
The format specifier contained a $(D '-') ($(D printf)
|
||||||
compatibility).
|
compatibility).
|
||||||
|
|
|
@ -383,8 +383,7 @@ template adjoin(F...) if (F.length)
|
||||||
Tuple!(Head, typeof(.adjoin!(F[1..$])(a)).Types) result = void;
|
Tuple!(Head, typeof(.adjoin!(F[1..$])(a)).Types) result = void;
|
||||||
foreach (i, Unused; result.Types)
|
foreach (i, Unused; result.Types)
|
||||||
{
|
{
|
||||||
auto store = (cast(void*) &result[i])[0 .. result[i].sizeof];
|
emplace(&result[i], F[i](a));
|
||||||
emplace!(typeof(result[i]))(store, F[i](a));
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
41
std/random.d
41
std/random.d
|
@ -878,7 +878,7 @@ auto a = uniform(0, 1024, gen);
|
||||||
auto a = uniform(0.0f, 1.0f, gen);
|
auto a = uniform(0.0f, 1.0f, gen);
|
||||||
----
|
----
|
||||||
*/
|
*/
|
||||||
version(D_Ddoc)
|
version(StdDdoc)
|
||||||
CommonType!(T1, T2) uniform(string boundaries = "[$(RPAREN)",
|
CommonType!(T1, T2) uniform(string boundaries = "[$(RPAREN)",
|
||||||
T1, T2, UniformRandomNumberGenerator)
|
T1, T2, UniformRandomNumberGenerator)
|
||||||
(T1 a, T2 b, ref UniformRandomNumberGenerator urng);
|
(T1 a, T2 b, ref UniformRandomNumberGenerator urng);
|
||||||
|
@ -964,7 +964,7 @@ if (is(CommonType!(T1, UniformRandomNumberGenerator) == void) &&
|
||||||
/**
|
/**
|
||||||
As above, but uses the default generator $(D rndGen).
|
As above, but uses the default generator $(D rndGen).
|
||||||
*/
|
*/
|
||||||
version(D_Ddoc)
|
version(StdDdoc)
|
||||||
CommonType!(T1, T2) uniform(string boundaries = "[$(RPAREN)", T1, T2)
|
CommonType!(T1, T2) uniform(string boundaries = "[$(RPAREN)", T1, T2)
|
||||||
(T1 a, T2 b) if (!is(CommonType!(T1, T2) == void));
|
(T1 a, T2 b) if (!is(CommonType!(T1, T2) == void));
|
||||||
else
|
else
|
||||||
|
@ -1082,34 +1082,39 @@ auto z = dice(70, 20, 10); // z is 0 70% of the time, 1 30% of the time,
|
||||||
// and 2 10% of the time
|
// and 2 10% of the time
|
||||||
----
|
----
|
||||||
*/
|
*/
|
||||||
size_t dice(R, Num)(ref R rnd, Num[] proportions...)
|
size_t dice(Rng, Num)(ref Rng rnd, Num[] proportions...)
|
||||||
if(isNumeric!Num) {
|
if (isNumeric!Num && isForwardRange!Rng)
|
||||||
|
{
|
||||||
return diceImpl(rnd, proportions);
|
return diceImpl(rnd, proportions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto
|
/// Ditto
|
||||||
size_t dice(R, Range)(ref R rnd, Range proportions)
|
size_t dice(R, Range)(ref R rnd, Range proportions)
|
||||||
if(isForwardRange!Range && isNumeric!(ElementType!Range) && !isArray!Range) {
|
if (isForwardRange!Range && isNumeric!(ElementType!Range) && !isArray!Range)
|
||||||
|
{
|
||||||
return diceImpl(rnd, proportions);
|
return diceImpl(rnd, proportions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto
|
/// Ditto
|
||||||
size_t dice(Num)(Num[] proportions...)
|
size_t dice(Range)(Range proportions)
|
||||||
if(isNumeric!Num) {
|
if (isForwardRange!Range && isNumeric!(ElementType!Range) && !isArray!Range)
|
||||||
|
{
|
||||||
return diceImpl(rndGen(), proportions);
|
return diceImpl(rndGen(), proportions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ditto
|
/// Ditto
|
||||||
size_t dice(Range)(Range proportions)
|
size_t dice(Num)(Num[] proportions...)
|
||||||
if(isForwardRange!Range && isNumeric!(ElementType!Range) && !isArray!Range) {
|
if (isNumeric!Num)
|
||||||
|
{
|
||||||
return diceImpl(rndGen(), proportions);
|
return diceImpl(rndGen(), proportions);
|
||||||
}
|
}
|
||||||
|
|
||||||
private size_t diceImpl(R, Range)(ref R rnd, Range proportions)
|
private size_t diceImpl(Rng, Range)(ref Rng rng, Range proportions)
|
||||||
if(isForwardRange!Range && isNumeric!(ElementType!Range)) {
|
if (isForwardRange!Range && isNumeric!(ElementType!Range) && isForwardRange!Rng)
|
||||||
immutable sum = reduce!("(assert(b >= 0), a + b)")(0.0, proportions.save);
|
{
|
||||||
|
double sum = reduce!("(assert(b >= 0), a + b)")(0.0, proportions.save);
|
||||||
enforce(sum > 0, "Proportions in a dice cannot sum to zero");
|
enforce(sum > 0, "Proportions in a dice cannot sum to zero");
|
||||||
immutable point = uniform(0.0, sum, rnd);
|
immutable point = uniform(0.0, sum, rng);
|
||||||
assert(point < sum);
|
assert(point < sum);
|
||||||
auto mass = 0.0;
|
auto mass = 0.0;
|
||||||
|
|
||||||
|
@ -1123,8 +1128,6 @@ if(isForwardRange!Range && isNumeric!(ElementType!Range)) {
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unittest {
|
unittest {
|
||||||
auto rnd = Random(unpredictableSeed);
|
auto rnd = Random(unpredictableSeed);
|
||||||
auto i = dice(rnd, 0.0, 100.0);
|
auto i = dice(rnd, 0.0, 100.0);
|
||||||
|
@ -1132,13 +1135,7 @@ unittest {
|
||||||
i = dice(rnd, 100.0, 0.0);
|
i = dice(rnd, 100.0, 0.0);
|
||||||
assert(i == 0);
|
assert(i == 0);
|
||||||
|
|
||||||
i = dice([100U, 0U]);
|
i = dice(100U, 0U);
|
||||||
assert(i == 0);
|
|
||||||
|
|
||||||
i = dice(filter!"a >= 0"([100U, 0U]));
|
|
||||||
assert(i == 0);
|
|
||||||
|
|
||||||
i = dice(rnd, filter!"a >= 0"([100U, 0U]));
|
|
||||||
assert(i == 0);
|
assert(i == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
3507
std/range.d
3507
std/range.d
File diff suppressed because it is too large
Load diff
23
std/traits.d
23
std/traits.d
|
@ -3376,6 +3376,29 @@ unittest
|
||||||
assert(is(S2 == immutable(int)), S2.stringof);
|
assert(is(S2 == immutable(int)), S2.stringof);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the corresponding unsigned value for $(D x), e.g. if $(D x)
|
||||||
|
* has type $(D int), returns $(D cast(uint) x). The advantage
|
||||||
|
* compared to the cast is that you do not need to rewrite the cast if
|
||||||
|
* $(D x) later changes type to e.g. $(D long).
|
||||||
|
*/
|
||||||
|
auto unsigned(T)(T x) if (isIntegral!T)
|
||||||
|
{
|
||||||
|
static if (is(Unqual!T == byte)) return cast(ubyte) x;
|
||||||
|
else static if (is(Unqual!T == short)) return cast(ushort) x;
|
||||||
|
else static if (is(Unqual!T == int)) return cast(uint) x;
|
||||||
|
else static if (is(Unqual!T == long)) return cast(ulong) x;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static assert(T.min == 0, "Bug in either unsigned or isIntegral");
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
static assert(is(typeof(unsigned(1 + 1)) == uint));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the most negative value of the numeric type T.
|
Returns the most negative value of the numeric type T.
|
||||||
|
|
|
@ -2286,7 +2286,7 @@ if (!is(T == class))
|
||||||
{
|
{
|
||||||
GC.addRange(p.ptr, sz);
|
GC.addRange(p.ptr, sz);
|
||||||
}
|
}
|
||||||
emplace!T(p[0 .. T.sizeof], args);
|
emplace(cast(T*) p.ptr, args);
|
||||||
_store = cast(typeof(_store)) p.ptr;
|
_store = cast(typeof(_store)) p.ptr;
|
||||||
_store._count = 1;
|
_store._count = 1;
|
||||||
debug(RefCounted) if (debugging) writeln(typeof(this).stringof,
|
debug(RefCounted) if (debugging) writeln(typeof(this).stringof,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue