仿STL实现变长数组( Iterator | Allocator | 动态扩容)

#inc

lude <iostream> #include <sstream> #include <stdexcept> #include <exception> #include <algorithm> #include <iterator> #include <type_traits> #include <cstdint> #include <cstddef> #include <assert.h> template<typename T> class arrayList; template <typename value_type> bool operator<( const arrayList<value_type>& lhs, const arrayList<value_type>& rhs){ register int i; for(i = 0; i < std::min( lhs.listSize, rhs.listSize ); ++i) if( !( *( lhs.elements + i ) == *(rhs.elements + i) ) ) return *( lhs.elements + i) < *(rhs.elements + i); return lhs.listSize < rhs.listSize; } template <typename value_type> bool operator==( const arrayList<value_type>& lhs, const arrayList<value_type>& rhs){ if( !( lhs.listSize == rhs.listSize ) ) return false; register int i; for(i = 0; i < lhs.listSize; ++i) if( !( *( lhs.elements + i ) == *(rhs.elements + i) ) ) return false; return true; } template <typename value_type> bool operator!=( const arrayList<value_type>& lhs, const arrayList<value_type>& rhs){ return !( lhs == rhs ); } template < typename T > std::ostream& operator<<( std::ostream& os, const arrayList< T >& x){ x.output( os ); return os; } template < class T > class linearList{ public: virtual ~linearList( void ) {}; virtual bool empty( void ) const = 0; virtual std::size_t size( void ) const = 0; virtual T& get( int theIndex ) const = 0; virtual int indexOf( const T& theElement ) const = 0; virtual void erase( int theIndex ) = 0; virtual void insert( int theIndex, const T& theElement ) = 0; virtual void output( std::ostream& os ) const = 0; }; template <class T> class arrayList : public linearList< T >{ friend bool operator==<T>( const arrayList<T>&, const arrayList<T>&); friend bool operator< <T>( const arrayList<T>&, const arrayList<T>&); friend bool operator!=<T>( const arrayList<T>&, const arrayList<T>&); friend std::ostream& operator<< <T>( std::ostream&, const arrayList<T>&); class iterator{ public: typedef std::bidirectional_iterator_tag iterator_category; typedef T value_type; typedef std::ptrdiff_t difference_type; typedef value_type* pointer; typedef value_type& reference; iterator(pointer thePosition = nullptr) : position( thePosition ) {} reference operator*( void ) const { return *position; } pointer operator->( void ) const { return &(*position); } iterator& operator++( void ) { ++position; return *this; } iterator& operator--( void ){ --position; return *this; } iterator operator++( int dummy ){ iterator tmp = *this; ++position; return tmp; } iterator operator--( int dummy ){ iterator tmp = *this; --position; return tmp; } bool operator!=( const iterator rhs ) const{ return position != rhs.position; } bool operator==( const iterator rhs ) const{ return position == rhs.position; } protected: pointer position; }; public: arrayList(int initialCapacity = 10, std::size_t Scaler = 2); arrayList( const arrayList< T >&); ~arrayList( void ){ if(elements) delete[]elements; elements = nullptr; } virtual bool empty( void ) const { return listSize == 0; } virtual std::size_t size( void ) const { return listSize; } virtual T& get( int theIndex ) const; virtual int indexOf( const T& theElement ) const; virtual void erase( int theIndex ); virtual void insert( int theIndex, const T& theElement ); virtual void output( std::ostream& os ) const; T& operator[]( std::size_t position ) const; std::size_t capacity( void ) const { return arrayLength; } iterator begin( void ){ return iterator( elements ); } iterator end( void ){ return iterator( elements + listSize ); } inline void trimToSize( void ); void setSize( std::size_t _Size ); protected: void checkIndex(int theIndex) const; T* elements { nullptr }; std::size_t arrayLength { 10 }; std::size_t listSize { 0 }; uint8_t Scaler; }; template < class T > void arrayList< T >::checkIndex( int theIndex ) const{ if( theIndex < 0 || theIndex >= listSize ){ std::ostringstream oss; char buf[ 64 ]; sprintf( buf, "given index = %d; size = %d", theIndex, listSize ); oss << buf; throw std::invalid_argument( oss.str() ); } return; } template < class T > arrayList< T >::arrayList(int initialCapacity, std::size_t Scaler) :Scaler( Scaler ){ if( initialCapacity < 1 ){ std::ostringstream oss; char buf[ 64 ]; sprintf( buf, "initial capacity = %d Must be > 0", initialCapacity); oss << buf; throw std::invalid_argument( oss.str() ); } arrayLength = initialCapacity; elements = new T[ arrayLength ]; } template < class T > inline void arrayList< T >::trimToSize( void ){ changeLength1D( elements, arrayLength, std::max( listSize, 1ULL ) ); arrayLength = std::max( listSize, 1ULL ); } template <class T> void arrayList< T >::setSize( std::size_t _Size ){ if( listSize > _Size ) for( std::ptrdiff_t i = _Size; i < listSize; ++i) delete (elements + i); listSize = _Size; } template <class T> T& arrayList< T >::operator[]( std::size_t position ) const{ checkIndex( position ); return *(elements + position); } template < class T > arrayList< T >::arrayList( const arrayList< T >& theList ) :arrayLength( theList.arrayLength ) ,listSize( theList.listSize ) ,elements( new T[ arrayLength ]) { std::copy(theList.elements, theList.element + listSize, elements ); } template < class T > int arrayList< T >::indexOf( const T& theElement ) const{ int ret {}; return ( int )( ( ret = std::find(elements, elements + listSize, theElement) - elements) ) == listSize ? -1 : ret; } template < typename T > void arrayList< T >::erase(int theIndex ){ checkIndex( theIndex ); std::copy( elements + theIndex + 1, elements + listSize, elements + theIndex ); elements[ --listSize ].~T(); } template < typename T > void arrayList< T >::insert( int theIndex, const T& theElement ){ checkIndex( theIndex ); if(listSize == arrayLength ){ changeLength1D( elements, arrayLength, arrayLength * Scaler ); arrayLength *= Scaler; } std::copy_backward( elements + theIndex, elements + listSize, elements + listSize+1 ); elements[ theIndex ] = theElement; } template < typename T > void arrayList< T >::output( std::ostream& os ) const{ std::copy( elements, elements + listSize, std::ostream_iterator< T >( os, " ") ); } template < typename value_type > void changeLength1D( value_type*& pArray, const signed long& N, const signed long& M ) { // static_assert(typename std::is_copy_constructible<value_type>::value, "requires copying"); if( nullptr == pArray ) throw std::domain_error( "array is nullptr" ); if( N < 0 || M < 0) throw std::invalid_argument( "illegalParameterValue N|M given" ); std::size_t checkedN = static_cast< std::size_t >( N ); std::size_t checkedM = static_cast< std::size_t >( M ); value_type* temp = new value_type[ checkedM ]; std::copy( pArray, pArray + std::min( checkedN, checkedM ), temp ); delete [] pArray; pArray = temp; } template < class T > T& arrayList< T >::get( int theIndex ) const{ checkIndex( theIndex ); return elements[ theIndex ]; } template < typename value_type, std::size_t formerN, std::size_t formerM > value_type** chanegeLeagth2D( value_type (&_Matrix)[ formerN ][ formerM], const signed long& newN, const signed long& newM){ assert(newN > 0 && newM > 0 || "invalid argument nagetive N | M given"); // static_assert(typename std::is_copy_constructible<value_type>::value, "requires copying"); value_type ** _ScaledMatrix = new value_type*[ newN ]; for( std::ptrdiff_t i = 0; i < newM; ++i) _ScaledMatrix[ i ] = new value_type[ newM ]; int i,j; std::size_t checkedN = static_cast< std::size_t >( newN ); std::size_t checkedM = static_cast< std::size_t >( newM ); for(i = 0; i < std::min( formerN, checkedN ); ++i) for(j = 0; j < std::min( formerM, checkedM ); ++j) _ScaledMatrix[i][j] = _Matrix[i][j]; return _ScaledMatrix; } template < typename InputIterator > void myCopy(InputIterator begIt, InputIterator endIt, InputIterator resIt ){ while( !( begIt == endIt ) ) *resIt++ = *begIt++; } int main( void ){ int *pArray = new int[5] { 1, 2, 3, 4, 5 }; changeLength1D( pArray, 5L, 10L ); int i; for(i = 0;i < 10;++i) std::clog << *( pArray + i ) << ' '; constexpr int N { 5 }; int *pEnd = pArray + N; for( std::ptrdiff_t i { N }; i > 0; --i ) std::clog << ( *( pEnd - i ) = i ) << ' '; std::endl( std::cout ); return 0; }