VCTR
Loading...
Searching...
No Matches
StdRatioHelpers.h
1/*
2 ==============================================================================
3 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
5 Copyright 2024- by sonible GmbH.
6
7 This file is part of VCTR - Versatile Container Templates Reconceptualized.
8
9 VCTR is free software: you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License version 3
11 only, as published by the Free Software Foundation.
12
13 VCTR is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Lesser General Public License version 3 for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 version 3 along with VCTR. If not, see <https://www.gnu.org/licenses/>.
20 ==============================================================================
21*/
22
23#pragma once
24
25namespace vctr::detail
26{
27
28template <class Ratio>
29struct ReducedToLowestFormHelper
30{
31 static constexpr auto gcd = std::gcd (Ratio::num, Ratio::den);
32
33 using Type = std::ratio<Ratio::num / gcd, Ratio::den / gcd>;
34};
35
37template <is::stdRatio Ratio>
38using ReducedToLowestForm = typename ReducedToLowestFormHelper<Ratio>::Type;
39
45template <is::stdRatio Ratio, is::intNumber T>
46constexpr auto multiplyBy (T valueToScale)
47{
48 using R = ReducedToLowestForm<Ratio>;
49 using IntType = std::make_signed_t<T>;
50 using DivType = decltype (std::div (std::declval<IntType>(), std::declval<IntType>()));
51 auto res = IntType (valueToScale) * IntType (R::num);
52
53 if (std::is_constant_evaluated())
54 {
55 DivType d { 0, 0 };
56 d.quot = res / IntType (R::den);
57 d.rem = res % IntType (R::den);
58 return d;
59 }
60
61 return std::div (res, IntType (R::den));
62}
63
65template <is::stdRatio Ratio, is::realOrComplexFloatNumber T>
66constexpr T multiplyBy (T valueToScale)
67{
68 using R = ReducedToLowestForm<Ratio>;
69 valueToScale *= T (R::num);
70 return valueToScale / T (R::den);
71}
72
78template <is::stdRatio Ratio, is::intNumber T>
79constexpr auto expectNoRemainderMultiplyBy (T valueToScale)
80{
81 auto res = multiplyBy<Ratio> (valueToScale);
82 VCTR_ASSERT (res.rem == 0);
83 return res.quot;
84}
85}