1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_SC_INC_COMPRESSEDARRAY_HXX
21 #define INCLUDED_SC_INC_COMPRESSEDARRAY_HXX
28 /** Compressed array of row (or column) entries, e.g. heights, flags, ...
30 The array stores ranges of values such that equal consecutive values occupy only
31 one entry. Initially it consists of one DataEntry with an implied start
32 row/column of 0 and an end row/column of access type maximum value.
34 typename A := access type, e.g. SCROW or SCCOL, must be a POD.
36 typename D := data type, e.g. sal_uInt16 or sal_uInt8 or whatever, may also be a
39 D::operator==() and D::operator=() must be implemented. Force template
40 instantiation for a specific type in source/core/data/compressedarray.cxx
42 TODO: Currently the allocated memory never shrinks, must manually invoke
46 template< typename A
, typename D
> class ScCompressedArray
51 friend ScCompressedArray
;
52 const ScCompressedArray
& mrArray
;
55 Iterator(const ScCompressedArray
& rArray
) : mrArray(rArray
) {}
56 Iterator(const ScCompressedArray
& rArray
, size_t nIndex
, A nRegion
) : mrArray(rArray
), mnIndex(nIndex
), mnRegion(nRegion
) {}
59 Iterator
operator+(size_t) const;
60 const D
& operator*() const { return mrArray
.pData
[mnIndex
].aValue
; }
64 A nEnd
; // start is end of previous entry + 1
66 DataEntry() {} //! uninitialized
69 /** Construct with nMaxAccess=MAXROW, for example. */
70 ScCompressedArray( A nMaxAccess
,
72 virtual ~ScCompressedArray();
73 void Reset( const D
& rValue
);
74 void SetValue( A nPos
, const D
& rValue
);
75 void SetValue( A nStart
, A nEnd
, const D
& rValue
);
77 const D
& GetValue( A nPos
) const;
79 A
GetLastPos() const { return pData
[nCount
-1].nEnd
; }
81 /** Get value for a row, and it's region end row */
83 const D
& GetValue( A nPos
, size_t& nIndex
, A
& nEnd
) const;
85 /** Get next value and it's region end row. If nIndex<nCount, nIndex is
86 incremented first. If the resulting nIndex>=nCount, the value of the
87 last entry is returned again. */
89 const D
& GetNextValue( size_t& nIndex
, A
& nEnd
) const;
91 /** Insert rows before nStart and copy value for inserted rows from
92 nStart-1, return that value. */
93 const D
& Insert( A nStart
, size_t nCount
);
94 void InsertPreservingSize( A nStart
, size_t nCount
, const D
& rFillValue
);
96 void Remove( A nStart
, size_t nCount
);
97 void RemovePreservingSize( A nStart
, size_t nCount
, const D
& rFillValue
);
99 /** Copy rArray.nStart+nSourceDy to this.nStart */
100 void CopyFrom( const ScCompressedArray
& rArray
,
102 { CopyFrom(rArray
, nStart
, nEnd
, nStart
); }
103 void CopyFrom( const ScCompressedArray
& rArray
,
104 A nDestStart
, A nDestEnd
, A nSrcStart
);
106 // methods public for the coupled array sum methods
107 /** Obtain index into entries for nPos */
108 SC_DLLPUBLIC
size_t Search( A nPos
) const;
110 Iterator
begin() const { return Iterator(*this); }
115 std::unique_ptr
<DataEntry
[]> pData
;
119 template< typename A
, typename D
>
120 void ScCompressedArray
<A
,D
>::Reset( const D
& rValue
)
122 // Create a temporary copy in case we got a reference passed that points to
123 // a part of the array to be reallocated.
126 pData
.reset(new DataEntry
[1]);
127 pData
[0].aValue
= aTmpVal
;
128 pData
[0].nEnd
= nMaxAccess
;
131 template< typename A
, typename D
>
132 void ScCompressedArray
<A
,D
>::SetValue( A nPos
, const D
& rValue
)
134 SetValue( nPos
, nPos
, rValue
);
137 template< typename A
, typename D
>
138 const D
& ScCompressedArray
<A
,D
>::GetValue( A nPos
) const
140 size_t nIndex
= Search( nPos
);
141 return pData
[nIndex
].aValue
;
144 template< typename A
, typename D
>
145 const D
& ScCompressedArray
<A
,D
>::GetValue( A nPos
, size_t& nIndex
, A
& nEnd
) const
147 nIndex
= Search( nPos
);
148 nEnd
= pData
[nIndex
].nEnd
;
149 return pData
[nIndex
].aValue
;
152 template< typename A
, typename D
>
153 const D
& ScCompressedArray
<A
,D
>::GetNextValue( size_t& nIndex
, A
& nEnd
) const
157 size_t nEntry
= (nIndex
< nCount
? nIndex
: nCount
-1);
158 nEnd
= pData
[nEntry
].nEnd
;
159 return pData
[nEntry
].aValue
;
162 // ScBitMaskCompressedArray
163 /** The data type represents bits, manageable by bitwise operations.
166 template< typename A
, typename D
> class ScBitMaskCompressedArray final
: public ScCompressedArray
<A
,D
>
169 ScBitMaskCompressedArray( A nMaxAccessP
,
171 : ScCompressedArray
<A
,D
>( nMaxAccessP
, rValue
)
173 void AndValue( A nPos
, const D
& rValueToAnd
);
174 void OrValue( A nPos
, const D
& rValueToOr
);
175 void AndValue( A nStart
, A nEnd
, const D
& rValueToAnd
);
176 void OrValue( A nStart
, A nEnd
, const D
& rValueToOr
);
178 /** Copy values from rArray and bitwise AND them with rValueToAnd. */
180 const ScBitMaskCompressedArray
& rArray
,
181 A nStart
, A nEnd
, const D
& rValueToAnd
);
183 /** Return the last row where an entry meets the condition:
184 ((aValue & rBitMask) != 0), start searching at 0. If no entry
185 meets this condition, ::std::numeric_limits<A>::max() is returned. */
186 A
GetLastAnyBitAccess( const D
& rBitMask
) const;
189 template< typename A
, typename D
>
190 void ScBitMaskCompressedArray
<A
,D
>::AndValue( A nPos
, const D
& rValueToAnd
)
192 const D
& rValue
= this->GetValue( nPos
);
193 if ((rValue
& rValueToAnd
) != rValue
)
194 this->SetValue( nPos
, rValue
& rValueToAnd
);
197 template< typename A
, typename D
>
198 void ScBitMaskCompressedArray
<A
,D
>::OrValue( A nPos
, const D
& rValueToOr
)
200 const D
& rValue
= this->GetValue( nPos
);
201 if ((rValue
| rValueToOr
) != rValue
)
202 this->SetValue( nPos
, rValue
| rValueToOr
);
205 #endif // INCLUDED_SC_INC_COMPRESSEDARRAY_HXX
207 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */