From c8f5eb2193b072465771f150bf2f3be3414b398b Mon Sep 17 00:00:00 2001 From: Adrian Thurston Date: Sun, 18 Apr 2010 19:41:34 +0000 Subject: Some more C porting. --- colm/rtvector.h | 218 ++++++++++---------------------------------------------- 1 file changed, 38 insertions(+), 180 deletions(-) (limited to 'colm/rtvector.h') diff --git a/colm/rtvector.h b/colm/rtvector.h index 45074e53..be74f2e9 100644 --- a/colm/rtvector.h +++ b/colm/rtvector.h @@ -27,204 +27,62 @@ #include #include -template < class T > class RtVector -{ -public: - static inline long upResize( long existing, long needed ) - { - return needed > existing ? (needed<<1) : existing; - } +typedef unsigned char Code; +typedef unsigned long Word; +typedef unsigned long Half; - static inline long downResize( long existing, long needed ) - { - return needed < (existing>>2) ? (needed<<1) : existing; - } +struct RtCodeVect; + +void rtCodeVectReplace( RtCodeVect *vect, long pos, const Code *val, long len ); +void rtCodeVectEmpty( RtCodeVect *vect ); +void rtCodeVectRemove( RtCodeVect *vect, long pos, long len ); - RtVector() : - data(0), - tabLen(0), - allocLen(0) - { } +void initRtCodeVect( RtCodeVect *codeVect ); +struct RtCodeVect +{ long length() const { return tabLen; } - T *data; + Code *data; long tabLen; long allocLen; - /* Free all mem used by the vector. */ - ~RtVector() { empty(); } - - /* Delete all items. */ - void empty(); + ~RtCodeVect() { rtCodeVectEmpty( this ); } /* Stack operations. */ - void push( const T &t ) { append( t ); } + void push( const Code &t ) { append( t ); } void pop() { remove( tabLen - 1 ); } - T &top() { return data[tabLen - 1]; } - - void remove(long pos) { remove(pos, 1); } - void remove(long pos, long len); - - void append(const T &val) { replace(tabLen, &val, 1); } - void append(const T *val, long len) { replace(tabLen, val, len); } - -protected: - void upResize(long len); - void downResize(long len); - -private: - void replace(long pos, const T *val, long len); -}; - - -/* Up resize the data for len elements using Resize::upResize to tell us the - * new tabLen. Reads and writes allocLen. Does not read or write tabLen. */ -template void RtVector:: - upResize(long len) -{ - /* Ask the resizer what the new tabLen will be. */ - long newLen = upResize(allocLen, len); - - /* Did the data grow? */ - if ( newLen > allocLen ) { - allocLen = newLen; - if ( data != 0 ) { - /* Table exists already, resize it up. */ - data = (T*) realloc( data, sizeof(T) * newLen ); - if ( data == 0 ) - throw std::bad_alloc(); - } - else { - /* Create the data. */ - data = (T*) malloc( sizeof(T) * newLen ); - if ( data == 0 ) - throw std::bad_alloc(); - } - } -} - -/* Down resize the data for len elements using Resize::downResize to determine - * the new tabLen. Reads and writes allocLen. Does not read or write tabLen. */ -template void RtVector:: - downResize(long len) -{ - /* Ask the resizer what the new tabLen will be. */ - long newLen = downResize( allocLen, len ); - - /* Did the data shrink? */ - if ( newLen < allocLen ) { - allocLen = newLen; - if ( newLen == 0 ) { - /* Simply free the data. */ - free( data ); - data = 0; - } - else { - /* Not shrinking to size zero, realloc it to the smaller size. */ - data = (T*) realloc( data, sizeof(T) * newLen ); - if ( data == 0 ) - throw std::bad_alloc(); - } - } -} + Code &top() { return data[tabLen - 1]; } + void remove(long pos) { rtCodeVectRemove( this, pos, 1 ); } -template void RtVector:: - empty() -{ - if ( data != 0 ) { - /* Call All destructors. */ - T *pos = data; - for ( long i = 0; i < tabLen; pos++, i++ ) - pos->~T(); - - /* Free the data space. */ - free( data ); - data = 0; - tabLen = allocLen = 0; - } -} + void append(const Code &val) { rtCodeVectReplace( this, tabLen, &val, 1 ); } + void append(const Code *val, long len) { rtCodeVectReplace( this, tabLen, val, len ); } -template void RtVector:: - replace(long pos, const T *val, long len) -{ - long endPos, i; - T *item; - - /* If we are given a negative position to replace at then - * treat it as a position relative to the length. */ - if ( pos < 0 ) - pos = tabLen + pos; - - /* The end is the one past the last item that we want - * to write to. */ - endPos = pos + len; - - /* Make sure we have enough space. */ - if ( endPos > tabLen ) { - upResize( endPos ); - - /* Delete any objects we need to delete. */ - item = data + pos; - for ( i = pos; i < tabLen; i++, item++ ) - item->~T(); - - /* We are extending the vector, set the new data length. */ - tabLen = endPos; - } - else { - /* Delete any objects we need to delete. */ - item = data + pos; - for ( i = pos; i < endPos; i++, item++ ) - item->~T(); + void appendHalf( Half half ) + { + /* not optimal. */ + append( half & 0xff ); + append( (half>>8) & 0xff ); } - - /* Copy data in using copy constructor. */ - T *dst = data + pos; - const T *src = val; - for ( i = 0; i < len; i++, dst++, src++ ) - new(dst) T(*src); -} - -template void RtVector:: - remove(long pos, long len) -{ - long newLen, lenToSlideOver, endPos; - T *dst, *item; - - /* If we are given a negative position to remove at then - * treat it as a position relative to the length. */ - if ( pos < 0 ) - pos = tabLen + pos; - - /* The first position after the last item deleted. */ - endPos = pos + len; - - /* The new data length. */ - newLen = tabLen - len; - - /* The place in the data we are deleting at. */ - dst = data + pos; - - /* Call Destructors. */ - item = dst; - for ( long i = 0; i < len; i += 1, item += 1 ) - item->~T(); - /* Shift data over if necessary. */ - lenToSlideOver = tabLen - endPos; - if ( len > 0 && lenToSlideOver > 0 ) - memmove(dst, dst + len, sizeof(T)*lenToSlideOver); - - /* Shrink the data if necessary. */ - downResize( newLen ); - - /* Set the new data length. */ - tabLen = newLen; -} + void appendWord( Word word ) + { + /* not optimal. */ + append( word & 0xff ); + append( (word>>8) & 0xff ); + append( (word>>16) & 0xff ); + append( (word>>24) & 0xff ); + #if SIZEOF_LONG == 8 + append( (word>>32) & 0xff ); + append( (word>>40) & 0xff ); + append( (word>>48) & 0xff ); + append( (word>>56) & 0xff ); + #endif + } +}; #endif -- cgit v1.2.1