Given this types:
template<Ratio r, Symbol s>
struct base_unit {
using ratio = r;
using symbol = s;
};
template <BaseUnit... baseUnits>
struct derived_unit {
using units = std::tuple<baseUnits...>;
};
If, for example, I have a type like:
template <typename T>
struct Computations {
using collection_ratios = /* */
static constexpr ratios_product = /* */
}
I wanted to know how can I:
derived_unit
in a container like std::array<T, N> with a fold expression (collection_ratios)units
member of derived_unit
and store it in a variable with a fold expression (ratios_product)Edit:
Where T
is a specialization of derived_unit
, like, for example:
struct MetersPerSecond :
public speed,
public derived_unit<
base_unit<Kilo, m>,
base_unit<Root, s>
>
{};
Edit 2:
template <typename T>
concept RatioV = (std::is_integral_v<T> || std::is_floating_point_v<T>)
&& !std::is_same_v<T, char>;
consteval double getFactor(double base, double exponent);
template <RatioV T = short, T Base = 10, T Exponent = 0>
struct ratio {
static constexpr T base = Base;
static constexpr T exponent = Exponent;
static constexpr T value = getFactor(base, exponent);
};
consteval double getFactor(double base, double exponent) {
double result = 1;
for (int i = 0; i < exponent; i++)
result *= base;
return result;
}
using Yocto = ratio<short, 10, -24>;
using Zepto = ratio<short, 10, -21>;
using Atto = ratio<short, 10, -18>;
using Femto = ratio<short, 10, -15>;
using Pico = ratio<short, 10, -12>;
using Nano = ratio<short, 10, -9>;
using Micro = ratio<short, 10, -6>;
using Milli = ratio<short, 10, -3>;
using Centi = ratio<short, 10, -2>;
using Deci = ratio<short, 10, -1>;
using Root = ratio<short, 10, 0>;
using Deca = ratio<short, 10, 1>;
using Hecto = ratio<short, 10, 2>;
using Kilo = ratio<short, 10, 3>;
using Mega = ratio<short, 10, 6>;
using Giga = ratio<short, 10, 9>;
using Tera = ratio<short, 10, 12>;
using Peta = ratio<short, 10, 15>;
using Exa = ratio<short, 10, 18>;
using Zetta = ratio<short, 10, 21>;
using Yotta = ratio<short, 10, 24>;
Is this what you are looking for?
All it does is get the list of ratio types into collection_ratios
. And using that list, multiples all of the static value
's into ratios_product
.
template<typename Tuple>
struct ratios;
template<typename... Ts>
struct ratios<std::tuple<Ts...>> {
using type = std::tuple<typename Ts::ratio...>;
};
template <typename Tuple>
struct ratios_product_impl;
template<typename... Ts>
struct ratios_product_impl<std::tuple<Ts...>>
{
static constexpr auto value = (1 * ... * Ts::value);
};
template <typename T>
struct Computations {
using collection_ratios = typename ratios<typename T::units>::type;
// Calculates the product of all ratio values.
static constexpr auto ratios_product = ratios_product_impl<collection_ratios>::value;
};
#include <iostream>
int main() {
Computations<MetersPerSecond> c;
std::cout << c.ratios_product; // Prints 10000 for MetersPerSecond.
return 0;
}