github.com/tcnksm/go@v0.0.0-20141208075154-439b32936367/src/cmd/gc/array.c (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #include <u.h> 6 #include <libc.h> 7 #include "go.h" 8 9 enum { 10 DEFAULTCAPACITY = 16, 11 }; 12 13 struct Array 14 { 15 int32 length; // number of elements 16 int32 size; // element size 17 int32 capacity; // size of data in elements 18 char *data; // element storage 19 }; 20 21 Array* 22 arraynew(int32 capacity, int32 size) 23 { 24 Array *result; 25 26 if(capacity < 0) 27 fatal("arraynew: capacity %d is not positive", capacity); 28 if(size < 0) 29 fatal("arraynew: size %d is not positive\n", size); 30 result = malloc(sizeof(*result)); 31 if(result == nil) 32 fatal("arraynew: malloc failed\n"); 33 result->length = 0; 34 result->size = size; 35 result->capacity = capacity == 0 ? DEFAULTCAPACITY : capacity; 36 result->data = malloc(result->capacity * result->size); 37 if(result->data == nil) 38 fatal("arraynew: malloc failed\n"); 39 return result; 40 } 41 42 void 43 arrayfree(Array *array) 44 { 45 if(array == nil) 46 return; 47 free(array->data); 48 free(array); 49 } 50 51 int32 52 arraylength(Array *array) 53 { 54 return array->length; 55 } 56 57 void* 58 arrayget(Array *array, int32 index) 59 { 60 if(array == nil) 61 fatal("arrayget: array is nil\n"); 62 if(index < 0 || index >= array->length) 63 fatal("arrayget: index %d is out of bounds for length %d\n", index, array->length); 64 return array->data + index * array->size; 65 } 66 67 void 68 arrayset(Array *array, int32 index, void *element) 69 { 70 if(array == nil) 71 fatal("arrayset: array is nil\n"); 72 if(element == nil) 73 fatal("arrayset: element is nil\n"); 74 if(index < 0 || index >= array->length) 75 fatal("arrayget: index %d is out of bounds for length %d\n", index, array->length); 76 memmove(array->data + index * array->size, element, array->size); 77 } 78 79 static void 80 ensurecapacity(Array *array, int32 capacity) 81 { 82 int32 newcapacity; 83 char *newdata; 84 85 if(array == nil) 86 fatal("ensurecapacity: array is nil\n"); 87 if(capacity < 0) 88 fatal("ensurecapacity: capacity %d is not positive", capacity); 89 if(capacity >= array->capacity) { 90 newcapacity = capacity + (capacity >> 1); 91 newdata = realloc(array->data, newcapacity * array->size); 92 if(newdata == nil) 93 fatal("ensurecapacity: realloc failed\n"); 94 array->capacity = newcapacity; 95 array->data = newdata; 96 } 97 } 98 99 void 100 arrayadd(Array *array, void *element) 101 { 102 if(array == nil) 103 fatal("arrayset: array is nil\n"); 104 if(element == nil) 105 fatal("arrayset: element is nil\n"); 106 ensurecapacity(array, array->length + 1); 107 array->length++; 108 arrayset(array, array->length - 1, element); 109 } 110 111 void 112 arraysort(Array *array, int (*cmp)(const void*, const void*)) 113 { 114 qsort(array->data, array->length, array->size, cmp); 115 }