// Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. #ifndef ARRAY_LIST_H #define ARRAY_LIST_H #include #include #include /** * A simple, resizable array list. Note that this only works with POD types * (because data is grown via realloc). */ template class array_list { static const size_t INITIAL_CAPACITY = 8; size_t _size; T * _data; size_t _capacity; private: // private and left undefined to disable copying array_list(const array_list& rhs); array_list& operator=(const array_list& rhs); public: array_list(); ~array_list(); size_t size() const; int32_t append(T value); int32_t push(T value); void pop(T *value); bool replace(T old_value, T new_value); int32_t index_of(T value) const; bool is_empty() const; T* data(); const T* data() const; T & operator[](size_t index); const T & operator[](size_t index) const; }; template array_list::array_list() { _size = 0; _capacity = INITIAL_CAPACITY; _data = (T *) malloc(sizeof(T) * _capacity); } template array_list::~array_list() { free(_data); } template size_t array_list::size() const { return _size; } template int32_t array_list::append(T value) { return push(value); } template int32_t array_list::push(T value) { if (_size == _capacity) { size_t new_capacity = _capacity * 2; void* buffer = realloc(_data, new_capacity * sizeof(T)); if (buffer == NULL) { fprintf(stderr, "array_list::push> " "Out of memory allocating %ld bytes", (long int) (new_capacity * sizeof(T))); abort(); } _data = (T *) buffer; _capacity = new_capacity; } _data[_size ++] = value; return _size - 1; } template void array_list::pop(T *value) { assert(_size > 0); if (value != NULL) { *value = _data[-- _size]; } else { -- _size; } } /** * Replaces the old_value in the list with the new_value. * Returns the true if the replacement succeeded, or false otherwise. */ template bool array_list::replace(T old_value, T new_value) { int index = index_of(old_value); if (index < 0) { return false; } _data[index] = new_value; return true; } template int32_t array_list::index_of(T value) const { for (size_t i = 0; i < _size; i++) { if (_data[i] == value) { return i; } } return -1; } template T & array_list::operator[](size_t index) { assert(index < size()); return _data[index]; } template const T & array_list::operator[](size_t index) const { assert(index < size()); return _data[index]; } template bool array_list::is_empty() const { return _size == 0; } template T* array_list::data() { return _data; } template const T* array_list::data() const { return _data; } #endif /* ARRAY_LIST_H */