Info
-
Did you know that C++20 added support for floating point values as non-type template parameters?
Example
template<double Value> constexpr auto value = Value;
int main() {
std::cout << value<4.2>; // prints 4.2
}
Puzzle
- Can you implement function calc which adds values from
Vl1s...
multipled by all values fromVls2...
? For example : Vl1s = { 1., 2. }, Vl2 { 3., 4.}; calc = (1. * 3. * 4.) + (2. * 3. * 4.)
template<double... Values> struct values {};
template<double... Vl1s, double... Vl2s>
[[nodiscard]] consteval auto calc(values<Vl1s...>, values<Vl2s...>) // TODO
template<double Epsilon = 0.1>
[[nodiscard]] consteval auto eq(double a, double b) {
return std::fabs(a - b) < Epsilon;
}
static_assert(eq(1. * 2., calc(values<1.>{}, values<2.>{})));
static_assert(eq(2.*3.*4., calc(values<2.>{}, values<3., 4.>{})));
static_assert(eq(4.2 * 2. * 3. + .1 * 2. * 3., calc(values<4.2, .1>{}, values<2., 3.>{})));
static_assert(eq(1. * 4. * 5. + 2. * 4. * 5., calc(values<1., 2.>{}, values<4., 5.>{})));
Solutions
template<double... Vl1s, double... Vl2s>
[[nodiscard]] consteval auto calc(values<Vl1s...>, values<Vl2s...>) {
constexpr auto mul = (Vl2s * ...);
return ((Vl1s * mul) + ...);
}
template <double... List1, double... List2>
[[nodiscard]] consteval auto calc(values<List1...>, values<List2...>) {
return (0 + ... + (List1 * (1 * ... * List2)));
}
template<double... Values> struct values {};
template<double... Vl1s, double... Vl2s>
[[nodiscard]] consteval auto calc(values<Vl1s...>, values<Vl2s...>) {
return ((Vl1s * (Vl2s * ...)) + ...);
}
template<double Epsilon = 0.1>
[[nodiscard]] consteval auto eq(double a, double b) {
return std::fabs(a - b) < Epsilon;
}
template<double... Values> struct values {};
template<double... Vl1s, double... Vl2s>
[[nodiscard]] consteval auto calc(values<Vl1s...>, values<Vl2s...>) {
constexpr auto c = (Vl2s * ...);
return ((Vl1s * c) + ...);
}
template<double Epsilon = 0.1>
[[nodiscard]] consteval auto eq(double a, double b) {
return std::fabs(a - b) < Epsilon;
}
template<double... Values> struct values {};
template<double... Vl1s, double... Vl2s>
[[nodiscard]] consteval auto calc(values<Vl1s...>, values<Vl2s...>) {
return (Vl1s + ...) * (Vl2s * ...);
}
template<double Epsilon = 0.1>
[[nodiscard]] consteval auto eq(double a, double b) {
return std::fabs(a - b) < Epsilon;
}
template<double... Values> struct values{};
template<double Vl1, double... Vl2s>
[[nodiscard]] consteval auto mult(){
return (Vl1 * ... * Vl2s);
}
template<double... Vl1s, double... Vl2s>
[[nodiscard]] consteval auto calc(values<Vl1s...>, values<Vl2s...>){
return (... + mult<Vl1s, Vl2s...>());
}
template<double Epsilon = 0.1>
[[nodiscard]] consteval auto eq(double a, double b) {
return std::fabs(a - b) < Epsilon;
}
template<double... Values> struct values {};
template<double... Vl1s, double... Vl2s>
[[nodiscard]] consteval auto calc(values<Vl1s...>, values<Vl2s...>){
return (0.0 + ... + (Vl1s * (Vl2s * ... )));
}
template<double Epsilon = 0.1>
[[nodiscard]] consteval auto eq(double a, double b) {
return std::fabs(a - b) < Epsilon;
}