Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef __Smart__hpp
- #define __Smart__hpp
- #ifndef __Smart__debug
- #define __Smart__debug false //By default, turn off debugging. :)
- // Even if it's not implemented yet...
- #endif
- #include "Iterable.h"
- //could be compounded to include all of iostream, but why bother? :P
- #include <istream>
- #include <ostream>
- #ifndef SmartArray_Debug
- #define SmartArray_Debug 0 //Default SmartArray_Debug to off. ( = 0 )
- #endif
- #define SmartObject_Type_Information(a) virtual const char* type() const{ return a; }
- template <class Type>
- class SmartArray:virtual public Iterable
- {
- protected:
- void Allocate( unsigned int len )
- {
- mAlloc = newSize(len);
- unsigned int lSize = mAlloc * sizeof(Reference);
- Reference* temp = static_cast<Reference*>(memset(new char[lSize],0x00,lSize));
- memcpy(temp,mItems,(sizeof(Reference))*mUsed);
- if(mItems) delete static_cast<void*>(mItems); //Prevent un-nescesary destruction of things...
- mItems = temp;
- }
- public:
- class Reference
- {
- private:
- Type* obj; //The item we are currently referencing. :)
- public:
- class SmartObject
- {
- protected:
- unsigned int _count;
- public:
- SmartObject():_count(0) {}
- virtual ~SmartObject(){}
- virtual const char* type() const = 0;//handy. plus, we don't want people to instantiate a plain-old SmartObject. :P
- //does nothing, by default. must be implemented by inheritants:
- virtual void LoadFromFile( std::istream& ){};
- virtual void ExportToFile( std::ostream& ){};
- static unsigned int gBufferSize;// controlled method of implementing a buffer.
- //DO NOT CALL THESE UNLESS YOU'RE SMART:
- //[ if you do, do so like a stack. ]
- //[ 1 push = 1 pop. etc ]
- void UpReference()
- {
- _count++;//Somebody wants me?! :o
- }
- bool UnReference()
- {
- return --_count == 0;
- }
- };
- class NullReference {};//Throw this when an attempt to read something that isn't there.
- Reference( Type* arg ):obj(NULL)
- {
- operator = ( arg );//again, simple enough.
- }
- Reference( Reference& ref ):obj(NULL)
- {
- operator = ( ref );//simple enough. copy.
- }
- Reference( void ):obj(NULL)
- {
- operator = ( (Type*)NULL ); // By default, we want a null-reference.
- }
- Reference& operator = ( Type* ptr ) // usually like so: reference= new object.
- {
- if ( obj )
- {
- if (obj->UnReference()) delete obj; // de-increment reference-count.
- obj = NULL; // we want no references to this at all.
- // However, functionality wouldn't be effected without this line.
- // It's just for concept.
- }
- if( obj = ptr ) // Assign either a null-reference,
- obj->UpReference(); // or an actual object.
- return *this;
- }
- Reference& operator = ( Reference& r)
- {
- return operator = ( r.obj );
- }
- ~Reference()
- {
- SmartObject* ptr = (Type*)0; // Ensure that TYPE is in fact derived from SmartObject!
- operator = ( NULL );
- }
- Type& operator () () const
- {
- if(obj) return *obj;
- throw NullReference();
- }
- bool Is( const Reference& ref )
- {
- return obj == ref.obj;
- }
- bool Is( const SmartObject& ref)
- {
- return obj == &ref;
- }
- };
- class Iterator
- {
- private:
- int numRemaining;
- typename Type* obj;
- public:
- Iterator(typename Type* t,int l):obj(t),numRemaining(l){}
- Iterator(const Iterator& i):obj(i.obj),numRemaining(i.numRemaining){}
- operator bool(){ return numRemaining > 0; }
- Iterator& operator ++(){ obj++; numRemaining--; return *this;}
- Iterator& operator ++(int a){ obj++; numRemaining--; return *this;}
- Type& operator()(){ return *obj; }
- };
- class Callback
- {
- public:
- virtual void operator ()(Type&,unsigned int) const = 0;
- };
- SmartArray(void):mItems(NULL){}
- SmartArray( const SmartArray<Type>& arr ):mItems(NULL)
- {
- Append( arr );
- }
- SmartArray( unsigned int d):mItems(NULL)
- {
- try{ Reserve(d); }
- catch( Iterable::UnneededAllocation ) {}
- }
- virtual ~SmartArray(void)
- {
- if( mItems ){
- for(unsigned int i=0; i<mUsed; i++) mItems[i] = NULL;
- delete static_cast<void*>(mItems);
- }
- }
- const SmartArray& ForEach( const typename Callback& cb) const
- {
- for( unsigned int i=0; i<mUsed; i++)
- cb((*this)[i],i);
- return *this;
- }
- SmartArray& Reserve( unsigned int d)
- {
- try{ Allocate(d); }
- catch( Iterable::UnneededAllocation ) {}
- return *this;
- }
- SmartArray& Append( Type* nItem )
- {
- try{ Allocate(1);}
- catch ( Iterable::UnneededAllocation ) {}
- mItems[mUsed++] = nItem;
- return *this;
- }
- SmartArray& Append( const Reference& nItem )
- {
- try{ Allocate(1);}
- catch ( Iterable::UnneededAllocation ) {}
- mItems[mUsed++] = nItem;
- return *this;
- }
- SmartArray& Append( SmartArray* aRef )
- {
- return Insert( aRef, -1);
- }
- SmartArray& Append( const SmartArray<Type>& aRef)
- {
- return Insert( aRef, -1);
- }
- SmartArray& Insert( Type* nItem, int aIndice)
- {
- try{ Allocate(1);}
- catch ( Iterable::UnneededAllocation ) {}
- aIndice = Iterable::Slice(0,aIndice).end(mUsed) + 1;
- SmartObject::Reference* oldItems = new SmartObject::Reference[ mUsed - aIndice ];
- for( unsigned int i = aIndice; i < mUsed; i++ ) oldItems[i - aIndice] = mItems[i];
- mItems[aIndice++] = nItem, mUsed++;
- for( unsigned int i = aIndice; i < mUsed; i++ ) mItems[i] = oldItems[i - aIndice];
- delete [] oldItems;
- return *this;
- }
- SmartArray& Insert( Reference&r, int aIndice)
- {
- return Insert(&r(),aIndice);
- }
- SmartArray& Insert( SmartArray<Type>* aRef, int aIndice )
- {
- SmartArray& ref = *aRef;
- try{ Allocate( ref.mUsed ); }
- catch( Iterable::UnneededAllocation ) {}
- aIndice = Iterable::Slice(0,aIndice).end(mUsed) + 1;
- Reference* oldItems = new Reference[ mUsed - aIndice ];
- for( unsigned int i = aIndice; i < mUsed; i++ )oldItems[i - aIndice] = mItems[i];
- for( unsigned int i = 0; i < ref.mUsed; i++ ) mItems[ aIndice + i ] = ref.mItems[i];
- for( unsigned int i = 0; i < mUsed - aIndice; i++ ) mItems[ i + ref.mUsed + aIndice ] = oldItems[ i ];
- mUsed += ref.mUsed;
- delete [] oldItems;
- return *this;
- }
- SmartArray& Insert( const SmartArray<Type>& aRef, int aIndice)
- {
- return Insert( ((SmartArray<Type>*)&aRef), aIndice);
- }
- SmartArray& Prepend( Type* nItem)
- {
- return Insert(nItem,0);
- }
- SmartArray& Prepend( typename Reference& r )
- {
- return Insert(r,0);
- }
- SmartArray& Prepend( SmartArray<Type>* arr )
- {
- return Insert(arr,0);
- }
- SmartArray& Empty(bool aKeepValid=true)
- {
- if(aKeepValid)
- for( unsigned int i = 0; i < mUsed; i++ )
- {
- try{ mItems[i](); }
- catch( Reference::NullReference )
- {
- for( unsigned int ii = i; ii < mUsed - 1; ii++ )
- {
- mItems[ii] = mItems[ii+1];
- }
- mItems[--mUsed] = NULL;
- }
- }
- else
- {
- for( unsigned int i = 0; i<mUsed; i++ )
- mItems[i] = NULL;
- mUsed = mAlloc = 0;
- delete static_cast<void*>(mItems);
- mItems = NULL;
- }
- return *this;
- }
- const SmartArray operator [] ( const Slice& aSlice ) const
- {
- SmartArray ret;
- unsigned int lStart = aSlice.start(mUsed), lEnd = aSlice.end(mUsed);
- for(unsigned int i = lStart; i ^ lEnd; i++) ret.Append(mItems[i]);
- return ret;
- }
- Type& operator[] ( int aIndice) const
- {
- return mItems[Iterable::Slice(0,aIndice).end(mUsed)]();
- }
- unsigned int Length() const
- {
- return mUsed;
- }
- void LoadFromFile( std::istream& in)
- {
- Empty(false);//Ensure it's all taken care of.
- in.read((char*)&mUsed,4);
- for( int i=0; i<mUsed; i++)
- mItems[i]().LoadFromFile(in);
- }
- void ExportToFile( std::ostream& out)
- {
- out.write((char*)&mUsed, 4);
- for( int i=0; i<mUsed; i++)
- mItems[i]().ExportToFile(out);
- }
- bool Contains( const typename Reference::SmartObject& cont, bool equivelant=false)
- {
- for( int i=0; i<mUsed; i++)
- {
- if( mItems[i].Is(cont)) return true;
- try
- {
- if( equivelant && mItems[i]() == cont) return true;
- }
- catch( Reference::NullReference) {}
- }
- return false;
- }
- const Iterator& Start()
- {
- return Iterator((Type*)&(mItems[0]),( int)mUsed);
- }
- private:
- Reference* mItems;
- };
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement