core: introduce a few user-defined literals for unit types

Thise makes initialization of unit types more palatable.

For example:

    surface.time = sample.time - duration_t { .seconds = 20 };
=>  surface.time = sample.time - 20_sec;

    delta_depth.mm = feet_to_mm(1.0); // 1ft
=>  delta_depth = 1_ft;

    get_cylinderid_at_time(..., { .seconds = 20 * 60 + 1 }));
=>  get_cylinderid_at_time(..., 20_min + 1_sec));

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-09-03 17:04:48 +02:00 committed by bstoeger
parent f09601bc93
commit ae81b42fe2
36 changed files with 320 additions and 264 deletions

View file

@ -390,8 +390,8 @@ void DiveListBase::redo()
AddDive::AddDive(std::unique_ptr<dive> d, bool autogroup, bool newNumber)
{
setText(Command::Base::tr("add dive"));
d->maxdepth.mm = 0;
d->dcs[0].maxdepth.mm = 0;
d->maxdepth = 0_m;
d->dcs[0].maxdepth = 0_m;
divelog.dives.fixup_dive(*d);
// this only matters if undoit were called before redoit

View file

@ -306,7 +306,7 @@ void EditDuration::set(struct dive *d, int value) const
{
d->dcs[0].duration.seconds = value;
d->duration = d->dcs[0].duration;
d->dcs[0].meandepth.mm = 0;
d->dcs[0].meandepth = 0_m;
d->dcs[0].samples.clear();
fake_dc(&d->dcs[0]);
}
@ -326,7 +326,7 @@ void EditDepth::set(struct dive *d, int value) const
{
d->dcs[0].maxdepth.mm = value;
d->maxdepth = d->dcs[0].maxdepth;
d->dcs[0].meandepth.mm = 0;
d->dcs[0].meandepth = 0_m;
d->dcs[0].samples.clear();
fake_dc(&d->dcs[0]);
}
@ -673,10 +673,10 @@ PasteState::PasteState(dive &d, const dive_paste_data &data, std::vector<dive_si
}
for (size_t i = data.cylinders->size(); i < cylinders->size(); ++i) {
cylinder_t &cyl = (*cylinders)[i];
cyl.start.mbar = 0;
cyl.end.mbar = 0;
cyl.sample_start.mbar = 0;
cyl.sample_end.mbar = 0;
cyl.start = 0_bar;
cyl.end = 0_bar;
cyl.sample_start = 0_bar;
cyl.sample_end = 0_bar;
cyl.manually_added = true;
}
}
@ -796,7 +796,7 @@ ReplanDive::ReplanDive(dive *source) : d(current_dive),
return;
// Fix source. Things might be inconsistent after modifying the profile.
source->maxdepth.mm = source->dcs[0].maxdepth.mm = 0;
source->maxdepth = source->dcs[0].maxdepth = 0_m;
divelog.dives.fixup_dive(*source);
when = source->when;

View file

@ -677,7 +677,7 @@ static void cochran_parse_dive(const unsigned char *decode, unsigned mod,
cylinder_t cyl = default_cylinder(dive.get());
cyl.gasmix.o2.permille = (log[CMD_O2_PERCENT] / 256
+ log[CMD_O2_PERCENT + 1]) * 10;
cyl.gasmix.he.permille = 0;
cyl.gasmix.he = 0_percent;
dive->cylinders.add(0, std::move(cyl));
} else {
dc->model = "Commander";
@ -686,7 +686,7 @@ static void cochran_parse_dive(const unsigned char *decode, unsigned mod,
cylinder_t cyl = default_cylinder(dive.get());
cyl.gasmix.o2.permille = (log[CMD_O2_PERCENT + g * 2] / 256
+ log[CMD_O2_PERCENT + g * 2 + 1]) * 10;
cyl.gasmix.he.permille = 0;
cyl.gasmix.he = 0_percent;
dive->cylinders.add(g, std::move(cyl));
}
}

View file

@ -239,19 +239,19 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct
read_bytes(1);
switch (tmp_1byte) {
case 1:
dt_dive->dcs[0].surface_pressure.mbar = 1013;
dt_dive->dcs[0].surface_pressure = 1_atm;
break;
case 2:
dt_dive->dcs[0].surface_pressure.mbar = 932;
dt_dive->dcs[0].surface_pressure = 932_mbar;
break;
case 3:
dt_dive->dcs[0].surface_pressure.mbar = 828;
dt_dive->dcs[0].surface_pressure = 828_mbar;
break;
case 4:
dt_dive->dcs[0].surface_pressure.mbar = 735;
dt_dive->dcs[0].surface_pressure = 735_mbar;
break;
default:
dt_dive->dcs[0].surface_pressure.mbar = 1013;
dt_dive->dcs[0].surface_pressure = 1_atm;
}
/*
@ -336,9 +336,9 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct
cylinder_t cyl;
cyl.type.size.mliter = tmp_2bytes * 10;
cyl.type.description = cyl_type_by_size(tmp_2bytes * 10);
cyl.start.mbar = 200000;
cyl.gasmix.he.permille = 0;
cyl.gasmix.o2.permille = 210;
cyl.start = 200_bar;
cyl.gasmix.he = 0_percent;
cyl.gasmix.o2 = 21_percent;
cyl.manually_added = true;
dt_dive->cylinders.push_back(std::move(cyl));
}
@ -365,7 +365,7 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct
if (tmp_2bytes != 0x7fff)
dt_dive->watertemp.mkelvin = dt_dive->dcs[0].watertemp.mkelvin = C_to_mkelvin((double)(tmp_2bytes / 100));
else
dt_dive->watertemp.mkelvin = 0;
dt_dive->watertemp = 0_K;
/*
* Air used in bar*100.

View file

@ -495,8 +495,8 @@ void clear_vpmb_state(struct deco_state *ds)
ds->max_he_crushing_pressure[ci] = 0.0;
}
ds->max_ambient_pressure = 0;
ds->first_ceiling_pressure.mbar = 0;
ds->max_bottom_ceiling_pressure.mbar = 0;
ds->first_ceiling_pressure = 0_bar;
ds->max_bottom_ceiling_pressure = 0_bar;
}
void clear_deco(struct deco_state *ds, double surface_pressure, bool in_planner)

View file

@ -498,7 +498,7 @@ void update_setpoint_events(const struct dive *dive, struct divecomputer *dc)
struct gasmix gasmix = loop.at(sample.time.seconds).first;
gas_pressures pressures = fill_pressures(lrint(calculate_depth_to_mbarf(sample.depth.mm, dc->surface_pressure, 0)), gasmix ,0, dc->divemode);
if (abs(sample.setpoint.mbar - (int)(1000 * pressures.o2)) <= 50)
sample.setpoint.mbar = 0;
sample.setpoint = 0_baro2;
}
}
@ -809,7 +809,7 @@ static void fixup_dc_temp(struct dive &dive, struct divecomputer &dc)
* the redundant ones.
*/
if (lasttemp == temp)
sample.temperature.mkelvin = 0;
sample.temperature = 0_K;
else
lasttemp = temp;
@ -839,7 +839,7 @@ static void simplify_dc_pressures(struct divecomputer &dc)
if (index == lastindex[j]) {
/* Remove duplicate redundant pressure information */
if (pressure == lastpressure[j])
sample.pressure[j].mbar = 0;
sample.pressure[j] = 0_bar;
}
lastindex[j] = index;
lastpressure[j] = pressure;
@ -912,7 +912,7 @@ static bool validate_gaschange(struct dive &dive, struct event &event)
/* We'll get rid of the per-event gasmix, but for now sanitize it */
if (gasmix_is_air(event.gas.mix))
event.gas.mix.o2.permille = 0;
event.gas.mix.o2 = 0_percent;
/* Do we already have a cylinder index for this gasmix? */
if (event.gas.index >= 0)
@ -993,7 +993,7 @@ static void fixup_dc_sample_sensors(struct dive &dive, struct divecomputer &dc)
// No invalid sensor ID's, please
if (sensor < 0 || sensor > MAX_SENSORS) {
sample.sensor[j] = NO_SENSOR;
sample.pressure[j].mbar = 0;
sample.pressure[j] = 0_bar;
continue;
}
@ -1076,9 +1076,9 @@ void dive::fixup_no_cylinder()
for (auto &cyl: cylinders) {
add_cylinder_description(cyl.type);
if (same_rounded_pressure(cyl.sample_start, cyl.start))
cyl.start.mbar = 0;
cyl.start = 0_bar;
if (same_rounded_pressure(cyl.sample_end, cyl.end))
cyl.end.mbar = 0;
cyl.end = 0_bar;
}
for (auto &ws: weightsystems)
@ -1120,7 +1120,7 @@ static void merge_one_sample(const struct sample &sample, struct divecomputer &d
append_sample(surface, &dc);
surface.time = sample.time - duration_t { .seconds = 20 };
surface.time = sample.time - 20_sec;
append_sample(surface, &dc);
}
}
@ -1399,7 +1399,7 @@ static void sample_renumber(struct sample &s, const struct sample *prev, const i
// Remove sensor and gas pressure info
if (!prev) {
s.sensor[j] = 0;
s.pressure[j].mbar = 0;
s.pressure[j] = 0_bar;
} else {
s.sensor[j] = prev->sensor[j];
s.pressure[j] = prev->pressure[j];
@ -2331,8 +2331,9 @@ fraction_t dive::best_o2(depth_t depth, bool in_planner) const
fo2.permille = (po2 * 100 / depth_to_mbar(depth.mm)) * 10; //use integer arithmetic to round down to nearest percent
// Don't permit >100% O2
// TODO: use std::min, once we have comparison
if (fo2.permille > 1000)
fo2.permille = 1000;
fo2 = 100_percent;
return fo2;
}
@ -2348,8 +2349,9 @@ fraction_t dive::best_he(depth_t depth, bool o2narcotic, fraction_t fo2) const
} else {
fhe.permille = 1000 - fo2.permille - N2_IN_AIR * pnarcotic / ambient;
}
// TODO: use std::max, once we have comparison
if (fhe.permille < 0)
fhe.permille = 0;
fhe = 0_percent;
return fhe;
}

