Mercurial > projects > dwt-mac
diff dwt/dwthelper/array.d @ 60:62202ce0039f
Updated and fixed many modules to 3.514
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Mon, 22 Dec 2008 15:10:19 +0100 |
parents | |
children | d32621bf0f90 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/dwthelper/array.d Mon Dec 22 15:10:19 2008 +0100 @@ -0,0 +1,325 @@ +/** + * Copyright: Copyright (c) 2008 Jacob Carlborg. All rights reserved. + * Authors: Jacob Carlborg + * Version: Initial created: 2008 + * License: $(LINK2 http://opensource.org/licenses/bsd-license.php, BSD Style) + * + */ +module dwt.dwthelper.array; + +version (Tango) +{ + static import tango.text.Util; + static import tango.core.Array; +} + +else + version = Phobos; + +/** + * Appends the specified element to the end of the array. + * + * Params: + * arr = the array to add the element to + * element = element to be appended to this list + * + * Returns: the modified array + * + * Throws: AssertException if the length of the array is 0 + * Throws: AssertException if the element is null + */ +T[] add (T) (ref T[] arr, T element) +in +{ + assert(arr.length > 0); +} +body +{ + return arr ~= element; +} + +/** + * Appends the specified element to the end of the array. + * + * Params: + * arr = the array to add the element to + * element = element to be appended to this list + * + * Returns: the modified array + * + * Throws: AssertException if the length of the array is 0 + * Throws: AssertException if the element is null + */ +alias add addElement; + +/** + * Gets the element at the specified index + * + * Params: + * arr = the array to get the element from + * index = the index of the element to get + * + * Returns: the element at the specified index + */ +T elementAt (T) (T[] arr, int index) +in +{ + assert(arr.length > 0); + assert(index > -1 && index < arr.length); +} +body +{ + return arr[index]; +} + +/** + * Returns the number of elements in the specified array. + * + * Params: + * arr = the array to get the number of elements from + * + * Returns: the number of elements in this list + */ +size_t size (T) (T[] arr) +{ + return arr.length; +} + +/** + * Removes the element at the specified position in the array + * if it could find it and returns it. + * Shifts any subsequent elements to the left. + * + * Params: + * arr = the array to remove the element from + * index = the index of the element to be removed + * + * Returns: the element that was removed or $(D_CODE null) + * + * Throws: AssertException if the length of the array is 0 + * Throws: AssertException if the $(D_CODE index) argument is + * negative or not less than the length of this array. + */ +T remove (T) (ref T[] arr, int index) +in +{ + assert(arr.length > 0); + assert(index > -1 && index < arr.length); +} +body +{ + T ret = arr[index]; + + // NOTE: Indexes are passed instead of references because DMD does + // not inline the reference-based version. + void exch (size_t p1, size_t p2) + { + T t = arr[p1]; + arr[p1] = arr[p2]; + arr[p2] = t; + } + + size_t cnt = 0; + + for (size_t pos = 0, len = arr.length; pos < len; ++pos) + { + if (pos == index) + ++cnt; + else + exch(pos, pos - cnt); + } + + arr = arr[0 .. $ - cnt]; + + return ret; +} + +/** + * Removes the specified element from the array + * if it could find it and returns it. + * Shifts any subsequent elements to the left. + * + * Params: + * arr = the array to remove the element from + * element = the element to be removed + * + * Returns: the element that was removed or $(null null) + * + * Throws: AssertException if the length of the array is 0 + */ +T remove (T) (ref T[] arr, T element) +in +{ + assert(arr.length > 0); +} +out (result) +{ + assert(result is element || result is null); +} +body +{ + int index = arr.indexOf(element); + + if (index == -1) + return null; + + return arr.remove(index); +} + +/** + * Removes the specified element from the array + * if it could find it and returns it. + * Shifts any subsequent elements to the left. + * + * Params: + * arr = the array to remove the element from + * element = the element to be removed + * + * Returns: the element that was removed or $(null null) + * + * Throws: AssertException if the length of the array is 0 + */ +alias remove removeElement; + +/** + * Returns the index of the first occurrence of the specified element + * in the array, or -1 if the array does not contain the element. + * + * Params: + * arr = the array to get the index of the element from + * element = the element to find + * + * Returns: the index of the element or -1 if it's not in the array + * + * Throws: AssertException if the length of the array is 0 + * Throws: AssertException if the return value is less than -1 or + * greater than the length of the array - 1. + */ +size_t indexOf (T, U = uint) (T[] arr, T element, U start = 0) +in +{ + assert(arr.length > 0); + assert(start >= 0); + assert(element !is null); +} +out (result) +{ + assert(result >= -1 && result < arr.length); +} +body +{ + uint index; + + version (Tango) + index = tango.text.Util.locate(arr, element); + + else + { + if (start > arr.length) + start = arr.length; + + index = privateIndexOf(arr.ptr, element, arr.length - start) + start; + } + + if (index == arr.length) + index = -1; + + return index; + + version (Phobos) + { + // tango.text.Util.locate + uint privateIndexOf (T* str, T match, uint length) + { + version (D_InlineAsm_X86) + { + static if (T.sizeof == 1) + { + asm + { + mov EDI, str; + mov ECX, length; + movzx EAX, match; + mov ESI, ECX; + and ESI, ESI; + jz end; + + cld; + repnz; + scasb; + jnz end; + sub ESI, ECX; + dec ESI; + end:; + mov EAX, ESI; + } + } + else static if (T.sizeof == 2) + { + asm + { + mov EDI, str; + mov ECX, length; + movzx EAX, match; + mov ESI, ECX; + and ESI, ESI; + jz end; + + cld; + repnz; + scasw; + jnz end; + sub ESI, ECX; + dec ESI; + end:; + mov EAX, ESI; + } + } + + else static if (T.sizeof == 4) + { + asm + { + mov EDI, str; + mov ECX, length; + mov EAX, match; + mov ESI, ECX; + and ESI, ESI; + jz end; + + cld; + repnz; + scasd; + jnz end; + sub ESI, ECX; + dec ESI; + end:; + mov EAX, ESI; + } + } + + else + { + auto len = length; + + for (auto p = str - 1; len--; ) + if (*++p is match) + return p - str; + + return length; + } + } + + else + { + auto len = length; + + for (auto p = str - 1; len--; ) + if (*++p is match) + return p - str; + + return length; + } + } + } +} \ No newline at end of file