Open mpusz opened 1 month ago
For example the following should be supported (as much as possible):
template<template<auto, typename> typename Q> concept complex_operations = requires(Q<isq::voltage_phasor[si::kilo<si::volt>], std::complex<double>> voltage_phasor, Q<isq::electric_current_phasor[si::ampere], std::complex<double>> electric_current_phasor, Q<isq::phase_angle[si::radian], double> phase_angle, Q<isq::complex_power[si::kilo<si::volt> * si::ampere], std::complex<double>> complex_power, Q<isq::apparent_power[si::kilo<si::volt> * si::ampere], double> apparent_power, Q<isq::active_power[si::watt], double> active_power, Q<isq::reactive_power[iec::volt_ampere_reactive_power], double> reactive_power, Q<isq::power_factor[one], double> power_factor) { // valid operations { voltage_phasor* conj(electric_current_phasor) } -> std::convertible_to<decltype(complex_power)>; { complex(active_power, reactive_power) } -> std::convertible_to<decltype(complex_power)>; { mod(complex_power) } -> std::convertible_to<decltype(apparent_power)>; { re(complex_power) } -> std::convertible_to<decltype(active_power)>; { im(complex_power) } -> std::convertible_to<decltype(reactive_power)>; { arg(complex_power) } -> std::convertible_to<decltype(phase_angle)>; { active_power / apparent_power } -> std::convertible_to<decltype(power_factor)>; { reactive_power.in(si::volt * si::ampere) }; // has to work according to ISO 80000 // invalid operations requires !requires { active_power + reactive_power; }; requires !requires { complex(apparent_power, reactive_power); } -> std::convertible_to<decltype(complex_power)>; // ? requires !requires { complex(reactive_power, active_power); } -> std::convertible_to<decltype(complex_power)>; requires !requires { complex_power = apparent_power; }; requires !requires { complex_power = active_power; }; requires !requires { complex_power = reactive_power; }; requires !requires { active_power = complex_power; }; requires !requires { active_power = reactive_power; }; requires !requires { active_power = apparent_power; }; // ? requires !requires { reactive_power = complex_power; }; requires !requires { reactive_power = active_power; }; requires !requires { reactive_power = apparent_power; }; requires !requires { complex_power.in(iec::volt_ampere_reactive_power); }; requires !requires { active_power.in(iec::volt_ampere_reactive_power); }; requires !requires { apparent_power.in(iec::volt_ampere_reactive_power); }; requires !requires { complex_power.in(si::watt); }; requires !requires { apparent_power.in(si::watt); }; // probably impossible to enforce requires !requires { active_power.in(si::watt * si::ampere); }; }; static_assert(complex_operations<quantity>);
This bug might be problematic in Clang (not present in MSVC). https://github.com/llvm/llvm-project/issues/55370
For example the following should be supported (as much as possible):