View file

@ -118,9 +118,9 @@ static void fill_samples_no_avg(std::vector<sample> &s, int max_d, int max_t, do
s[2].time.seconds = max_t - lrint(max_d / slope) - 180;
s[2].depth.mm = max_d;
s[3].time.seconds = max_t - lrint(5000 / slope) - 180;
s[3].depth.mm = 5000;
s[3].depth = 5_m;
s[4].time.seconds = max_t - lrint(5000 / slope);
s[4].depth.mm = 5000;
s[4].depth = 5_m;
}
}

View file

@ -51,18 +51,18 @@ void dive_table::force_fixup_dive(struct dive &d) const
duration_t old_duration = d.duration;
std::vector<start_end_pressure> old_pressures(d.cylinders.size());
d.maxdepth.mm = 0;
dc->maxdepth.mm = 0;
d.watertemp.mkelvin = 0;
dc->watertemp.mkelvin = 0;
d.duration.seconds = 0;
d.maxtemp.mkelvin = 0;
d.mintemp.mkelvin = 0;
d.maxdepth = 0_m;
dc->maxdepth = 0_m;
d.watertemp = 0_K;
dc->watertemp = 0_K;
d.duration = 0_sec;
d.maxtemp = 0_K;
d.mintemp = 0_K;
for (auto [i, cyl]: enumerated_range(d.cylinders)) {
old_pressures[i].start = cyl.start;
old_pressures[i].end = cyl.end;
cyl.start.mbar = 0;
cyl.end.mbar = 0;
cyl.start = 0_bar;
cyl.end = 0_bar;
}
fixup_dive(d);
@ -95,7 +95,7 @@ std::unique_ptr<dive> dive_table::default_dive()
{
auto d = std::make_unique<dive>();
d->when = time(nullptr) + gettimezoneoffset() + 3600;
d->dcs[0].duration.seconds = 40 * 60;
d->dcs[0].duration = 40_min;
d->dcs[0].maxdepth.mm = M_OR_FT(15, 45);
d->dcs[0].meandepth.mm = M_OR_FT(13, 39); // this creates a resonable looking safety stop
make_manually_added_dive_dc(&d->dcs[0]);

View file

@ -80,7 +80,7 @@ static void exportHTMLstatistics(const QString filename, struct htmlExportSettin
stats_summary stats = calculate_stats_summary(hes.selectedOnly);
total_stats.selection_size = 0;
total_stats.total_time.seconds = 0;
total_stats.total_time = 0_sec;
out << "divestat=[";
if (hes.yearlyStatistics) {

View file

@ -317,8 +317,8 @@ void reset_cylinders(struct dive *dive, bool track_gas)
cyl.depth = dive->gas_mod(cyl.gasmix, decopo2, M_OR_FT(3,10));
if (track_gas)
cyl.start.mbar = cyl.end.mbar = cyl.type.workingpressure.mbar;
cyl.gas_used.mliter = 0;
cyl.deco_gas_used.mliter = 0;
cyl.gas_used = 0_l;
cyl.deco_gas_used = 0_l;
}
}
@ -404,8 +404,8 @@ void add_default_cylinder(struct dive *d)
} else {
// roughly an AL80
cyl.type.description = translate("gettextFromC", "unknown");
cyl.type.size.mliter = 11100;
cyl.type.workingpressure.mbar = 207000;
cyl.type.size = 11100_ml;
cyl.type.workingpressure = 207_bar;
}
d->cylinders.add(0, std::move(cyl));
reset_cylinders(d, false);

View file

@ -54,7 +54,7 @@ void sanitize_gasmix(struct gasmix &mix)
return;
/* 20.8% to 21% O2 is just air */
if (gasmix_is_air(mix)) {
mix.o2.permille = 0;
mix.o2 = 0_percent;
return;
}
}

View file

