Mercurial > projects > orange
diff orange/util/collection/Array.d @ 1:11a31bd929f9
Removed dependency on private library
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Mon, 31 May 2010 16:06:36 +0200 |
parents | |
children | 99c52d46822a |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/orange/util/collection/Array.d Mon May 31 16:06:36 2010 +0200 @@ -0,0 +1,625 @@ +/** + * Copyright: Copyright (c) 2008-2009 Jacob Carlborg. All rights reserved. + * Authors: Jacob Carlborg + * Version: Initial created: 2008 + * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) + * + */ +module orange.util.collection.Array; + +version (Tango) +{ + static import tango.core.Array; + import tango.stdc.string : memmove; + static import tango.text.Util; +} + +else +{ + version = Phobos; + + import std.c.string : memmove; +} + +/** + * Inserts the specified element at the specified position in the array. Shifts the + * element currently at that position (if any) and any subsequent elements to the right. + * + * Params: + * arr = the array to insert the element into + * index = the index at which the specified element is to be inserted + * element = the element to be inserted + * + * Returns: the modified array + * + * Throws: AssertException if the length of the array is 0 + * Throws: AssertException if the $(D_PARAM index) argument is + * greater than the length of this array. + */ +T[] insert (T, U = size_t) (ref T[] arr, U index, T element) +in +{ + assert(arr.length > 0, "mambo.collection.Array.insert: The length of the array was 0"); + assert(index <= arr.length, "mambo.collection.Array.insert: The index was greater than the length of the array"); +} +body +{ + if (index == arr.length) + { + arr ~= element; + return arr; + } + + else if (index == 0) + arr = element ~ arr; + + else + arr = arr[0 .. index] ~ element ~ arr[index .. $]; + + return arr; +} + +/** + * Inserts the specified elements at the specified position in the array. Shifts the + * element currently at that position (if any) and any subsequent elements to the right. + * + * Params: + * arr = the array to insert the element into + * index = the index at which the specified element is to be inserted + * element = the element to be inserted + * + * Returns: the modified array + * + * Throws: AssertException if the length of the array is 0 + * Throws: AssertException if the $(D_PARAM index) argument is + * not less or equal than the length of this array. + */ +T[] insert (T, U = size_t) (ref T[] arr, U index, T[] element) +in +{ + assert(arr.length > 0, "mambo.collection.Array.insert: The length of the array was 0"); + assert(index <= arr.length, "mambo.collection.Array.insert: The index was greater than the length of the array"); +} +body +{ + if (index == arr.length) + { + arr ~= element; + return arr; + } + + else if (index == 0) + arr = element ~ arr; + + else + arr = arr[0 .. index] ~ element ~ arr[index .. $]; + + return arr; +} + +/** + * Inserts the specified element at the specified position in the array. Shifts the + * element currently at that position (if any) and any subsequent elements to the right. + * + * Params: + * arr = the array to add the element to + * index = the index at which the specified element is to be inserted + * element = the element to be inserted + * + * Returns: the modified array + * + * Throws: AssertException if the length of the array is 0 + * Throws: AssertException if the $(D_PARAM index) argument is + * not less than the length of this array. + */ +T[] add (T, U = size_t) (ref T[] arr, U index, T element) +in +{ + assert(arr.length > 0, "mambo.collection.Array.add: The length of the array was 0"); + assert(index <= arr.length, "mambo.collection.Array.add: The index was greater than the length of the array"); +} +body +{ + return insert(arr, index, 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 + */ +T[] add (T) (ref T[] arr, T element) +{ + return arr ~= element; +} + +/** + * 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 + * + * Throws: AssertException if the length of the array is 0 + * Throws: AssertException if the $(D_PARAM index) argument is + * not less than the length of this array. + */ +T remove (T, U = size_t) (ref T[] arr, U index) +in +{ + assert(arr.length > 0, "mambo.collection.Array.remove: The length of the array was 0"); + assert(index < arr.length, "mambo.collection.Array.remove: The index was greater than the length of the array"); +} +body +{ + T ret = arr[index]; + + if (index == 0) + arr = arr[1 .. $]; + + else if (index == arr.length - 1) + arr = arr[0 .. $ - 1]; + + else + { + if (index < arr.length - 1) + memmove(&arr[index], &arr[index + 1], T.sizeof * (arr.length - index - 1)); + + arr.length = arr.length - 1; + } + + 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 T.max + * + * Throws: AssertException if the length of the array is 0 + */ +T remove (T) (ref T[] arr, T element) +in +{ + assert(arr.length > 0, "mambo.collection.Array.remove: The length of the array was 0"); +} +out (result) +{ + assert(result is element); +} +body +{ + size_t index = arr.indexOf(element); + + if (index == size_t.max) + return T.max; + + return arr.remove(index); +} + +/** + * Returns the index of the first occurrence of the specified element in the array, or + * U.max 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 + * start = the index where to begin the search + * + * Returns: the index of the element or U.max if it's not in the array + * + * Throws: AssertException if the length of the array is 0 + * Throws: AssertException if the return value is greater or + * equal to the length of the array. + */ +U indexOf (T, U = size_t) (T[] arr, T element, U start = 0) +in +{ + assert(start >= 0, "mambo.collection.Array.indexOf: The start index was less than 0"); +} +body +{ + version (Tango) + { + U index = tango.text.Util.locate(arr, element, start); + + if (index == arr.length) + index = U.max; + + return index; + } + + else + { + if (start > arr.length) + start = arr.length; + + for (U i = start; i < arr.length; i++) + if (arr[i] == element) + return i; + + return U.max; + } +} + +/** + * Returns $(D_KEYWORD true) if the array contains the specified element. + * + * Params: + * arr = the array to check if it contains the element + * element = the element whose presence in the array is to be tested + * + * Returns: $(D_KEYWORD true) if the array contains the specified element + * + * Throws: AssertException if the length of the array is 0 + */ +bool contains (T) (T[] arr, T element) +in +{ + assert(arr.length > 0, "mambo.collection.Array.contains: The length of the array was 0"); +} +body +{ + return arr.indexOf!(T, size_t)(element) < size_t.max; +} + +/** + * Returns $(D_KEYWORD true) if this array contains no elements. + * + * Params: + * arr = the array to check if it's empty + * + * Returns: $(D_KEYWORD true) if this array contains no elements + */ +bool isEmpty (T) (T[] arr) +{ + return arr.length == 0; +} + +/** + * Returns $(D_KEYWORD true) if this array contains no elements. + * + * Params: + * arr = the array to check if it's empty + * + * Returns: $(D_KEYWORD true) if this array contains no elements + */ +alias isEmpty empty; + +/** + * Removes all of the elements from this array. The array will be empty after this call + * returns. + * + * Params: + * arr = the array to clear + * + * Returns: the cleared array + * + * Throws: AssertException if length of the return array isn't 0 + */ +T[] clear (T) (T[] arr) +out (result) +{ + assert(result.length == 0, "mambo.collection.Array.clear: The length of the resulting array was not 0"); +} +body +{ + return arr.length = 0; +} + +/** + * Returns the element at the specified position in the array. + * + * Params: + * arr = the array to get the element from + * index = index of the element to return + * + * Returns: the element at the specified position in the array + * + * Throws: AssertException if the length of the array is 0 + * Throws: AssertException if the $(D_PARAM index) argument is + * not less than the length of this array. + */ +T get (T, U = size_t) (T[] arr, U index) +in +{ + assert(arr.length > 0, "mambo.collection.Array.get: The length of the array was 0"); + assert(index < arr.length, "mambo.collection.Array.get: The index was greater than the length of the array"); +} +body +{ + return arr[index]; +} + +/** + * Returns the index of the last occurrence of the specifed element + * + * Params: + * arr = the array to get the index of the element from + * element = the element to find the index of + * + * Returns: the index of the last occurrence of the element in the + * specified array, or U.max + * if the element does not occur. + * + * 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. + */ +U lastIndexOf (T, U = size_t) (T[] arr, T element) +in +{ + assert(arr.length > 0, "mambo.collection.Array.lastIndexOf: The length of the array was 0"); +} +body +{ + version (Tango) + { + U index = tango.text.Util.locatePrior(arr, element); + + if (index == arr.length) + return U.max; + + return index; + } + + else + { + foreach_reverse (i, e ; arr) + if (e is element) + return i; + + return U.max; + } +} + +/** + * 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 + */ +U size (T, U = size_t) (T[] arr) +{ + return arr.length; +} + +/** + * Finds the first occurence of element in arr + * + * Params: + * arr = the array to find the element in + * element = the element to find + * start = at which position to start finding + * + * Returns: the index of the first match or U.max if no match was found. + */ +alias indexOf find; + +/** + * Replaces a section of $(D_PARAM arr) with elements starting at $(D_PARAM pos) ending + * $(D_PARAM n) elements after + * + * Params: + * arr = the array to do the replace in + * pos = position within the array of the first element of the section to be replaced + * n = length of the section to be replaced within the array + * elements = the elements to replace with + * + * Throws: + * AssertException if pos is greater than the length of the array + * + * Returns: the array + */ +T[] replace (T, U = size_t) (ref T[] arr, U pos, U n, T[] elements) +in +{ + assert(pos <= arr.length, "mambo.collection.Array.replace: The position was greter than the length of the array"); +} +body +{ + U i; + U nr = n; + + if (nr > arr.length) + nr = arr.length - 1; + + if (nr == elements.length) + { + U eIndex; + + for (i = pos, eIndex = 0; i <= nr; i++, eIndex++) + arr[i] = elements[eIndex]; + + return arr; + } + + else if (elements.length == 0) + { + U index = pos + n; + + if (index >= arr.length) + index = arr.length; + + return arr = arr[0 .. pos] ~ arr[index .. $]; + } + + else + { + U eIndex; + + for (i = pos, eIndex = 0; eIndex < nr && i < arr.length && eIndex < elements.length; i++, eIndex++) + arr[i] = elements[eIndex]; + + // no positions left and elements are left in elements, insert elements + if (eIndex < elements.length) + return arr = arr[0 .. i] ~ elements[eIndex .. $] ~ arr[i .. $]; + + // positions left to replace but no elements, remove those positions + else if (nr > eIndex) + { + U index = pos + nr; + + if (index >= arr.length) + index = arr.length; + + return arr = arr[0 .. pos + eIndex] ~ arr[index .. $]; + } + + } + + return arr; +} + +/** + * Erases a part of the array content, shortening the length of the array. + * + * Params: + * arr = the array to erase elements from + * start = the position within the array of the first element to be erased + * n = amount of elements to be removed. It may remove less elements if the + * end of the array is reached before the n elements have been erased. + * The default value of n indicates that all the elements until the end + * of the array should be erased. + * + * Throws: + * AssertException if pos is greater than the length of the array + * + * Returns: the array + */ +T[] erase (T, U = size_t) (ref T[] arr, U start = 0, U n = U.max) +in +{ + assert(start <= arr.length, "mambo.collection.Array.erase: The start position was greater than the length of the array"); +} +body +{ + U end; + + if (n == U.max) + end = arr.length; + + else + { + end = start + n; + + if (end > arr.length) + end = arr.length; + } + + return arr = arr[0 .. start] ~ arr[end .. $]; +} + +/** + * Compares to arrays. Returns 0 if the content matches, less than zero + * if a is "less" than b, or greater than zero where a is "bigger". + * + * Params: + * a = the first array + * b = the second array + * end = the index where the comparision will end + * + * Returns: Returns 0 if the content matches, less than zero if a is + * "less" than b, or greater than zero where a is "bigger". + */ +int compare (T, U = size_t) (T[] a, T[] b, U end = U.max) +{ + U ia = end; + U ib = end; + + if (ia > a.length) + ia = a.length; + + if (ib > b.length) + ib = b.length; + + return typeid(T[]).compare(&a[0 .. ia], &b[0 .. ib]); +} + +/** + * Compares the content of the given array to the content of a comparing + * array, which is formed according to the arguments passed. + * + * The function returns 0 if all the elements in the compared contents compare + * equal, a negative value if the first element that does not match compares to + * less in the array than in the comparing array, and a positive value in + * the opposite case. + * + * Params: + * a = the first array to compare with + * pos = position of the beginning of the compared slice, i.e. the first element in the array (in a) to be compared against the comparing array. + * n = length of the compared slice. + * b = array with the content to be used as comparing array. + * + * Returns: 0 if the compared array are equal, otherwise a number different from 0 is returned, with its sign indicating whether the array is considered greater than the comparing array passed as parameter (positive sign), or smaller (negative sign). + * + * Throws: AssertException if pos is specified with a position greater than the length of the corresponding array + */ +int compare (T, U = size_t) (T[] a, size_t pos, size_t n, T[] b) +in +{ + assert(pos <= b.length); +} +body +{ + U end = pos + n; + + if (end > b.length) + end = b.length; + + return typeid(T[]).compare(&b[pos .. end], &a[0 .. $]); +} + +/** + * Reserves the given amount of allocated storage for the given array. + * + * Params: + * a = the array to reserve allocated storage for + * capacity = the amount of allocated storage to be reserved + */ +void reserve (T) (ref T[] a, size_t amount = 0) +{ + a = (new T[amount])[0 .. 0]; +} + +/** + * Returns true if a begins with b + * + * Params: + * a = the array to + * b = + * + * Returns: true if a begins with b, otherwise false + */ +bool beginsWith (T) (T[] a, T[] b) +{ + return a.length > b.length && a[0 .. b.length] == b; +} + +/** + * Returns true if a ends with b + * + * Params: + * a = the array to + * b = + * + * Returns: true if a ends with b, otherwise false + */ +bool endsWith (T) (T[] a, T[] b) +{ + return a.length > b.length && a[$ - b.length .. $] == b; +} \ No newline at end of file