00001
00011
00012
00013 #if (_MSC_VER > 1000) || defined(SGI_COMPILER)
00014 #pragma once
00015 #endif
00016
00017 #ifndef __XSIINDEXSET_H__
00018 #define __XSIINDEXSET_H__
00019
00020 #include <sicppsdk.h>
00021 #include <xsi_icenodecontext.h>
00022
00023 namespace XSI {
00024
00025 static const char kRevLogTable256[] =
00026 {
00027 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00028 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00029 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00030 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00031 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00032 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00033 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00034 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00035 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00036 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00037 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00038 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00039 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00040 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00041 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
00042 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
00043 };
00044
00045 const LONG kBitShift= 5;
00046 const LONG kBitSize = 32;
00047
00048 class CBitsetHelper
00049 {
00050 public:
00051 SICPPSDK_INLINE CBitsetHelper( );
00052
00053 SICPPSDK_INLINE LONG& GetCountRef( );
00054 SICPPSDK_INLINE LONG GetCount( ) const;
00055 SICPPSDK_INLINE ULONG*& GetArrayRef();
00056
00057 SICPPSDK_INLINE bool GetNextBit( LONG& in_index) const;
00058 SICPPSDK_INLINE CStatus SetBit( LONG in_index, bool in_bVal );
00059 SICPPSDK_INLINE bool GetBit( LONG in_index ) const;
00060 SICPPSDK_INLINE void Clear( );
00061
00062 SICPPSDK_INLINE CBitsetHelper& operator = ( const CBitsetHelper& in_bitset );
00063
00064 private:
00065 SICPPSDK_INLINE LONG GetNextBitInternal(LONG& in_index) const;
00066 SICPPSDK_INLINE LONG GetFirstBit( ULONG in_nVal) const;
00067 SICPPSDK_INLINE LONG GetRevLogBase2( ULONG in_nVal ) const;
00068 SICPPSDK_INLINE CStatus SetBit( LONG in_index );
00069 SICPPSDK_INLINE CStatus ClearBit( LONG in_index );
00070
00071 LONG m_nCount;
00072 ULONG* m_pArray;
00073 };
00074
00075
00120
00121
00122 class CIndexSet
00123 {
00124 public:
00125 typedef CIndexSet* PtrType;
00126
00127 enum StorageMode
00128 {
00129 Range,
00130 Bitset,
00131 Indices,
00132 Unknown
00133 };
00134
00135
00143
00144 class Iterator
00145 {
00146 public:
00147 friend class CIndexSet;
00148
00153 SICPPSDK_INLINE void Remove();
00154
00158 SICPPSDK_INLINE bool HasNext() const;
00159
00163 SICPPSDK_INLINE ULONG GetIndex() const;
00164
00168 SICPPSDK_INLINE ULONG GetAbsoluteIndex() const;
00169
00172 SICPPSDK_INLINE void Next();
00173
00177 SICPPSDK_INLINE operator ULONG () const;
00178
00179 private:
00180 SICPPSDK_INLINE Iterator( PtrType in_pSet );
00181
00182 bool m_bEnd;
00183 LONG m_nPos;
00184 PtrType m_pSet;
00185 };
00186
00187 friend class ICENodeContext;
00188 friend class Iterator;
00189
00193 SICPPSDK_INLINE CIndexSet( const ICENodeContext& in_ctxt );
00194
00197 SICPPSDK_INLINE ~CIndexSet();
00198
00202 SICPPSDK_INLINE Iterator Begin();
00203
00204 protected:
00205 SICPPSDK_INLINE void RemoveElement( Iterator& io_it );
00206 SICPPSDK_INLINE bool GetNextBit(LONG& in_it) const;
00207 SICPPSDK_INLINE ULONG*& GetDataRef();
00208 SICPPSDK_INLINE ULONG& GetIndexOffsetRef();
00209 SICPPSDK_INLINE void*& GetHandleRef();
00210 SICPPSDK_INLINE ULONG& GetCountRef();
00211 SICPPSDK_INLINE StorageMode& GetStorageModeRef();
00212 SICPPSDK_INLINE ICENodeContext& GetContextRef();
00213 SICPPSDK_INLINE CBitsetHelper& GetBitsetRef();
00214
00215 ULONG* m_pData;
00216 ULONG m_nIndexOffset;
00217 void* m_pHandle;
00218 ULONG m_nCount;
00219 StorageMode m_eStorageMode;
00220 ICENodeContext m_ctxt;
00221 CBitsetHelper m_bitset;
00222 };
00223
00224 SICPPSDK_INLINE CIndexSet::CIndexSet( const ICENodeContext& in_ctxt )
00225 {
00226 m_ctxt = in_ctxt;
00227 m_eStorageMode = Unknown;
00228 m_nIndexOffset = 0;
00229 m_pHandle = NULL;
00230 m_pData = NULL;
00231 m_nCount = 0;
00232 m_pData = NULL;
00233 }
00234
00235 SICPPSDK_INLINE CIndexSet::~CIndexSet()
00236 {
00237 m_ctxt.ReleaseIndexSet( *this );
00238 }
00239
00240 SICPPSDK_INLINE CIndexSet::Iterator CIndexSet::Begin()
00241 {
00242 m_ctxt.AcquireIndexSet( *this );
00243 return CIndexSet::Iterator((PtrType)this);
00244 }
00245
00246 SICPPSDK_INLINE void CIndexSet::RemoveElement( CIndexSet::Iterator& io_it )
00247 {
00248 m_ctxt.RemoveElementFromIndexSet( *this, io_it.m_nPos, io_it.m_nPos, io_it.m_bEnd );
00249 }
00250
00251 SICPPSDK_INLINE bool CIndexSet::GetNextBit(LONG& in_it) const
00252 {
00253 if ( m_eStorageMode != Bitset )
00254 {
00255 assert(false);
00256 return false;
00257 }
00258
00259 return m_bitset.GetNextBit( in_it );
00260 }
00261
00262 SICPPSDK_INLINE ULONG*& CIndexSet::GetDataRef()
00263 {
00264 return m_pData;
00265 }
00266
00267 SICPPSDK_INLINE ULONG& CIndexSet::GetIndexOffsetRef()
00268 {
00269 return m_nIndexOffset;
00270 }
00271
00272 SICPPSDK_INLINE void*& CIndexSet::GetHandleRef()
00273 {
00274 return m_pHandle;
00275 }
00276
00277 SICPPSDK_INLINE ULONG& CIndexSet::GetCountRef()
00278 {
00279 return m_nCount;
00280 }
00281
00282 SICPPSDK_INLINE CIndexSet::StorageMode& CIndexSet::GetStorageModeRef()
00283 {
00284 return m_eStorageMode;
00285 }
00286
00287 SICPPSDK_INLINE ICENodeContext& CIndexSet::GetContextRef()
00288 {
00289 return m_ctxt;
00290 }
00291
00292 SICPPSDK_INLINE CBitsetHelper& CIndexSet::GetBitsetRef()
00293 {
00294 return m_bitset;
00295 }
00296
00297 SICPPSDK_INLINE CIndexSet::Iterator::Iterator( CIndexSet::PtrType in_pSet ) : m_pSet(in_pSet), m_nPos(0), m_bEnd(false)
00298 {
00299 }
00300
00301
00302 SICPPSDK_INLINE void CIndexSet::Iterator::Next()
00303 {
00304 switch(m_pSet->m_eStorageMode)
00305 {
00306 case Range:
00307 m_bEnd = (ULONG)(++m_nPos) == m_pSet->m_nCount;
00308 break;
00309 case Bitset:
00310 m_bEnd = !m_pSet->GetNextBit(m_nPos);
00311 break;
00312 case Indices:
00313 while(true)
00314 {
00315 ++m_nPos;
00316 if (m_nPos == m_pSet->m_nCount)
00317 {
00318 m_bEnd = true;
00319 break;
00320 }
00321
00322 if(m_pSet->m_pData[m_nPos] != UINT_MAX)
00323 {
00324 break;
00325 }
00326 }
00327 break;
00328 };
00329 }
00330
00331 SICPPSDK_INLINE ULONG CIndexSet::Iterator::GetIndex() const
00332 {
00333 switch(m_pSet->m_eStorageMode)
00334 {
00335 case Indices:
00336 return m_pSet->m_pData[m_nPos];
00337 default:
00338 return m_nPos;
00339 }
00340 }
00341
00342 SICPPSDK_INLINE ULONG CIndexSet::Iterator::GetAbsoluteIndex() const
00343 {
00344 return GetIndex() + m_pSet->m_nIndexOffset;
00345 }
00346
00347 SICPPSDK_INLINE CIndexSet::Iterator::operator ULONG () const
00348 {
00349 return GetIndex( );
00350 }
00351
00352 SICPPSDK_INLINE bool CIndexSet::Iterator::HasNext() const
00353 {
00354 return m_bEnd == false && m_pSet->m_nCount > 0;
00355 }
00356
00357 SICPPSDK_INLINE void CIndexSet::Iterator::Remove()
00358 {
00359 if (m_bEnd )
00360 {
00361 return;
00362 }
00363
00364 m_pSet->RemoveElement( *this );
00365 }
00366
00367
00368 SICPPSDK_INLINE CBitsetHelper::CBitsetHelper( ) : m_nCount(UINT_MAX), m_pArray(NULL) {}
00369
00370 SICPPSDK_INLINE void CBitsetHelper::Clear( )
00371 {
00372 m_nCount = 0;
00373 m_pArray = 0;
00374 }
00375
00376 SICPPSDK_INLINE CBitsetHelper& CBitsetHelper::operator = ( const CBitsetHelper& in_bitset )
00377 {
00378 m_nCount = in_bitset.m_nCount;
00379 m_pArray = in_bitset.m_pArray;
00380 return *this;
00381 }
00382
00383 SICPPSDK_INLINE LONG& CBitsetHelper::GetCountRef( )
00384 {
00385 return m_nCount;
00386 }
00387
00388 SICPPSDK_INLINE LONG CBitsetHelper::GetCount( ) const
00389 {
00390 return m_nCount;
00391 }
00392
00393 SICPPSDK_INLINE ULONG*& CBitsetHelper::GetArrayRef()
00394 {
00395 return m_pArray;
00396 }
00397
00398 SICPPSDK_INLINE bool CBitsetHelper::GetNextBit( LONG& in_it ) const
00399 {
00400 return ( in_it = GetNextBitInternal( in_it ) ) != m_nCount;
00401 }
00402
00403 SICPPSDK_INLINE bool CBitsetHelper::GetBit( LONG in_index ) const
00404 {
00405 if ( in_index >= (LONG)m_nCount )
00406 {
00407 assert( false );
00408 return false;
00409 }
00410
00411 return ( m_pArray[ in_index >> kBitShift ] & ( 1 << ( in_index % kBitSize ) ) ) != 0;
00412 }
00413
00414 SICPPSDK_INLINE CStatus CBitsetHelper::SetBit( LONG in_index, bool in_bVal )
00415 {
00416 if ( in_bVal )
00417 {
00418 SetBit( in_index );
00419 }
00420 else
00421 {
00422 ClearBit( in_index );
00423 }
00424 return CStatus::OK;
00425 }
00426
00427 SICPPSDK_INLINE CStatus CBitsetHelper::SetBit( LONG in_index )
00428 {
00429 assert ( in_index < m_nCount );
00430 m_pArray[ in_index >> kBitShift ] |= ( 1 << ( in_index % kBitSize ) );
00431 return CStatus::OK;
00432 }
00433
00434 SICPPSDK_INLINE CStatus CBitsetHelper::ClearBit( LONG in_index )
00435 {
00436 assert ( in_index < m_nCount );
00437 m_pArray[ in_index >> kBitShift ] &= ~( 1 << ( in_index % kBitSize ) );
00438 return CStatus::OK;
00439 }
00440
00441 SICPPSDK_INLINE LONG CBitsetHelper::GetNextBitInternal( LONG& in_index ) const
00442 {
00443 LONG nCurrentBit = in_index+1;
00444 if (nCurrentBit >= m_nCount)
00445 {
00446 return m_nCount;
00447 }
00448
00449 LONG nCurrentIdx = nCurrentBit >> kBitShift;
00450
00451 ULONG nVal = m_pArray[nCurrentIdx];
00452 nVal >>= (nCurrentBit - (nCurrentIdx << kBitShift));
00453
00454 LONG nDeltaBit;
00455 if ((nDeltaBit = GetFirstBit(nVal)) == 32)
00456 {
00457 LONG nMaxIdx = ((m_nCount-1)>>kBitShift)+1;
00458
00459 for( nCurrentIdx++; nCurrentIdx != nMaxIdx; nCurrentIdx++ )
00460 {
00461 nDeltaBit = GetFirstBit(m_pArray[nCurrentIdx]);
00462
00463 if(nDeltaBit != 32)
00464 {
00465 break;
00466 }
00467 }
00468
00469 if( nCurrentIdx == nMaxIdx )
00470 {
00471 return m_nCount;
00472 }
00473 else
00474 {
00475 nCurrentBit = ( nCurrentIdx << kBitShift ) + nDeltaBit;
00476 }
00477 }
00478 else
00479 {
00480 nCurrentBit += nDeltaBit;
00481 }
00482
00483 if( nCurrentBit > m_nCount )
00484 {
00485 return m_nCount;
00486 }
00487
00488 return nCurrentBit;
00489 }
00490
00491 SICPPSDK_INLINE LONG CBitsetHelper::GetFirstBit( ULONG in_nVal ) const
00492 {
00493 return GetRevLogBase2( in_nVal );
00494 }
00495
00496 SICPPSDK_INLINE LONG CBitsetHelper::GetRevLogBase2( ULONG in_nVal ) const
00497 {
00498 register unsigned int t, tt;
00499
00500 if ( tt = in_nVal & 0xFFFF, tt != 0 )
00501 {
00502 return (t = in_nVal & 0xFF, t != 0 ) ? kRevLogTable256[t] : 8 + kRevLogTable256[tt >> 8];
00503 }
00504 else
00505 {
00506 return (t = in_nVal & 0x00FF0000, t != 0 ) ? 16 + kRevLogTable256[t >> 16] : 24 + kRevLogTable256[in_nVal >> 24];
00507 }
00508 }
00509
00510 };
00511
00512 #endif // __XSIINDEXSET_H__