/* * Copyright (c) 2004-2008 Apple Inc. All rights reserved. * * @APPLE_APACHE_LICENSE_HEADER_START@ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @APPLE_APACHE_LICENSE_HEADER_END@ */ #pragma once #ifndef __AUTO_LIST__ #define __AUTO_LIST__ #include "AutoDefs.h" #include "AutoHashTable.h" #include "AutoRange.h" namespace Auto { //----- List -----// // // Manage an unordered growable list of objects. Using home grow version because // we need to control memory allocation (investigate STL.) // template <typename T> class List { private: enum { list_growth = 256 // default growth rate }; T *_entries; // array of entries usword_t _length; // virtual length of list usword_t _maximum; // actual length of list usword_t _growth; // rate of growth public: // // Constructor // List(usword_t growth = list_growth) : _entries(NULL), _length(0), _maximum(0), _growth(growth) {} // // Destructor // ~List() { dispose(); } // // initialize // // Set up the list for use. // inline void initialize(usword_t growth = list_growth) { _entries = NULL; _length = 0; _maximum = 0; _growth = growth; } // // dispose // // Release memory used by List. // inline void dispose() { if (_entries) aux_free(_entries); _entries = NULL; _length = 0; _maximum = 0; } // // grab // // Grabs the entries for someone else to maintain. // inline T *grab() { T *entries = _entries; _entries = NULL; _length = 0; _maximum = 0; return entries; } // // allocate // // allocate a new slot in the list // inline T *allocate() { if (_length >= _maximum) { _maximum += _growth; _entries = (T *)aux_realloc(_entries, _maximum * sizeof(T)); } return _entries + _length++; } // // add // // Adds a new range to the list. // inline T *add(T *entry) { T *slot = allocate(); *slot = *entry; return slot; } inline T *add(T entry) { T *slot = allocate(); *slot = entry; return slot; } // // set_growth // // Change the default growth rate. // inline void set_growth(usword_t growth) { _growth = growth; } // // memory // // Return address of memory used for entries (used by InUseEnumerator.) // inline void *memory() { return (void *)_entries; } // // length // // Actual number of entries in list. // inline usword_t length() const { return _length; } // // maximum // // Current maximum number of entries in list. // inline usword_t maximum() { return _maximum; } // // index // // Return the index of the specified entry. // inline size_t index(T *entry) const { size_t i = entry - _entries; ASSERTION(0 <= i && i < _length); return i; } // // find // // Locate an entry in the list. Requires that entries define an operator==. // inline T* find(T entry) { for (size_t i = 0; i < _length; i++) { if (_entries[i] == entry) return _entries + i; } return NULL; } // // [] operator // // Simplify use of the list. // // An assert would be appropriate here but it slows things down considerably. // inline T& operator[](size_t i) { return _entries[i]; } // // remove // // Remove an entry from the list. // inline void remove(size_t i) { if (i != --_length) _entries[i] = _entries[_length]; } inline void remove(T *entry) { if (entry) remove(index(entry)); } // // is_empty // // Return true if the list contains no elements. // inline bool is_empty() const { return _length == 0; } // // push // // Push an element on to the list // inline void push(T *entry) { add(entry); } inline void push(T entry) { add(entry); } // // pop // // Push an element on to the list // inline T pop() { return _entries[--_length]; } }; }; #endif // __AUTO_LIST__