1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #ifndef SC_COMPRESSEDARRAY_HXX 29*cdf0e10cSrcweir #define SC_COMPRESSEDARRAY_HXX 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #ifndef INCLUDED_CSTDDEF 32*cdf0e10cSrcweir #include <cstddef> 33*cdf0e10cSrcweir #define INCLUDED_CSTDDEF 34*cdf0e10cSrcweir #endif 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir #ifndef INCLUDED_ALGORITHM 37*cdf0e10cSrcweir #include <algorithm> 38*cdf0e10cSrcweir #define INCLUDED_ALGORITHM 39*cdf0e10cSrcweir #endif 40*cdf0e10cSrcweir #include "scdllapi.h" 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir const size_t nScCompressedArrayDelta = 4; 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir template< typename A, typename D > class ScCompressedArrayIterator; 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir /** Compressed array of row (or column) entries, e.g. heights, flags, ... 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir The array stores ranges of values such that consecutive values occupy only 49*cdf0e10cSrcweir one entry. Initially it consists of one DataEntry with an implied start 50*cdf0e10cSrcweir row/column of 0 and an end row/column of access type maximum value. 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir typename A := access type, e.g. SCROW or SCCOL, must be a POD. 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir typename D := data type, e.g. sal_uInt16 or sal_uInt8 or whatever, may also be a 55*cdf0e10cSrcweir struct or class. 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir D::operator==() and D::operator=() must be implemented. Force template 58*cdf0e10cSrcweir instantiation for a specific type in source/core/data/compressedarray.cxx 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir TODO: Currently the allocated memory never shrinks, must manually invoke 61*cdf0e10cSrcweir Resize() if needed. 62*cdf0e10cSrcweir */ 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir template< typename A, typename D > class ScCompressedArray 65*cdf0e10cSrcweir { 66*cdf0e10cSrcweir public: 67*cdf0e10cSrcweir struct DataEntry 68*cdf0e10cSrcweir { 69*cdf0e10cSrcweir A nEnd; // start is end of previous entry + 1 70*cdf0e10cSrcweir D aValue; 71*cdf0e10cSrcweir DataEntry() {} //! uninitialized 72*cdf0e10cSrcweir }; 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir /** Construct with nMaxAccess=MAXROW, for example. */ 75*cdf0e10cSrcweir ScCompressedArray( A nMaxAccess, 76*cdf0e10cSrcweir const D& rValue, 77*cdf0e10cSrcweir size_t nDelta = nScCompressedArrayDelta ); 78*cdf0e10cSrcweir /** Construct from a plain array of D */ 79*cdf0e10cSrcweir ScCompressedArray( A nMaxAccess, 80*cdf0e10cSrcweir const D* pDataArray, size_t nDataCount ); 81*cdf0e10cSrcweir virtual ~ScCompressedArray(); 82*cdf0e10cSrcweir void Resize( size_t nNewSize ); 83*cdf0e10cSrcweir void Reset( const D& rValue ); 84*cdf0e10cSrcweir void SetValue( A nPos, const D& rValue ); 85*cdf0e10cSrcweir void SetValue( A nStart, A nEnd, const D& rValue ); 86*cdf0e10cSrcweir const D& GetValue( A nPos ) const; 87*cdf0e10cSrcweir 88*cdf0e10cSrcweir /** Get value for a row, and it's region end row */ 89*cdf0e10cSrcweir const D& GetValue( A nPos, size_t& nIndex, A& nEnd ) const; 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir /** Get value for a row, and it's region start row and end row */ 92*cdf0e10cSrcweir const D& GetValue( A nPos, size_t& nIndex, A& nStart, A& nEnd ) const; 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir /** Get next value and it's region end row. If nIndex<nCount, nIndex is 95*cdf0e10cSrcweir incremented first. If the resulting nIndex>=nCount, the value of the 96*cdf0e10cSrcweir last entry is returned again. */ 97*cdf0e10cSrcweir const D& GetNextValue( size_t& nIndex, A& nEnd ) const; 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir /** Get previous value and it's region start row. If nIndex==0, nIndex is 100*cdf0e10cSrcweir not decremented and the value of the first entry is returned again. */ 101*cdf0e10cSrcweir const D& GetPrevValue( size_t& nIndex, A& nStart ) const; 102*cdf0e10cSrcweir 103*cdf0e10cSrcweir /** Return the last row where an entry meets the condition: 104*cdf0e10cSrcweir (aValue != rCompare). If no entry meets this condition 105*cdf0e10cSrcweir ::std::numeric_limits<A>::max() is returned. */ 106*cdf0e10cSrcweir A GetLastUnequalAccess( A nStart, const D& rCompare ); 107*cdf0e10cSrcweir 108*cdf0e10cSrcweir /** Insert rows before nStart and copy value for inserted rows from 109*cdf0e10cSrcweir nStart-1, return that value. */ 110*cdf0e10cSrcweir const D& Insert( A nStart, size_t nCount ); 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir void Remove( A nStart, size_t nCount ); 113*cdf0e10cSrcweir 114*cdf0e10cSrcweir /** Copy rArray.nStart+nSourceDy to this.nStart */ 115*cdf0e10cSrcweir void CopyFrom( const ScCompressedArray& rArray, 116*cdf0e10cSrcweir A nStart, A nEnd, long nSourceDy = 0 ); 117*cdf0e10cSrcweir 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir // methods public for the coupled array sum methods 120*cdf0e10cSrcweir /** Obtain index into entries for nPos */ 121*cdf0e10cSrcweir SC_DLLPUBLIC size_t Search( A nPos ) const; 122*cdf0e10cSrcweir /** Get number of entries */ 123*cdf0e10cSrcweir size_t GetEntryCount() const; 124*cdf0e10cSrcweir /** Get data entry for an index */ 125*cdf0e10cSrcweir const DataEntry& GetDataEntry( size_t nIndex ) const; 126*cdf0e10cSrcweir 127*cdf0e10cSrcweir protected: 128*cdf0e10cSrcweir 129*cdf0e10cSrcweir friend class ScCompressedArrayIterator<A,D>; 130*cdf0e10cSrcweir 131*cdf0e10cSrcweir size_t nCount; 132*cdf0e10cSrcweir size_t nLimit; 133*cdf0e10cSrcweir size_t nDelta; 134*cdf0e10cSrcweir DataEntry* pData; 135*cdf0e10cSrcweir A nMaxAccess; 136*cdf0e10cSrcweir }; 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir template< typename A, typename D > 140*cdf0e10cSrcweir void ScCompressedArray<A,D>::Reset( const D& rValue ) 141*cdf0e10cSrcweir { 142*cdf0e10cSrcweir // Create a temporary copy in case we got a reference passed that points to 143*cdf0e10cSrcweir // a part of the array to be reallocated. 144*cdf0e10cSrcweir D aTmpVal( rValue); 145*cdf0e10cSrcweir delete[] pData; 146*cdf0e10cSrcweir nCount = nLimit = 1; 147*cdf0e10cSrcweir pData = new DataEntry[1]; 148*cdf0e10cSrcweir pData[0].aValue = aTmpVal; 149*cdf0e10cSrcweir pData[0].nEnd = nMaxAccess; 150*cdf0e10cSrcweir } 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir template< typename A, typename D > 154*cdf0e10cSrcweir void ScCompressedArray<A,D>::SetValue( A nPos, const D& rValue ) 155*cdf0e10cSrcweir { 156*cdf0e10cSrcweir SetValue( nPos, nPos, rValue); 157*cdf0e10cSrcweir } 158*cdf0e10cSrcweir 159*cdf0e10cSrcweir 160*cdf0e10cSrcweir template< typename A, typename D > 161*cdf0e10cSrcweir const D& ScCompressedArray<A,D>::GetValue( A nPos ) const 162*cdf0e10cSrcweir { 163*cdf0e10cSrcweir size_t nIndex = Search( nPos); 164*cdf0e10cSrcweir return pData[nIndex].aValue; 165*cdf0e10cSrcweir } 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir 168*cdf0e10cSrcweir template< typename A, typename D > 169*cdf0e10cSrcweir const D& ScCompressedArray<A,D>::GetValue( A nPos, size_t& nIndex, A& nEnd ) const 170*cdf0e10cSrcweir { 171*cdf0e10cSrcweir nIndex = Search( nPos); 172*cdf0e10cSrcweir nEnd = pData[nIndex].nEnd; 173*cdf0e10cSrcweir return pData[nIndex].aValue; 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir template< typename A, typename D > 178*cdf0e10cSrcweir const D& ScCompressedArray<A,D>::GetValue( A nPos, size_t& nIndex, A& nStart, 179*cdf0e10cSrcweir A& nEnd ) const 180*cdf0e10cSrcweir { 181*cdf0e10cSrcweir nIndex = Search( nPos); 182*cdf0e10cSrcweir nStart = (nIndex > 0 ? pData[nIndex-1].nEnd + 1 : 0); 183*cdf0e10cSrcweir nEnd = pData[nIndex].nEnd; 184*cdf0e10cSrcweir return pData[nIndex].aValue; 185*cdf0e10cSrcweir } 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir template< typename A, typename D > 189*cdf0e10cSrcweir const D& ScCompressedArray<A,D>::GetNextValue( size_t& nIndex, A& nEnd ) const 190*cdf0e10cSrcweir { 191*cdf0e10cSrcweir if (nIndex < nCount) 192*cdf0e10cSrcweir ++nIndex; 193*cdf0e10cSrcweir size_t nEntry = (nIndex < nCount ? nIndex : nCount-1); 194*cdf0e10cSrcweir nEnd = pData[nEntry].nEnd; 195*cdf0e10cSrcweir return pData[nEntry].aValue; 196*cdf0e10cSrcweir } 197*cdf0e10cSrcweir 198*cdf0e10cSrcweir 199*cdf0e10cSrcweir template< typename A, typename D > 200*cdf0e10cSrcweir const D& ScCompressedArray<A,D>::GetPrevValue( size_t& nIndex, A& nStart ) const 201*cdf0e10cSrcweir { 202*cdf0e10cSrcweir if (nIndex > 0) 203*cdf0e10cSrcweir --nIndex; 204*cdf0e10cSrcweir nStart = (nIndex > 0 ? pData[nIndex-1].nEnd + 1 : 0); 205*cdf0e10cSrcweir return pData[nIndex].aValue; 206*cdf0e10cSrcweir } 207*cdf0e10cSrcweir 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir template< typename A, typename D > 210*cdf0e10cSrcweir size_t ScCompressedArray<A,D>::GetEntryCount() const 211*cdf0e10cSrcweir { 212*cdf0e10cSrcweir return nCount; 213*cdf0e10cSrcweir } 214*cdf0e10cSrcweir 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir template< typename A, typename D > 217*cdf0e10cSrcweir const typename ScCompressedArray<A,D>::DataEntry& 218*cdf0e10cSrcweir ScCompressedArray<A,D>::GetDataEntry( size_t nIndex ) const 219*cdf0e10cSrcweir { 220*cdf0e10cSrcweir return pData[nIndex]; 221*cdf0e10cSrcweir } 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir 224*cdf0e10cSrcweir // === ScCompressedArrayIterator ============================================= 225*cdf0e10cSrcweir 226*cdf0e10cSrcweir /** Iterator for ScCompressedArray. 227*cdf0e10cSrcweir 228*cdf0e10cSrcweir @ATTENTION: the iterator is not persistant if the underlying 229*cdf0e10cSrcweir ScCompressedArray happens to be changed by any means, for example by 230*cdf0e10cSrcweir setting new values or adding or removing or combining entries. If you do 231*cdf0e10cSrcweir such things inside a loop you MUST resynchronize the iterator by calling 232*cdf0e10cSrcweir <method>Resync()</method> with the row where resynchronization should 233*cdf0e10cSrcweir start. After doing so, <method>GetRangeStart()</method> and 234*cdf0e10cSrcweir <method>GetRangeEnd()</method> may not point to the previous access points 235*cdf0e10cSrcweir anymore. Use with care. 236*cdf0e10cSrcweir */ 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir template< typename A, typename D > class ScCompressedArrayIterator 239*cdf0e10cSrcweir { 240*cdf0e10cSrcweir public: 241*cdf0e10cSrcweir ScCompressedArrayIterator( 242*cdf0e10cSrcweir const ScCompressedArray<A,D> & rArray, 243*cdf0e10cSrcweir A nStart, A nEnd ); 244*cdf0e10cSrcweir /// Set new start and end, position on start. 245*cdf0e10cSrcweir void NewLimits( A nStart, A nEnd ); 246*cdf0e10cSrcweir A GetIterStart() const; 247*cdf0e10cSrcweir A GetIterEnd() const; 248*cdf0e10cSrcweir /// Advance by a single access point (e.g. row). 249*cdf0e10cSrcweir bool operator ++(); 250*cdf0e10cSrcweir A GetPos() const; 251*cdf0e10cSrcweir operator bool() const; 252*cdf0e10cSrcweir const D& operator *() const; 253*cdf0e10cSrcweir /// Advance an entire range, one entry of the array. 254*cdf0e10cSrcweir bool NextRange(); 255*cdf0e10cSrcweir A GetRangeStart() const; 256*cdf0e10cSrcweir A GetRangeEnd() const; 257*cdf0e10cSrcweir /// Resync to underlying array, calling Search(). 258*cdf0e10cSrcweir void Resync( A nPos ); 259*cdf0e10cSrcweir /** Set position without resyncing, avoid calling Search() if possible. 260*cdf0e10cSrcweir Position obtained from steering coupled iterator is NOT checked for 261*cdf0e10cSrcweir iterator bounds. */ 262*cdf0e10cSrcweir template< typename X > 263*cdf0e10cSrcweir void Follow( const ScCompressedArrayIterator<A,X>& ); 264*cdf0e10cSrcweir 265*cdf0e10cSrcweir private: 266*cdf0e10cSrcweir const ScCompressedArray<A,D> & rArray; 267*cdf0e10cSrcweir size_t nIndex; 268*cdf0e10cSrcweir A nIterStart; 269*cdf0e10cSrcweir A nIterEnd; 270*cdf0e10cSrcweir A nCurrent; 271*cdf0e10cSrcweir bool bEnd; 272*cdf0e10cSrcweir }; 273*cdf0e10cSrcweir 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir template< typename A, typename D > 276*cdf0e10cSrcweir ScCompressedArrayIterator<A,D>::ScCompressedArrayIterator( 277*cdf0e10cSrcweir const ScCompressedArray<A,D> & rArrayP, A nStart, A nEnd ) 278*cdf0e10cSrcweir : rArray( rArrayP ) 279*cdf0e10cSrcweir // other values set in NewLimits() 280*cdf0e10cSrcweir { 281*cdf0e10cSrcweir NewLimits( nStart, nEnd); 282*cdf0e10cSrcweir } 283*cdf0e10cSrcweir 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir template< typename A, typename D > 286*cdf0e10cSrcweir void ScCompressedArrayIterator<A,D>::NewLimits( A nStart, A nEnd ) 287*cdf0e10cSrcweir { 288*cdf0e10cSrcweir nIterStart = nStart; 289*cdf0e10cSrcweir nIterEnd = nEnd; 290*cdf0e10cSrcweir nIndex = rArray.Search( nStart); 291*cdf0e10cSrcweir nCurrent = GetRangeStart(); 292*cdf0e10cSrcweir bEnd = (nIterEnd < nIterStart); 293*cdf0e10cSrcweir } 294*cdf0e10cSrcweir 295*cdf0e10cSrcweir 296*cdf0e10cSrcweir template< typename A, typename D > 297*cdf0e10cSrcweir A ScCompressedArrayIterator<A,D>::GetIterStart() const 298*cdf0e10cSrcweir { 299*cdf0e10cSrcweir return nIterStart; 300*cdf0e10cSrcweir } 301*cdf0e10cSrcweir 302*cdf0e10cSrcweir 303*cdf0e10cSrcweir template< typename A, typename D > 304*cdf0e10cSrcweir A ScCompressedArrayIterator<A,D>::GetIterEnd() const 305*cdf0e10cSrcweir { 306*cdf0e10cSrcweir return nIterEnd; 307*cdf0e10cSrcweir } 308*cdf0e10cSrcweir 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir template< typename A, typename D > 311*cdf0e10cSrcweir bool ScCompressedArrayIterator<A,D>::operator++() 312*cdf0e10cSrcweir { 313*cdf0e10cSrcweir if (nCurrent < GetRangeEnd()) 314*cdf0e10cSrcweir { 315*cdf0e10cSrcweir ++nCurrent; 316*cdf0e10cSrcweir return true; 317*cdf0e10cSrcweir } 318*cdf0e10cSrcweir else 319*cdf0e10cSrcweir return NextRange(); 320*cdf0e10cSrcweir } 321*cdf0e10cSrcweir 322*cdf0e10cSrcweir 323*cdf0e10cSrcweir template< typename A, typename D > 324*cdf0e10cSrcweir A ScCompressedArrayIterator<A,D>::GetPos() const 325*cdf0e10cSrcweir { 326*cdf0e10cSrcweir return nCurrent; 327*cdf0e10cSrcweir } 328*cdf0e10cSrcweir 329*cdf0e10cSrcweir 330*cdf0e10cSrcweir template< typename A, typename D > 331*cdf0e10cSrcweir bool ScCompressedArrayIterator<A,D>::NextRange() 332*cdf0e10cSrcweir { 333*cdf0e10cSrcweir if (!operator bool()) 334*cdf0e10cSrcweir return false; 335*cdf0e10cSrcweir 336*cdf0e10cSrcweir if (rArray.pData[nIndex].nEnd >= nIterEnd) 337*cdf0e10cSrcweir bEnd = true; 338*cdf0e10cSrcweir else if (++nIndex >= rArray.GetEntryCount()) 339*cdf0e10cSrcweir { 340*cdf0e10cSrcweir nIndex = rArray.GetEntryCount() - 1; 341*cdf0e10cSrcweir bEnd = true; 342*cdf0e10cSrcweir } 343*cdf0e10cSrcweir nCurrent = bEnd ? nIterEnd : GetRangeStart(); 344*cdf0e10cSrcweir return operator bool(); 345*cdf0e10cSrcweir } 346*cdf0e10cSrcweir 347*cdf0e10cSrcweir 348*cdf0e10cSrcweir template< typename A, typename D > 349*cdf0e10cSrcweir ScCompressedArrayIterator<A,D>::operator bool() const 350*cdf0e10cSrcweir { 351*cdf0e10cSrcweir return !bEnd; 352*cdf0e10cSrcweir } 353*cdf0e10cSrcweir 354*cdf0e10cSrcweir 355*cdf0e10cSrcweir template< typename A, typename D > 356*cdf0e10cSrcweir const D& ScCompressedArrayIterator<A,D>::operator*() const 357*cdf0e10cSrcweir { 358*cdf0e10cSrcweir return rArray.pData[nIndex].aValue; 359*cdf0e10cSrcweir } 360*cdf0e10cSrcweir 361*cdf0e10cSrcweir 362*cdf0e10cSrcweir template< typename A, typename D > 363*cdf0e10cSrcweir A ScCompressedArrayIterator<A,D>::GetRangeStart() const 364*cdf0e10cSrcweir { 365*cdf0e10cSrcweir if (nIndex == 0) 366*cdf0e10cSrcweir return nIterStart > 0 ? nIterStart : 0; 367*cdf0e10cSrcweir else 368*cdf0e10cSrcweir return nIterStart > rArray.pData[nIndex-1].nEnd ? nIterStart : 369*cdf0e10cSrcweir rArray.pData[nIndex-1].nEnd + 1; 370*cdf0e10cSrcweir } 371*cdf0e10cSrcweir 372*cdf0e10cSrcweir 373*cdf0e10cSrcweir template< typename A, typename D > 374*cdf0e10cSrcweir A ScCompressedArrayIterator<A,D>::GetRangeEnd() const 375*cdf0e10cSrcweir { 376*cdf0e10cSrcweir return nIterEnd < rArray.pData[nIndex].nEnd ? nIterEnd : 377*cdf0e10cSrcweir rArray.pData[nIndex].nEnd; 378*cdf0e10cSrcweir } 379*cdf0e10cSrcweir 380*cdf0e10cSrcweir 381*cdf0e10cSrcweir template< typename A, typename D > 382*cdf0e10cSrcweir void ScCompressedArrayIterator<A,D>::Resync( A nPos ) 383*cdf0e10cSrcweir { 384*cdf0e10cSrcweir if (nPos < nIterStart) 385*cdf0e10cSrcweir nPos = nIterStart; 386*cdf0e10cSrcweir else if (nPos > nIterEnd) 387*cdf0e10cSrcweir nPos = nIterEnd; 388*cdf0e10cSrcweir nCurrent = nPos; 389*cdf0e10cSrcweir bEnd = (nIterEnd < nIterStart); 390*cdf0e10cSrcweir nIndex = rArray.Search( nPos); 391*cdf0e10cSrcweir } 392*cdf0e10cSrcweir 393*cdf0e10cSrcweir 394*cdf0e10cSrcweir // === ScSummableCompressedArray ============================================= 395*cdf0e10cSrcweir 396*cdf0e10cSrcweir /** Data type D must be of a type that is convertable to unsigned long. The 397*cdf0e10cSrcweir advantage is that specialized methods exist to act on a region of values 398*cdf0e10cSrcweir for performance reasons. 399*cdf0e10cSrcweir */ 400*cdf0e10cSrcweir 401*cdf0e10cSrcweir template< typename A, typename D > class ScSummableCompressedArray : public ScCompressedArray<A,D> 402*cdf0e10cSrcweir { 403*cdf0e10cSrcweir public: 404*cdf0e10cSrcweir ScSummableCompressedArray( A nMaxAccessP, 405*cdf0e10cSrcweir const D& rValue, 406*cdf0e10cSrcweir size_t nDeltaP = nScCompressedArrayDelta ) 407*cdf0e10cSrcweir : ScCompressedArray<A,D>( nMaxAccessP, 408*cdf0e10cSrcweir rValue, nDeltaP) 409*cdf0e10cSrcweir {} 410*cdf0e10cSrcweir ScSummableCompressedArray( A nMaxAccessP, 411*cdf0e10cSrcweir const D* pDataArray, size_t nDataCount ) 412*cdf0e10cSrcweir : ScCompressedArray<A,D>( nMaxAccessP, 413*cdf0e10cSrcweir pDataArray, nDataCount) 414*cdf0e10cSrcweir {} 415*cdf0e10cSrcweir 416*cdf0e10cSrcweir /** Returns the sum of all values for a region. If an overflow would occur, 417*cdf0e10cSrcweir ::std::numeric_limits<unsigned long>::max() is returned. */ 418*cdf0e10cSrcweir unsigned long SumValues( A nStart, A nEnd ) const; 419*cdf0e10cSrcweir 420*cdf0e10cSrcweir /** Returns the sum of all values for a region. If an overflow would occur, 421*cdf0e10cSrcweir ::std::numeric_limits<unsigned long>::max() is returned. 422*cdf0e10cSrcweir The caller has to assure that nIndex matches an entry belonging to 423*cdf0e10cSrcweir nStart, for example, by calling Search(nStart) first! */ 424*cdf0e10cSrcweir unsigned long SumValuesContinuation( A nStart, A nEnd, 425*cdf0e10cSrcweir size_t& nIndex ) const; 426*cdf0e10cSrcweir 427*cdf0e10cSrcweir /** Returns the sum of all scaled values for a region. If an overflow would 428*cdf0e10cSrcweir occur, ::std::numeric_limits<unsigned long>::max() is returned. 429*cdf0e10cSrcweir Summed values are treated as if for each row the expression 430*cdf0e10cSrcweir (sum += (unsigned long) (scale * value)) had been applied. 431*cdf0e10cSrcweir The caller has to assure that nIndex matches an entry belonging to 432*cdf0e10cSrcweir nStart, for example, by calling Search(nStart) first! */ 433*cdf0e10cSrcweir unsigned long SumScaledValuesContinuation( A nStart, A nEnd, 434*cdf0e10cSrcweir size_t& nIndex, double fScale ) const; 435*cdf0e10cSrcweir 436*cdf0e10cSrcweir }; 437*cdf0e10cSrcweir 438*cdf0e10cSrcweir 439*cdf0e10cSrcweir // === ScBitMaskCompressedArray ============================================== 440*cdf0e10cSrcweir 441*cdf0e10cSrcweir /** The data type represents bits, managable by bitwise operations. 442*cdf0e10cSrcweir */ 443*cdf0e10cSrcweir 444*cdf0e10cSrcweir template< typename A, typename D > class ScBitMaskCompressedArray : public ScCompressedArray<A,D> 445*cdf0e10cSrcweir { 446*cdf0e10cSrcweir public: 447*cdf0e10cSrcweir ScBitMaskCompressedArray( A nMaxAccessP, 448*cdf0e10cSrcweir const D& rValue, 449*cdf0e10cSrcweir size_t nDeltaP = nScCompressedArrayDelta ) 450*cdf0e10cSrcweir : ScCompressedArray<A,D>( nMaxAccessP, rValue, nDeltaP) 451*cdf0e10cSrcweir {} 452*cdf0e10cSrcweir ScBitMaskCompressedArray( A nMaxAccessP, 453*cdf0e10cSrcweir const D* pDataArray, size_t nDataCount ) 454*cdf0e10cSrcweir : ScCompressedArray<A,D>( nMaxAccessP, 455*cdf0e10cSrcweir pDataArray, nDataCount) 456*cdf0e10cSrcweir {} 457*cdf0e10cSrcweir void AndValue( A nPos, const D& rValueToAnd ); 458*cdf0e10cSrcweir void OrValue( A nPos, const D& rValueToOr ); 459*cdf0e10cSrcweir void AndValue( A nStart, A nEnd, const D& rValueToAnd ); 460*cdf0e10cSrcweir void OrValue( A nStart, A nEnd, const D& rValueToOr ); 461*cdf0e10cSrcweir 462*cdf0e10cSrcweir /** Copy values from rArray and bitwise AND them with rValueToAnd. */ 463*cdf0e10cSrcweir void CopyFromAnded( 464*cdf0e10cSrcweir const ScBitMaskCompressedArray& rArray, 465*cdf0e10cSrcweir A nStart, A nEnd, const D& rValueToAnd, 466*cdf0e10cSrcweir long nSourceDy = 0 ); 467*cdf0e10cSrcweir 468*cdf0e10cSrcweir /** Copy values from rArray and bitwise OR them with rValueToOr. */ 469*cdf0e10cSrcweir void CopyFromOred( 470*cdf0e10cSrcweir const ScBitMaskCompressedArray& rArray, 471*cdf0e10cSrcweir A nStart, A nEnd, const D& rValueToOr, 472*cdf0e10cSrcweir long nSourceDy = 0 ); 473*cdf0e10cSrcweir 474*cdf0e10cSrcweir /** Return the start row of a region where all entries meet the condition: 475*cdf0e10cSrcweir ((aValue & rBitMask) == rMaskedCompare). If not even nEnd meets 476*cdf0e10cSrcweir this condition, ::std::numeric_limits<A>::max() is returned. */ 477*cdf0e10cSrcweir A GetBitStateStart( A nEnd, const D& rBitMask, 478*cdf0e10cSrcweir const D& rMaskedCompare ) const; 479*cdf0e10cSrcweir 480*cdf0e10cSrcweir /** Return the end row of a region where all entries meet the condition: 481*cdf0e10cSrcweir ((aValue & rBitMask) == rMaskedCompare). If not even nStart meets 482*cdf0e10cSrcweir this condition, ::std::numeric_limits<A>::max() is returned. */ 483*cdf0e10cSrcweir A GetBitStateEnd( A nStart, const D& rBitMask, 484*cdf0e10cSrcweir const D& rMaskedCompare ) const; 485*cdf0e10cSrcweir 486*cdf0e10cSrcweir /** Return the first row where an entry meets the condition: 487*cdf0e10cSrcweir ((aValue & rBitMask) == rMaskedCompare), searching between nStart and 488*cdf0e10cSrcweir nEnd. If no entry meets this condition, ::std::numeric_limits<A>::max() 489*cdf0e10cSrcweir is returned. */ 490*cdf0e10cSrcweir SC_DLLPUBLIC A GetFirstForCondition( A nStart, A nEnd, 491*cdf0e10cSrcweir const D& rBitMask, 492*cdf0e10cSrcweir const D& rMaskedCompare ) const; 493*cdf0e10cSrcweir 494*cdf0e10cSrcweir /** Return the last row where an entry meets the condition: 495*cdf0e10cSrcweir ((aValue & rBitMask) == rMaskedCompare), searching between nStart and 496*cdf0e10cSrcweir nEnd. If no entry meets this condition, ::std::numeric_limits<A>::max() 497*cdf0e10cSrcweir is returned. */ 498*cdf0e10cSrcweir SC_DLLPUBLIC A GetLastForCondition( A nStart, A nEnd, 499*cdf0e10cSrcweir const D& rBitMask, 500*cdf0e10cSrcweir const D& rMaskedCompare ) const; 501*cdf0e10cSrcweir 502*cdf0e10cSrcweir /** Count rows between nStart and nEnd where entries meet the condition: 503*cdf0e10cSrcweir ((aValue & rBitMask) == rMaskedCompare) */ 504*cdf0e10cSrcweir A CountForCondition( A nStart, A nEnd, 505*cdf0e10cSrcweir const D& rBitMask, 506*cdf0e10cSrcweir const D& rMaskedCompare ) const; 507*cdf0e10cSrcweir 508*cdf0e10cSrcweir /** Whether there is any entry between nStart and nEnd where the condition 509*cdf0e10cSrcweir is met: ((aValue & rBitMask) == rMaskedCompare) */ 510*cdf0e10cSrcweir SC_DLLPUBLIC bool HasCondition( A nStart, A nEnd, 511*cdf0e10cSrcweir const D& rBitMask, 512*cdf0e10cSrcweir const D& rMaskedCompare ) const; 513*cdf0e10cSrcweir 514*cdf0e10cSrcweir /** Fill an array with row numbers between nStart and nEnd where entries 515*cdf0e10cSrcweir meet the condition: ((aValue & rBitMask) == rMaskedCompare). 516*cdf0e10cSrcweir @return the count of used elements in array. */ 517*cdf0e10cSrcweir size_t FillArrayForCondition( A nStart, A nEnd, 518*cdf0e10cSrcweir const D& rBitMask, 519*cdf0e10cSrcweir const D& rMaskedCompare, 520*cdf0e10cSrcweir A * pArray, size_t nArraySize ) const; 521*cdf0e10cSrcweir 522*cdf0e10cSrcweir /** Count rows between nStart and nEnd where entries meet the condition: 523*cdf0e10cSrcweir ((aValue & rBitMask) != 0) */ 524*cdf0e10cSrcweir A CountForAnyBitCondition( A nStart, A nEnd, 525*cdf0e10cSrcweir const D& rBitMask ) const; 526*cdf0e10cSrcweir 527*cdf0e10cSrcweir /** Return the last row where an entry meets the condition: 528*cdf0e10cSrcweir ((aValue & rBitMask) != 0), start searching at nStart. If no entry 529*cdf0e10cSrcweir meets this condition, ::std::numeric_limits<A>::max() is returned. */ 530*cdf0e10cSrcweir A GetLastAnyBitAccess( A nStart, 531*cdf0e10cSrcweir const D& rBitMask ) const; 532*cdf0e10cSrcweir 533*cdf0e10cSrcweir /** Sum values of a ScSummableCompressedArray for each row where in *this* 534*cdf0e10cSrcweir array the condition is met: ((aValue & rBitMask) == rMaskedCompare). */ 535*cdf0e10cSrcweir template< typename S > 536*cdf0e10cSrcweir SC_DLLPUBLIC unsigned long SumCoupledArrayForCondition( A nStart, A nEnd, 537*cdf0e10cSrcweir const D& rBitMask, const D& rMaskedCompare, 538*cdf0e10cSrcweir const ScSummableCompressedArray<A,S>& rArray ) const; 539*cdf0e10cSrcweir 540*cdf0e10cSrcweir /** Sum scaled values of a ScSummableCompressedArray for each row where in 541*cdf0e10cSrcweir *this* array the condition is met: ((aValue & rBitMask) == rMaskedCompare). */ 542*cdf0e10cSrcweir template< typename S > 543*cdf0e10cSrcweir SC_DLLPUBLIC unsigned long SumScaledCoupledArrayForCondition( A nStart, A nEnd, 544*cdf0e10cSrcweir const D& rBitMask, const D& rMaskedCompare, 545*cdf0e10cSrcweir const ScSummableCompressedArray<A,S>& rArray, 546*cdf0e10cSrcweir double fScale ) const; 547*cdf0e10cSrcweir }; 548*cdf0e10cSrcweir 549*cdf0e10cSrcweir 550*cdf0e10cSrcweir template< typename A, typename D > 551*cdf0e10cSrcweir void ScBitMaskCompressedArray<A,D>::AndValue( A nPos, const D& rValueToAnd ) 552*cdf0e10cSrcweir { 553*cdf0e10cSrcweir const D& rValue = GetValue( nPos); 554*cdf0e10cSrcweir if ((rValue & rValueToAnd) != rValue) 555*cdf0e10cSrcweir SetValue( nPos, rValue & rValueToAnd); 556*cdf0e10cSrcweir } 557*cdf0e10cSrcweir 558*cdf0e10cSrcweir 559*cdf0e10cSrcweir template< typename A, typename D > 560*cdf0e10cSrcweir void ScBitMaskCompressedArray<A,D>::OrValue( A nPos, const D& rValueToOr ) 561*cdf0e10cSrcweir { 562*cdf0e10cSrcweir const D& rValue = GetValue( nPos); 563*cdf0e10cSrcweir if ((rValue | rValueToOr) != rValue) 564*cdf0e10cSrcweir SetValue( nPos, rValue | rValueToOr); 565*cdf0e10cSrcweir } 566*cdf0e10cSrcweir 567*cdf0e10cSrcweir 568*cdf0e10cSrcweir // === ScCoupledCompressedArrayIterator ====================================== 569*cdf0e10cSrcweir 570*cdf0e10cSrcweir /** Iterate over a ScBitMaskCompressedArray and retrieve values from a coupled 571*cdf0e10cSrcweir array for positions where in the bit mask array the condition ((*aIter1 & 572*cdf0e10cSrcweir rBitMask) == rMaskedCompare) is met. 573*cdf0e10cSrcweir */ 574*cdf0e10cSrcweir 575*cdf0e10cSrcweir template< typename A, typename D, typename S > class ScCoupledCompressedArrayIterator 576*cdf0e10cSrcweir { 577*cdf0e10cSrcweir public: 578*cdf0e10cSrcweir SC_DLLPUBLIC ScCoupledCompressedArrayIterator( 579*cdf0e10cSrcweir const ScBitMaskCompressedArray<A,D> & rArray1, 580*cdf0e10cSrcweir A nStart, A nEnd, 581*cdf0e10cSrcweir const D& rBitMask, 582*cdf0e10cSrcweir const D& rMaskedCompare, 583*cdf0e10cSrcweir const ScCompressedArray<A,S> & rArray2 ); 584*cdf0e10cSrcweir void NewLimits( A nStart, A nEnd ); 585*cdf0e10cSrcweir A GetIterStart() const; 586*cdf0e10cSrcweir A GetIterEnd() const; 587*cdf0e10cSrcweir bool operator ++(); 588*cdf0e10cSrcweir A GetPos() const; 589*cdf0e10cSrcweir operator bool() const; 590*cdf0e10cSrcweir const S& operator *() const; 591*cdf0e10cSrcweir SC_DLLPUBLIC bool NextRange(); 592*cdf0e10cSrcweir A GetRangeStart() const; 593*cdf0e10cSrcweir A GetRangeEnd() const; 594*cdf0e10cSrcweir void Resync( A nPos ); 595*cdf0e10cSrcweir 596*cdf0e10cSrcweir private: 597*cdf0e10cSrcweir ScCompressedArrayIterator<A,D> aIter1; 598*cdf0e10cSrcweir ScCompressedArrayIterator<A,S> aIter2; 599*cdf0e10cSrcweir const D& rBitMask; 600*cdf0e10cSrcweir const D& rMaskedCompare; 601*cdf0e10cSrcweir 602*cdf0e10cSrcweir void InitLimits(); 603*cdf0e10cSrcweir }; 604*cdf0e10cSrcweir 605*cdf0e10cSrcweir 606*cdf0e10cSrcweir template< typename A, typename D, typename S > 607*cdf0e10cSrcweir A ScCoupledCompressedArrayIterator<A,D,S>::GetIterStart() const 608*cdf0e10cSrcweir { 609*cdf0e10cSrcweir return aIter1.GetIterStart(); 610*cdf0e10cSrcweir } 611*cdf0e10cSrcweir 612*cdf0e10cSrcweir 613*cdf0e10cSrcweir template< typename A, typename D, typename S > 614*cdf0e10cSrcweir A ScCoupledCompressedArrayIterator<A,D,S>::GetIterEnd() const 615*cdf0e10cSrcweir { 616*cdf0e10cSrcweir return aIter1.GetIterEnd(); 617*cdf0e10cSrcweir } 618*cdf0e10cSrcweir 619*cdf0e10cSrcweir 620*cdf0e10cSrcweir template< typename A, typename D, typename S > 621*cdf0e10cSrcweir ScCoupledCompressedArrayIterator<A,D,S>::operator bool() const 622*cdf0e10cSrcweir { 623*cdf0e10cSrcweir return aIter1 && aIter2; 624*cdf0e10cSrcweir } 625*cdf0e10cSrcweir 626*cdf0e10cSrcweir 627*cdf0e10cSrcweir template< typename A, typename D, typename S > 628*cdf0e10cSrcweir const S& ScCoupledCompressedArrayIterator<A,D,S>::operator*() const 629*cdf0e10cSrcweir { 630*cdf0e10cSrcweir return *aIter2; 631*cdf0e10cSrcweir } 632*cdf0e10cSrcweir 633*cdf0e10cSrcweir 634*cdf0e10cSrcweir template< typename A, typename D, typename S > 635*cdf0e10cSrcweir bool ScCoupledCompressedArrayIterator<A,D,S>::operator ++() 636*cdf0e10cSrcweir { 637*cdf0e10cSrcweir if (aIter1.GetPos() < aIter1.GetRangeEnd()) 638*cdf0e10cSrcweir { 639*cdf0e10cSrcweir ++aIter1; 640*cdf0e10cSrcweir ++aIter2; 641*cdf0e10cSrcweir return operator bool(); 642*cdf0e10cSrcweir } 643*cdf0e10cSrcweir else 644*cdf0e10cSrcweir return NextRange(); 645*cdf0e10cSrcweir } 646*cdf0e10cSrcweir 647*cdf0e10cSrcweir 648*cdf0e10cSrcweir template< typename A, typename D, typename S > 649*cdf0e10cSrcweir A ScCoupledCompressedArrayIterator<A,D,S>::GetPos() const 650*cdf0e10cSrcweir { 651*cdf0e10cSrcweir return aIter2.GetPos(); 652*cdf0e10cSrcweir } 653*cdf0e10cSrcweir 654*cdf0e10cSrcweir 655*cdf0e10cSrcweir template< typename A, typename D, typename S > 656*cdf0e10cSrcweir A ScCoupledCompressedArrayIterator<A,D,S>::GetRangeStart() const 657*cdf0e10cSrcweir { 658*cdf0e10cSrcweir return ::std::max( aIter1.GetRangeStart(), aIter2.GetRangeStart()); 659*cdf0e10cSrcweir } 660*cdf0e10cSrcweir 661*cdf0e10cSrcweir 662*cdf0e10cSrcweir template< typename A, typename D, typename S > 663*cdf0e10cSrcweir A ScCoupledCompressedArrayIterator<A,D,S>::GetRangeEnd() const 664*cdf0e10cSrcweir { 665*cdf0e10cSrcweir return ::std::min( aIter1.GetRangeEnd(), aIter2.GetRangeEnd()); 666*cdf0e10cSrcweir } 667*cdf0e10cSrcweir 668*cdf0e10cSrcweir 669*cdf0e10cSrcweir #endif // SC_COMPRESSEDARRAY_HXX 670