diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2021-11-22 09:08:46 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2021-11-22 11:25:38 +0100 |
commit | de4cb026b5fe3ecd1c9557817565cff4ca4e8408 (patch) | |
tree | 90072778d17ffc45e394760dc765f5e8d79bffd6 /include | |
parent | 003b2d0c36c62800257c688c65109bf2fc7d4f32 (diff) |
Generalize DegreeN
This potentially allows to introduce other degree fractions easily,
like Degree<sal_Int64, 60000>, with automatically defined conversion
functions.
Change-Id: Id1c32d9e029943844bdc833178c1f99387ff87fc
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125640
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/tools/degree.hxx | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/include/tools/degree.hxx b/include/tools/degree.hxx index 74a27a2c2d35..1f2b2e2f8853 100644 --- a/include/tools/degree.hxx +++ b/include/tools/degree.hxx @@ -13,17 +13,28 @@ #include <basegfx/numeric/ftools.hxx> #include <sal/types.h> #include <o3tl/strong_int.hxx> +#include <o3tl/unit_conversion.hxx> #include <cstdlib> #include <math.h> +#include <numeric> +#include <utility> + +template <int N> struct FractionTag; +// 1/Nth fraction of a degree +template <typename I, int N> using Degree = o3tl::strong_int<I, FractionTag<N>>; + +template <typename I, int N> char (&NofDegree(Degree<I, N>))[N]; // helper +// Nof<DegreeN> gives compile-time constant N, needed in templates +template <class D> constexpr int Nof = sizeof(NofDegree(std::declval<D>())); /** tenths of a Degree, normally rotation */ -typedef o3tl::strong_int<sal_Int16, struct Degree10Tag> Degree10; +typedef Degree<sal_Int16, 10> Degree10; /** custom literal */ constexpr Degree10 operator""_deg10(unsigned long long n) { return Degree10{ n }; } /** hundredths of a Degree, normally rotation */ -typedef o3tl::strong_int<sal_Int32, struct Degree100Tag> Degree100; +typedef Degree<sal_Int32, 100> Degree100; // Android has trouble calling the correct overload of std::abs #ifdef ANDROID @@ -37,12 +48,14 @@ constexpr Degree100 operator""_deg100(unsigned long long n) { return Degree100{ /** conversion functions */ -inline Degree100 toDegree100(Degree10 x) { return Degree100(x.get() * 10); } -inline double toRadians(Degree10 x) { return basegfx::deg2rad<10>(x.get()); } -inline double toDegrees(Degree10 x) { return x.get() / 10.0; } +template <class To, typename IofFrom, int NofFrom> inline To to(Degree<IofFrom, NofFrom> x) +{ + constexpr sal_Int64 m = Nof<To> / std::gcd(Nof<To>, NofFrom); + constexpr sal_Int64 d = NofFrom / std::gcd(Nof<To>, NofFrom); + return To{ o3tl::convert(x.get(), m, d) }; +} -inline Degree10 toDegree10(Degree100 x) { return Degree10((x.get() + 5) / 10); } -inline double toRadians(Degree100 x) { return basegfx::deg2rad<100>(x.get()); } -inline double toDegrees(Degree100 x) { return x.get() / 100.0; } +template <class D> inline double toRadians(D x) { return basegfx::deg2rad<Nof<D>>(x.get()); } +template <class D> inline double toDegrees(D x) { return x.get() / static_cast<double>(Nof<D>); } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |