fortran/trans-openmp.cc: Use the correct member in gfc_omp_namelist [PR118745]
[gcc.git] / libphobos / libdruntime / core / internal / util / array.d
blob066ee7e72db91e63510cb7b4f2ce02843df06745
1 /**
2 * Array utilities.
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)
8 */
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);
24 return _store;
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);
33 if (!allowOverlap)
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)
41 return;
43 UnsignedStringBuf tmpBuff = void;
44 string msg = "Array lengths don't match for ";
45 msg ~= action;
46 msg ~= ": ";
47 msg ~= length1.unsignedToTempString(tmpBuff);
48 msg ~= " != ";
49 msg ~= length2.unsignedToTempString(tmpBuff);
50 assert(0, msg);
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;
57 if (d >= bytes)
58 return;
59 const overlappedBytes = bytes - d;
61 UnsignedStringBuf tmpBuff = void;
62 string msg = "Overlapping arrays in ";
63 msg ~= action;
64 msg ~= ": ";
65 msg ~= overlappedBytes.unsignedToTempString(tmpBuff);
66 msg ~= " byte(s) overlap of ";
67 msg ~= bytes.unsignedToTempString(tmpBuff);
68 assert(0, msg);
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);
75 if (!allowOverlap)
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;
83 if (d >= bytes)
84 return;
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)
95 return;
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;