1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
/**
Array utilities.
Copyright: Denis Shelomovskij 2013
License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
Authors: Denis Shelomovskij
Source: $(DRUNTIMESRC src/rt/util/_array.d)
*/
module rt.util.array;
import core.internal.string;
import core.stdc.stdint;
@safe /* pure dmd @@@BUG11461@@@ */ nothrow:
void enforceTypedArraysConformable(T)(const char[] action,
const T[] a1, const T[] a2, in bool allowOverlap = false)
{
_enforceSameLength(action, a1.length, a2.length);
if (!allowOverlap)
_enforceNoOverlap(action, arrayToPtr(a1), arrayToPtr(a2), T.sizeof * a1.length);
}
void enforceRawArraysConformable(const char[] action, in size_t elementSize,
const void[] a1, const void[] a2, in bool allowOverlap = false)
{
_enforceSameLength(action, a1.length, a2.length);
if (!allowOverlap)
_enforceNoOverlap(action, arrayToPtr(a1), arrayToPtr(a2), elementSize * a1.length);
}
private void _enforceSameLength(const char[] action,
in size_t length1, in size_t length2)
{
if (length1 == length2)
return;
UnsignedStringBuf tmpBuff = void;
string msg = "Array lengths don't match for ";
msg ~= action;
msg ~= ": ";
msg ~= length1.unsignedToTempString(tmpBuff, 10);
msg ~= " != ";
msg ~= length2.unsignedToTempString(tmpBuff, 10);
throw new Error(msg);
}
private void _enforceNoOverlap(const char[] action,
uintptr_t ptr1, uintptr_t ptr2, in size_t bytes)
{
const d = ptr1 > ptr2 ? ptr1 - ptr2 : ptr2 - ptr1;
if (d >= bytes)
return;
const overlappedBytes = bytes - d;
UnsignedStringBuf tmpBuff = void;
string msg = "Overlapping arrays in ";
msg ~= action;
msg ~= ": ";
msg ~= overlappedBytes.unsignedToTempString(tmpBuff, 10);
msg ~= " byte(s) overlap of ";
msg ~= bytes.unsignedToTempString(tmpBuff, 10);
throw new Error(msg);
}
private uintptr_t arrayToPtr(const void[] array) @trusted
{
// Ok because the user will never dereference the pointer
return cast(uintptr_t)array.ptr;
}
|