home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 October / Chip_1997-10_cd.bin / tema / sybase / powerj / hpp.z / WARRAY.HPP < prev    next >
C/C++ Source or Header  |  1996-12-09  |  14KB  |  507 lines

  1. /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2.    %     Copyright (C) 1994, by WATCOM International Inc.  All rights    %
  3.    %     reserved.  No part of this software may be reproduced or        %
  4.    %     used in any form or by any means - graphic, electronic or       %
  5.    %     mechanical, including photocopying, recording, taping or        %
  6.    %     information storage and retrieval systems - except with the     %
  7.    %     written permission of WATCOM International Inc.                 %
  8.    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  9. */
  10.  
  11. #ifndef _WARRAY_HPP_INCLUDED
  12. #define _WARRAY_HPP_INCLUDED
  13.  
  14. #ifndef _WNO_PRAGMA_PUSH
  15. #pragma pack(push,8);
  16. #pragma enum int;
  17. #endif
  18.  
  19. #ifndef _WOBJECT_HPP_INCLUDED
  20. #  include "wobject.hpp"
  21. #endif
  22. #ifndef _WDEBUG_HPP_INCLUDED
  23. #  include "wdebug.hpp"
  24. #endif
  25. #ifndef _WREFOBJ_HPP_INCLUDED
  26. #  include "wrefobj.hpp"
  27. #endif
  28.  
  29. /*************************************************************************
  30.  *
  31.  * WArrayReference
  32.  *
  33.  *************************************************************************/
  34.  
  35. template <class T>
  36. class WCMCLASS WArrayReference : public WReferenceObject {
  37.  
  38.         /**********************************************************
  39.          * Constructors and Destructors
  40.          *********************************************************/
  41.  
  42.         // This class is meant to be used as a reference class, with
  43.         // objects allocated via new.  As such we don't allow
  44.         // copies to be made except via the MakeCopy method.  New
  45.         // objects are allocated via the static function Allocate.
  46.     
  47.     private:
  48.         WArrayReference( const WArrayReference & ar );
  49.         WArrayReference & operator=( const WArrayReference & ar );
  50.  
  51.     protected:
  52.         WArrayReference( size_t count );
  53.  
  54.     public:
  55.         ~WArrayReference();
  56.  
  57.         /**********************************************************
  58.          * Properties
  59.          *********************************************************/
  60.  
  61.         // Count
  62.  
  63.         int   GetCount() const { return _count; }
  64.         WBool SetCount( int count );
  65.  
  66.         // Data
  67.  
  68.         T * GetData() const { return _objs; }
  69.  
  70.         // RealCount
  71.  
  72.         int GetRealCount() const;
  73.  
  74.         /**********************************************************
  75.          * Methods
  76.          *********************************************************/
  77.  
  78.         // Allocate
  79.         //
  80.         //    Allocates a new object.
  81.  
  82.         static WArrayReference *Allocate( size_t count );
  83.  
  84.         // MakeCopy
  85.         //
  86.         //    Creates a new memory object based on the current
  87.         //    one, copying the data.
  88.  
  89.         WArrayReference *MakeCopy( WInt newCount=-1 );
  90.  
  91.         /**********************************************************
  92.          * Private
  93.          *********************************************************/
  94.  
  95.     private:
  96.  
  97.         T *                     _objs;
  98.         int                     _count;
  99.         int                     _realCount;
  100. };
  101.  
  102. #if defined( _DEBUG ) && !defined( new )
  103.     #define _UNINCLUDE_NEW
  104.     #include "wnew.hpp"
  105. #endif
  106.  
  107. template<class T> WArrayReference<T>::WArrayReference( size_t count ) {
  108.     _count     = count;
  109.     _realCount = count;
  110.     _objs      = NULL;
  111.  
  112.     if( count > 0 ) {
  113.         _objs = new T[ count ];
  114.     }
  115. }
  116.  
  117. template<class T> WArrayReference<T>::~WArrayReference() {
  118.     delete [] _objs;
  119.  
  120.     _objs      = NULL;
  121.     _count     = 0;
  122.     _realCount = 0;
  123. }
  124.  
  125. template<class T> int WArrayReference<T>::GetRealCount() const {
  126.     return _realCount;
  127. }
  128.  
  129. template<class T> WBool WArrayReference<T>::SetCount( int count ) {
  130.     WASSERT( count <= _realCount && count >= 0 );
  131.     _count = count;
  132.     return TRUE;
  133. }
  134.  
  135. template<class T> static WArrayReference<T> * WArrayReference<T>::Allocate( size_t count ){
  136.     WArrayReference * ref;
  137.     ref = new WArrayReference<T>( count );
  138.     if( ref != NULL ) {
  139.         ref->Reference();
  140.         return ref;
  141.     }
  142.     return NULL;
  143. }
  144.  
  145. template<class T> WArrayReference<T>* WArrayReference<T>::MakeCopy( WInt newCount ){
  146.     WArrayReference * ref;
  147.     WInt              oldRealCount = _realCount;
  148.     if( newCount < 0 ) {
  149.         newCount = _realCount;
  150.     }
  151.     ref = new WArrayReference<T>( newCount );
  152.     WASSERT( ref != NULL );
  153.     if( ref != NULL ){
  154.         ref->Reference();
  155.         if( _realCount != 0 ) {
  156.             T *         oldData;
  157.             T *         newData;
  158.  
  159.             if( oldRealCount < newCount ) {
  160.                 newCount = oldRealCount;
  161.             }
  162.             oldData = GetData();
  163.             newData = ref->GetData();
  164.             for( int i = 0; i < newCount; i++ ) {
  165.                 newData[i] = oldData[i];
  166.             }
  167.         }
  168.     }
  169.  
  170.     return ref; 
  171. }
  172.  
  173. /*************************************************************************
  174.  *
  175.  * WArray
  176.  *
  177.  *************************************************************************/
  178.  
  179.  
  180. template<class T>
  181. class WCMCLASS WArray {
  182.  
  183.     public:
  184.  
  185.         /**********************************************************
  186.          * Constructors and Destructors
  187.          *********************************************************/
  188.  
  189.         WArray();
  190.         WArray( const T & t );
  191.         WArray( const WArray & array );
  192.  
  193.         ~WArray();
  194.  
  195.         /**********************************************************
  196.          * Properties
  197.          *********************************************************/
  198.  
  199.         // Count
  200.         //
  201.         //    Returns the count of items in the array.
  202.  
  203.         inline WInt GetCount() const;
  204.         WBool       SetCount( WInt count );
  205.  
  206.         // Size
  207.         //
  208.         //    Returns the size (max # of items) of the array.
  209.  
  210.         WInt GetSize() const;
  211.  
  212.         /**********************************************************
  213.          * Operators
  214.          *********************************************************/
  215.  
  216.         inline const T & operator[]( int index ) const;
  217.         T & operator[]( int index );
  218.  
  219.         inline operator const T &() const;
  220.         operator T &();
  221.  
  222.         WArray & operator=( const T & t );
  223.         WArray & operator=( const WArray & array );
  224.  
  225.         /**********************************************************
  226.          * Methods
  227.          *********************************************************/
  228.  
  229.         // Lock
  230.         //
  231.         //    Lock the array for direct manipulation, possibly growing
  232.         //    it at the same time.  Ensures that no one else is
  233.         //    referencing the array.
  234.  
  235.         T* Lock( WInt count=-1 );
  236.  
  237.         // Unlock
  238.         //
  239.         //    Unlock the array after direct manipulation.
  240.  
  241.         void Unlock();
  242.  
  243.         /**********************************************************
  244.          * Other
  245.          *********************************************************/
  246.  
  247.         WInt GetRealCount() const;
  248.  
  249.         static const T & GetOutOfBoundsValue();
  250.         static T &       GetDummyValue();
  251.  
  252.         /**********************************************************
  253.          * Data Members
  254.          *********************************************************/
  255.  
  256.     protected:
  257.  
  258.         WArrayReference< T > *_arrRef;
  259. };
  260.  
  261. template<class T> static const T & WArray<T>::GetOutOfBoundsValue(){
  262.     static T _outOfBoundsValue;
  263.     return _outOfBoundsValue;
  264. }
  265.  
  266. template<class T> static T & WArray<T>::GetDummyValue(){
  267.     static T _dummyValue;
  268.     return _dummyValue;
  269. }
  270.  
  271. template<class T> WArray<T>::WArray(){
  272.     _arrRef = WArrayReference<T>::Allocate( 0 );
  273.     WASSERT( _arrRef != NULL );
  274. }
  275.  
  276. template<class T> WArray<T>::WArray( const T & t ) {
  277.     _arrRef = WArrayReference<T>::Allocate( 1 );
  278.     WASSERT( _arrRef != NULL );
  279.     if( _arrRef ) _arrRef->GetData()[0] = t;
  280. }
  281.  
  282. template<class T> WArray<T>::WArray( const WArray<T> & array ) {
  283.     _arrRef = array._arrRef;
  284.     WASSERT( _arrRef != NULL );
  285.     if( _arrRef ) _arrRef->Reference();
  286. }
  287.  
  288. template<class T> WArray<T>::~WArray() {
  289.     WASSERT( _arrRef != NULL );
  290.     _arrRef->Unreference();
  291. }
  292.  
  293. template<class T> WBool WArray<T>::SetCount( WInt count ) {
  294.     WASSERT( _arrRef != NULL );
  295.     if( count <= GetSize() && _arrRef->GetReferenceCount() == 1 ) {
  296.         return _arrRef->SetCount( count );
  297.     } else {
  298.         WArrayReference<T> *    newRef = _arrRef->MakeCopy( count );
  299.         _arrRef->Unreference();
  300.         _arrRef = newRef;
  301.         return TRUE;
  302.     }
  303. }
  304.  
  305. template<class T> WInt WArray<T>::GetCount() const {
  306.     WASSERT( _arrRef != NULL );
  307.     return _arrRef->GetCount();
  308. }
  309.  
  310. template<class T> WInt WArray<T>::GetRealCount() const {
  311.     return GetSize();
  312. }
  313.  
  314. template<class T> WInt WArray<T>::GetSize() const {
  315.     WASSERT( _arrRef != NULL );
  316.     return _arrRef->GetRealCount();
  317. }
  318.  
  319. template<class T> const T & WArray<T>::operator[]( int index ) const {
  320.     WASSERTEX( _arrRef && index < _arrRef->GetCount(), "Array index out of bounds" );
  321.     if( !_arrRef || index < 0 || index >= _arrRef->GetCount() ){
  322.         return GetOutOfBoundsValue();
  323.     }
  324.     return _arrRef->GetData()[index];
  325. }
  326.  
  327. template<class T> T & WArray<T>::operator[]( int index ){
  328.     WASSERTEX( _arrRef && index < _arrRef->GetCount(), "Array index out of bounds" );
  329.     if( !_arrRef || index < 0 || index >= _arrRef->GetCount() ){
  330.         return GetDummyValue();
  331.     }
  332.     WArrayReference<T> * oldArrRef = _arrRef;
  333.     if( _arrRef->GetReferenceCount() > 1 ){
  334.         _arrRef = _arrRef->MakeCopy();
  335.         oldArrRef->Unreference();
  336.     }
  337.     return _arrRef->GetData()[index];
  338. }
  339.  
  340. template<class T> WArray<T>::operator const T&() const {
  341.     WASSERTEX( _arrRef && _arrRef->GetCount() > 0, "Empty array" );
  342.     if( !_arrRef || _arrRef->GetCount() == 0 ){
  343.         return GetOutOfBoundsValue();
  344.     }
  345.     return _arrRef->GetData()[0];
  346. }
  347.  
  348. template<class T> WArray<T>::operator T&(){
  349.     WASSERTEX( _arrRef && _arrRef->GetCount() > 0, "Empty array" );
  350.     if( !_arrRef || _arrRef->GetCount() == 0 ){
  351.         return GetDummyValue();
  352.     }
  353.     WArrayReference<T> * oldArrRef = _arrRef;
  354.     if( _arrRef->GetReferenceCount() > 1 ) {
  355.         _arrRef = _arrRef->MakeCopy();
  356.         oldArrRef->Unreference();
  357.     }
  358.     return _arrRef->GetData()[0];
  359. }
  360.  
  361. template<class T> WArray<T> & WArray<T>::operator=( const T & t ){
  362.     if( _arrRef ) _arrRef->Unreference();
  363.     _arrRef = WArrayReference<T>::Allocate( 1 );
  364.     if( _arrRef ) _arrRef->GetData()[0] = t;
  365.     return *this;
  366. }
  367.  
  368. template<class T> WArray<T> & WArray<T>::operator=( const WArray<T> & array ){
  369.     if( this != &array ){
  370.         WArrayReference<T> *old = _arrRef;
  371.         _arrRef = array._arrRef;
  372.         if( _arrRef) _arrRef->Reference();
  373.         if( old ) old->Unreference();
  374.     }
  375.     return *this;
  376. }
  377.  
  378. template<class T> T* WArray<T>::Lock( WInt count ){
  379.     WASSERT( _arrRef );
  380.     if( count < 0 ){
  381.         count = GetCount();
  382.     }
  383.     if( count == 0 ){
  384.         count = 1;
  385.     }
  386.     SetCount( count ); 
  387.     WASSERT( _arrRef->GetReferenceCount() == 1 );
  388.     WASSERT( _arrRef->GetData() != NULL );
  389.     return _arrRef->GetData();
  390. }
  391.  
  392. template<class T> void WArray<T>::Unlock(){
  393.     WASSERT( _arrRef );
  394.     // nothing to do...
  395. }
  396.  
  397. typedef int WCMDEF (*WArraySysCompRtn)( const void *, const void * );
  398.  
  399. extern int              WArrayCompare( const void *, const void * );
  400. extern WArraySysCompRtn WArrayCompareRoutine;
  401. extern void             WArrayAcquire();
  402. extern void             WArrayRelease();
  403.  
  404. template<class T>
  405. class WCMCLASS WSortableArray : public WArray<T> {
  406.  
  407.     public:
  408.  
  409.         typedef int WCMDEF (*WArrayCompareRoutine)( const T *, const T * );
  410.  
  411.     public:
  412.  
  413.         /**********************************************************
  414.          * Constructors and Destructors
  415.          *********************************************************/
  416.  
  417.         WSortableArray();
  418.         WSortableArray( const T & t );
  419.         WSortableArray( const WArray & array );
  420.  
  421.         ~WSortableArray();
  422.  
  423.         /**********************************************************
  424.          * Methods
  425.          *********************************************************/
  426.  
  427.         // Sort
  428.         //
  429.         //    Sorts the array using qsort.  First locks it, then sorts.
  430.         //    If no sort function is provided, sorts in ascending
  431.         //    order using '<' and '==' operators.
  432.  
  433.         void Sort( WArrayCompareRoutine routine=NULL );
  434.  
  435.         static int DefaultCompare( const T *, const T * );
  436. };
  437.  
  438. template<class T> WSortableArray<T>::WSortableArray() : WArray() {
  439. }
  440.  
  441. template<class T> WSortableArray<T>::WSortableArray( const T & t )
  442.   : WArray( t ) {
  443. }
  444.  
  445. template<class T> WSortableArray<T>::WSortableArray( const WArray & array )
  446.   : WArray( array ) {
  447. }
  448.  
  449. template<class T> WSortableArray<T>::~WSortableArray() {
  450. }
  451.  
  452. template<class T> static WSortableArray<T>::DefaultCompare( const T *l, const T *r ){
  453.     if( *l < *r ){
  454.         return -1;
  455.     } else if( *l == *r ){
  456.         return 0;
  457.     } else {
  458.         return 1;
  459.     }
  460. }
  461.  
  462. template<class T> void WSortableArray<T>::Sort( WArrayCompareRoutine routine ){
  463.     int count = GetCount();
  464.     if( !_arrRef || count == 0 ) return;
  465.     if( !routine ) routine = DefaultCompare;
  466.     WArrayAcquire();
  467.     T *data = Lock();
  468.     WArrayCompareRoutine = (WArraySysCompRtn) routine;
  469.     qsort( data, count, sizeof( T ), WArrayCompare );
  470.     Unlock();
  471.     WArrayRelease();
  472. }
  473.  
  474. //
  475. // Standard array types
  476. //
  477.  
  478. extern template WArrayReference<WInt>;
  479. extern template WArray<WInt>;
  480. typedef WArray<WInt>                    WIntArray;
  481.  
  482. extern template WArrayReference<WULong>;
  483. extern template WArray<WULong>;
  484. typedef WArray<WULong>                  WULongArray;
  485.  
  486. extern template WArrayReference<WLong>;
  487. extern template WArray<WLong>;
  488. typedef WArray<WLong>                   WLongArray;
  489.  
  490. extern template WArrayReference<WBool>;
  491. extern template WArray<WBool>;
  492. typedef WArray<WBool>                   WBoolArray;
  493.  
  494. #if defined( _UNINCLUDE_NEW )
  495.     #undef new
  496.     #undef delete
  497.     #undef WNew
  498.     #undef WDelete
  499. #endif
  500.  
  501. #ifndef _WNO_PRAGMA_PUSH
  502. #pragma enum pop;
  503. #pragma pack(pop);
  504. #endif
  505.  
  506. #endif // _WARRAY_HPP_INCLUDED
  507.