@ -17,7 +17,7 @@ struct gasmix {
std::string name() const;
};
static const struct gasmix gasmix_invalid = { { .permille = -1 }, { .permille = -1 } };
static const struct gasmix gasmix_air = { { .permille = 0 }, { .permille = 0 } };
static const struct gasmix gasmix_air = { 0_percent, 0_percent };
enum gastype {
GASTYPE_AIR,

View file

@ -519,10 +519,10 @@ int parse_txt_file(const char *filename, const char *csv, struct divelog *log)
{
cylinder_t cyl;
cyl.cylinder_use = OXYGEN;
cyl.type.size.mliter = 3000;
cyl.type.workingpressure.mbar = 200000;
cyl.type.size = 3_l;
cyl.type.workingpressure = 200_bar;
cyl.type.description = "3l Mk6";
cyl.gasmix.o2.permille = 1000;
cyl.gasmix.o2 = 100_percent;
cyl.manually_added = true;
cyl.bestmix_o2 = 0;
cyl.bestmix_he = 0;
@ -532,8 +532,8 @@ int parse_txt_file(const char *filename, const char *csv, struct divelog *log)
{
cylinder_t cyl;
cyl.cylinder_use = DILUENT;
cyl.type.size.mliter = 3000;
cyl.type.workingpressure.mbar = 200000;
cyl.type.size = 3_l;
cyl.type.workingpressure = 200_bar;
cyl.type.description = "3l Mk6";
value = parse_mkvi_value(memtxt.data(), "Helium percentage");
he = atoi(value.c_str());

View file

@ -171,7 +171,7 @@ static int divinglog_profile(void *param, int, char **data, char **)
*/
int val = atoi_n(ptr4, 3);
if (state->cur_sample->in_deco) {
state->cur_sample->ndl.seconds = 0;
state->cur_sample->ndl = 0_sec;
if (val)
state->cur_sample->tts.seconds = val * 60;
} else {

View file

@ -316,7 +316,7 @@ static int dm5_cylinders(void *param, int, char **data, char **)
* value is 0 (and using metric units). So we just use
* the same 12 liters when size is not available */
if (permissive_strtod(data[6], NULL) == 0.0 && cyl->start.mbar)
cyl->type.size.mliter = 12000;
cyl->type.size = 12_l;
else
cyl->type.size.mliter = lrint((permissive_strtod(data[6], NULL)) * 1000);
}

View file

@ -160,7 +160,7 @@ static dc_status_t parse_gasmixes(device_data_t *devdata, struct dive *dive, dc_
}
}
bool no_volume = true;
struct gasmix bottom_gas = { { .permille = 1000}, {} }; /* Default to pure O2, or air if there are no mixes defined */
struct gasmix bottom_gas = { 100_percent, 0_percent }; /* Default to pure O2, or air if there are no mixes defined */
if (ngases == 0) {
bottom_gas = gasmix_air;
}
@ -291,7 +291,7 @@ static dc_status_t parse_gasmixes(device_data_t *devdata, struct dive *dive, dc_
cyl.end.mbar = lrint(tank.endpressure * 1000);
} else if (devdata->vendor == "Uwatec") {
cyl.start.mbar = lrint(tank.beginpressure * 1000 + 30000);
cyl.end.mbar = 30000;
cyl.end = 30_bar;
}
}
}
@ -850,7 +850,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
/* Various libdivecomputer interface fixups */
if (dive->dcs[0].airtemp.mkelvin == 0 && first_temp_is_air && !dive->dcs[0].samples.empty()) {
dive->dcs[0].airtemp = dive->dcs[0].samples[0].temperature;
dive->dcs[0].samples[0].temperature.mkelvin = 0;
dive->dcs[0].samples[0].temperature = 0_K;
}
/* special case for bug in Tecdiving DiveComputer.eu

View file

@ -667,8 +667,8 @@ static struct sample *new_sample(struct git_parser_state *state)
size_t num_samples = state->active_dc->samples.size();
if (num_samples >= 2) {
*sample = state->active_dc->samples[num_samples - 2];
sample->pressure[0].mbar = 0;
sample->pressure[1].mbar = 0;
sample->pressure[0] = 0_bar;
sample->pressure[1] = 0_bar;
} else {
sample->sensor[0] = sanitize_sensor_id(state->active_dive.get(), !state->o2pressure_sensor);
sample->sensor[1] = sanitize_sensor_id(state->active_dive.get(), state->o2pressure_sensor);

View file

@ -531,7 +531,7 @@ static bool parseASF(QFile &f, metadata *metadata)
mediatype_t get_metadata(const char *filename_in, metadata *data)
{
data->timestamp = 0;
data->duration.seconds = 0;
data->duration = 0_sec;
data->location.lat.udeg = 0;
data->location.lon.udeg = 0;

View file

@ -328,7 +328,7 @@ static void temperature(const char *buffer, temperature_t *temperature, struct p
/* temperatures outside -40C .. +70C should be ignored */
if (temperature->mkelvin < ZERO_C_IN_MKELVIN - 40000 ||
temperature->mkelvin > ZERO_C_IN_MKELVIN + 70000)
temperature->mkelvin = 0;
*temperature = 0_K;
}
static void sampletime(const char *buffer, duration_t *time)
@ -351,7 +351,7 @@ static void sampletime(const char *buffer, duration_t *time)
time->seconds = (hr * 60 + min) * 60 + sec;
break;
default:
time->seconds = 0;
*time = 0_sec;
report_info("Strange sample time reading %s", buffer);
}
}
@ -715,7 +715,7 @@ static void parse_libdc_deco(const char *buffer, struct sample *s)
s->in_deco = false;
// The time wasn't stoptime, it was ndl
s->ndl = s->stoptime;
s->stoptime.seconds = 0;
s->stoptime = 0_sec;
}
}

View file

