Avoid potential negative array index access to cached text.
[LibreOffice.git] / include / tools / bigint.hxx
blobf8f57fc45de7074a8c839adafe5595934fcd3a38
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
19 #ifndef INCLUDED_TOOLS_BIGINT_HXX
20 #define INCLUDED_TOOLS_BIGINT_HXX
22 #include <tools/toolsdllapi.h>
23 #include <tools/long.hxx>
25 #include <cassert>
26 #include <string_view>
28 #define MAX_DIGITS 8
30 class SAL_WARN_UNUSED TOOLS_DLLPUBLIC BigInt
32 private:
33 // we only use one of these two fields at a time
34 union {
35 sal_Int32 nVal;
36 sal_uInt16 nNum[MAX_DIGITS];
38 sal_uInt8 nLen : 5; // current length, if 0, data is in nVal, otherwise data is in nNum
39 bool bIsNeg : 1; // Is Sign negative?
41 TOOLS_DLLPRIVATE void MakeBigInt(BigInt const &);
42 TOOLS_DLLPRIVATE void Normalize();
43 TOOLS_DLLPRIVATE void Mult(BigInt const &, sal_uInt16);
44 TOOLS_DLLPRIVATE void Div(sal_uInt16, sal_uInt16 &);
45 TOOLS_DLLPRIVATE bool IsLess(BigInt const &) const;
46 TOOLS_DLLPRIVATE void AddLong(BigInt &, BigInt &);
47 TOOLS_DLLPRIVATE void SubLong(BigInt &, BigInt &);
48 TOOLS_DLLPRIVATE void MultLong(BigInt const &, BigInt &) const;
49 TOOLS_DLLPRIVATE void DivLong(BigInt const &, BigInt &) const;
50 TOOLS_DLLPRIVATE void ModLong(BigInt const &, BigInt &) const;
51 TOOLS_DLLPRIVATE bool ABS_IsLess(BigInt const &) const;
53 public:
54 BigInt()
55 : nVal(0)
56 , nLen(0)
57 , bIsNeg(false)
61 BigInt(sal_Int32 nValue)
62 : nVal(nValue)
63 , nLen(0)
64 , bIsNeg(false)
68 #if SAL_TYPES_SIZEOFLONG == 4
69 BigInt(int nValue)
70 : nVal(nValue)
71 , nLen(0)
72 , bIsNeg(false)
75 #endif
77 BigInt( double nVal );
78 BigInt( sal_uInt32 nVal );
79 BigInt( sal_Int64 nVal );
80 BigInt( const BigInt& rBigInt );
81 BigInt( std::u16string_view rString );
83 operator sal_Int16() const;
84 operator sal_uInt16() const;
85 operator sal_Int32() const;
86 operator sal_uInt32() const;
87 operator double() const;
88 #if SAL_TYPES_SIZEOFPOINTER == 8
89 operator tools::Long() const;
90 #endif
92 bool IsNeg() const;
93 bool IsZero() const;
94 bool IsLong() const { return nLen == 0; }
96 void Abs();
98 BigInt& operator =( const BigInt& rVal );
99 BigInt& operator +=( const BigInt& rVal );
100 BigInt& operator -=( const BigInt& rVal );
101 BigInt& operator *=( const BigInt& rVal );
102 BigInt& operator /=( const BigInt& rVal );
103 BigInt& operator %=( const BigInt& rVal );
105 BigInt& operator =( sal_Int32 nValue );
107 /* Scale and round value */
108 static tools::Long Scale(tools::Long nVal, tools::Long nMult, tools::Long nDiv);
110 friend inline BigInt operator +( const BigInt& rVal1, const BigInt& rVal2 );
111 friend inline BigInt operator -( const BigInt& rVal1, const BigInt& rVal2 );
112 friend inline BigInt operator *( const BigInt& rVal1, const BigInt& rVal2 );
113 friend inline BigInt operator /( const BigInt& rVal1, const BigInt& rVal2 );
114 friend inline BigInt operator %( const BigInt& rVal1, const BigInt& rVal2 );
116 TOOLS_DLLPUBLIC friend bool operator==( const BigInt& rVal1, const BigInt& rVal2 );
117 friend inline bool operator!=( const BigInt& rVal1, const BigInt& rVal2 );
118 TOOLS_DLLPUBLIC friend bool operator< ( const BigInt& rVal1, const BigInt& rVal2 );
119 friend inline bool operator> ( const BigInt& rVal1, const BigInt& rVal2 );
120 friend inline bool operator<=( const BigInt& rVal1, const BigInt& rVal2 );
121 friend inline bool operator>=( const BigInt& rVal1, const BigInt& rVal2 );
123 friend class Fraction;
126 inline BigInt::operator sal_Int16() const
128 if ( nLen == 0 && nVal >= SAL_MIN_INT16 && nVal <= SAL_MAX_INT16 )
129 return static_cast<sal_Int16>(nVal);
130 assert(false && "out of range");
131 return 0;
134 inline BigInt::operator sal_uInt16() const
136 if ( nLen == 0 && nVal >= 0 && nVal <= SAL_MAX_UINT16 )
137 return static_cast<sal_uInt16>(nVal);
138 assert(false && "out of range");
139 return 0;
142 inline BigInt::operator sal_Int32() const
144 if (nLen == 0)
145 return nVal;
146 assert(false && "out of range");
147 return 0;
150 inline BigInt::operator sal_uInt32() const
152 if ( nLen == 0 && nVal >= 0 )
153 return static_cast<sal_uInt32>(nVal);
154 assert(false && "out of range");
155 return 0;
158 #if SAL_TYPES_SIZEOFPOINTER == 8
159 inline BigInt::operator tools::Long() const
161 // Clamp to int32 since long is int32 on Windows.
162 if (nLen == 0)
163 return nVal;
164 assert(false && "out of range");
165 return 0;
167 #endif
169 inline BigInt& BigInt::operator =( sal_Int32 nValue )
171 nLen = 0;
172 nVal = nValue;
174 return *this;
177 inline bool BigInt::IsNeg() const
179 if ( nLen == 0 )
180 return (nVal < 0);
181 else
182 return bIsNeg;
185 inline bool BigInt::IsZero() const
187 if ( nLen != 0 )
188 return false;
189 else
190 return (nVal == 0);
193 inline void BigInt::Abs()
195 if ( nLen != 0 )
196 bIsNeg = false;
197 else if ( nVal < 0 )
198 nVal = -nVal;
201 inline BigInt operator+( const BigInt &rVal1, const BigInt &rVal2 )
203 BigInt aErg( rVal1 );
204 aErg += rVal2;
205 return aErg;
208 inline BigInt operator-( const BigInt &rVal1, const BigInt &rVal2 )
210 BigInt aErg( rVal1 );
211 aErg -= rVal2;
212 return aErg;
215 inline BigInt operator*( const BigInt &rVal1, const BigInt &rVal2 )
217 BigInt aErg( rVal1 );
218 aErg *= rVal2;
219 return aErg;
222 inline BigInt operator/( const BigInt &rVal1, const BigInt &rVal2 )
224 BigInt aErg( rVal1 );
225 aErg /= rVal2;
226 return aErg;
229 inline BigInt operator%( const BigInt &rVal1, const BigInt &rVal2 )
231 BigInt aErg( rVal1 );
232 aErg %= rVal2;
233 return aErg;
236 inline bool operator!=( const BigInt& rVal1, const BigInt& rVal2 )
238 return !(rVal1 == rVal2);
241 inline bool operator>(const BigInt& rVal1, const BigInt& rVal2) { return rVal2 < rVal1; }
243 inline bool operator<=( const BigInt& rVal1, const BigInt& rVal2 )
245 return !( rVal1 > rVal2);
248 inline bool operator>=( const BigInt& rVal1, const BigInt& rVal2 )
250 return !(rVal1 < rVal2);
253 #endif
255 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */