4 * Copyright: Denis Shelomovskij 2013
5 * License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
6 * Authors: Denis Shelomovskij
7 * Source: $(DRUNTIMESRC core/internal/util/_array.d)
9 module core
.internal
.util
.array
;
12 import core
.internal
.string
;
13 import core
.stdc
.stdint
;
16 // TLS storage shared for all error messages.
17 private align(2 * size_t
.sizeof
) char[256] _store
;
19 private char[] errorMessage(Args
...)(scope const(char*) format
,
20 const char[] action
, Args args
) @trusted
22 import core
.stdc
.stdio
: snprintf
;
23 snprintf(&_store
[0], _store
.sizeof
, format
, &action
[0], args
);
27 @safe /* pure dmd @@@BUG11461@@@ */ nothrow:
29 void enforceRawArraysConformable(const char[] action
, const size_t elementSize
,
30 const void[] a1
, const void[] a2
, const bool allowOverlap
= false)
32 _enforceSameLength(action
, a1
.length
, a2
.length
);
34 _enforceNoOverlap(action
, arrayToPtr(a1
), arrayToPtr(a2
), elementSize
* a1
.length
);
37 private void _enforceSameLength(const char[] action
,
38 const size_t length1
, const size_t length2
)
40 if (length1
== length2
)
43 UnsignedStringBuf tmpBuff
= void;
44 string msg
= "Array lengths don't match for ";
47 msg
~= length1
.unsignedToTempString(tmpBuff
);
49 msg
~= length2
.unsignedToTempString(tmpBuff
);
53 private void _enforceNoOverlap(const char[] action
,
54 uintptr_t ptr1
, uintptr_t ptr2
, const size_t bytes
)
56 const d
= ptr1
> ptr2 ? ptr1
- ptr2
: ptr2
- ptr1
;
59 const overlappedBytes
= bytes
- d
;
61 UnsignedStringBuf tmpBuff
= void;
62 string msg
= "Overlapping arrays in ";
65 msg
~= overlappedBytes
.unsignedToTempString(tmpBuff
);
66 msg
~= " byte(s) overlap of ";
67 msg
~= bytes
.unsignedToTempString(tmpBuff
);
71 void enforceRawArraysConformableNogc(const char[] action
, const size_t elementSize
,
72 const void[] a1
, const void[] a2
, const bool allowOverlap
= false)
74 _enforceSameLengthNogc(action
, a1
.length
, a2
.length
);
76 _enforceNoOverlapNogc(action
, arrayToPtr(a1
), arrayToPtr(a2
), elementSize
* a1
.length
);
79 private void _enforceNoOverlapNogc(const ref char[] action
,
80 uintptr_t ptr1
, uintptr_t ptr2
, const size_t bytes
)
82 const d
= ptr1
> ptr2 ? ptr1
- ptr2
: ptr2
- ptr1
;
85 const overlappedBytes
= bytes
- d
;
87 assert(0, errorMessage("Overlapping arrays in %s: %zu byte(s) overlap of %zu",
88 action
, overlappedBytes
, bytes
));
91 private void _enforceSameLengthNogc(const ref char[] action
,
92 const size_t length1
, const size_t length2
)
94 if (length1
== length2
)
97 assert(0, errorMessage("Array lengths don't match for %s: %zu != %zu",
98 action
, length1
, length2
));
101 private uintptr_t
arrayToPtr(const void[] array
) @trusted
103 // Ok because the user will never dereference the pointer
104 return cast(uintptr_t
)array
.ptr
;