#pragma once #include "serif/dimensions/quantities.hpp" #include "serif/utils/misc/concepts/numeric.hpp" namespace serif::dimensions { template struct WithRespectTo final {}; template class PartialDerivative final { public: explicit constexpr PartialDerivative(const double value) noexcept : m_value(value){} [[nodiscard]] constexpr double value() const noexcept { return m_value; } friend constexpr PartialDerivative operator+( const PartialDerivative& lhs, const PartialDerivative& rhs ) noexcept { return PartialDerivative{lhs.m_value + rhs.m_value}; } friend constexpr PartialDerivative operator-( const PartialDerivative& lhs, const PartialDerivative& rhs ) noexcept { return PartialDerivative{lhs.m_value - rhs.m_value}; } template friend constexpr PartialDerivative operator*( const PartialDerivative& lhs, const Scalar& rhs ) noexcept { return PartialDerivative{lhs.m_value * rhs}; } template friend constexpr PartialDerivative operator*( const Scalar& lhs, const PartialDerivative& rhs ) noexcept { return PartialDerivative{lhs * rhs.m_value}; } template friend constexpr PartialDerivative operator/( const PartialDerivative& lhs, const Scalar& rhs ) noexcept { return PartialDerivative{lhs.m_value / rhs}; } template friend constexpr std::partial_ordering operator<=>( const PartialDerivative& lhs, Scalar rhs ) noexcept { return lhs.m_value <=> rhs; } template friend constexpr std::partial_ordering operator<=>( Scalar lhs, const PartialDerivative& rhs ) noexcept { return lhs <=> rhs.m_value; } friend constexpr std::partial_ordering operator<=>( const PartialDerivative &lhs, const PartialDerivative &rhs ) noexcept { return lhs.m_value <=> rhs.m_value; } private: double m_value; }; }