2 #ifndef SYDEVS_QUANTITY_H_
3 #define SYDEVS_QUANTITY_H_
22 constexpr
bool valid()
const;
23 constexpr
bool finite()
const;
26 constexpr
bool fixed()
const;
36 quantity_base&
operator=(
const quantity_base&) =
default;
38 quantity_base&
operator=(quantity_base&&) =
default;
301 template<
typename U_>
304 template<
typename U_>
307 template<
typename U_>
310 template<
typename U_>
324 constexpr
quantity autoscaled()
const;
325 constexpr
quantity autorounded()
const;
366 template<
typename U_>
369 template<
typename U_>
372 template<
typename U_>
375 template<
typename U_>
378 constexpr
operator float64()
const;
384 constexpr
quantity autoscaled()
const;
385 constexpr
quantity autorounded()
const;
397 return multiplier_ < inf_float64 && multiplier_ > -
inf_float64;
423 : multiplier_(nan_float64)
431 : multiplier_(convert_multiplier(multiplier))
439 : multiplier_(convert_multiplier(multiplier))
440 , precision_(convert_level(multiplier, precision.level()))
447 : multiplier_(convert_multiplier(multiplier))
448 , precision_(convert_level(multiplier, precision.level()))
455 : multiplier_(multiplier)
456 , precision_(precision)
464 return n < 0 ? -n : n;
470 return x < 0 ? -x : x;
492 return multiplier >= 0 ? multiplier + 0.5 :
565 : quantity_base(multiplier, precision, fixed)
572 : quantity_base(precision, multiplier, fixed)
578 : quantity_base(precision, multiplier, fixed)
613 quantity<U>(scale_multiplier(multiplier_, precision_/precision), precision,
int8(1));
628 quantity<U>(scale_multiplier(multiplier_, precision_/precision), precision, fixed_ == 1);
645 constexpr_abs(round_multiplier(1000.0*multiplier_)) >=
quantity_limit ? *
this :
666 multiplier_ != 1000.0*round_multiplier(0.001*multiplier_) ? *
this :
729 return quantity<U>(precision_, multiplier_, fixed_);
742 return quantity<U>(precision_, -multiplier_, fixed_);
801 return fixed_ ?
quantity<U>(precision_, multiplier_*rhs,
int8(1)).autorounded() :
802 quantity<U>(precision_, multiplier_*rhs,
int8(0)).autoscaled();
816 return fixed_ ?
quantity<U>(precision_, multiplier_/rhs,
int8(1)).autorounded() :
817 quantity<U>(precision_, multiplier_/rhs,
int8(0)).autoscaled();
829 template<
typename U_>
836 template<
typename U_>
844 template<
typename U_>
852 template<
typename U_>
861 template<
typename U_>
868 template<
typename U_>
876 template<
typename U_>
879 return quantity<decltype(U()/U_())>(precision_, multiplier_,
int8(0));
883 template<
typename U_>
943 multiplier_ == -inf_float64 ? -
quantity<U>::inf() :
945 1000.0*constexpr_abs(multiplier_) + 0.5 >=
quantity_limit ? autorounded() :
946 multiplier_ ==
int64(multiplier_) ? autorounded() :
947 quantity<U>(precision_ - 1, 1000.0*multiplier_,
int8(0)).autoscaled();
951 constexpr quantity<no_units> quantity<no_units>::autoscaled()
const
953 return !
valid() ? quantity<no_units>() :
964 constexpr quantity<U> quantity<U>::autorounded()
const
966 return !valid() ? quantity<U>() :
969 quantity(
int64(offset_multiplier(multiplier_)), precision_, fixed_ == 1);
973 constexpr quantity<no_units> quantity<no_units>::autorounded()
const
975 return !
valid() ? quantity<no_units>() :
984 return precision_ ==
unit ? multiplier_ :
1015 constexpr
mass operator"" _ag(
unsigned long long multiplier) {
return mass(
int64(multiplier),
atto); }
1017 constexpr
mass operator"" _pg(
unsigned long long multiplier) {
return mass(
int64(multiplier),
pico); }
1018 constexpr
mass operator"" _ng(
unsigned long long multiplier) {
return mass(
int64(multiplier),
nano); }
1021 constexpr
mass operator"" _g(
unsigned long long multiplier) {
return mass(
int64(multiplier)); }
1022 constexpr
mass operator"" _kg(
unsigned long long multiplier) {
return mass(
int64(multiplier),
kilo); }
1023 constexpr
mass operator"" _Mg(
unsigned long long multiplier) {
return mass(
int64(multiplier),
mega); }
1024 constexpr
mass operator"" _Gg(
unsigned long long multiplier) {
return mass(
int64(multiplier),
giga); }
1025 constexpr
mass operator"" _Tg(
unsigned long long multiplier) {
return mass(
int64(multiplier),
tera); }
1026 constexpr
mass operator"" _Pg(
unsigned long long multiplier) {
return mass(
int64(multiplier),
peta); }
1027 constexpr
mass operator"" _Eg(
unsigned long long multiplier) {
return mass(
int64(multiplier),
exa); }
1158 os << (rhs < 0
_g ?
"-" :
"") <<
"mass::inf()";
1183 os << (rhs < 0
_m ?
"-" :
"") <<
"distance::inf()";
1208 os << (rhs < 0
_s ?
"-" :
"") <<
"duration::inf()";
1229 os <<
"electric_current()";
1233 os << (rhs < 0
_A ?
"-" :
"") <<
"electric_current::inf()";
1254 os <<
"thermodynamic_temperature()";
1258 os << (rhs < 0
_K ?
"-" :
"") <<
"thermodynamic_temperature::inf()";
1279 os <<
"amount_of_substance()";
1283 os << (rhs < 0
_mol ?
"-" :
"") <<
"amount_of_substance::inf()";
1304 os <<
"luminous_intensity()";
1308 os << (rhs < 0
_cd ?
"-" :
"") <<
"luminous_intensity::inf()";
1326 inline std::ostream& operator<<(std::ostream& os, const quantity<no_units>& rhs)
1328 if (rhs.valid() && rhs < quantity<no_units>(0)) {
1331 os <<
"quantity<no_units>";
1335 else if (!rhs.finite()) {
1339 os <<
"(" << (rhs.multiplier() < 0 ? -rhs.multiplier() : rhs.multiplier()) <<
", " << rhs.precision() <<
")";
1345 template<
typename U>
1346 inline std::ostream& operator<<(std::ostream& os, const quantity<U>& rhs)
1348 if (rhs.valid() && rhs < quantity<U>(0)) {
1351 os <<
"quantity<decltype(";
1352 bool starting =
true;
1353 for (
int64 i = 0; i != U::g_; i += (U::g_ > 0 ? 1 : -1)) {
1355 os << (starting ? (U::g_ > 0 ?
"" :
"_1/") :
1356 (U::g_ > 0 ?
"*" :
"/"));
1361 for (
int64 i = 0; i != U::m_; i += (U::m_ > 0 ? 1 : -1)) {
1363 os << (starting ? (U::m_ > 0 ?
"" :
"_1/") :
1364 (U::m_ > 0 ?
"*" :
"/"));
1369 for (
int64 i = 0; i != U::s_; i += (U::s_ > 0 ? 1 : -1)) {
1371 os << (starting ? (U::s_ > 0 ?
"" :
"_1/") :
1372 (U::s_ > 0 ?
"*" :
"/"));
1377 for (
int64 i = 0; i != U::A_; i += (U::A_ > 0 ? 1 : -1)) {
1379 os << (starting ? (U::A_ > 0 ?
"" :
"_1/") :
1380 (U::A_ > 0 ?
"*" :
"/"));
1385 for (
int64 i = 0; i != U::K_; i += (U::K_ > 0 ? 1 : -1)) {
1387 os << (starting ? (U::K_ > 0 ?
"" :
"_1/") :
1388 (U::K_ > 0 ?
"*" :
"/"));
1393 for (
int64 i = 0; i != U::mol_; i += (U::mol_ > 0 ? 1 : -1)) {
1395 os << (starting ? (U::mol_ > 0 ?
"" :
"_1/") :
1396 (U::mol_ > 0 ?
"*" :
"/"));
1401 for (
int64 i = 0; i != U::cd_; i += (U::cd_ > 0 ? 1 : -1)) {
1403 os << (starting ? (U::cd_ > 0 ?
"" :
"_1/") :
1404 (U::cd_ > 0 ?
"*" :
"/"));
1413 else if (!rhs.finite()) {
1417 os <<
"(" << (rhs.multiplier() < 0 ? -rhs.multiplier() : rhs.multiplier()) <<
", " << rhs.precision() <<
")";
quantity< amperes > electric_current
Definition: quantity.h:1007
static constexpr int64 round_multiplier(float64 multiplier)
Definition: quantity.h:505
~quantity_base()=default
Destructor.
constexpr scale pico
Definition: scale.h:159
constexpr scale exa
Definition: scale.h:169
quantity< candelas > luminous_intensity
Definition: quantity.h:1010
constexpr scale yotta
Definition: scale.h:171
constexpr const quantity operator-() const
Returns the negation of the quantity value.
Definition: quantity.h:740
units< 0, 0, 0, 0, 0, 0, 0 > no_units
Definition: units.h:115
constexpr auto _cd
Definition: units.h:132
constexpr quantity_base()
Definition: quantity.h:422
quantity< meters > distance
Definition: quantity.h:1005
std::ostream & operator<<(std::ostream &os, const arraynd< T, ndims > &rhs)
Definition: arraynd.h:1156
constexpr scale atto
Definition: scale.h:157
constexpr const quantity coarsened() const
Returns a new quantity value with the length precision maximized without losing precision.
Definition: quantity.h:661
constexpr int64 quantity_limit
The maximum precision multiplier, plus 1.
Definition: quantity.h:12
constexpr const quantity fixed_at(scale precision) const
Returns a new quantity value with the length precision changed and fixed.
Definition: quantity.h:610
constexpr scale nano
Definition: scale.h:160
static constexpr int64 scale_multiplier(float64 multiplier, float64 factor)
Definition: quantity.h:511
constexpr scale yocto
Definition: scale.h:155
float64 multiplier_
Definition: quantity.h:55
constexpr quantity()
Constructs an invalid quantity value.
Definition: quantity.h:519
A base class for quantities, defining operations that do not depend on the dimension.
Definition: quantity.h:19
constexpr auto _mol
Definition: units.h:131
quantity_base & operator=(const quantity_base &)=default
Copy assignment.
constexpr scale zetta
Definition: scale.h:170
constexpr auto _g
Definition: units.h:126
constexpr bool operator>(quantity rhs) const
Returns true if the quantity value is greater than rhs.
Definition: quantity.h:915
quantity< moles > amount_of_substance
Definition: quantity.h:1009
constexpr const quantity operator+() const
Returns a copy of the quantity value.
Definition: quantity.h:727
constexpr bool operator<(quantity rhs) const
Returns true if the quantity value is less than rhs.
Definition: quantity.h:907
constexpr bool fixed() const
Returns true if the quantity value has a fixed length precision.
Definition: quantity.h:416
constexpr auto _s
Definition: units.h:128
constexpr scale milli
Definition: scale.h:162
constexpr scale peta
Definition: scale.h:168
constexpr bool operator<=(quantity rhs) const
Returns true if the quantity value is at most rhs.
Definition: quantity.h:923
constexpr auto _K
Definition: units.h:130
constexpr bool finite() const
Returns true if the quantity value is finite.
Definition: quantity.h:395
constexpr scale micro
Definition: scale.h:161
scale precision_
Definition: quantity.h:56
constexpr bool operator!=(quantity rhs) const
Returns true if the quantity value does not equal rhs.
Definition: quantity.h:899
constexpr bool operator==(quantity rhs) const
Returns true if the quantity value equals rhs.
Definition: quantity.h:891
A data type which represents the general concept of scale as a dimensionless power of 1000...
Definition: scale.h:70
static constexpr int64 convert_level(int64 multiplier, int64 level)
Definition: quantity.h:483
static constexpr quantity inf()
Definition: quantity.h:584
static constexpr int64 inf_int64
Definition: quantity.h:43
quantity & operator*=(float64 rhs)
Multiplies the quantity value by rhs.
Definition: quantity.h:711
static constexpr quantity max(scale precision)
Definition: quantity.h:597
constexpr int64 level() const
Returns the level integer.
Definition: scale.h:174
constexpr auto _A
Definition: units.h:129
A speciaulization to facilitate the conversion of dimensionless quantities into floats.
Definition: quantity.h:334
constexpr scale precision() const
Returns the length precision.
Definition: quantity.h:410
static constexpr quantity inf()
Definition: quantity.h:590
~quantity()=default
Destructor.
char symbol() const
Provdes the metric prefix symbol.
Definition: scale.cpp:53
int8 fixed_
Definition: quantity.h:57
quantity & operator+=(quantity rhs)
Adds rhs to the quantity value.
Definition: quantity.h:695
static constexpr int64 truncate_multiplier(float64 multiplier)
Definition: quantity.h:497
constexpr scale tera
Definition: scale.h:167
quantity< seconds > duration
Definition: quantity.h:1006
constexpr scale zepto
Definition: scale.h:156
static constexpr int64 nan_int64
Definition: quantity.h:44
static constexpr float64 offset_multiplier(float64 multiplier)
Definition: quantity.h:490
constexpr scale giga
Definition: scale.h:166
quantity & operator=(const quantity &)=default
Copy assignment.
A template which represents Standard International (SI) units inclusing the base units such as grams...
Definition: units.h:79
constexpr scale kilo
Definition: scale.h:164
constexpr const quantity operator/(float64 rhs) const
Returns a new quantity value divided by rhs.
Definition: quantity.h:814
constexpr const quantity unfixed() const
Returns a new quantity value with the length precision unfixed.
Definition: quantity.h:682
static constexpr float64 convert_multiplier(int64 multiplier)
Definition: quantity.h:474
constexpr bool operator>=(quantity rhs) const
Returns true if the quantity value is at least rhs.
Definition: quantity.h:931
constexpr bool valid() const
Returns true if the quantity value is valid.
Definition: quantity.h:389
quantity & operator-=(quantity rhs)
Subtracts rhs from the quantity value.
Definition: quantity.h:703
arraynd< T, ndims > operator*(const arraynd< T, ndims > &lhs, const arraynd< T, ndims > &rhs)
Definition: arraynd.h:796
constexpr scale unit
Definition: scale.h:163
quantity< grams > mass
Definition: quantity.h:1004
int64_t int64
Definition: number_types.h:14
constexpr auto _m
Definition: units.h:127
constexpr const quantity operator*(float64 rhs) const
Returns a new quantity value multiplied by rhs.
Definition: quantity.h:799
int8_t int8
Definition: number_types.h:11
static constexpr int64 constexpr_abs(int64 n)
Definition: quantity.h:462
constexpr const quantity rescaled(scale precision) const
Returns a new quantity value with the length precision changed but neither fixed nor unfixed...
Definition: quantity.h:625
quantity & operator/=(float64 rhs)
Divides the quantity value by rhs.
Definition: quantity.h:719
constexpr const quantity refined() const
Returns a new quantity value with the length precision minimized without losing precision.
Definition: quantity.h:640
quantity< kelvins > thermodynamic_temperature
Definition: quantity.h:1008
double float64
Definition: number_types.h:22
constexpr auto _1
Definition: units.h:125
constexpr scale femto
Definition: scale.h:158
constexpr int64 multiplier() const
Returns the number that multiples the length precision.
Definition: quantity.h:401
static constexpr float64 inf_float64
Definition: quantity.h:41
A data type template which represents a dimensioned quantity as a multiple of a precision level...
Definition: quantity.h:234
constexpr scale mega
Definition: scale.h:165
arraynd< T, ndims > operator/(const arraynd< T, ndims > &lhs, const arraynd< T, ndims > &rhs)
Definition: arraynd.h:824
static constexpr float64 nan_float64
Definition: quantity.h:42