@ -267,8 +267,7 @@ void dive_end(struct parser_state *state)
}
state->cur_dive.reset();
state->cur_dc = NULL;
state->cur_location.lat.udeg = 0;
state->cur_location.lon.udeg = 0;
state->cur_location = location_t();
}
void trip_start(struct parser_state *state)
@ -350,8 +349,8 @@ void sample_start(struct parser_state *state)
if (dc->samples.size() > 1) {
*sample = dc->samples[dc->samples.size() - 2];
sample->pressure[0].mbar = 0;
sample->pressure[1].mbar = 0;
sample->pressure[0] = 0_bar;
sample->pressure[1] = 0_bar;
} else {
sample->sensor[0] = sanitize_sensor_id(state->cur_dive.get(), !state->o2pressure_sensor);
sample->sensor[1] = sanitize_sensor_id(state->cur_dive.get(), state->o2pressure_sensor);

View file

@ -201,7 +201,7 @@ static void create_dive_from_plan(struct diveplan &diveplan, struct dive *dive,
cylinder_t *cyl;
int oldpo2 = 0;
int lasttime = 0, last_manual_point = 0;
depth_t lastdepth = {.mm = 0};
depth_t lastdepth;
int lastcylid;
enum divemode_t type = dc->divemode;
@ -305,7 +305,7 @@ divedatapoint::divedatapoint(int time_incr, int depth, int cylinderid, int po2,
time(time_incr),
depth{ .mm = depth },
cylinderid(cylinderid),
minimum_gas{ .mbar = 0 },
minimum_gas = 0_bar;
setpoint(po2),
entered(entered),
divemode(OC)
@ -654,7 +654,7 @@ std::vector<decostop> plan(struct deco_state *ds, struct diveplan &diveplan, str
}
clear_deco(ds, dive->surface_pressure.mbar / 1000.0, true);
ds->max_bottom_ceiling_pressure.mbar = ds->first_ceiling_pressure.mbar = 0;
ds->max_bottom_ceiling_pressure = ds->first_ceiling_pressure = 0_bar;
create_dive_from_plan(diveplan, dive, dc, is_planner);
// Do we want deco stop array in metres or feet?

View file

@ -41,7 +41,7 @@ preferences::preferences() :
ascratestops(9000 / 60),
ascrate50(9000 / 60),
ascrate75(9000 / 60),
bestmixend({ .mm = 30'000 }),
bestmixend(30_m),
bottompo2(1400),
bottomsac(20000),
decopo2(1600),

View file

@ -209,7 +209,6 @@ static void check_setpoint_events(const struct dive *, const struct divecomputer
{
size_t i = 0;
pressure_t setpoint;
setpoint.mbar = 0;
event_loop loop("SP change", *dc);
bool found = false;
@ -848,7 +847,7 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_
if (!in_planner) {
ds->deco_time = 0;
ds->first_ceiling_pressure.mbar = 0;
ds->first_ceiling_pressure = 0_bar;
} else {
ds->deco_time = planner_ds->deco_time;
ds->first_ceiling_pressure = planner_ds->first_ceiling_pressure;
@ -1179,7 +1178,7 @@ static void fill_o2_values(const struct dive *dive, const struct divecomputer *d
o2pressure.mbar = calculate_ccr_po2(entry, dc); // ...calculate the po2 based on the sensor data
entry.o2pressure.mbar = std::min(o2pressure.mbar, amb_pressure.mbar);
} else {
entry.o2pressure.mbar = 0; // initialise po2 to zero for dctype = OC
entry.o2pressure = 0_bar; // initialise po2 to zero for dctype = OC
}
}
}

View file

@ -1293,10 +1293,11 @@ fraction_t string_to_fraction(const char *str)
/*
* Don't permit values less than zero or greater than 100%
*/
// TODO: use std::clamp() once we have comparison on unit types
if (fraction.permille < 0)
fraction.permille = 0;
fraction = 0_percent;
else if (fraction.permille > 1000)
fraction.permille = 1000;
fraction = 100_percent;
return fraction;
}

View file

@ -21,7 +21,7 @@
static void process_temperatures(const struct dive &dp, stats_t &stats)
{
temperature_t min_temp, mean_temp, max_temp = {.mkelvin = 0};
temperature_t min_temp, mean_temp, max_temp;
max_temp.mkelvin = dp.maxtemp.mkelvin;
if (max_temp.mkelvin && (!stats.max_temp.mkelvin || max_temp.mkelvin > stats.max_temp.mkelvin))
@ -262,7 +262,7 @@ std::vector<volume_t> get_gas_used(struct dive *dive)
if (end.mbar && start.mbar > end.mbar)
gases[idx] = cyl.gas_volume(start) - cyl.gas_volume(end);
else
gases[idx].mliter = 0;
gases[idx] = 0_l;
}
return gases;
@ -277,7 +277,7 @@ static std::pair<volume_t, volume_t> get_gas_parts(struct gasmix mix, volume_t v
volume_t air { .mliter = int_cast<int>(((double)vol.mliter * get_n2(mix)) / (1000 - o2_in_topup)) };
volume_t he { .mliter = int_cast<int>(((double)vol.mliter * get_he(mix)) / 1000.0) };
volume_t o2 { .mliter = vol.mliter - he.mliter - air.mliter };
volume_t o2 = vol - he - air;
return std::make_pair(o2, he);
}

View file

@ -254,7 +254,7 @@ void uemis::event(struct dive *dive, struct divecomputer *dc, struct sample *sam
sample->in_deco = true;
sample->stopdepth.mm = stopdepth;
sample->stoptime.seconds = u_sample->hold_time * 60;
sample->ndl.seconds = 0;
sample->ndl = 0_sec;
} else if (flags[0] & 128) {
/* safety stop - distinguished from deco stop by having
* both ndl and stop information */
@ -266,8 +266,8 @@ void uemis::event(struct dive *dive, struct divecomputer *dc, struct sample *sam
/* NDL */
sample->in_deco = false;
lastndl = sample->ndl.seconds = u_sample->hold_time * 60;
sample->stopdepth.mm = 0;
sample->stoptime.seconds = 0;
sample->stopdepth = 0_m;
sample->stoptime = 0_sec;
}
#if UEMIS_DEBUG & 32
printf("%dm:%ds: p_amb_tol:%d surface:%d holdtime:%d holddepth:%d/%d ---> stopdepth:%d stoptime:%d ndl:%d\n",
@ -326,9 +326,9 @@ void uemis::parse_divelog_binary(std::string_view base64, struct dive *dive)
*/
cylinder_t *cyl = dive->get_or_create_cylinder(i);
cyl->type.size.mliter = lrintf(volume);
cyl->type.workingpressure.mbar = 202600;
cyl->type.workingpressure = 202600_mbar;
cyl->gasmix.o2.permille = *(uint8_t *)(data.data() + 120 + 25 * (gasoffset + i)) * 10;
cyl->gasmix.he.permille = 0;
cyl->gasmix.he = 0_percent;
}
/* first byte of divelog data is at offset 0x123 */
size_t i = 0x123;
@ -353,7 +353,7 @@ void uemis::parse_divelog_binary(std::string_view base64, struct dive *dive)
u_sample++;
}
if (sample)
dive->dcs[0].duration = sample->time - duration_t { .seconds = 1 };
dive->dcs[0].duration = sample->time - 1_sec;
/* get data from the footer */
add_extra_data(dc, "FW Version",

View file

@ -120,6 +120,14 @@ struct duration_t : public unit_base<duration_t>
{
int32_t seconds = 0; // durations up to 34 yrs
};
static inline duration_t operator""_sec(unsigned long long sec)
{
return { .seconds = static_cast<int32_t>(sec) };
}
static inline duration_t operator""_min(unsigned long long min)
{
return { .seconds = static_cast<int32_t>(min * 60) };
}
struct offset_t : public unit_base<offset_t>
{
@ -130,16 +138,44 @@ struct depth_t : public unit_base<depth_t> // depth to 2000 km
{
int32_t mm = 0;
};
static inline depth_t operator""_mm(unsigned long long mm)
{
return { .mm = static_cast<int32_t>(mm) };
}
static inline depth_t operator""_m(unsigned long long m)
{
return { .mm = static_cast<int32_t>(m * 1000) };
}
static inline depth_t operator""_ft(unsigned long long ft)
{
return { .mm = static_cast<int32_t>(round(ft * 304.8)) };
}
struct pressure_t : public unit_base<pressure_t>
{
int32_t mbar = 0; // pressure up to 2000 bar
};
static inline pressure_t operator""_mbar(unsigned long long mbar)
{
return { .mbar = static_cast<int32_t>(mbar) };
}
static inline pressure_t operator""_bar(unsigned long long bar)
{
return { .mbar = static_cast<int32_t>(bar * 1000) };
}
static inline pressure_t operator""_atm(unsigned long long atm)
{
return { .mbar = static_cast<int32_t>(round(atm * 1013.25)) };
}
struct o2pressure_t : public unit_base<o2pressure_t>
{
uint16_t mbar = 0;
};
static inline o2pressure_t operator""_baro2(unsigned long long bar)
{
return { .mbar = static_cast<uint16_t>(bar * 1000) };
}
struct bearing_t : public unit_base<bearing_t>
{
@ -150,6 +186,10 @@ struct temperature_t : public unit_base<temperature_t>
{
uint32_t mkelvin = 0; // up to 4 MK (temperatures in K are always positive)
};
static inline temperature_t operator""_K(unsigned long long K)
{
return { .mkelvin = static_cast<uint32_t>(K * 1000) };
}
struct temperature_sum_t : public unit_base<temperature_sum_t>
{
@ -160,11 +200,27 @@ struct volume_t : public unit_base<volume_t>
{
int mliter = 0;
};
static inline volume_t operator""_ml(unsigned long long ml)
{
return { .mliter = static_cast<int>(ml) };
}
static inline volume_t operator""_l(unsigned long long l)
{
return { .mliter = static_cast<int>(l * 1000) };
}
struct fraction_t : public unit_base<fraction_t>
{
int permille = 0;
};
static inline fraction_t operator""_permille(unsigned long long permille)
{
return { .permille = static_cast<int>(permille) };
}
static inline fraction_t operator""_percent(unsigned long long percent)
{
return { .permille = static_cast<int>(percent * 10) };
}
struct weight_t : public unit_base<weight_t>
{

View file

@ -345,7 +345,7 @@ void ProfileWidget::exitEditMode()
// Update depths of edited dive
static void calcDepth(dive &d, int dcNr)
{
d.maxdepth.mm = d.get_dc(dcNr)->maxdepth.mm = 0;
d.maxdepth = d.get_dc(dcNr)->maxdepth = 0_m;
divelog.dives.fixup_dive(d);
}

View file

@ -460,7 +460,7 @@ void TabDiveInformation::updateTextBox(int event) // Either the text box has bee
setIndexNoSignal(ui->atmPressType, 0); // reset combobox to mbar
break;
default:
atmpress.mbar = 1013; // This line should never execute
atmpress = 1_atm; // This line should never execute
break;
}
if (atmpress.mbar)

View file

@ -1379,7 +1379,7 @@ void QMLManager::commitChanges(QString diveId, QString number, QString date, QSt
// let's create an actual profile so the desktop version can work it
// first clear out the mean depth (or the fake_dc() function tries
// to be too clever)
d->meandepth.mm = d->dcs[0].meandepth.mm = 0;
d->meandepth = d->dcs[0].meandepth = 0_m;
fake_dc(&d->dcs[0]);
}
divelog.dives.fixup_dive(*d);

View file

@ -551,7 +551,7 @@ void ProfileScene::plotDive(const struct dive *dIn, int dcIn, DivePlannerPointsM
// while all other items are up there on the constructor.
qDeleteAll(eventItems);
eventItems.clear();
struct gasmix lastgasmix = d->get_gasmix_at_time(*currentdc, duration_t{ .seconds = 1 });
struct gasmix lastgasmix = d->get_gasmix_at_time(*currentdc, 1_sec);
for (auto [idx, event]: enumerated_range(currentdc->events)) {
// if print mode is selected only draw headings, SP change, gas events or bookmark event

View file

@ -149,7 +149,6 @@ void DivePlannerPointsModel::loadFromDive(dive *dIn, int dcNrIn)
int j = 0;
int cylinderid = 0;
last_sp.mbar = 0;
divemode_loop loop(*dc);
for (int i = 0; i < plansamples - 1; i++) {
if (dc->last_manual_time.seconds && dc->last_manual_time.seconds > 120 && lasttime.seconds >= dc->last_manual_time.seconds)
@ -216,7 +215,7 @@ void DivePlannerPointsModel::setupCylinders()
bool DivePlannerPointsModel::updateMaxDepth()
{
int prevMaxDepth = d->maxdepth.mm;
d->maxdepth.mm = 0;
d->maxdepth = 0_m;
for (int i = 0; i < rowCount(); i++) {
divedatapoint p = at(i);
if (p.depth.mm > d->maxdepth.mm)
@ -1069,7 +1068,7 @@ bool DivePlannerPointsModel::tankInUse(int cylinderid) const
void DivePlannerPointsModel::clear()
{
cylinders.clear();
preserved_until.seconds = 0;
preserved_until = 0_sec;
beginResetModel();
divepoints.clear();
endResetModel();
@ -1223,16 +1222,16 @@ void DivePlannerPointsModel::computeVariations(std::unique_ptr<struct diveplan>
int my_instance = ++instanceCounter;
save.cache(&ds);
duration_t delta_time = { .seconds = 60 };
duration_t delta_time = 1_min;
QString time_units = tr("min");
depth_t delta_depth;
QString depth_units;
if (prefs.units.length == units::METERS) {
delta_depth.mm = 1000; // 1m
delta_depth = 1_m;
depth_units = tr("m");
} else {
delta_depth.mm = feet_to_mm(1.0); // 1ft
delta_depth = 1_ft;
depth_units = tr("ft");
}

View file

@ -978,7 +978,7 @@ void smartrak_import(const char *file, struct divelog *log)
if (tmptank->gasmix.he.permille == 0)
tmptank->gasmix.he.permille = lrint(strtod((char *)col[i + hefraccol]->bind_ptr, NULL) * 10);
} else {
tmptank->gasmix.he.permille = 0;
tmptank->gasmix.he = 0_percent;
}
smtk_build_tank_info(mdb_clon, tmptank, (char *)col[i + tankidxcol]->bind_ptr);
}

View file

@ -19,8 +19,8 @@ void TestformatDiveGasString::test_air()
struct dive dive;
cylinder_t *cylinder = dive.get_or_create_cylinder(0);
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
QCOMPARE(formatDiveGasString(&dive), "air");
}
@ -30,9 +30,9 @@ void TestformatDiveGasString::test_nitrox()
struct dive dive;
cylinder_t *cylinder = dive.get_or_create_cylinder(0);
cylinder->gasmix.o2.permille = 320;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 32_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
QCOMPARE(formatDiveGasString(&dive), "32%");
}
@ -42,16 +42,16 @@ void TestformatDiveGasString::test_nitrox_not_use()
struct dive dive;
cylinder_t *cylinder = dive.get_or_create_cylinder(0);
cylinder->gasmix.o2.permille = 320;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 32_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
cylinder = dive.get_or_create_cylinder(1);
cylinder->gasmix.o2.permille = 1000;
cylinder->gasmix.o2 = 100_percent;
cylinder->cylinder_use = NOT_USED;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
QCOMPARE(formatDiveGasString(&dive), "32%");
}
@ -61,15 +61,15 @@ void TestformatDiveGasString::test_nitrox_deco()
struct dive dive;
cylinder_t *cylinder = dive.get_or_create_cylinder(0);
cylinder->gasmix.o2.permille = 320;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 32_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
cylinder = dive.get_or_create_cylinder(1);
cylinder->gasmix.o2.permille = 1000;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 100_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
QCOMPARE(formatDiveGasString(&dive), "32…100%");
}
@ -79,15 +79,15 @@ void TestformatDiveGasString::test_reverse_nitrox_deco()
struct dive dive;
cylinder_t *cylinder = dive.get_or_create_cylinder(0);
cylinder->gasmix.o2.permille = 1000;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 100_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
cylinder = dive.get_or_create_cylinder(1);
cylinder->gasmix.o2.permille = 270;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 27_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
QCOMPARE(formatDiveGasString(&dive), "27…100%");
}
@ -97,10 +97,10 @@ void TestformatDiveGasString::test_trimix()
struct dive dive;
cylinder_t *cylinder = dive.get_or_create_cylinder(0);
cylinder->gasmix.o2.permille = 210;
cylinder->gasmix.he.permille = 350;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 21_percent;
cylinder->gasmix.he = 35_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
QCOMPARE(formatDiveGasString(&dive), "21/35");
}
@ -110,23 +110,23 @@ void TestformatDiveGasString::test_trimix_deco()
struct dive dive;
cylinder_t *cylinder = dive.get_or_create_cylinder(0);
cylinder->gasmix.o2.permille = 210;
cylinder->gasmix.he.permille = 350;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 21_percent;
cylinder->gasmix.he = 35_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
cylinder = dive.get_or_create_cylinder(1);
cylinder->gasmix.o2.permille = 500;
cylinder->gasmix.he.permille = 200;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 50_percent;
cylinder->gasmix.he = 20_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
cylinder = dive.get_or_create_cylinder(2);
cylinder->gasmix.o2.permille = 1000;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 100_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
QCOMPARE(formatDiveGasString(&dive), "21/35…100%");
}
@ -136,23 +136,23 @@ void TestformatDiveGasString::test_reverse_trimix_deco()
struct dive dive;
cylinder_t *cylinder = dive.get_or_create_cylinder(0);
cylinder->gasmix.o2.permille = 1000;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 100_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
cylinder = dive.get_or_create_cylinder(1);
cylinder->gasmix.o2.permille = 500;
cylinder->gasmix.he.permille = 200;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 50_percent;
cylinder->gasmix.he = 20_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
cylinder = dive.get_or_create_cylinder(2);
cylinder->gasmix.o2.permille = 210;
cylinder->gasmix.he.permille = 350;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 21_percent;
cylinder->gasmix.he = 35_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
QCOMPARE(formatDiveGasString(&dive), "21/35…100%");
}
@ -162,17 +162,17 @@ void TestformatDiveGasString::test_trimix_and_nitrox_same_o2()
struct dive dive;
cylinder_t *cylinder = dive.get_or_create_cylinder(0);
cylinder->gasmix.o2.permille = 250;
cylinder->gasmix.he.permille = 0;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 25_percent;
cylinder->gasmix.he = 0_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
cylinder = dive.get_or_create_cylinder(1);
cylinder->gasmix.o2.permille = 250;
cylinder->gasmix.he.permille = 250;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 25_percent;
cylinder->gasmix.he = 25_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
QCOMPARE(formatDiveGasString(&dive), "25/25");
}
@ -182,17 +182,17 @@ void TestformatDiveGasString::test_trimix_and_nitrox_lower_o2()
struct dive dive;
cylinder_t *cylinder = dive.get_or_create_cylinder(0);
cylinder->gasmix.o2.permille = 220;
cylinder->gasmix.he.permille = 0;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 22_percent;
cylinder->gasmix.he = 0_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
cylinder = dive.get_or_create_cylinder(1);
cylinder->gasmix.o2.permille = 250;
cylinder->gasmix.he.permille = 250;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 25_percent;
cylinder->gasmix.he = 25_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
QCOMPARE(formatDiveGasString(&dive), "25/25");
}
@ -202,18 +202,18 @@ void TestformatDiveGasString::test_ccr()
struct dive dive;
cylinder_t *cylinder = dive.get_or_create_cylinder(0);
cylinder->gasmix.o2.permille = 1000;
cylinder->gasmix.o2 = 100_percent;
cylinder->cylinder_use = OXYGEN;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
cylinder = dive.get_or_create_cylinder(1);
cylinder->gasmix.o2.permille = 210;
cylinder->gasmix.he.permille = 350;
cylinder->gasmix.o2 = 21_percent;
cylinder->gasmix.he = 35_percent;
cylinder->cylinder_use = DILUENT;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
QCOMPARE(formatDiveGasString(&dive), "21/35");
}
@ -223,25 +223,25 @@ void TestformatDiveGasString::test_ccr_bailout()
struct dive dive;
cylinder_t *cylinder = dive.get_or_create_cylinder(0);
cylinder->gasmix.o2.permille = 1000;
cylinder->gasmix.o2 = 100_percent;
cylinder->cylinder_use = OXYGEN;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
cylinder = dive.get_or_create_cylinder(1);
cylinder->gasmix.o2.permille = 220;
cylinder->gasmix.he.permille = 200;
cylinder->gasmix.o2 = 22_percent;
cylinder->gasmix.he = 20_percent;
cylinder->cylinder_use = DILUENT;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
cylinder = dive.get_or_create_cylinder(2);
cylinder->gasmix.o2.permille = 210;
cylinder->gasmix.he.permille = 0;
cylinder->start.mbar = 230000;
cylinder->end.mbar = 100000;
cylinder->gasmix.o2 = 21_percent;
cylinder->gasmix.he = 0_percent;
cylinder->start = 230_bar;
cylinder->end = 100_bar;
QCOMPARE(formatDiveGasString(&dive), "22/20");
}

View file

@ -47,10 +47,10 @@ diveplan setupPlan()
dp.bottomsac = prefs.bottomsac;
dp.decosac = prefs.decosac;
struct gasmix bottomgas = {{.permille = 150}, {.permille = 450}};
struct gasmix ean36 = {{.permille = 360}, {}};
struct gasmix oxygen = {{.permille = 1000}, {}};
pressure_t po2 = {.mbar = 1600};
struct gasmix bottomgas = { 15_percent, 45_percent};
struct gasmix ean36 = { 36_percent, 0_percent};
struct gasmix oxygen = { 100_percent, 0_percent};
pressure_t po2 = 1600_mbar;;
// Note: we add the highest-index cylinder first, because
// pointers to cylinders are not stable when reallocating.
// For testing OK - don't do this in actual code!
@ -58,8 +58,8 @@ diveplan setupPlan()
cylinder_t *cyl0 = dive.get_or_create_cylinder(0);
cylinder_t *cyl1 = dive.get_or_create_cylinder(1);
cyl0->gasmix = bottomgas;
cyl0->type.size.mliter = 36000;
cyl0->type.workingpressure.mbar = 232000;
cyl0->type.size = 36_l;
cyl0->type.workingpressure = 232_bar;
cyl1->gasmix = ean36;
cyl2->gasmix = oxygen;
reset_cylinders(&dive, true);
@ -82,10 +82,10 @@ diveplan setupPlanVpmb45m30mTx()
dp.bottomsac = prefs.bottomsac;
dp.decosac = prefs.decosac;
struct gasmix bottomgas = {{.permille = 210}, {.permille = 350}};
struct gasmix ean50 = {{.permille = 500}, {}};
struct gasmix oxygen = {{.permille = 1000}, {}};
pressure_t po2 = {.mbar = 1600};
struct gasmix bottomgas = { 21_percent, 35_percent};
struct gasmix ean50 = { 50_percent, 0_percent};
struct gasmix oxygen = { 100_percent, 0_percent};
pressure_t po2 = 1600_mbar;
// Note: we add the highest-index cylinder first, because
// pointers to cylinders are not stable when reallocating.
// For testing OK - don't do this in actual code!
@ -93,8 +93,8 @@ diveplan setupPlanVpmb45m30mTx()
cylinder_t *cyl0 = dive.get_or_create_cylinder(0);
cylinder_t *cyl1 = dive.get_or_create_cylinder(1);
cyl0->gasmix = bottomgas;
cyl0->type.size.mliter = 24000;
cyl0->type.workingpressure.mbar = 232000;
cyl0->type.size = 24_l;
cyl0->type.workingpressure = 232_bar;
cyl1->gasmix = ean50;
cyl2->gasmix = oxygen;
reset_cylinders(&dive, true);
@ -117,10 +117,10 @@ diveplan setupPlanVpmb60m10mTx()
dp.bottomsac = prefs.bottomsac;
dp.decosac = prefs.decosac;
struct gasmix bottomgas = {{.permille = 180}, {.permille = 450}};
struct gasmix tx50_15 = {{.permille = 500}, {.permille = 150}};
struct gasmix oxygen = {{.permille = 1000}, {}};
pressure_t po2 = {.mbar = 1600};
struct gasmix bottomgas = { 18_percent, 45_percent };
struct gasmix tx50_15 = { 50_percent, 15_percent };
struct gasmix oxygen = { 100_percent, 0_percent };
pressure_t po2 = 1600_mbar;
// Note: we add the highest-index cylinder first, because
// pointers to cylinders are not stable when reallocating.
// For testing OK - don't do this in actual code!
@ -128,8 +128,8 @@ diveplan setupPlanVpmb60m10mTx()
cylinder_t *cyl0 = dive.get_or_create_cylinder(0);
cylinder_t *cyl1 = dive.get_or_create_cylinder(1);
cyl0->gasmix = bottomgas;
cyl0->type.size.mliter = 24000;
cyl0->type.workingpressure.mbar = 232000;
cyl0->type.size = 24_l;
cyl0->type.workingpressure = 232_bar;
cyl1->gasmix = tx50_15;
cyl2->gasmix = oxygen;
reset_cylinders(&dive, true);
@ -150,12 +150,12 @@ diveplan setupPlanVpmb60m30minAir()
dp.bottomsac = prefs.bottomsac;
dp.decosac = prefs.decosac;
struct gasmix bottomgas = {{.permille = 210}, {}};
struct gasmix bottomgas = { 21_percent, 0_percent};
cylinder_t *cyl0 = dive.get_or_create_cylinder(0);
cyl0->gasmix = bottomgas;
cyl0->type.size.mliter = 100000;
cyl0->type.workingpressure.mbar = 232000;
dive.surface_pressure.mbar = 1013;
cyl0->type.size = 100_l;
cyl0->type.workingpressure = 232_bar;
dive.surface_pressure = 1_atm;
reset_cylinders(&dive, true);
int droptime = M_OR_FT(60, 200) * 60 / M_OR_FT(99, 330);
@ -172,19 +172,19 @@ diveplan setupPlanVpmb60m30minEan50()
dp.bottomsac = prefs.bottomsac;
dp.decosac = prefs.decosac;
struct gasmix bottomgas = {{.permille = 210}, {}};
struct gasmix ean50 = {{.permille = 500}, {}};
pressure_t po2 = {.mbar = 1600};
struct gasmix bottomgas = { 21_percent, 0_percent };
struct gasmix ean50 = { 50_percent, 0_percent };
pressure_t po2 = 1600_mbar;
// Note: we add the highest-index cylinder first, because
// pointers to cylinders are not stable when reallocating.
// For testing OK - don't do this in actual code!
cylinder_t *cyl1 = dive.get_or_create_cylinder(1);
cylinder_t *cyl0 = dive.get_or_create_cylinder(0);
cyl0->gasmix = bottomgas;
cyl0->type.size.mliter = 36000;
cyl0->type.workingpressure.mbar = 232000;
cyl0->type.size = 36_l;
cyl0->type.workingpressure = 232_bar;
cyl1->gasmix = ean50;
dive.surface_pressure.mbar = 1013;
dive.surface_pressure = 1_atm;
reset_cylinders(&dive, true);
int droptime = M_OR_FT(60, 200) * 60 / M_OR_FT(99, 330);
@ -202,19 +202,19 @@ diveplan setupPlanVpmb60m30minTx()
dp.bottomsac = prefs.bottomsac;
dp.decosac = prefs.decosac;
struct gasmix bottomgas = {{.permille = 180}, {.permille = 450}};
struct gasmix ean50 = {{.permille = 500}, {}};
pressure_t po2 = {.mbar = 1600};
struct gasmix bottomgas = { 18_percent, 45_percent };
struct gasmix ean50 = { 50_percent, 0_percent };
pressure_t po2 = 1600_mbar;
// Note: we add the highest-index cylinder first, because
// pointers to cylinders are not stable when reallocating.
// For testing OK - don't do this in actual code!
cylinder_t *cyl1 = dive.get_or_create_cylinder(1);
cylinder_t *cyl0 = dive.get_or_create_cylinder(0);
cyl0->gasmix = bottomgas;
cyl0->type.size.mliter = 36000;
cyl0->type.workingpressure.mbar = 232000;
cyl0->type.size = 36_l;
cyl0->type.workingpressure = 232_bar;
cyl1->gasmix = ean50;
dive.surface_pressure.mbar = 1013;
dive.surface_pressure = 1_atm;
reset_cylinders(&dive, true);
int droptime = M_OR_FT(60, 200) * 60 / M_OR_FT(99, 330);
@ -232,12 +232,12 @@ diveplan setupPlanVpmbMultiLevelAir()
dp.bottomsac = prefs.bottomsac;
dp.decosac = prefs.decosac;
struct gasmix bottomgas = {{.permille = 210}, {}};
struct gasmix bottomgas = { 21_percent, 0_percent };
cylinder_t *cyl0 = dive.get_or_create_cylinder(0);
cyl0->gasmix = bottomgas;
cyl0->type.size.mliter = 200000;
cyl0->type.workingpressure.mbar = 232000;
dive.surface_pressure.mbar = 1013;
cyl0->type.size = 200_l;
cyl0->type.workingpressure = 232_bar;
dive.surface_pressure = 1_atm;
reset_cylinders(&dive, true);
int droptime = M_OR_FT(20, 66) * 60 / M_OR_FT(99, 330);
@ -256,10 +256,10 @@ diveplan setupPlanVpmb100m60min()
dp.bottomsac = prefs.bottomsac;
dp.decosac = prefs.decosac;
struct gasmix bottomgas = {{.permille = 180}, {.permille = 450}};
struct gasmix ean50 = {{.permille = 500}, {}};
struct gasmix oxygen = {{.permille = 1000}, {}};
pressure_t po2 = {.mbar = 1600};
struct gasmix bottomgas = { 18_percent, 45_percent };
struct gasmix ean50 = { 50_percent, 0_percent };
struct gasmix oxygen = { 100_percent, 0_percent };
pressure_t po2 = 1600_mbar;
// Note: we add the highest-index cylinder first, because
// pointers to cylinders are not stable when reallocating.
// For testing OK - don't do this in actual code!
@ -267,11 +267,11 @@ diveplan setupPlanVpmb100m60min()
cylinder_t *cyl0 = dive.get_or_create_cylinder(0);
cylinder_t *cyl1 = dive.get_or_create_cylinder(1);
cyl0->gasmix = bottomgas;
cyl0->type.size.mliter = 200000;
cyl0->type.workingpressure.mbar = 232000;
cyl0->type.size = 200_l;
cyl0->type.workingpressure = 232_bar;
cyl1->gasmix = ean50;
cyl2->gasmix = oxygen;
dive.surface_pressure.mbar = 1013;
dive.surface_pressure = 1_atm;
reset_cylinders(&dive, true);
int droptime = M_OR_FT(100, 330) * 60 / M_OR_FT(99, 330);
@ -290,10 +290,10 @@ diveplan setupPlanVpmb100m10min()
dp.bottomsac = prefs.bottomsac;
dp.decosac = prefs.decosac;
struct gasmix bottomgas = {{.permille = 180}, {.permille = 450}};
struct gasmix ean50 = {{.permille = 500}, {}};
struct gasmix oxygen = {{.permille = 1000}, {}};
pressure_t po2 = {.mbar = 1600};
struct gasmix bottomgas = { 18_percent, 45_percent };
struct gasmix ean50 = { 50_percent, 0_percent};
struct gasmix oxygen = { 100_percent, 0_percent};
pressure_t po2 = 1600_mbar;
// Note: we add the highest-index cylinder first, because
// pointers to cylinders are not stable when reallocating.
// For testing OK - don't do this in actual code!
@ -301,11 +301,11 @@ diveplan setupPlanVpmb100m10min()
cylinder_t *cyl0 = dive.get_or_create_cylinder(0);
cylinder_t *cyl1 = dive.get_or_create_cylinder(1);
cyl0->gasmix = bottomgas;
cyl0->type.size.mliter = 60000;
cyl0->type.workingpressure.mbar = 232000;
cyl0->type.size = 60_l;
cyl0->type.workingpressure = 232_bar;
cyl1->gasmix = ean50;
cyl2->gasmix = oxygen;
dive.surface_pressure.mbar = 1013;
dive.surface_pressure = 1_atm;
reset_cylinders(&dive, true);
int droptime = M_OR_FT(100, 330) * 60 / M_OR_FT(99, 330);
@ -324,12 +324,12 @@ diveplan setupPlanVpmb30m20min()
dp.bottomsac = prefs.bottomsac;
dp.decosac = prefs.decosac;
struct gasmix bottomgas = {{.permille = 210}, {}};
struct gasmix bottomgas = { 21_percent, 0_percent };
cylinder_t *cyl0 = dive.get_or_create_cylinder(0);
cyl0->gasmix = bottomgas;
cyl0->type.size.mliter = 36000;
cyl0->type.workingpressure.mbar = 232000;
dive.surface_pressure.mbar = 1013;
cyl0->type.size = 36_l;
cyl0->type.workingpressure = 232_bar;
dive.surface_pressure = 1_atm;
reset_cylinders(&dive, true);
int droptime = M_OR_FT(30, 100) * 60 / M_OR_FT(18, 60);
@ -346,11 +346,11 @@ diveplan setupPlanVpmb100mTo70m30min()
dp.bottomsac = prefs.bottomsac;
dp.decosac = prefs.decosac;
struct gasmix bottomgas = {{.permille = 120}, {.permille = 650}};
struct gasmix tx21_35 = {{.permille = 210}, {.permille = 350}};
struct gasmix ean50 = {{.permille = 500}, {}};
struct gasmix oxygen = {{.permille = 1000}, {}};
pressure_t po2 = {.mbar = 1600};
struct gasmix bottomgas = { 12_percent, 65_percent };
struct gasmix tx21_35 = { 21_percent, 35_percent };
struct gasmix ean50 = { 50_percent, 0_percent };
struct gasmix oxygen = { 100_percent, 0_percent };
pressure_t po2 = 1600_mbar;
// Note: we add the highest-index cylinder first, because
// pointers to cylinders are not stable when reallocating.
// For testing OK - don't do this in actual code!
@ -359,12 +359,12 @@ diveplan setupPlanVpmb100mTo70m30min()
cylinder_t *cyl1 = dive.get_or_create_cylinder(1);
cylinder_t *cyl2 = dive.get_or_create_cylinder(2);
cyl0->gasmix = bottomgas;
cyl0->type.size.mliter = 36000;
cyl0->type.workingpressure.mbar = 232000;
cyl0->type.size = 36_l;
cyl0->type.workingpressure = 232_bar;
cyl1->gasmix = tx21_35;
cyl2->gasmix = ean50;
cyl3->gasmix = oxygen;
dive.surface_pressure.mbar = 1013;
dive.surface_pressure = 1_atm;
reset_cylinders(&dive, true);
int droptime = M_OR_FT(100, 330) * 60 / M_OR_FT(18, 60);
@ -388,8 +388,8 @@ diveplan setupPlanSeveralGases()
dp.bottomsac = prefs.bottomsac;
dp.decosac = prefs.decosac;
struct gasmix ean36 = {{.permille = 360}, {}};
struct gasmix tx11_50 = {{.permille = 110}, {.permille = 500}};
struct gasmix ean36 = { 36_percent, 0_percent };
struct gasmix tx11_50 = { 11_percent, 50_percent };
// Note: we add the highest-index cylinder first, because
// pointers to cylinders are not stable when reallocating.
@ -397,10 +397,10 @@ diveplan setupPlanSeveralGases()
cylinder_t *cyl1 = dive.get_or_create_cylinder(1);
cylinder_t *cyl0 = dive.get_or_create_cylinder(0);
cyl0->gasmix = ean36;
cyl0->type.size.mliter = 36000;
cyl0->type.workingpressure.mbar = 232000;
cyl0->type.size = 36_l;
cyl0->type.workingpressure = 232_bar;
cyl1->gasmix = tx11_50;
dive.surface_pressure.mbar = 1013;
dive.surface_pressure = 1_atm;
reset_cylinders(&dive, true);
plan_add_segment(dp, 120, 40000, 0, 0, true, OC);
@ -420,10 +420,10 @@ diveplan setupPlanCcr()
dp.bottomsac = prefs.bottomsac;
dp.decosac = prefs.decosac;
pressure_t po2 = {.mbar = 1600};
struct gasmix diluent = {{.permille = 200}, {.permille = 210}};
struct gasmix ean53 = {{.permille = 530}, {}};
struct gasmix tx19_33 = {{.permille = 190}, {.permille = 330}};
pressure_t po2 = 1600_mbar;
struct gasmix diluent = { 20_percent, 21_percent};
struct gasmix ean53 = { 53_percent, 0_percent};
struct gasmix tx19_33 = { 19_percent, 33_percent};
// Note: we add the highest-index cylinder first, because
// pointers to cylinders are not stable when reallocating.
// For testing OK - don't do this in actual code!
@ -432,8 +432,8 @@ diveplan setupPlanCcr()
cylinder_t *cyl1 = dive.get_or_create_cylinder(1);
cyl0->gasmix = diluent;
cyl0->depth = dive.gas_mod(diluent, po2, M_OR_FT(3, 10));
cyl0->type.size.mliter = 3000;
cyl0->type.workingpressure.mbar = 200000;
cyl0->type.size = 3_l;
cyl0->type.workingpressure = 200_bar;
cyl0->cylinder_use = DILUENT;
cyl1->gasmix = ean53;
cyl1->depth = dive.gas_mod(ean53, po2, M_OR_FT(3, 10));
@ -754,7 +754,7 @@ void TestPlan::testMultipleGases()
save_dive(stdout, dive, false);
#endif
gasmix gas = dive.get_gasmix_at_time(dive.dcs[0], {.seconds = 20 * 60 + 1});
gasmix gas = dive.get_gasmix_at_time(dive.dcs[0], 20_min + 1_sec);
QCOMPARE(get_o2(gas), 110);
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 2480u, 2480u));
}
@ -934,17 +934,17 @@ void TestPlan::testCcrBailoutGasSelection()
#endif
// check diluent used
cylinder_t *cylinder = dive.get_cylinder(get_cylinderid_at_time(&dive, &dive.dcs[0], { .seconds = 20 * 60 - 1 }));
cylinder_t *cylinder = dive.get_cylinder(get_cylinderid_at_time(&dive, &dive.dcs[0], 20_min - 1_sec));
QCOMPARE(cylinder->cylinder_use, DILUENT);
QCOMPARE(get_o2(cylinder->gasmix), 200);
// check deep bailout used
cylinder = dive.get_cylinder(get_cylinderid_at_time(&dive, &dive.dcs[0], { .seconds = 20 * 60 + 1 }));
cylinder = dive.get_cylinder(get_cylinderid_at_time(&dive, &dive.dcs[0], 20_min + 1_sec));
QCOMPARE(cylinder->cylinder_use, OC_GAS);
QCOMPARE(get_o2(cylinder->gasmix), 190);
// check shallow bailout used
cylinder = dive.get_cylinder(get_cylinderid_at_time(&dive, &dive.dcs[0], { .seconds = 30 * 60 }));
cylinder = dive.get_cylinder(get_cylinderid_at_time(&dive, &dive.dcs[0], 30_min));
QCOMPARE(cylinder->cylinder_use, OC_GAS);
QCOMPARE(get_o2(cylinder->gasmix), 530);

View file

@ -17,7 +17,7 @@ void TestUnitConversion::testUnitConversions()
QCOMPARE(C_to_mkelvin(373.85), 647000UL);
QCOMPARE(nearly_equal(psi_to_bar(14.6959488), 1.01325), true);
QCOMPARE(psi_to_mbar(14.6959488), 1013L);
QCOMPARE(nearly_equal(to_PSI(pressure_t{ .mbar = 1013}), 14.6923228594), true);
QCOMPARE(nearly_equal(to_PSI(1_atm), 14.6923228594), true);
QCOMPARE(nearly_equal(bar_to_atm(1.013), 1.0), true);
QCOMPARE(nearly_equal(mbar_to_atm(1013), 1.0), true);
QCOMPARE(nearly_equal(mbar_to_PSI(1013), 14.6923228594), true);