core: replace divesite_table_t by a vector of std::unique_ptr<>s

This is a long commit, because it introduces a new abstraction:
a general std::vector<> of std::unique_ptrs<>.

Moreover, it replaces a number of pointers by C++ references,
when the callee does not suppoert null objects.

This simplifies memory management and makes ownership more
explicit. It is a proof-of-concept and a test-bed for
the other core data structrures.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-05-11 11:47:45 +02:00 committed by bstoeger
parent 411188728d
commit e39dea3d68
41 changed files with 451 additions and 426 deletions

View file

@ -2,9 +2,10 @@
#ifndef DIVESITE_H
#define DIVESITE_H
#include "units.h"
#include "taxonomy.h"
#include "divelist.h"
#include "owning_table.h"
#include "taxonomy.h"
#include "units.h"
#include <stdlib.h>
#include <QObject>
@ -21,52 +22,39 @@ struct dive_site
dive_site();
dive_site(const std::string &name);
dive_site(const std::string &name, const location_t *loc);
dive_site(uint32_t uuid);
~dive_site();
};
typedef struct dive_site_table {
int nr, allocated;
struct dive_site **dive_sites;
} dive_site_table_t;
static const dive_site_table_t empty_dive_site_table = { 0, 0, (struct dive_site **)0 };
static inline struct dive_site *get_dive_site(int nr, struct dive_site_table *ds_table)
inline int divesite_comp_uuid(const dive_site &ds1, const dive_site &ds2)
{
if (nr >= ds_table->nr || nr < 0)
return NULL;
return ds_table->dive_sites[nr];
if (ds1.uuid == ds2.uuid)
return 0;
return ds1.uuid < ds2.uuid ? -1 : 1;
}
/* iterate over each dive site */
#define for_each_dive_site(_i, _x, _ds_table) \
for ((_i) = 0; ((_x) = get_dive_site(_i, _ds_table)) != NULL; (_i)++)
class dive_site_table : public sorted_owning_table<dive_site, &divesite_comp_uuid> {
public:
put_result register_site(std::unique_ptr<dive_site> site);
};
int get_divesite_idx(const struct dive_site *ds, struct dive_site_table *ds_table);
struct dive_site *get_dive_site_by_uuid(uint32_t uuid, struct dive_site_table *ds_table);
void sort_dive_site_table(struct dive_site_table *ds_table);
int add_dive_site_to_table(struct dive_site *ds, struct dive_site_table *ds_table);
struct dive_site *alloc_or_get_dive_site(uint32_t uuid, struct dive_site_table *ds_table);
struct dive_site *alloc_dive_site();
int get_divesite_idx(const struct dive_site *ds, dive_site_table &ds_table);
struct dive_site *get_dive_site_by_uuid(uint32_t uuid, dive_site_table &ds_table);
struct dive_site *alloc_or_get_dive_site(uint32_t uuid, dive_site_table &ds_table);
size_t nr_of_dives_at_dive_site(const struct dive_site &ds);
bool is_dive_site_selected(const struct dive_site &ds);
int unregister_dive_site(struct dive_site *ds);
int register_dive_site(struct dive_site *ds);
void delete_dive_site(struct dive_site *ds, struct dive_site_table *ds_table);
struct dive_site *create_dive_site(const std::string &name, struct dive_site_table *ds_table);
struct dive_site *create_dive_site_with_gps(const std::string &name, const location_t *, struct dive_site_table *ds_table);
struct dive_site *get_dive_site_by_name(const std::string &name, struct dive_site_table *ds_table);
struct dive_site *get_dive_site_by_gps(const location_t *, struct dive_site_table *ds_table);
struct dive_site *get_dive_site_by_gps_and_name(const std::string &name, const location_t *, struct dive_site_table *ds_table);
struct dive_site *get_dive_site_by_gps_proximity(const location_t *, int distance, struct dive_site_table *ds_table);
struct dive_site *get_same_dive_site(const struct dive_site *);
struct dive_site *create_dive_site(const std::string &name, dive_site_table &ds_table);
struct dive_site *create_dive_site_with_gps(const std::string &name, const location_t *, dive_site_table &ds_table);
struct dive_site *get_dive_site_by_name(const std::string &name, dive_site_table &ds_table);
struct dive_site *get_dive_site_by_gps(const location_t *, dive_site_table &ds_table);
struct dive_site *get_dive_site_by_gps_and_name(const std::string &name, const location_t *, dive_site_table &ds_table);
struct dive_site *get_dive_site_by_gps_proximity(const location_t *, int distance, dive_site_table &ds_table);
struct dive_site *get_same_dive_site(const struct dive_site &);
bool dive_site_is_empty(struct dive_site *ds);
void merge_dive_site(struct dive_site *a, struct dive_site *b);
unsigned int get_distance(const location_t *loc1, const location_t *loc2);
struct dive_site *find_or_create_dive_site_with_name(const std::string &name, struct dive_site_table *ds_table);
void purge_empty_dive_sites(struct dive_site_table *ds_table);
void clear_dive_site_table(struct dive_site_table *ds_table);
void move_dive_site_table(struct dive_site_table *src, struct dive_site_table *dst);
struct dive_site *find_or_create_dive_site_with_name(const std::string &name, dive_site_table &ds_table);
void purge_empty_dive_sites(dive_site_table &ds_table);
void add_dive_to_dive_site(struct dive *d, struct dive_site *ds);
struct dive_site *unregister_dive_from_dive_site(struct dive *d);
std::string constructLocationTags(const taxonomy_data &taxonomy, bool for_maintab);