Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 : #ifndef INCLUDED_TOOLS_FRACT_HXX
20 : #define INCLUDED_TOOLS_FRACT_HXX
21 :
22 : #include <boost/rational.hpp>
23 : #include <sal/log.hxx>
24 : #include <tools/toolsdllapi.h>
25 :
26 : class SvStream;
27 :
28 : // This class uses the platform defined type 'long' as valid values but do all
29 : // calculations using sal_Int64 with checks for 'long' overflows.
30 : class TOOLS_DLLPUBLIC SAL_WARN_UNUSED Fraction
31 : {
32 : private:
33 : bool valid;
34 : boost::rational<sal_Int64> value;
35 :
36 : bool HasOverflowValue();
37 :
38 : public:
39 611088 : Fraction() { valid = true; }
40 : Fraction( const Fraction & rFrac );
41 : Fraction( long nNum, long nDen=1 );
42 : Fraction( double dVal );
43 :
44 : bool IsValid() const;
45 :
46 : long GetNumerator() const;
47 : long GetDenominator() const;
48 :
49 : operator long() const;
50 : operator double() const;
51 :
52 : Fraction& operator=( const Fraction& rfrFrac );
53 :
54 : Fraction& operator+=( const Fraction& rfrFrac );
55 : Fraction& operator-=( const Fraction& rfrFrac );
56 : Fraction& operator*=( const Fraction& rfrFrac );
57 : Fraction& operator/=( const Fraction& rfrFrac );
58 :
59 : void ReduceInaccurate( unsigned nSignificantBits );
60 :
61 : friend inline Fraction operator+( const Fraction& rVal1, const Fraction& rVal2 );
62 : friend inline Fraction operator-( const Fraction& rVal1, const Fraction& rVal2 );
63 : friend inline Fraction operator*( const Fraction& rVal1, const Fraction& rVal2 );
64 : friend inline Fraction operator/( const Fraction& rVal1, const Fraction& rVal2 );
65 :
66 : TOOLS_DLLPUBLIC friend bool operator==( const Fraction& rVal1, const Fraction& rVal2 );
67 : friend inline bool operator!=( const Fraction& rVal1, const Fraction& rVal2 );
68 : TOOLS_DLLPUBLIC friend bool operator< ( const Fraction& rVal1, const Fraction& rVal2 );
69 : TOOLS_DLLPUBLIC friend bool operator> ( const Fraction& rVal1, const Fraction& rVal2 );
70 : friend inline bool operator<=( const Fraction& rVal1, const Fraction& rVal2 );
71 : friend inline bool operator>=( const Fraction& rVal1, const Fraction& rVal2 );
72 :
73 : TOOLS_DLLPUBLIC friend SvStream& ReadFraction( SvStream& rIStream, Fraction& rFract );
74 : TOOLS_DLLPUBLIC friend SvStream& WriteFraction( SvStream& rOStream, const Fraction& rFract );
75 : };
76 :
77 14051270 : inline Fraction::Fraction( const Fraction& rFrac )
78 : {
79 14051270 : valid = rFrac.valid;
80 14051270 : if ( valid )
81 14050942 : value.assign( rFrac.value.numerator(), rFrac.value.denominator() );
82 14051270 : }
83 :
84 21771802 : inline long Fraction::GetNumerator() const
85 : {
86 21771802 : if ( !valid ) {
87 : SAL_WARN( "tools.fraction", "'GetNumerator()' on invalid fraction" );
88 624 : return 0;
89 : }
90 21771178 : return value.numerator();
91 : }
92 :
93 28725863 : inline long Fraction::GetDenominator() const {
94 28725863 : if ( !valid ) {
95 : SAL_WARN( "tools.fraction", "'GetDenominator()' on invalid fraction" );
96 700 : return -1;
97 : }
98 28725163 : return value.denominator();
99 : }
100 :
101 903316 : inline Fraction& Fraction::operator=( const Fraction& rFrac )
102 : {
103 903316 : if ( this != &rFrac ) {
104 903316 : valid = rFrac.valid;
105 903316 : if ( valid )
106 903316 : value.assign( rFrac.value.numerator(), rFrac.value.denominator() );
107 : }
108 903316 : return *this;
109 : }
110 :
111 6264 : inline bool Fraction::IsValid() const
112 : {
113 6264 : return valid;
114 : }
115 :
116 47012 : inline Fraction::operator long() const
117 : {
118 47012 : if ( !valid ) {
119 : SAL_WARN( "tools.fraction", "'operator long()' on invalid fraction" );
120 0 : return 0;
121 : }
122 47012 : return boost::rational_cast<long>(value);
123 : }
124 :
125 20 : inline Fraction operator+( const Fraction& rVal1, const Fraction& rVal2 )
126 : {
127 20 : Fraction aErg( rVal1 );
128 20 : aErg += rVal2;
129 20 : return aErg;
130 : }
131 :
132 20 : inline Fraction operator-( const Fraction& rVal1, const Fraction& rVal2 )
133 : {
134 20 : Fraction aErg( rVal1 );
135 20 : aErg -= rVal2;
136 20 : return aErg;
137 : }
138 :
139 2232 : inline Fraction operator*( const Fraction& rVal1, const Fraction& rVal2 )
140 : {
141 2232 : Fraction aErg( rVal1 );
142 2232 : aErg *= rVal2;
143 2232 : return aErg;
144 : }
145 :
146 5494 : inline Fraction operator/( const Fraction& rVal1, const Fraction& rVal2 )
147 : {
148 5494 : Fraction aErg( rVal1 );
149 5494 : aErg /= rVal2;
150 5494 : return aErg;
151 : }
152 :
153 65571 : inline bool operator !=( const Fraction& rVal1, const Fraction& rVal2 )
154 : {
155 65571 : return !(rVal1 == rVal2);
156 : }
157 :
158 0 : inline bool operator <=( const Fraction& rVal1, const Fraction& rVal2 )
159 : {
160 0 : return !(rVal1 > rVal2);
161 : }
162 :
163 : inline bool operator >=( const Fraction& rVal1, const Fraction& rVal2 )
164 : {
165 : return !(rVal1 < rVal2);
166 : }
167 :
168 : #endif
169 :
170 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|