From 64945a1c96e4017446445f33fb907ed5ac3434e9 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Sat, 14 Dec 2024 09:49:31 +0100 Subject: [PATCH] core: implement interpolate() function for unit types Calls the global interpolate() function for integer types. For now, the template is enabled if the arguments are not integer types. Might want to refine that in the future. Signed-off-by: Berthold Stoeger --- core/divelist.cpp | 2 +- core/planner.cpp | 2 +- core/profile.cpp | 5 +++-- core/units.h | 17 +++++++++++++++++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/core/divelist.cpp b/core/divelist.cpp index 9b3ebf4f3..d198800fc 100644 --- a/core/divelist.cpp +++ b/core/divelist.cpp @@ -432,7 +432,7 @@ static void add_dive_to_deco(struct deco_state *ds, const struct dive &dive, boo int j; for (j = t0; j < t1; j++) { - depth_t depth = { .mm = interpolate(psample.depth.mm, sample.depth.mm, j - t0, t1 - t0) }; + depth_t depth = interpolate(psample.depth, sample.depth, j - t0, t1 - t0); auto gasmix = loop.at(j).first; add_segment(ds, dive.depth_to_bar(depth), gasmix, 1, sample.setpoint.mbar, loop_d.at(j), dive.sac, diff --git a/core/planner.cpp b/core/planner.cpp index 7489c8c35..69be37dbf 100644 --- a/core/planner.cpp +++ b/core/planner.cpp @@ -104,7 +104,7 @@ static void interpolate_transition(struct deco_state *ds, struct dive *dive, dur int32_t j; for (j = t0.seconds; j < t1.seconds; j++) { - depth_t depth = depth_t { .mm = interpolate(d0.mm, d1.mm, j - t0.seconds, t1.seconds - t0.seconds) }; + depth_t depth = interpolate(d0, d1, j - t0.seconds, t1.seconds - t0.seconds); add_segment(ds, dive->depth_to_bar(depth), gasmix, 1, po2.mbar, divemode, prefs.bottomsac, true); } if (d1.mm > d0.mm) diff --git a/core/profile.cpp b/core/profile.cpp index bd14ac536..7a85dd660 100644 --- a/core/profile.cpp +++ b/core/profile.cpp @@ -876,6 +876,7 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_ int time_stepsize = 20; depth_t max_ceiling; depth_t depth { .mm = entry.depth }; + depth_t prev_depth { .mm = prev.depth }; divemode_t current_divemode = loop_d.at(entry.sec); struct gasmix gasmix = loop.at(t1).first; @@ -888,7 +889,7 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_ if (t0 != t1 && t1 - t0 < time_stepsize) time_stepsize = t1 - t0; for (int j = t0 + time_stepsize; j <= t1; j += time_stepsize) { - depth_t new_depth { .mm = interpolate(prev.depth, depth.mm, j - t0, t1 - t0) }; + depth_t new_depth = interpolate(prev_depth, depth, j - t0, t1 - t0); add_segment(ds, dive->depth_to_bar(new_depth), gasmix, time_stepsize, entry.o2pressure.mbar, current_divemode, entry.sac, in_planner); entry.icd_warning = ds->icd_warning; @@ -915,7 +916,7 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_ /* If using VPM-B, take first_ceiling_pressure as the deepest ceiling */ if (decoMode(in_planner) == VPMB) { if (current_ceiling.mm >= first_ceiling.mm || - (time_deep_ceiling == t0 && depth.mm == prev.depth)) { + (time_deep_ceiling == t0 && depth.mm == prev_depth.mm)) { time_deep_ceiling = t1; first_ceiling = current_ceiling; ds->first_ceiling_pressure.mbar = dive->depth_to_mbar(first_ceiling); diff --git a/core/units.h b/core/units.h index 0515076df..dc32322d7 100644 --- a/core/units.h +++ b/core/units.h @@ -2,6 +2,8 @@ #ifndef UNITS_H #define UNITS_H +#include "interpolate.h" + #include #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -86,6 +88,12 @@ * _permille -> fraction_t in ‰ * _percent -> fraction_t in % * + * For now, addition and subtraction of values of the same type + * are supported. + * + * A free standing interpolate() function can be used to interpolate + * between types of the same kind (see also the interpolate.h header). + * * We don't actually use these all yet, so maybe they'll change, but * I made a number of types as guidelines. */ @@ -140,6 +148,15 @@ struct unit_base { } }; +template ::value, bool> = true> +T interpolate(T a, T b, int part, int whole) +{ + return T::from_base( + interpolate(a.get_base(), b.get_base(), part, whole) + ); +} + struct duration_t : public unit_base { int32_t seconds = 0; // durations up to 34 yrs