📄 l3_array_auto.h
字号:
#ifndef _INCLUDED_L3_ARRAY_AUTO_H#define _INCLUDED_L3_ARRAY_AUTO_H// Copyright (C) Krzysztof Bosak, 1999-07-22...2001-01-10.// All rights reserved.// kbosak@box43.pl// http://www.kbosak.prv.pl#include "l3_array_common.h"/////////////////////////////////////////////////////////////////////////////template<class type>class autoarray: protected common_array_algorithms<type>{ // Corresponds to std::vector. // For objects with non-trivial constructors and destructors! // new/delete in constructors/destructors ARE ALLOWED. // Unused objects ARE NOT DESTROYED IMMEDIATELY during resizing, often much later. // Uses memory amount proportional to _size // (no additional buffered allocations). // operator= and copy constructor changes size. // Is EXCEPTION NEUTRAL.protected: int _size; int _capacity; type * _data;public: autoarray(); explicit autoarray(int requested_size); // EXCEPTION NEUTRAL autoarray(const autoarray<type>& src); // EXCEPTION NEUTRAL // Implicit. autoarray(const type * const arr, int requested_size); // not STL vector // EXCEPTION NEUTRAL autoarray(int requested_size, const type& fill_value); // EXCEPTION NEUTRAL // Efficient nonstandard extension: void setsize(int requested_size); // not STL // EXCEPTION NEUTRAL autoarray<type>& operator=(const autoarray<type>& other); // EXCEPTION NEUTRAL inline virtual ~autoarray() // NOTHROW { // Formal destructor delete[] _data; } inline type& operator[](int element_index) // EXCEPTION NEUTRAL { // Returns object contained in array by reference, changes are possible INDEXING_TEST(_size); return _data[element_index]; } inline const type& operator[](int element_index) const // EXCEPTION NEUTRAL { // Returns object contained in array by reference, no changes to data INDEXING_TEST(_size); return _data[element_index]; } inline void clear() // NOTHROW { _size=0; } inline int size() const // NOTHROW { // Returns current size of array return _size; } inline int max_size() const // NOTHROW { // 2 times smaller than for std::allocator due to 'int' used instead of 'unsigned' return INT_MAX/sizeof(type); } inline bool empty() const // NOTHROW { // Is array empty? return _size==0; } inline int capacity() const // NOTHROW { // Returns current capacity of array return _capacity; } void resize(int requested_size); // EXCEPTION NEUTRAL void reserve(int reserve_size); // EXCEPTION NEUTRAL inline void swap(autoarray<type>& other); // NOTHROW // STL compliant, but less recommended: /// inline type& front() // NOTHROW { assert(_size>0); return _data[0]; } inline const type& front() const // NOTHROW { assert(_size>0); return _data[0]; } inline type& back() // NOTHROW { assert(_size>0); return _data[_size-1]; } inline const type& back() const // NOTHROW { assert(_size>0); return _data[_size-1]; } /// inline void push_back(const type& object) // EXCEPTION NEUTRAL { #ifdef USE_ARRAY_EXCEPTIONS // Commit or rollback... Very costly. autoarray<type> temp(_size+1); temp.setsize(_size+1); _UnrolledCopyLoop(temp._data, _data, _size); temp.back()=object; swap(temp); #else // Rather costly. const int oldsize=_size; if(oldsize+1>_capacity) { resize(((oldsize+1)<<1)+1); } _size=oldsize+1; _data[oldsize]=object; #endif } void pop_back() // NOTHROW { assert(_size>0); _size--; } /// inline type& at(int element_index) // NOTHROW { // Returns object contained in array by reference. INDEXING_TEST(_size); return _data[element_index]; } inline const type& at(int element_index) const // NOTHROW { // Returns object contained in array by reference, no changes allowed. INDEXING_TEST(_size); return _data[element_index]; } /// inline type* begin() // NOTHROW { assert(_size>0);// STL doesn't require to have nonempty sequence here. return _data; } inline const type* begin() const // NOTHROW { assert(_size>0);// STL doesn't require to have nonempty sequence here. return _data; } inline type* end() // NOTHROW { assert(_size>0);// STL doesn't require to have nonempty sequence here. return _data+_size; } inline const type* end() const // NOTHROW { assert(_size>0);// STL doesn't require to have nonempty sequence here. return _data+_size; } /// inline type* rbegin() // NOTHROW { assert(_size>0);// STL doesn't require to have nonempty sequence here. return _data+_size-1; } inline const type* rbegin() const // NOTHROW { assert(_size>0);// STL doesn't require to have nonempty sequence here. return _data+_size-1; } inline type* rend() // NOTHROW { assert(_size>0);// STL doesn't require to have nonempty sequence here. return _data-1; } inline const type* rend() const // NOTHROW { assert(_size>0);// STL doesn't require to have nonempty sequence here. return _data-1; } /// inline int memory() const // not STL // NOTHROW { // Returns memory usage of array in bytes assert(_capacity>=_size); return _capacity*sizeof(type)+sizeof(*this); } inline void free() // not STL // NOTHROW { // Sets array to minimum usage of memory delete[] _data; _data=NULL;// A must: delete operator must not set _data to NULL, by C++ standards, (and very rarely does it) _size=0; _capacity=0; } void trim(); // not STL // EXCEPTION NEUTRAL void reverse(); // not STL // NOTHROW inline void fill(const type fill_value) // not STL // NOTHROW { // Fills the whole array with given value _UnrolledFillLoop(_data, fill_value, _size); }};template<class type>autoarray<type>::autoarray() // NOTHROW : _size(0), _capacity(0), _data(NULL){ // Quick default constructor}template<class type>autoarray<type>::autoarray(int requested_size) // EXCEPTION NEUTRAL{ // Constructor assert(requested_size>=0); assert(requested_size<=max_size()); if(requested_size==0) { _size=0; _capacity=0; _data=NULL; return; } _size=requested_size; _capacity=requested_size; _data=new type[requested_size]; MEMORY_ALLOCATION_TEST(_data, requested_size);}template<class type>autoarray<type>::autoarray(const autoarray<type>& src) // EXCEPTION NEUTRAL{ // Copy constructor assert(&src!=this); if(src._size==0) { _size=0; _capacity=0; _data=NULL; return; } _size=src._size; _capacity=src._size; _data=new type[src._size]; MEMORY_ALLOCATION_TEST(_data, src._size); _UnrolledCopyLoop(_data, src._data, _size);}template<class type>autoarray<type>::autoarray(const type * const arr, int requested_size) // EXCEPTION NEUTRAL{ // Constructor from const C array assert(requested_size>=0); assert(requested_size<=max_size()); if(requested_size==0) { _size=0; _capacity=0; _data=NULL; return; } assert(arr!=NULL); _size=requested_size; _capacity=requested_size; _data=new type[requested_size]; MEMORY_ALLOCATION_TEST(_data, requested_size); _UnrolledCopyLoop(_data, arr, _size);}template<class type>autoarray<type>::autoarray(int requested_size, const type& fill_value) // EXCEPTION NEUTRAL{ // Filling constructor assert(requested_size>=0); assert(requested_size<=max_size()); if(requested_size==0) { _size=0; _capacity=0; _data=NULL; return; } _size=requested_size; _capacity=requested_size; _data=new type[requested_size]; MEMORY_ALLOCATION_TEST(_data, requested_size); _UnrolledFillLoop(_data, fill_value, _size);}// Efficient nonstandard extension:template<class type>void autoarray<type>::setsize(int requested_size) // not STL // EXCEPTION NEUTRAL{ // Resizes, but does not prevents content of array, may preserwe some old, // unused memory for future assert(requested_size>=0); assert(requested_size<=max_size()); assert(_size<=_capacity); if(requested_size>_capacity) { assert(requested_size>0); _capacity=requested_size; type * const temp=new type[requested_size]; MEMORY_ALLOCATION_TEST(temp, requested_size); delete[] _data; _data=temp; } _size=requested_size;}template<class type>autoarray<type>& autoarray<type>::operator=(const autoarray<type>& other) // EXCEPTION NEUTRAL{ assert(this!=&other);// This line can be safely ommitted. autoarray<type> temp(other); swap(temp); return *this;}template<class type>void autoarray<type>::resize(int requested_size) // EXCEPTION NEUTRAL{ // Resizes and prevents content of array assert(requested_size>=0); assert(requested_size<=max_size()); assert(_size<=_capacity); if(requested_size>_capacity) { assert(requested_size>0); _capacity=requested_size; type * const temp=new type[requested_size]; MEMORY_ALLOCATION_TEST(temp, requested_size); if(_size>0) { assert(_data!=NULL); _UnrolledCopyLoop(temp, _data, _size); } delete[] _data; _data=temp; } _size=requested_size;}template<class type>void autoarray<type>::reserve(int reserve_size) // EXCEPTION NEUTRAL{ // Sets _capacity for max(reserve_size, _capacity), // will ensure quick resizing in future for up to reserve_size array size assert(reserve_size>=0); assert(reserve_size<=max_size()); if(reserve_size<=_capacity) { return; } const int oldsize=_size; resize(reserve_size); _size=oldsize;}template<class type>void autoarray<type>::swap(autoarray<type>& other) // NOTHROW{ // Swaps whole content of 2 arrays (useful for updating new vector of values), // array size can differ. int itemp=other._size; other._size=_size; _size=itemp; itemp=other._capacity; other._capacity=_capacity; _capacity=itemp; type * const ptemp=other._data; other._data=_data; _data=ptemp;}template<class type>void autoarray<type>::trim() // not STL // EXCEPTION NEUTRAL{ // Sets _capacity for _size, type * const buffer=new type[_size]; //memcpy(buffer, _data, _size*sizeof(type)); _UnrolledCopyLoop(buffer, _data, _size); delete[] _data; _data=buffer; _capacity=_size;}template<class type>void autoarray<type>::reverse() // not STL // NOTHROW{ const int sb2=_size>>1; for(int i1=0, i2=_size-1; i1<sb2; i1++, i2--) { const type temp=_data[i1]; _data[i1]=_data[i2]; _data[i2]=temp; }}/////////////////////////////////////////////////////////////////////////////#endif //_INCLUDED_L3_ARRAY_AUTO_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -