Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions std/datetime/timezone.d
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ public:
else version(DragonFlyBSD) enum utcZone = "UTC";
else version(linux) enum utcZone = "UTC";
else version(OSX) enum utcZone = "UTC";
else version(Solaris) enum utcZone = "UTC";
else static assert(0, "The location of the UTC timezone file on this Posix platform must be set.");

auto tzs = [testTZ("America/Los_Angeles", "PST", "PDT", dur!"hours"(-8), dur!"hours"(1)),
Expand Down Expand Up @@ -2007,6 +2008,14 @@ public:
// Android concatenates all time zone data into a single file and stores it here.
enum defaultTZDatabaseDir = "/system/usr/share/zoneinfo/";
}
else version(Solaris)
{
/++
The default directory where the TZ Database files are. It's empty
for Windows, since Windows doesn't have them.
+/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this comment need to be copy-pasted for every platform?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAICT just because the version(TZDatabaseDir) branch (which seems obsolete) doesn't start with the enum, but needs a prior import; otherwise, the comment could be placed once before the version branches. [Outside the scope of this PR though.]

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was added a week ago: #5966

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW we only support building the docs on Posix since 1.5 years, so adding comments in other branches isn't needed, but doesn't hurt either.
Anyhow @kinke said, it doesn't block this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ddoc comment really should be put in a StdDdoc version block and removed from the other versions.

Copy link
Contributor

@joakim-noah joakim-noah Jan 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see no reason to put this off for later, I'd rather it were at the top with a StdDdoc version or just as a comment. Just change it to say that Windows doesn't have one and TZDatabaseDir lets you set one at compile-time in an external file, which btw it doesn't even explain now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who can take care of this in a follow up?

enum defaultTZDatabaseDir = "/usr/share/lib/zoneinfo/";
}
else version(Posix)
{
/++
Expand Down
82 changes: 68 additions & 14 deletions std/digest/murmurhash.d
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ $(BR) $(LINK2 https://en.wikipedia.org/wiki/MurmurHash, Wikipedia)
*/
module std.digest.murmurhash;

version (X86)
version = HaveUnalignedLoads;
else version (X86_64)
version = HaveUnalignedLoads;

///
@safe unittest
{
Expand Down Expand Up @@ -500,28 +505,74 @@ struct MurmurHash3(uint size /* 32 or 128 */ , uint opt = size_t.sizeof == 8 ? 6
// Buffer should never be full while entering this function.
assert(bufferSize < Element.sizeof);

// Check if we have some leftover data in the buffer. Then fill the first block buffer.
// Check if we don't fill up a whole block buffer.
if (bufferSize + data.length < Element.sizeof)
{
buffer.data[bufferSize .. bufferSize + data.length] = data[];
bufferSize += data.length;
return;
}
const bufferLeeway = Element.sizeof - bufferSize;
assert(bufferLeeway <= Element.sizeof);
buffer.data[bufferSize .. $] = data[0 .. bufferLeeway];
putElement(buffer.block);
data = data[bufferLeeway .. $];

// Check if we have some leftover data in the buffer. Then fill the first block buffer.
if (bufferSize != 0)
{
const bufferLeeway = Element.sizeof - bufferSize;
buffer.data[bufferSize .. $] = data[0 .. bufferLeeway];
putElement(buffer.block);
element_count += Element.sizeof;
data = data[bufferLeeway .. $];
}

// Do main work: process chunks of `Element.sizeof` bytes.
const numElements = data.length / Element.sizeof;
const remainderStart = numElements * Element.sizeof;
foreach (ref const Element block; cast(const(Element[]))(data[0 .. remainderStart]))
version (HaveUnalignedLoads)
{
putElement(block);
foreach (ref const Element block; cast(const(Element[])) data[0 .. remainderStart])
{
putElement(block);
}
}
// +1 for bufferLeeway Element.
element_count += (numElements + 1) * Element.sizeof;
else
{
void processChunks(T)() @trusted
{
alias TChunk = T[Element.sizeof / T.sizeof];
foreach (ref const chunk; cast(const(TChunk[])) data[0 .. remainderStart])
{
static if (T.alignof >= Element.alignof)
{
putElement(*cast(const(Element)*) chunk.ptr);
}
else
{
Element[1] alignedCopy = void;
(cast(T[]) alignedCopy)[] = chunk[];
putElement(alignedCopy[0]);
}
}
}

const startAddress = cast(size_t) data.ptr;
static if (size >= 64)
{
if ((startAddress & 7) == 0)
{
processChunks!ulong();
goto L_end;
}
}
static assert(size >= 32);
if ((startAddress & 3) == 0)
processChunks!uint();
else if ((startAddress & 1) == 0)
processChunks!ushort();
else
processChunks!ubyte();

L_end:
}
element_count += numElements * Element.sizeof;
data = data[remainderStart .. $];

// Now add remaining data to buffer.
Expand Down Expand Up @@ -743,10 +794,13 @@ version (unittest)
// Pushing unaligned data and making sure the result is still coherent.
void testUnalignedHash(H)()
{
immutable ubyte[1025] data = 0xAC;
immutable alignedHash = digest!H(data[0 .. $ - 1]); // 0 .. 1023
immutable unalignedHash = digest!H(data[1 .. $]); // 1 .. 1024
assert(alignedHash == unalignedHash);
immutable ubyte[1028] data = 0xAC;
immutable alignedHash = digest!H(data[0 .. 1024]);
foreach (i; 1 .. 5)
{
immutable unalignedHash = digest!H(data[i .. 1024 + i]);
assert(alignedHash == unalignedHash);
}
}

testUnalignedHash!(MurmurHash3!32)();
Expand Down
89 changes: 80 additions & 9 deletions std/math.d
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ version (X86) version = X86_Any;
version (X86_64) version = X86_Any;
version (PPC) version = PPC_Any;
version (PPC64) version = PPC_Any;
version (MIPS) version = MIPS_Any;
version (MIPS64) version = MIPS_Any;

version(D_InlineAsm_X86)
{
Expand All @@ -169,7 +171,7 @@ version (StaticallyHaveSSE)
{
private enum bool haveSSE = true;
}
else
else version (X86)
{
static import core.cpuid;
private alias haveSSE = core.cpuid.sse;
Expand Down Expand Up @@ -881,8 +883,10 @@ Lret: {}
}
else
{
enum realFormat = floatTraits!real.realFormat;

// Coefficients for tan(x) and PI/4 split into three parts.
static if (floatTraits!real.realFormat == RealFormat.ieeeQuadruple)
static if (realFormat == RealFormat.ieeeQuadruple)
{
static immutable real[6] P = [
2.883414728874239697964612246732416606301E10L,
Expand Down Expand Up @@ -946,9 +950,10 @@ Lret: {}
// Compute x mod PI/4.
real y = floor(x / PI_4);
// Strip high bits of integer part.
real z = ldexp(y, -4);
// Compute y - 16 * (y / 16).
z = y - ldexp(floor(z), 4);
enum numHighBits = (realFormat == RealFormat.ieeeDouble ? 3 : 4);
real z = ldexp(y, -numHighBits);
// Compute y - 2^numHighBits * (y / 2^numHighBits).
z = y - ldexp(floor(z), numHighBits);

// Integer and fraction part modulo one octant.
int j = cast(int)(z);
Expand All @@ -963,7 +968,8 @@ Lret: {}
z = ((x - y * P1) - y * P2) - y * P3;
const real zz = z * z;

if (zz > 1.0e-20L)
enum zzThreshold = (realFormat == RealFormat.ieeeDouble ? 1.0e-14L : 1.0e-20L);
if (zz > zzThreshold)
y = z + z * (zz * poly(zz, P) / poly(zz, Q));
else
y = z;
Expand Down Expand Up @@ -4880,6 +4886,18 @@ version(X86_Any)
{
version = IeeeFlagsSupport;
}
else version(PPC_Any)
{
version = IeeeFlagsSupport;
}
else version(MIPS_Any)
{
version = IeeeFlagsSupport;
}
else version(AArch64)
{
version = IeeeFlagsSupport;
}
else version(ARM)
{
version = IeeeFlagsSupport;
Expand Down Expand Up @@ -5024,6 +5042,21 @@ struct FloatingPointControl
allExceptions, /// ditto
}
}
else version(AArch64)
{
enum : ExceptionMask
{
inexactException = 0x1000,
underflowException = 0x0800,
overflowException = 0x0400,
divByZeroException = 0x0200,
invalidException = 0x0100,
severeExceptions = overflowException | divByZeroException
| invalidException,
allExceptions = severeExceptions | underflowException
| inexactException,
}
}
else version(ARM)
{
enum : ExceptionMask
Expand Down Expand Up @@ -5055,6 +5088,21 @@ struct FloatingPointControl
| inexactException,
}
}
else version(MIPS_Any)
{
enum : ExceptionMask
{
inexactException = 0x0800,
divByZeroException = 0x0400,
overflowException = 0x0200,
underflowException = 0x0100,
invalidException = 0x0080,
severeExceptions = overflowException | divByZeroException
| invalidException,
allExceptions = severeExceptions | underflowException
| inexactException,
}
}
else version (X86_Any)
{
enum : ExceptionMask
Expand Down Expand Up @@ -5082,6 +5130,18 @@ public:
return true;
else version(PPC_Any)
return true;
else version(MIPS_Any)
return true;
else version(AArch64)
{
auto oldState = getControlState();
// If exceptions are not supported, we set the bit but read it back as zero
// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/aarch64/fpu/feenablxcpth.c
setControlState(oldState | (divByZeroException & allExceptions));
immutable result = (getControlState() & allExceptions) != 0;
setControlState(oldState);
return result;
}
else version(ARM)
{
auto oldState = getControlState();
Expand Down Expand Up @@ -5141,14 +5201,22 @@ private:

bool initialized = false;

version(ARM)
version(AArch64)
{
alias ControlState = uint;
}
else version(ARM)
{
alias ControlState = uint;
}
else version(PPC_Any)
{
alias ControlState = uint;
}
else version(MIPS_Any)
{
alias ControlState = uint;
}
else version (X86_Any)
{
alias ControlState = ushort;
Expand Down Expand Up @@ -7687,9 +7755,12 @@ bool approxEqual(T, U)(T lhs, U rhs)

// Verify correct behavior for large inputs
assert(!isNaN(tan(0x1p63)));
assert(!isNaN(tan(0x1p300L)));
assert(!isNaN(tan(-0x1p63)));
assert(!isNaN(tan(-0x1p300L)));
static if (real.mant_dig >= 64)
{
assert(!isNaN(tan(0x1p300L)));
assert(!isNaN(tan(-0x1p300L)));
}
}

@safe pure nothrow unittest
Expand Down