Advertisement
Tyler_Elric

Smart.hpp

Jan 23rd, 2012
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.06 KB | None | 0 0
  1. #ifndef __Smart__hpp
  2. #define __Smart__hpp
  3.  
  4. #ifndef __Smart__debug
  5. #define __Smart__debug false //By default, turn off debugging. :)
  6. // Even if it's not implemented yet...
  7. #endif
  8.  
  9. #include "Iterable.h"
  10. //could be compounded to include all of iostream, but why bother? :P
  11. #include <istream>
  12. #include <ostream>
  13.  
  14. #ifndef SmartArray_Debug
  15. #define SmartArray_Debug 0 //Default SmartArray_Debug to off. ( = 0 )
  16. #endif
  17.  
  18. #define SmartObject_Type_Information(a) virtual const char* type() const{ return a; }
  19.  
  20. template <class Type>
  21. class SmartArray:virtual public Iterable
  22. {
  23. protected:
  24.     void Allocate( unsigned int len )
  25.     {
  26.         mAlloc = newSize(len);
  27.         unsigned int lSize = mAlloc * sizeof(Reference);
  28.         Reference* temp = static_cast<Reference*>(memset(new char[lSize],0x00,lSize));
  29.         memcpy(temp,mItems,(sizeof(Reference))*mUsed);
  30.         if(mItems) delete static_cast<void*>(mItems); //Prevent un-nescesary destruction of things...
  31.         mItems = temp;
  32.     }
  33. public:
  34.     class Reference
  35.     {
  36.         private:
  37.             Type* obj; //The item we are currently referencing. :)
  38.         public:
  39.             class SmartObject
  40.             {
  41.             protected:
  42.                 unsigned int _count;
  43.             public:
  44.                 SmartObject():_count(0) {}
  45.                 virtual ~SmartObject(){}
  46.                 virtual const char* type() const = 0;//handy. plus, we don't want people to instantiate a plain-old SmartObject. :P
  47.                 //does nothing, by default. must be implemented by inheritants:
  48.                 virtual void LoadFromFile( std::istream& ){};
  49.                 virtual void ExportToFile( std::ostream& ){};
  50.                 static unsigned int gBufferSize;// controlled method of implementing a buffer.
  51.                 //DO NOT CALL THESE UNLESS YOU'RE SMART:
  52.                 //[ if you do, do so like a stack. ]
  53.                 //[ 1 push = 1 pop. etc ]
  54.                 void UpReference()
  55.                 {
  56.                     _count++;//Somebody wants me?! :o
  57.                 }
  58.                 bool UnReference()
  59.                 {
  60.                     return --_count == 0;
  61.                 }
  62.             };
  63.             class NullReference {};//Throw this when an attempt to read something that isn't there.
  64.             Reference( Type* arg ):obj(NULL)
  65.             {
  66.                 operator = ( arg );//again, simple enough.
  67.             }
  68.             Reference( Reference& ref ):obj(NULL)
  69.             {
  70.                 operator = ( ref );//simple enough. copy.
  71.             }
  72.             Reference( void ):obj(NULL)
  73.             {
  74.                 operator = ( (Type*)NULL ); // By default, we want a null-reference.
  75.             }
  76.             Reference& operator = ( Type* ptr ) // usually like so: reference= new object.
  77.             {
  78.                 if ( obj )
  79.                 {
  80.                     if (obj->UnReference()) delete obj; // de-increment reference-count.
  81.                     obj = NULL; // we want no references to this at all.
  82.                     // However, functionality wouldn't be effected without this line.
  83.                     // It's just for concept.
  84.                 }
  85.                 if( obj = ptr ) // Assign either a null-reference,
  86.                     obj->UpReference(); // or an actual object.
  87.                 return *this;
  88.             }
  89.             Reference& operator = ( Reference& r)
  90.             {
  91.                 return operator = ( r.obj );
  92.             }
  93.             ~Reference()
  94.             {
  95.                 SmartObject* ptr = (Type*)0; // Ensure that TYPE is in fact derived from SmartObject!
  96.                 operator = ( NULL );
  97.             }
  98.             Type& operator () () const
  99.             {
  100.                 if(obj) return *obj;
  101.                 throw NullReference();
  102.             }
  103.             bool Is( const Reference& ref )
  104.             {
  105.                 return obj == ref.obj;
  106.             }
  107.             bool Is( const SmartObject& ref)
  108.             {
  109.                 return obj == &ref;
  110.             }
  111.     };
  112.     class Iterator
  113.     {
  114.     private:
  115.         int numRemaining;
  116.         typename Type* obj;
  117.     public:
  118.         Iterator(typename Type* t,int l):obj(t),numRemaining(l){}
  119.         Iterator(const Iterator& i):obj(i.obj),numRemaining(i.numRemaining){}
  120.         operator bool(){ return numRemaining > 0; }
  121.         Iterator& operator ++(){ obj++; numRemaining--; return *this;}
  122.         Iterator& operator ++(int a){ obj++; numRemaining--; return *this;}
  123.         Type& operator()(){ return *obj; }
  124.     };
  125.     class Callback
  126.     {
  127.         public:
  128.             virtual void operator ()(Type&,unsigned int) const = 0;
  129.     };
  130.     SmartArray(void):mItems(NULL){}
  131.     SmartArray( const SmartArray<Type>& arr ):mItems(NULL)
  132.     {
  133.         Append( arr );
  134.     }
  135.     SmartArray( unsigned int d):mItems(NULL)
  136.     {
  137.         try{ Reserve(d); }
  138.         catch( Iterable::UnneededAllocation ) {}
  139.     }
  140.     virtual ~SmartArray(void)
  141.     {
  142.         if( mItems ){
  143.             for(unsigned int i=0; i<mUsed; i++) mItems[i] = NULL;
  144.             delete static_cast<void*>(mItems);
  145.         }
  146.     }
  147.     const SmartArray& ForEach( const typename Callback& cb) const
  148.     {
  149.         for( unsigned int i=0; i<mUsed; i++)
  150.             cb((*this)[i],i);
  151.         return *this;
  152.     }
  153.     SmartArray& Reserve( unsigned int d)
  154.     {
  155.         try{ Allocate(d); }
  156.         catch( Iterable::UnneededAllocation ) {}
  157.         return *this;
  158.     }
  159.     SmartArray& Append( Type* nItem )
  160.     {
  161.         try{ Allocate(1);}
  162.         catch ( Iterable::UnneededAllocation ) {}
  163.         mItems[mUsed++] = nItem;
  164.         return *this;
  165.     }
  166.     SmartArray& Append( const Reference& nItem )
  167.     {
  168.         try{ Allocate(1);}
  169.         catch ( Iterable::UnneededAllocation ) {}
  170.         mItems[mUsed++] = nItem;
  171.         return *this;
  172.     }
  173.     SmartArray& Append( SmartArray* aRef )
  174.     {
  175.         return Insert( aRef, -1);
  176.     }
  177.     SmartArray& Append( const SmartArray<Type>& aRef)
  178.     {
  179.         return Insert( aRef, -1);
  180.     }
  181.     SmartArray& Insert( Type* nItem, int aIndice)
  182.     {
  183.         try{ Allocate(1);}
  184.         catch ( Iterable::UnneededAllocation ) {}
  185.         aIndice = Iterable::Slice(0,aIndice).end(mUsed) + 1;
  186.         SmartObject::Reference* oldItems = new SmartObject::Reference[ mUsed - aIndice ];
  187.         for( unsigned int i = aIndice; i < mUsed; i++ ) oldItems[i - aIndice] = mItems[i];
  188.         mItems[aIndice++] = nItem, mUsed++;
  189.         for( unsigned int i = aIndice; i < mUsed; i++ ) mItems[i] = oldItems[i - aIndice];
  190.         delete [] oldItems;
  191.         return *this;
  192.     }
  193.     SmartArray& Insert( Reference&r, int aIndice)
  194.     {
  195.         return Insert(&r(),aIndice);
  196.     }
  197.     SmartArray& Insert( SmartArray<Type>* aRef, int aIndice )
  198.     {
  199.         SmartArray& ref = *aRef;
  200.         try{ Allocate( ref.mUsed ); }
  201.         catch( Iterable::UnneededAllocation ) {}
  202.         aIndice = Iterable::Slice(0,aIndice).end(mUsed) + 1;
  203.         Reference* oldItems = new Reference[ mUsed - aIndice ];
  204.         for( unsigned int i = aIndice; i < mUsed; i++ )oldItems[i - aIndice] = mItems[i];
  205.         for( unsigned int i = 0; i < ref.mUsed; i++ ) mItems[ aIndice + i ] = ref.mItems[i];
  206.         for( unsigned int i = 0; i < mUsed - aIndice; i++ ) mItems[ i + ref.mUsed + aIndice ] = oldItems[ i ];
  207.         mUsed += ref.mUsed;
  208.         delete [] oldItems;
  209.         return *this;
  210.     }
  211.     SmartArray& Insert( const SmartArray<Type>& aRef, int aIndice)
  212.     {
  213.         return Insert( ((SmartArray<Type>*)&aRef), aIndice);
  214.     }
  215.     SmartArray& Prepend( Type* nItem)
  216.     {
  217.         return Insert(nItem,0);
  218.     }
  219.     SmartArray& Prepend( typename Reference& r )
  220.     {
  221.         return Insert(r,0);
  222.     }
  223.     SmartArray& Prepend( SmartArray<Type>* arr )
  224.     {
  225.         return Insert(arr,0);
  226.     }
  227.     SmartArray& Empty(bool aKeepValid=true)
  228.     {
  229.         if(aKeepValid)
  230.             for( unsigned int i = 0; i < mUsed; i++ )
  231.             {
  232.                 try{ mItems[i](); }
  233.                 catch( Reference::NullReference )
  234.                 {
  235.                     for( unsigned int ii = i; ii < mUsed - 1; ii++ )
  236.                     {
  237.                         mItems[ii] = mItems[ii+1];
  238.                     }
  239.                     mItems[--mUsed] = NULL;
  240.                 }
  241.             }
  242.         else
  243.         {
  244.             for( unsigned int i = 0; i<mUsed; i++ )
  245.                 mItems[i] = NULL;
  246.             mUsed = mAlloc = 0;
  247.             delete static_cast<void*>(mItems);
  248.             mItems = NULL;
  249.         }
  250.         return *this;
  251.     }
  252.     const SmartArray operator [] ( const Slice& aSlice ) const
  253.     {
  254.         SmartArray ret;
  255.         unsigned int lStart = aSlice.start(mUsed), lEnd = aSlice.end(mUsed);
  256.         for(unsigned int i = lStart; i ^ lEnd; i++) ret.Append(mItems[i]);
  257.         return ret;
  258.     }
  259.     Type& operator[] ( int aIndice) const
  260.     {
  261.         return mItems[Iterable::Slice(0,aIndice).end(mUsed)]();
  262.     }
  263.     unsigned int Length() const
  264.     {
  265.         return mUsed;
  266.     }
  267.     void LoadFromFile( std::istream& in)
  268.     {
  269.         Empty(false);//Ensure it's all taken care of.
  270.         in.read((char*)&mUsed,4);
  271.         for( int i=0; i<mUsed; i++)
  272.             mItems[i]().LoadFromFile(in);
  273.     }
  274.     void ExportToFile( std::ostream& out)
  275.     {
  276.         out.write((char*)&mUsed, 4);
  277.         for( int i=0; i<mUsed; i++)
  278.             mItems[i]().ExportToFile(out);
  279.     }
  280.     bool Contains( const typename Reference::SmartObject& cont, bool equivelant=false)
  281.     {
  282.         for( int i=0; i<mUsed; i++)
  283.         {
  284.             if( mItems[i].Is(cont)) return true;
  285.             try
  286.             {
  287.                 if( equivelant && mItems[i]() == cont) return true;
  288.             }
  289.             catch( Reference::NullReference) {}
  290.         }
  291.         return false;
  292.     }
  293.     const Iterator& Start()
  294.     {
  295.         return Iterator((Type*)&(mItems[0]),( int)mUsed);
  296.     }
  297. private:
  298.     Reference* mItems;
  299. };
  300.  
  301. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement