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 .
19 #ifndef INCLUDED_TOOLS_FRACT_HXX
20 #define INCLUDED_TOOLS_FRACT_HXX
22 #include <sal/types.h>
23 #include <tools/toolsdllapi.h>
24 #include <tools/long.hxx>
26 #include <type_traits>
30 class SAL_WARN_UNUSED TOOLS_DLLPUBLIC Fraction final
32 /// these two fields form a boost::rational, but I didn't want to put more boost headers into the global space
33 sal_Int32 mnNumerator
= 0;
34 sal_Int32 mnDenominator
= 1;
38 Fraction( const Fraction
& rFrac
) = default;
39 Fraction( Fraction
&& rFrac
) = default;
40 explicit Fraction( double dVal
);
41 Fraction( double nNum
, double nDen
);
42 Fraction( sal_Int64 nNum
, sal_Int64 nDen
);
43 // just to prevent ambiguity between the sal_Int64 and double constructors
44 template<typename T1
, typename T2
> Fraction(
46 typename
std::enable_if
<std::is_integral
<T1
>::value
&& std::is_integral
<T2
>::value
, int>::type
= 0)
47 : Fraction( sal_Int64(nNum
), sal_Int64(nDen
) ) {}
49 bool IsValid() const { return mbValid
; }
51 sal_Int32
GetNumerator() const;
52 sal_Int32
GetDenominator() const;
54 explicit operator sal_Int32() const;
55 #if SAL_TYPES_SIZEOFPOINTER == 8
56 explicit operator ::tools::Long() const { return operator sal_Int32(); }
58 explicit operator double() const;
60 Fraction
& operator=( const Fraction
& rfrFrac
) = default;
61 Fraction
& operator=( Fraction
&& rfrFrac
) = default;
62 Fraction
& operator=( double v
) { return operator=(Fraction(v
)); }
64 Fraction
& operator+=( const Fraction
& rfrFrac
);
65 Fraction
& operator-=( const Fraction
& rfrFrac
);
66 Fraction
& operator*=( const Fraction
& rfrFrac
);
67 Fraction
& operator/=( const Fraction
& rfrFrac
);
68 Fraction
& operator+=( double v
) { return operator+=(Fraction(v
)); }
69 Fraction
& operator-=( double v
) { return operator-=(Fraction(v
)); }
70 Fraction
& operator*=( double v
) { return operator*=(Fraction(v
)); }
71 Fraction
& operator/=( double v
) { return operator/=(Fraction(v
)); }
73 void ReduceInaccurate( unsigned nSignificantBits
);
75 /// Multiply the two fractions represented here and reduce inaccuracy to 32-bits, used by vcl
76 static Fraction
MakeFraction(tools::Long nN1
, tools::Long nN2
, tools::Long nD1
, tools::Long nD2
);
78 // Compute value usable as hash.
79 size_t GetHashValue() const;
81 TOOLS_DLLPUBLIC
friend Fraction
operator+( const Fraction
& rVal1
, const Fraction
& rVal2
);
82 TOOLS_DLLPUBLIC
friend Fraction
operator-( const Fraction
& rVal1
, const Fraction
& rVal2
);
83 TOOLS_DLLPUBLIC
friend Fraction
operator*( const Fraction
& rVal1
, const Fraction
& rVal2
);
84 TOOLS_DLLPUBLIC
friend Fraction
operator/( const Fraction
& rVal1
, const Fraction
& rVal2
);
86 TOOLS_DLLPUBLIC
friend bool operator==( const Fraction
& rVal1
, const Fraction
& rVal2
);
87 TOOLS_DLLPUBLIC
friend bool operator!=( const Fraction
& rVal1
, const Fraction
& rVal2
);
88 TOOLS_DLLPUBLIC
friend bool operator< ( const Fraction
& rVal1
, const Fraction
& rVal2
);
89 TOOLS_DLLPUBLIC
friend bool operator> ( const Fraction
& rVal1
, const Fraction
& rVal2
);
90 TOOLS_DLLPUBLIC
friend bool operator<=( const Fraction
& rVal1
, const Fraction
& rVal2
);
91 TOOLS_DLLPUBLIC
friend bool operator>=( const Fraction
& rVal1
, const Fraction
& rVal2
);
94 TOOLS_DLLPUBLIC Fraction
operator+( const Fraction
& rVal1
, const Fraction
& rVal2
);
95 TOOLS_DLLPUBLIC Fraction
operator-( const Fraction
& rVal1
, const Fraction
& rVal2
);
96 TOOLS_DLLPUBLIC Fraction
operator*( const Fraction
& rVal1
, const Fraction
& rVal2
);
97 TOOLS_DLLPUBLIC Fraction
operator/( const Fraction
& rVal1
, const Fraction
& rVal2
);
98 TOOLS_DLLPUBLIC
bool operator !=( const Fraction
& rVal1
, const Fraction
& rVal2
);
99 TOOLS_DLLPUBLIC
bool operator <=( const Fraction
& rVal1
, const Fraction
& rVal2
);
100 TOOLS_DLLPUBLIC
bool operator >=( const Fraction
& rVal1
, const Fraction
& rVal2
);
102 inline Fraction
operator+( double v1
, const Fraction
& rVal2
) { return Fraction(v1
) + rVal2
; }
103 inline Fraction
operator-( double v1
, const Fraction
& rVal2
) { return Fraction(v1
) - rVal2
; }
104 inline Fraction
operator*( double v1
, const Fraction
& rVal2
) { return Fraction(v1
) * rVal2
; }
105 inline Fraction
operator/( double v1
, const Fraction
& rVal2
) { return Fraction(v1
) / rVal2
; }
107 inline Fraction
operator+( const Fraction
& rVal1
, double v2
) { return rVal1
+ Fraction(v2
); }
108 inline Fraction
operator-( const Fraction
& rVal1
, double v2
) { return rVal1
- Fraction(v2
); }
109 inline Fraction
operator*( const Fraction
& rVal1
, double v2
) { return rVal1
* Fraction(v2
); }
110 inline Fraction
operator/( const Fraction
& rVal1
, double v2
) { return rVal1
/ Fraction(v2
); }
112 template<typename charT
, typename traits
>
113 inline std::basic_ostream
<charT
, traits
> & operator <<(
114 std::basic_ostream
<charT
, traits
> & rStream
, const Fraction
& rFraction
)
116 rStream
<< "(" << rFraction
.GetNumerator() << "/" << rFraction
.GetDenominator() << ")";
122 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */