29#ifndef OPENSWMM_API_COMMON_HPP
30#define OPENSWMM_API_COMMON_HPP
32#include "SWMMEngine.hpp"
50static inline openswmm::SWMMEngine* to_engine(
SWMM_Engine e)
noexcept {
51 return static_cast<openswmm::SWMMEngine*
>(e);
90static inline double snap_display(
double v)
noexcept {
91 static constexpr double kPow10[23] = {1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7,
92 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
93 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
94 const double a = std::fabs(v);
95 if (!(a >= 1e-8 && a < 1e15))
98 int k = 14 -
static_cast<int>(std::floor(std::log10(a)));
99 double m = std::nearbyint(a * kPow10[k]);
100 if (m >= 1e15 && k > 0)
101 m = std::nearbyint(a * kPow10[--k]);
102 else if (m < 1e14 && k < 22)
103 m = std::nearbyint(a * kPow10[++k]);
104 const double r = std::copysign(m / kPow10[k], v);
105 const double two_ulps = 2.0 * (std::nextafter(a, HUGE_VAL) - a);
106 return std::fabs(r - v) <= two_ulps ? r : v;
120template <
class Ctx>
static inline double to_display(
const Ctx& ctx,
int q,
double v)
noexcept {
122 return f == 1.0 ? v : snap_display(v * f);
138static inline double exact_inverse(
double internal,
double factor,
double display)
noexcept {
139 if (internal * factor == display || !std::isfinite(internal))
141 const double up = std::nextafter(internal, HUGE_VAL);
142 if (up * factor == display)
144 const double down = std::nextafter(internal, -HUGE_VAL);
145 return down * factor == display ? down : internal;
159template <
class Ctx>
static inline double to_internal(
const Ctx& ctx,
int q,
double v)
noexcept {
164#define CHECK_HANDLE(e) \
167 return SWMM_ERR_BADHANDLE; \
169#define CHECK_INDEX(cond) \
172 return SWMM_ERR_BADINDEX; \
180#define CHECK_GEOMETRY(ctx) \
182 if ((ctx).state != openswmm::EngineState::BUILDING && \
183 (ctx).state != openswmm::EngineState::OPENED) \
184 return SWMM_ERR_LIFECYCLE; \
192#define CHECK_EDITABLE(ctx) \
194 if ((ctx).state != openswmm::EngineState::BUILDING && \
195 (ctx).state != openswmm::EngineState::OPENED) \
196 return SWMM_ERR_LIFECYCLE; \
200#define CHECK_INITIAL_COND(ctx) \
202 if ((ctx).state != openswmm::EngineState::BUILDING && \
203 (ctx).state != openswmm::EngineState::OPENED && \
204 (ctx).state != openswmm::EngineState::INITIALIZED) \
205 return SWMM_ERR_LIFECYCLE; \
209#define CHECK_RUNNING(ctx) \
211 if ((ctx).state != openswmm::EngineState::RUNNING) \
212 return SWMM_ERR_LIFECYCLE; \
216#define CHECK_READABLE(ctx) \
218 if ((ctx).state == openswmm::EngineState::CREATED || \
219 (ctx).state == openswmm::EngineState::CLOSED || \
220 (ctx).state == openswmm::EngineState::ERROR_STATE) \
221 return SWMM_ERR_LIFECYCLE; \
Global unit conversion factors — matching legacy SWMM Ucf[]/Qcf[].
double UCF(int quantity, const SimulationOptions &opts)
Get unit conversion factor for a quantity.
Definition UnitConversion.cpp:39
double UCF_inv(int quantity, const SimulationOptions &opts)
Reciprocal of UCF — multiply display by this to get internal units.
Definition UnitConversion.cpp:53
void * SWMM_Engine
Opaque handle to an OpenSWMM Engine instance.
Definition openswmm_callbacks.h:55
OpenSWMM Engine — primary transparent C API (master header).