42 explicit QttyException(
const std::string &msg) : std::runtime_error(msg) {}
91inline void check_status(QttyStatus status,
const char *operation) {
92 if (status == QTTY_STATUS_OK) {
96 std::string msg = std::string(operation) +
" failed: ";
98 case QTTY_STATUS_UNKNOWN_UNIT:
100 case QTTY_STATUS_INCOMPATIBLE_DIM:
102 case QTTY_STATUS_NULL_OUT:
104 case QTTY_STATUS_BUFFER_TOO_SMALL:
116template <
typename UnitTag>
class Quantity;
117template <
typename NumeratorTag,
typename DenominatorTag>
struct CompoundTag;
134 static constexpr std::string_view
symbol() {
return ""; }
138template <
typename Tag,
typename =
void>
struct has_dimension : std::false_type {};
139template <
typename Tag>
140struct has_dimension<Tag, std::void_t<decltype(UnitTraits<Tag>::dimension())>> : std::true_type {};
193 constexpr double value()
const {
return m_value; }
196 constexpr const double &
value_ref()
const {
return m_value; }
236 qtty_derived_quantity_t src_qty;
237 qtty_derived_quantity_t dst_qty;
241 check_status(status,
"Creating derived source quantity");
250 qtty_quantity_t src_qty;
251 qtty_quantity_t dst_qty;
253 QttyStatus status = qtty_quantity_make(m_value,
unit_id(), &src_qty);
316 m_value += other.m_value;
321 m_value -= other.m_value;
353 return Quantity(std::max(min_val.m_value, std::min(m_value, max_val.m_value)));
363 bool is_nan()
const {
return std::isnan(m_value); }
365 bool is_finite()
const {
return std::isfinite(m_value); }
372 double signum()
const {
return std::copysign(1.0, m_value); }
387 double r = std::fmod(m_value, rhs);
410 if (std::isnan(m_value) || std::isnan(rhs)) {
454 std::string
format(
int precision = -1, uint32_t flags = QTTY_FMT_DEFAULT)
const {
456 QttyStatus make_status = qtty_quantity_make(m_value,
unit_id(), &qty);
460 QttyStatus result = qtty_quantity_format(qty, precision, flags, buf,
sizeof(buf));
461 if (result == QTTY_STATUS_BUFFER_TOO_SMALL) {
464 result = qtty_quantity_format(qty, precision, flags, big_buf,
sizeof(big_buf));
466 throw QttyException(
"format: buffer too small even at 4096 bytes");
468 return std::string(big_buf);
473 return std::string(buf);
518#if __cplusplus >= 202002L
523template <
typename UnitTag>
struct formatter<qtty::Quantity<UnitTag>> {
525 std::formatter<double> double_fmt_;
529 template <
typename ParseContext>
constexpr auto parse(ParseContext &ctx) {
530 return double_fmt_.parse(ctx);
535 template <
typename FormatContext>
536 auto format(
const qtty::Quantity<UnitTag> &qty, FormatContext &ctx)
const {
537 auto out = double_fmt_.format(qty.
value(), ctx);
ConversionError(const std::string &msg)
Raised when mixing incompatible dimensions in conversion/arithmetic.
IncompatibleDimensionsError(const std::string &msg)
Raised when an unknown or invalid unit identifier is used.
InvalidUnitError(const std::string &msg)
Raised when a required output pointer was null.
NullPointerError(const std::string &msg)
Base exception for all qtty wrapper failures.
QttyException(const std::string &msg)
static Quantity infinity()
Quantity & operator*=(double scalar)
bool operator<=(const Quantity &other) const
static constexpr Quantity zero()
static Quantity neg_infinity()
constexpr const double & value_ref() const
bool operator!=(const Quantity &other) const
Quantity mean(const Quantity &other) const
bool operator<(const Quantity &other) const
Quantity max(const Quantity &other) const
std::string format(int precision=-1, uint32_t flags=QTTY_FMT_DEFAULT) const
Format this quantity as a string.
Quantity operator+(const Quantity &other) const
Quantity rem_euclid(double rhs) const
bool operator==(const Quantity &other) const
double scalar_sqrt() const
constexpr double value() const
Quantity operator*(double scalar) const
Quantity operator-(const Quantity &other) const
Quantity operator-() const
Quantity & operator+=(const Quantity &other)
constexpr double erase_unit_raw() const
Quantity & operator-=(const Quantity &other)
Quantity & operator/=(double scalar)
bool operator>(const Quantity &other) const
Quantity operator/(double scalar) const
std::optional< int > cmp_unit(const Quantity< V > &other) const
static constexpr Quantity one()
static constexpr UnitId unit_id()
friend Quantity operator*(double scalar, const Quantity &q)
constexpr Quantity(double value)
Quantity min(const Quantity &other) const
bool eq_unit(const Quantity< V > &other) const
bool operator>=(const Quantity &other) const
Quantity clamp(const Quantity &min_val, const Quantity &max_val) const
Quantity< typename ExtractTag< TargetType >::type > to() const
constexpr bool is_compound_v
void check_status(QttyStatus status, const char *operation)
Convert qtty FFI status codes into typed C++ exceptions.
constexpr bool is_dimensionless_v
constexpr bool is_dimensionless_tag()
std::ostream & operator<<(std::ostream &os, const Quantity< UnitTag > &q)
static constexpr std::string_view symbol()