Base: Units: refactor

Refactor Units making it constexpr, immutable, with repetition reduced.
Separate data from code.

Constexpr constructed units allow constructing predefined Quantities
from predefined unit types.
This commit is contained in:
bofdahof
2025-01-01 18:17:00 +10:00
committed by Ladislav Michl
parent a0917bcc7c
commit 2e0df80e84
8 changed files with 729 additions and 1155 deletions

View File

@@ -91,45 +91,37 @@ int QuantityPy::PyInit(PyObject* args, PyObject* /*kwd*/)
*self = *(static_cast<QuantityPy*>(object)->getQuantityPtr());
return 0;
}
PyErr_Clear(); // set by PyArg_ParseTuple()
double f = std::numeric_limits<double>::max();
if (PyArg_ParseTuple(args, "dO!", &f, &(UnitPy::Type), &object)) {
*self = Quantity(f, *(static_cast<UnitPy*>(object)->getUnitPtr()));
return 0;
}
PyErr_Clear(); // set by PyArg_ParseTuple()
if (PyArg_ParseTuple(args, "dO!", &f, &(QuantityPy::Type), &object)) {
PyErr_SetString(PyExc_TypeError, "Second argument must be a Unit not a Quantity");
return -1;
}
int i1 = 0;
int i2 = 0;
int i3 = 0;
int i4 = 0;
int i5 = 0;
int i6 = 0;
int i7 = 0;
int i8 = 0;
PyErr_Clear(); // set by PyArg_ParseTuple()
int i1 {0};
int i2 {0};
int i3 {0};
int i4 {0};
int i5 {0};
int i6 {0};
int i7 {0};
int i8 {0};
if (PyArg_ParseTuple(args, "|diiiiiiii", &f, &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8)) {
if (f < std::numeric_limits<double>::max()) {
*self = Quantity(f,
Unit {static_cast<int8_t>(i1),
static_cast<int8_t>(i2),
static_cast<int8_t>(i3),
static_cast<int8_t>(i4),
static_cast<int8_t>(i5),
static_cast<int8_t>(i6),
static_cast<int8_t>(i7),
static_cast<int8_t>(i8)});
*self = Quantity {f, Unit(i1, i2, i3, i4, i5, i6, i7, i8)};
}
return 0;
}
PyErr_Clear(); // set by PyArg_ParseTuple()
char* string {};
if (PyArg_ParseTuple(args, "et", "utf-8", &string)) {
std::string str(string);
@@ -144,13 +136,13 @@ int QuantityPy::PyInit(PyObject* args, PyObject* /*kwd*/)
return 0;
}
PyErr_Clear(); // set by PyArg_ParseTuple()
if (PyArg_ParseTuple(args, "det", &f, "utf-8", &string)) {
std::string unit(string);
std::string str(string);
PyMem_Free(string);
try {
*self = Quantity(f, unit);
*self = Quantity(f, str);
}
catch (const ParserError& e) {
PyErr_SetString(PyExc_ValueError, e.what());
@@ -210,7 +202,7 @@ PyObject* QuantityPy::getValueAs(PyObject* args) const
};
auto tryUnitPartsAndValue = [&]() -> std::optional<Quantity> {
double f = std::numeric_limits<double>::max();
double f;
int i1 {0};
int i2 {0};
int i3 {0};
@@ -219,20 +211,11 @@ PyObject* QuantityPy::getValueAs(PyObject* args) const
int i6 {0};
int i7 {0};
int i8 {0};
PyErr_Clear();
if (!PyArg_ParseTuple(args, "d|iiiiiiii", &f, &i1, &i2, &i3, &i4, &i5, &i6, &i7, &i8)) {
return std::nullopt;
}
if (f >= std::numeric_limits<double>::max()) {
return std::nullopt;
}
auto re = [](auto val) {
return static_cast<int8_t>(val);
};
return Quantity {f, Unit {re(i1), re(i2), re(i3), re(i4), re(i5), re(i6), re(i7), re(i8)}};
return Quantity {f, Unit(i1, i2, i3, i4, i5, i6, i7, i8)};
};
auto tryString = [&]() -> std::optional<Quantity> {