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