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