github.com/bgentry/go@v0.0.0-20150121062915-6cf5a733d54d/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  }