quantities.hpp type_traits compare concepts tuple serif/utils/misc/std_helper/cleaning.hpp serif/utils/misc/concepts/numeric.hpp src/compile_time_checks/serif/dimensions/quantities.cpp src/include/serif/dimensions/dimensions.hpp src/include/serif/dimensions/partial.hpp src/include/serif/dimensions/type_alias.hpp src/include/serif/eos/models/traits.hpp src/include/serif/eos/relations/catalog.hpp src/include/serif/model/specification.hpp src/include/serif/solver/continuation/parameters.hpp src/include/serif/solver/normalization/plan.hpp serif::dimensions::PhysicalQuantity serif::dimensions::ThermodynamicQuantity serif::dimensions::QuantityValue serif::dimensions::IsQuantityValue serif::dimensions::IsQuantityValue< QuantityValue< Quantity > > serif::dimensions::QuantityOf< QuantityValue< Quantity > > serif::dimensions::QuantityList serif::dimensions::QuantityAt< Index, QuantityList< Quantities... > > serif serif::dimensions This file contains the code to associate numeric data to a dimension. We call this a Quantity and a QuantityValue. Emily M. Boudreaux #pragmaonce #include<type_traits> #include<compare> #include<concepts> #include<tuple> #include"serif/utils/misc/std_helper/cleaning.hpp" #include"serif/utils/misc/concepts/numeric.hpp" namespaceserif::dimensions{ usingutils::misc::std_helper::NeitherConstNorVolatile; usingutils::misc::std_helper::NeitherConstNorVolatileReference; usingutils::misc::concepts::IsNumeric; structPhysicalQuantity{}; structThermodynamicQuantity:PhysicalQuantity{}; template<typenameQuantityCandidate> conceptPhysicalQuantityType= std::same_as<QuantityCandidate,NeitherConstNorVolatile<QuantityCandidate>>&& std::derived_from<QuantityCandidate,PhysicalQuantity>; template<typenameQuantityCandidate> conceptThermodynamicQuantityType= PhysicalQuantityType<QuantityCandidate>&& std::derived_from<QuantityCandidate,ThermodynamicQuantity>; template<PhysicalQuantityTypeQuantity> classQuantityValuefinal{ public: explicitconstexprQuantityValue(constdoublevalue)noexcept:m_value(value){} [[nodiscard]]constexprdoublevalue()constnoexcept{ returnm_value; } [[nodiscard]]friendconstexprbooloperator==( constQuantityValue&, constQuantityValue& )noexcept=default; friendconstexprQuantityValueoperator+( constQuantityValue&lhs, constQuantityValue&rhs )noexcept{ returnQuantityValue{lhs.m_value+rhs.m_value}; } friendconstexprQuantityValueoperator-( constQuantityValue&lhs, constQuantityValue&rhs )noexcept{ returnQuantityValue{lhs.m_value-rhs.m_value}; } template<IsNumericScalar> friendconstexprQuantityValueoperator*( constQuantityValue&lhs, constScalarrhs )noexcept{ returnQuantityValue{lhs.m_value*static_cast<double>(rhs)}; } template<IsNumericScalar> friendconstexprQuantityValueoperator*( constScalarlhs, constQuantityValue&rhs )noexcept{ returnQuantityValue{static_cast<double>(lhs)*rhs.m_value}; } template<IsNumericScalar> friendconstexprQuantityValueoperator/( constQuantityValue&lhs, constScalarrhs )noexcept{ returnQuantityValue{lhs.m_value/static_cast<double>(rhs)}; } template<IsNumericScalar> friendconstexprstd::partial_orderingoperator<=>( constQuantityValue&lhs, constScalarrhs )noexcept{ returnlhs.m_value<=>static_cast<double>(rhs); } template<IsNumericScalar> friendconstexprstd::partial_orderingoperator<=>( constScalarlhs, constQuantityValue&rhs )noexcept{ returnstatic_cast<double>(lhs)<=>rhs.m_value; } friendconstexprstd::partial_orderingoperator<=>( constQuantityValue&lhs, constQuantityValue&rhs )noexcept{ returnlhs.m_value<=>rhs.m_value; } private: doublem_value; }; template<typenameCandidate> structIsQuantityValue:std::false_type{}; template<PhysicalQuantityTypeQuantity> structIsQuantityValue<QuantityValue<Quantity>>:std::true_type{}; template<typenameCandidate> conceptQuantityValueType=IsQuantityValue<std::remove_cvref_t<Candidate>>::value; template<typenameCandidate> structQuantityOf; template<PhysicalQuantityTypeQuantity> structQuantityOf<QuantityValue<Quantity>>{ usingType=Quantity; }; template<QuantityValueTypeValue> usingQuantityOfT=typenameQuantityOf<NeitherConstNorVolatileReference<Value>>::Type; template<typename...Quantities> structQuantityListfinal{}; template<std::size_tIndex,typenameQuantities> structQuantityAt; template<std::size_tIndex,typename...Quantities> structQuantityAt<Index,QuantityList<Quantities...>>{ usingType=std::tuple_element_t<Index,std::tuple<Quantities...>>; }; template<typenameCandidate> conceptThermodynamicQuantityValueType=QuantityValueType<Candidate>&&ThermodynamicQuantityType<QuantityOfT<Candidate>>; }