Program Listing for File BaseUnit.hpp
↰ Return to documentation for file (src/LouLib/Units/BaseUnit.hpp
)
#ifndef LOULIB_BASEUNIT_HPP
#define LOULIB_BASEUNIT_HPP
#include <ratio>
#include <stdexcept>
namespace LouLib {
namespace Units {
template<typename lengthDim, typename massDim, typename timeDim, typename currentDim,
typename temperatureDim, typename substanceDim, typename luminosityDim,
typename angleDim>
class BaseUnit {
private:
double value;
template <typename L, typename M, typename t, typename Q,
typename T, typename N, typename J, typename A>
constexpr bool sameDim(const BaseUnit<L, M, t, Q, T, N, J, A>& a) const{
if(!std::ratio_equal<lengthDim, L>::value) return false;
if(!std::ratio_equal<massDim, M>::value) return false;
if(!std::ratio_equal<timeDim, t>::value) return false;
if(!std::ratio_equal<currentDim, Q>::value) return false;
if(!std::ratio_equal<temperatureDim, T>::value) return false;
if(!std::ratio_equal<substanceDim, N>::value) return false;
if(!std::ratio_equal<luminosityDim, J>::value) return false;
if(!std::ratio_equal<angleDim, A>::value) return false;
return true;
}
public:
constexpr explicit BaseUnit(double val) : value(val){}
constexpr BaseUnit const& operator+=(const BaseUnit& a){
if(!sameDim(a)){
throw std::invalid_argument("Dimensions do not match");
}
value += a.val();
return *this;
}
constexpr BaseUnit const& operator-=(const BaseUnit& a){
if(!sameDim(a)){
throw std::invalid_argument("Dimensions do not match");
}
value -= a.val();
return *this;
}
constexpr BaseUnit const& operator*=(const double& a){
value *= a;
return *this;
}
constexpr BaseUnit const& operator/=(const double& a){
value /= a;
return *this;
}
constexpr BaseUnit operator-(){
return BaseUnit(-value);
}
constexpr double to(const BaseUnit& a) const{
if(!sameDim(a)){
throw std::invalid_argument("Dimensions do not match");
}
return value / a.val();
}
constexpr double val() const{
return value;
}
};
//Defining unit types
#define DEFINE_NEW_UNIT(_Ldim, _Mdim, _tdim, _Qdim, _Tdim, _Ndim, _Jdim, _Adim, name) \
typedef BaseUnit<std::ratio<_Ldim>, std::ratio<_Mdim>, std::ratio<_tdim>, std::ratio<_Qdim>, \
std::ratio<_Tdim>, std::ratio<_Ndim>, std::ratio<_Jdim>, std::ratio<_Adim>> name;
//Unitless type
DEFINE_NEW_UNIT(0, 0, 0, 0, 0, 0, 0, 0, Number)
constexpr Number number(1.0);
} // Units
} // LouLib
#endif //LOULIB_BASEUNIT_HPP