Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #ifndef SC_COMPRESSEDARRAY_HXX
30 : : #define SC_COMPRESSEDARRAY_HXX
31 : :
32 : : #include <cstddef>
33 : : #include <algorithm>
34 : :
35 : : #include "scdllapi.h"
36 : :
37 : : const size_t nScCompressedArrayDelta = 4;
38 : :
39 : : /** Compressed array of row (or column) entries, e.g. heights, flags, ...
40 : :
41 : : The array stores ranges of values such that consecutive values occupy only
42 : : one entry. Initially it consists of one DataEntry with an implied start
43 : : row/column of 0 and an end row/column of access type maximum value.
44 : :
45 : : typename A := access type, e.g. SCROW or SCCOL, must be a POD.
46 : :
47 : : typename D := data type, e.g. sal_uInt16 or sal_uInt8 or whatever, may also be a
48 : : struct or class.
49 : :
50 : : D::operator==() and D::operator=() must be implemented. Force template
51 : : instantiation for a specific type in source/core/data/compressedarray.cxx
52 : :
53 : : TODO: Currently the allocated memory never shrinks, must manually invoke
54 : : Resize() if needed.
55 : : */
56 : :
57 : : template< typename A, typename D > class ScCompressedArray
58 : : {
59 : : public:
60 : : struct DataEntry
61 : : {
62 : : A nEnd; // start is end of previous entry + 1
63 : : D aValue;
64 : 2553 : DataEntry() {} //! uninitialized
65 : : };
66 : :
67 : : /** Construct with nMaxAccess=MAXROW, for example. */
68 : : ScCompressedArray( A nMaxAccess,
69 : : const D& rValue,
70 : : size_t nDelta = nScCompressedArrayDelta );
71 : : /** Construct from a plain array of D */
72 : : ScCompressedArray( A nMaxAccess,
73 : : const D* pDataArray, size_t nDataCount );
74 : : virtual ~ScCompressedArray();
75 : : void Resize( size_t nNewSize );
76 : : void Reset( const D& rValue );
77 : : void SetValue( A nPos, const D& rValue );
78 : : void SetValue( A nStart, A nEnd, const D& rValue );
79 : : const D& GetValue( A nPos ) const;
80 : :
81 : : /** Get value for a row, and it's region end row */
82 : : const D& GetValue( A nPos, size_t& nIndex, A& nEnd ) const;
83 : :
84 : : /** Get next value and it's region end row. If nIndex<nCount, nIndex is
85 : : incremented first. If the resulting nIndex>=nCount, the value of the
86 : : last entry is returned again. */
87 : : const D& GetNextValue( size_t& nIndex, A& nEnd ) const;
88 : :
89 : : /** Insert rows before nStart and copy value for inserted rows from
90 : : nStart-1, return that value. */
91 : : const D& Insert( A nStart, size_t nCount );
92 : :
93 : : void Remove( A nStart, size_t nCount );
94 : :
95 : : /** Copy rArray.nStart+nSourceDy to this.nStart */
96 : : void CopyFrom( const ScCompressedArray& rArray,
97 : : A nStart, A nEnd, long nSourceDy = 0 );
98 : :
99 : :
100 : : // methods public for the coupled array sum methods
101 : : /** Obtain index into entries for nPos */
102 : : SC_DLLPUBLIC size_t Search( A nPos ) const;
103 : :
104 : : protected:
105 : : size_t nCount;
106 : : size_t nLimit;
107 : : size_t nDelta;
108 : : DataEntry* pData;
109 : : A nMaxAccess;
110 : : };
111 : :
112 : :
113 : : template< typename A, typename D >
114 : 95 : void ScCompressedArray<A,D>::Reset( const D& rValue )
115 : : {
116 : : // Create a temporary copy in case we got a reference passed that points to
117 : : // a part of the array to be reallocated.
118 : 95 : D aTmpVal( rValue);
119 [ + - ]: 95 : delete[] pData;
120 : 95 : nCount = nLimit = 1;
121 [ + - ][ + + ]: 190 : pData = new DataEntry[1];
122 : 95 : pData[0].aValue = aTmpVal;
123 : 95 : pData[0].nEnd = nMaxAccess;
124 : 95 : }
125 : :
126 : :
127 : : template< typename A, typename D >
128 : 0 : void ScCompressedArray<A,D>::SetValue( A nPos, const D& rValue )
129 : : {
130 : 0 : SetValue( nPos, nPos, rValue);
131 : 0 : }
132 : :
133 : :
134 : : template< typename A, typename D >
135 : 2968 : const D& ScCompressedArray<A,D>::GetValue( A nPos ) const
136 : : {
137 : 2968 : size_t nIndex = Search( nPos);
138 : 2968 : return pData[nIndex].aValue;
139 : : }
140 : :
141 : :
142 : : template< typename A, typename D >
143 : 1924 : const D& ScCompressedArray<A,D>::GetValue( A nPos, size_t& nIndex, A& nEnd ) const
144 : : {
145 : 1924 : nIndex = Search( nPos);
146 : 1924 : nEnd = pData[nIndex].nEnd;
147 : 1924 : return pData[nIndex].aValue;
148 : : }
149 : :
150 : :
151 : : template< typename A, typename D >
152 : 2 : const D& ScCompressedArray<A,D>::GetNextValue( size_t& nIndex, A& nEnd ) const
153 : : {
154 [ + - ]: 2 : if (nIndex < nCount)
155 : 2 : ++nIndex;
156 [ + - ]: 2 : size_t nEntry = (nIndex < nCount ? nIndex : nCount-1);
157 : 2 : nEnd = pData[nEntry].nEnd;
158 : 2 : return pData[nEntry].aValue;
159 : : }
160 : :
161 : : // === ScBitMaskCompressedArray ==============================================
162 : :
163 : : /** The data type represents bits, managable by bitwise operations.
164 : : */
165 : :
166 [ - + ]: 2412 : template< typename A, typename D > class ScBitMaskCompressedArray : public ScCompressedArray<A,D>
167 : : {
168 : : public:
169 : 1488 : ScBitMaskCompressedArray( A nMaxAccessP,
170 : : const D& rValue,
171 : : size_t nDeltaP = nScCompressedArrayDelta )
172 : 1488 : : ScCompressedArray<A,D>( nMaxAccessP, rValue, nDeltaP)
173 : 1488 : {}
174 : 0 : ScBitMaskCompressedArray( A nMaxAccessP,
175 : : const D* pDataArray, size_t nDataCount )
176 : : : ScCompressedArray<A,D>( nMaxAccessP,
177 : 0 : pDataArray, nDataCount)
178 : 0 : {}
179 : : void AndValue( A nPos, const D& rValueToAnd );
180 : : void OrValue( A nPos, const D& rValueToOr );
181 : : void AndValue( A nStart, A nEnd, const D& rValueToAnd );
182 : : void OrValue( A nStart, A nEnd, const D& rValueToOr );
183 : :
184 : : /** Copy values from rArray and bitwise AND them with rValueToAnd. */
185 : : void CopyFromAnded(
186 : : const ScBitMaskCompressedArray& rArray,
187 : : A nStart, A nEnd, const D& rValueToAnd,
188 : : long nSourceDy = 0 );
189 : :
190 : : /** Return the first row where an entry meets the condition:
191 : : ((aValue & rBitMask) == rMaskedCompare), searching between nStart and
192 : : nEnd. If no entry meets this condition, ::std::numeric_limits<A>::max()
193 : : is returned. */
194 : : SC_DLLPUBLIC A GetFirstForCondition( A nStart, A nEnd,
195 : : const D& rBitMask,
196 : : const D& rMaskedCompare ) const;
197 : :
198 : : /** Return the last row where an entry meets the condition:
199 : : ((aValue & rBitMask) != 0), start searching at nStart. If no entry
200 : : meets this condition, ::std::numeric_limits<A>::max() is returned. */
201 : : A GetLastAnyBitAccess( A nStart,
202 : : const D& rBitMask ) const;
203 : : };
204 : :
205 : :
206 : : template< typename A, typename D >
207 : 0 : void ScBitMaskCompressedArray<A,D>::AndValue( A nPos, const D& rValueToAnd )
208 : : {
209 : 0 : const D& rValue = this->GetValue( nPos);
210 [ # # ]: 0 : if ((rValue & rValueToAnd) != rValue)
211 [ # # ]: 0 : this->SetValue( nPos, rValue & rValueToAnd);
212 : 0 : }
213 : :
214 : :
215 : : template< typename A, typename D >
216 : 0 : void ScBitMaskCompressedArray<A,D>::OrValue( A nPos, const D& rValueToOr )
217 : : {
218 : 0 : const D& rValue = this->GetValue( nPos);
219 [ # # ]: 0 : if ((rValue | rValueToOr) != rValue)
220 [ # # ]: 0 : this->SetValue( nPos, rValue | rValueToOr);
221 : 0 : }
222 : :
223 : :
224 : : #endif // SC_COMPRESSEDARRAY_HXX
225 : :
226 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|