From 5cd8859feeb51e5ecc629a1ab39d942ee1bbd818 Mon Sep 17 00:00:00 2001
From: PepMS <jmarti@iri.upc.edu>
Date: Wed, 8 Apr 2020 07:21:03 +0200
Subject: [PATCH] [modification] changed `equal` functions by operators

---
 include/gnss_utils/utils/utils.h |  48 ++-
 src/utils/utils.cpp              | 637 +++++++++++--------------------
 2 files changed, 257 insertions(+), 428 deletions(-)

diff --git a/include/gnss_utils/utils/utils.h b/include/gnss_utils/utils/utils.h
index a4c6598..43556de 100644
--- a/include/gnss_utils/utils/utils.h
+++ b/include/gnss_utils/utils/utils.h
@@ -155,29 +155,45 @@ bool equalArray3d(const T*   array_1,
   return true;
 }
 
-bool equalTime(const gtime_t& time1, const gtime_t& time2);
-
-bool equalObservations(const obsd_t& obs1, const obsd_t& obs2);
-bool equalObservations(const obs_t& obs1, const obs_t& obs2);
-
-bool equalEphemeris(const eph_t& eph1, const eph_t& eph2);
-bool equalGlonassEphemeris(const geph_t& geph1, const geph_t& geph2);
-bool equalSbasEphemeris(const seph_t& seph1, const seph_t& seph2);
-bool equalPreciseEphemeris(const peph_t& peph1, const peph_t& peph2);
-bool equalPreciseClock(const pclk_t& pclk1, const pclk_t& pclk2);
-bool equalAlmanac(const alm_t& alm1, const alm_t& alm2);
-bool equalTecGrid(const tec_t& tec1, const tec_t& tec2);
-bool equalFcb(const fcbd_t& fcbd1, const fcbd_t& fcbd2);
-bool equalEarthRotationParameters(const erp_t& erp1, const erp_t& erp2);
-bool equalNavigations(const nav_t& nav1, const nav_t& nav2);
-
 }  // namespace GnssUtils
 
 bool operator==(const gtime_t& time1, const gtime_t& time2);
 bool operator!=(const gtime_t& time1, const gtime_t& time2);
+
 bool operator==(const obsd_t& obs1, const obsd_t& obs2);
 bool operator!=(const obsd_t& obs1, const obsd_t& obs2);
 bool operator==(const obs_t& obs1, const obs_t& obs2);
 bool operator!=(const obs_t& obs1, const obs_t& obs2);
 
+bool operator==(const eph_t& eph1, const eph_t& eph2);
+bool operator!=(const eph_t& eph1, const eph_t& eph2);
+
+bool operator==(const geph_t& geph1, const geph_t& geph2);
+bool operator!=(const geph_t& geph1, const geph_t& geph2);
+
+bool operator==(const seph_t& seph1, const seph_t& seph2);
+bool operator!=(const seph_t& seph1, const seph_t& seph2);
+
+bool operator==(const peph_t& peph1, const peph_t& peph2);
+bool operator!=(const peph_t& peph1, const peph_t& peph2);
+
+bool operator==(const pclk_t& pclk1, const pclk_t& pclk2);
+bool operator!=(const pclk_t& pclk1, const pclk_t& pclk2);
+
+bool operator==(const alm_t& alm1, const alm_t& alm2);
+bool operator!=(const alm_t& alm1, const alm_t& alm2);
+
+bool operator==(const tec_t& tec1, const tec_t& tec2);
+bool operator!=(const tec_t& tec1, const tec_t& tec2);
+
+bool operator==(const fcbd_t& fcbd1, const fcbd_t& fcbd2);
+bool operator!=(const fcbd_t& fcbd1, const fcbd_t& fcbd2);
+
+bool operator==(const erp_t& erp1, const erp_t& erp2);
+bool operator!=(const erp_t& erp1, const erp_t& erp2);
+
+bool operator==(const nav_t& nav1, const nav_t& nav2);
+bool operator!=(const nav_t& nav1, const nav_t& nav2);
+
+
 #endif  // INCLUDE_GNSS_UTILS_UTILS_UTILS_H_
diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp
index d8167cc..85f109b 100644
--- a/src/utils/utils.cpp
+++ b/src/utils/utils.cpp
@@ -61,456 +61,269 @@ void printArray(std::string _name, float* _array, int size)
   }
 }
 
-bool equalEphemeris(const eph_t& eph1, const eph_t& eph2)
-{
-  if (eph1.sat != eph2.sat)
-    return false;
-  if (eph1.iode != eph2.iode)
-    return false;
-  if (eph1.iodc != eph2.iodc)
-    return false;
-  if (eph1.sva != eph2.sva)
-    return false;
-  if (eph1.svh != eph2.svh)
-    return false;
-  if (eph1.week != eph2.week)
-    return false;
-  if (eph1.code != eph2.code)
-    return false;
-  if (eph1.flag != eph2.flag)
-    return false;
-
-  if (eph1.toe != eph2.toe)
-    return false;
-  if (eph1.toc != eph2.toc)
-    return false;
-  if (eph1.ttr != eph2.ttr)
-    return false;
-
-  if (eph1.A != eph2.A)
-    return false;
-  if (eph1.e != eph2.e)
-    return false;
-  if (eph1.i0 != eph2.i0)
-    return false;
-  if (eph1.OMG0 != eph2.OMG0)
-    return false;
-  if (eph1.omg != eph2.omg)
-    return false;
-  if (eph1.M0 != eph2.M0)
-    return false;
-  if (eph1.deln != eph2.deln)
-    return false;
-  if (eph1.OMGd != eph2.OMGd)
-    return false;
-  if (eph1.idot != eph2.idot)
-    return false;
-  if (eph1.crc != eph2.crc)
-    return false;
-  if (eph1.crs != eph2.crs)
-    return false;
-  if (eph1.cuc != eph2.cuc)
-    return false;
-  if (eph1.cus != eph2.cus)
-    return false;
-  if (eph1.cic != eph2.cic)
-    return false;
-  if (eph1.cis != eph2.cis)
-    return false;
-  if (eph1.toes != eph2.toes)
-    return false;
-  if (eph1.fit != eph2.fit)
-    return false;
-  if (eph1.f0 != eph2.f0)
-    return false;
-  if (eph1.f1 != eph2.f1)
-    return false;
-  if (eph1.f2 != eph2.f2)
-    return false;
-
-  if (!equalArray<double>(eph1.tgd, eph2.tgd, ARRAY_SIZE(eph1.tgd), ARRAY_SIZE(eph2.tgd)))
-    return false;
-
-  if (eph1.Adot != eph2.Adot)
-    return false;
-  if (eph1.ndot != eph2.ndot)
-    return false;
+}  // namespace GnssUtils
 
-  return true;
+bool operator==(const gtime_t& time1, const gtime_t& time2)
+{
+  return (difftime(time1.time, time2.time) == 0.0 && time1.sec == time2.sec);
 }
-
-bool equalGlonassEphemeris(const geph_t& geph1, const geph_t& geph2)
-{
-  if (geph1.sat != geph2.sat)
-    return false;
-  if (geph1.iode != geph2.iode)
-    return false;
-  if (geph1.frq != geph2.frq)
-    return false;
-  if (geph1.svh != geph2.svh)
-    return false;
-  if (geph1.sva != geph2.sva)
-    return false;
-  if (geph1.age != geph2.age)
-    return false;
-
-  if (geph1.toe != geph2.toe)
-    return false;
-  if (geph1.tof != geph2.tof)
-    return false;
-
-  if (!equalArray<double>(geph1.pos, geph2.pos, ARRAY_SIZE(geph1.pos), ARRAY_SIZE(geph2.pos)))
-    return false;
-  if (!equalArray<double>(geph1.vel, geph2.vel, ARRAY_SIZE(geph1.vel), ARRAY_SIZE(geph2.vel)))
-    return false;
-  if (!equalArray<double>(geph1.acc, geph2.acc, ARRAY_SIZE(geph1.acc), ARRAY_SIZE(geph2.acc)))
-    return false;
-
-  if (geph1.taun != geph2.taun)
-    return false;
-  if (geph1.gamn != geph2.gamn)
-    return false;
-  if (geph1.dtaun != geph2.dtaun)
-    return false;
-
-  return true;
+bool operator!=(const gtime_t& time1, const gtime_t& time2)
+{
+  return not(time1 == time2);
 }
 
-bool equalSbasEphemeris(const seph_t& seph1, const seph_t& seph2)
+bool operator==(const obsd_t& obs1, const obsd_t& obs2)
 {
-  if (seph1.sat != seph2.sat)
-    return false;
-
-  if (seph1.t0 != seph2.t0)
-    return false;
-  if (seph1.tof != seph2.tof)
-    return false;
-
-  if (seph1.sva != seph2.sva)
-    return false;
-  if (seph1.svh != seph2.svh)
-    return false;
-
-  if (!equalArray<double>(seph1.pos, seph2.pos, ARRAY_SIZE(seph1.pos), ARRAY_SIZE(seph2.pos)))
-    return false;
-  if (!equalArray<double>(seph1.vel, seph2.vel, ARRAY_SIZE(seph1.vel), ARRAY_SIZE(seph2.vel)))
-    return false;
-  if (!equalArray<double>(seph1.acc, seph2.acc, ARRAY_SIZE(seph1.acc), ARRAY_SIZE(seph2.acc)))
-    return false;
-
-  if (seph1.af0 != seph2.af0)
-    return false;
-  if (seph1.af1 != seph2.af1)
-    return false;
-
-  return true;
+  return obs1.time == obs2.time && obs1.eventime == obs2.eventime && obs1.timevalid == obs2.timevalid &&
+         obs1.sat == obs2.sat && obs1.rcv == obs2.rcv && memcmp(obs1.SNR, obs2.SNR, sizeof(obs1.SNR)) == 0 &&
+         memcmp(obs1.LLI, obs2.LLI, sizeof(obs1.LLI)) == 0 && memcmp(obs1.code, obs2.code, sizeof(obs1.code)) == 0 &&
+         memcmp(obs1.qualL, obs2.qualL, sizeof(obs1.qualL)) == 0 &&
+         memcmp(obs1.qualP, obs2.qualP, sizeof(obs1.qualP)) == 0 && obs1.freq == obs2.freq &&
+         GnssUtils::equalArray<double>(
+             obs1.L, obs2.L, sizeof(obs1.L) / sizeof(obs1.L[0]), sizeof(obs2.L) / sizeof(obs2.L[0])) &&
+         GnssUtils::equalArray<double>(
+             obs1.P, obs2.P, sizeof(obs1.P) / sizeof(obs1.P[0]), sizeof(obs2.P) / sizeof(obs2.P[0])) &&
+         GnssUtils::equalArray<float>(
+             obs1.D, obs2.D, sizeof(obs1.D) / sizeof(obs1.D[0]), sizeof(obs2.D) / sizeof(obs2.D[0]));
 }
-
-bool equalPreciseEphemeris(const peph_t& peph1, const peph_t& peph2)
+bool operator!=(const obsd_t& obs1, const obsd_t& obs2)
 {
-  if (peph1.time != peph2.time)
-    return false;
-
-  if (peph1.index != peph2.index)
-    return false;
-
-  if (!equalArray2d<double>(&peph1.pos[0][0],
-                            &peph2.pos[0][0],
-                            ARRAY2D_NROWS(peph1.pos),
-                            ARRAY2D_NCOLS(peph1.pos),
-                            ARRAY2D_NROWS(peph2.pos),
-                            ARRAY2D_NCOLS(peph2.pos)))
-    return false;
-  if (!equalArray2d<float>(&peph1.std[0][0],
-                           &peph2.std[0][0],
-                           ARRAY2D_NROWS(peph1.std),
-                           ARRAY2D_NCOLS(peph1.std),
-                           ARRAY2D_NROWS(peph2.std),
-                           ARRAY2D_NCOLS(peph2.std)))
-    return false;
-  if (!equalArray2d<double>(&peph1.vel[0][0],
-                            &peph2.vel[0][0],
-                            ARRAY2D_NROWS(peph1.vel),
-                            ARRAY2D_NCOLS(peph1.vel),
-                            ARRAY2D_NROWS(peph2.vel),
-                            ARRAY2D_NCOLS(peph2.vel)))
-    return false;
-  if (!equalArray2d<float>(&peph1.vst[0][0],
-                           &peph2.vst[0][0],
-                           ARRAY2D_NROWS(peph1.vst),
-                           ARRAY2D_NCOLS(peph1.vst),
-                           ARRAY2D_NROWS(peph2.vst),
-                           ARRAY2D_NCOLS(peph2.vst)))
-    return false;
-  if (!equalArray2d<float>(&peph1.cov[0][0],
-                           &peph2.cov[0][0],
-                           ARRAY2D_NROWS(peph1.cov),
-                           ARRAY2D_NCOLS(peph1.cov),
-                           ARRAY2D_NROWS(peph2.cov),
-                           ARRAY2D_NCOLS(peph2.cov)))
-    return false;
-  if (!equalArray2d<float>(&peph1.vco[0][0],
-                           &peph2.vco[0][0],
-                           ARRAY2D_NROWS(peph1.vco),
-                           ARRAY2D_NCOLS(peph1.vco),
-                           ARRAY2D_NROWS(peph2.vco),
-                           ARRAY2D_NCOLS(peph2.vco)))
-    return false;
-
-  return true;
+  return not(obs1 == obs2);
 }
 
-bool equalPreciseClock(const pclk_t& pclk1, const pclk_t& pclk2)
+bool operator==(const obs_t& obs1, const obs_t& obs2)
 {
-  if (pclk1.time != pclk2.time)
-    return false;
-
-  if (pclk1.index != pclk2.index)
-    return false;
-
-  if (!equalArray2d<double>(&pclk1.clk[0][0],
-                            &pclk2.clk[0][0],
-                            ARRAY2D_NROWS(pclk1.clk),
-                            ARRAY2D_NCOLS(pclk1.clk),
-                            ARRAY2D_NROWS(pclk2.clk),
-                            ARRAY2D_NCOLS(pclk2.clk)))
-    return false;
-  if (!equalArray2d<float>(&pclk1.std[0][0],
-                           &pclk2.std[0][0],
-                           ARRAY2D_NROWS(pclk1.std),
-                           ARRAY2D_NCOLS(pclk1.std),
-                           ARRAY2D_NROWS(pclk2.std),
-                           ARRAY2D_NCOLS(pclk2.std)))
-    return false;
-
-  return true;
+  return obs1.n == obs2.n && obs1.nmax == obs2.nmax && obs1.flag == obs2.flag && obs1.rcvcount == obs2.rcvcount &&
+         obs1.tmcount == obs2.tmcount && *(obs1.data) == *(obs2.data);
 }
-bool equalAlmanac(const alm_t& alm1, const alm_t& alm2)
-{
-  if (alm1.sat != alm2.sat)
-    return false;
-  if (alm1.svh != alm2.svh)
-    return false;
-  if (alm1.svconf != alm2.svconf)
-    return false;
-  if (alm1.week != alm2.week)
-    return false;
-
-  if (alm1.toa != alm2.toa)
-    return false;
-
-  if (alm1.A != alm2.A)
-    return false;
-  if (alm1.e != alm2.e)
-    return false;
-  if (alm1.i0 != alm2.i0)
-    return false;
-  if (alm1.OMG0 != alm2.OMG0)
-    return false;
-  if (alm1.omg != alm2.omg)
-    return false;
-  if (alm1.M0 != alm2.M0)
-    return false;
-  if (alm1.OMGd != alm2.OMGd)
-    return false;
-  if (alm1.toas != alm2.toas)
-    return false;
-  if (alm1.f0 != alm2.f0)
-    return false;
-  if (alm1.f1 != alm2.f1)
-    return false;
-
-  return true;
+bool operator!=(const obs_t& obs1, const obs_t& obs2)
+{
+  return not(obs1 == obs2);
 }
 
-bool equalTecGrid(const tec_t& tec1, const tec_t& tec2)
+bool operator==(const eph_t& eph1, const eph_t& eph2)
 {
-  if (tec1.time != tec2.time)
-    return false;
-
-  if (!equalArray<int>(tec1.ndata, tec2.ndata, ARRAY_SIZE(tec1.ndata), ARRAY_SIZE(tec2.ndata)))
-    return false;
-
-  if (tec1.rb != tec2.rb)
-    return false;
-
-  if (!equalArray<double>(tec1.lats, tec2.lats, ARRAY_SIZE(tec1.lats), ARRAY_SIZE(tec2.lats)))
-    return false;
-  if (!equalArray<double>(tec1.lons, tec2.lons, ARRAY_SIZE(tec1.lons), ARRAY_SIZE(tec2.lons)))
-    return false;
-  if (!equalArray<double>(tec1.hgts, tec2.hgts, ARRAY_SIZE(tec1.hgts), ARRAY_SIZE(tec2.hgts)))
-    return false;
-
-  // TODO: *data and *rms
-
-  return true;
+  return eph1.sat == eph2.sat && eph1.iode == eph2.iode && eph1.iodc == eph2.iodc && eph1.sva == eph2.sva &&
+         eph1.svh == eph2.svh && eph1.week == eph2.week && eph1.code == eph2.code && eph1.flag == eph2.flag &&
+         eph1.toe == eph2.toe && eph1.toc == eph2.toc && eph1.ttr == eph2.ttr && eph1.A == eph2.A && eph1.e == eph2.e &&
+         eph1.i0 == eph2.i0 && eph1.OMG0 == eph2.OMG0 && eph1.omg == eph2.omg && eph1.M0 == eph2.M0 &&
+         eph1.deln == eph2.deln && eph1.OMGd == eph2.OMGd && eph1.idot == eph2.idot && eph1.crc == eph2.crc &&
+         eph1.crs == eph2.crs && eph1.cuc == eph2.cuc && eph1.cus == eph2.cus && eph1.cic == eph2.cic &&
+         eph1.cis == eph2.cis && eph1.toes == eph2.toes && eph1.fit == eph2.fit && eph1.f0 == eph2.f0 &&
+         eph1.f1 == eph2.f1 && eph1.f2 == eph2.f2 &&
+         GnssUtils::equalArray<double>(eph1.tgd, eph2.tgd, ARRAY_SIZE(eph1.tgd), ARRAY_SIZE(eph2.tgd)) &&
+         eph1.Adot == eph2.Adot && eph1.ndot == eph2.ndot;
 }
-
-bool equalFcb(const fcbd_t& fcbd1, const fcbd_t& fcbd2)
+bool operator!=(const eph_t& eph1, const eph_t& eph2)
 {
-  if (fcbd1.ts != fcbd2.ts)
-    return false;
-  if (fcbd1.te != fcbd2.te)
-    return false;
-
-  if (!equalArray2d<double>(&fcbd1.bias[0][0],
-                            &fcbd2.bias[0][0],
-                            ARRAY2D_NROWS(fcbd1.bias),
-                            ARRAY2D_NCOLS(fcbd1.bias),
-                            ARRAY2D_NROWS(fcbd2.bias),
-                            ARRAY2D_NCOLS(fcbd2.bias)))
-    return false;
-  if (!equalArray2d<double>(&fcbd1.std[0][0],
-                            &fcbd2.std[0][0],
-                            ARRAY2D_NROWS(fcbd1.std),
-                            ARRAY2D_NCOLS(fcbd1.std),
-                            ARRAY2D_NROWS(fcbd2.std),
-                            ARRAY2D_NCOLS(fcbd2.std)))
-    return false;
+  return not(eph1 == eph2);
+}
 
-  return true;
+bool operator==(const geph_t& geph1, const geph_t& geph2)
+{
+  return geph1.sat == geph2.sat && geph1.iode == geph2.iode && geph1.frq == geph2.frq && geph1.svh == geph2.svh &&
+         geph1.sva == geph2.sva && geph1.age == geph2.age && geph1.toe == geph2.toe && geph1.tof == geph2.tof &&
+         GnssUtils::equalArray<double>(geph1.pos, geph2.pos, ARRAY_SIZE(geph1.pos), ARRAY_SIZE(geph2.pos)) &&
+         GnssUtils::equalArray<double>(geph1.vel, geph2.vel, ARRAY_SIZE(geph1.vel), ARRAY_SIZE(geph2.vel)) &&
+         GnssUtils::equalArray<double>(geph1.acc, geph2.acc, ARRAY_SIZE(geph1.acc), ARRAY_SIZE(geph2.acc)) &&
+         geph1.taun == geph2.taun && geph1.gamn == geph2.gamn && geph1.dtaun == geph2.dtaun;
 }
-bool equalEarthRotationParameters(const erp_t& erp1, const erp_t& erp2)
+bool operator!=(const geph_t& geph1, const geph_t& geph2)
 {
-  // TODO
-
-  return true;
+  return not(geph1 == geph2);
 }
 
-bool equalNavigation(const nav_t& nav1, const nav_t& nav2)
-{
-  if (nav1.n != nav2.n)
-    return false;
-  if (nav1.nmax != nav2.nmax)
-    return false;
-  if (nav1.ng != nav2.ng)
-    return false;
-  if (nav1.ngmax != nav2.ngmax)
-    return false;
-  if (nav1.ns != nav2.ns)
-    return false;
-  if (nav1.nsmax != nav2.nsmax)
-    return false;
-  if (nav1.ne != nav2.ne)
-    return false;
-  if (nav1.nemax != nav2.nemax)
-    return false;
-  if (nav1.nc != nav2.nc)
-    return false;
-  if (nav1.ncmax != nav2.ncmax)
-    return false;
-  if (nav1.na != nav2.na)
-    return false;
-  if (nav1.namax != nav2.namax)
-    return false;
-  if (nav1.nt != nav2.nt)
-    return false;
-  if (nav1.ntmax != nav2.ntmax)
-    return false;
-  if (nav1.nf != nav2.nf)
-    return false;
-  if (nav1.nfmax != nav2.nfmax)
-    return false;
-
-  // eph
-  // geph
-  // seph
-  // peph
-  // pclk
-  // alm
-  // tec
-  // fcb
-  // erp
-  if (!equalArray<double>(nav1.utc_gps, nav2.utc_gps, ARRAY_SIZE(nav1.utc_gps), ARRAY_SIZE(nav2.utc_gps)))
-    return false;
-  if (!equalArray<double>(nav1.utc_glo, nav2.utc_glo, ARRAY_SIZE(nav1.utc_glo), ARRAY_SIZE(nav2.utc_glo)))
-    return false;
-  if (!equalArray<double>(nav1.utc_gal, nav2.utc_gal, ARRAY_SIZE(nav1.utc_gal), ARRAY_SIZE(nav2.utc_gal)))
-    return false;
-  if (!equalArray<double>(nav1.utc_qzs, nav2.utc_qzs, ARRAY_SIZE(nav1.utc_qzs), ARRAY_SIZE(nav2.utc_qzs)))
-    return false;
-  if (!equalArray<double>(nav1.utc_cmp, nav2.utc_cmp, ARRAY_SIZE(nav1.utc_cmp), ARRAY_SIZE(nav2.utc_cmp)))
-    return false;
-  if (!equalArray<double>(nav1.utc_irn, nav2.utc_irn, ARRAY_SIZE(nav1.utc_irn), ARRAY_SIZE(nav2.utc_irn)))
-    return false;
-  if (!equalArray<double>(nav1.utc_sbs, nav2.utc_sbs, ARRAY_SIZE(nav1.utc_sbs), ARRAY_SIZE(nav2.utc_sbs)))
-    return false;
-  if (!equalArray<double>(nav1.ion_gps, nav2.ion_gps, ARRAY_SIZE(nav1.ion_gps), ARRAY_SIZE(nav2.ion_gps)))
-    return false;
-  if (!equalArray<double>(nav1.ion_gal, nav2.ion_gal, ARRAY_SIZE(nav1.ion_gal), ARRAY_SIZE(nav2.ion_gal)))
-    return false;
-  if (!equalArray<double>(nav1.ion_qzs, nav2.ion_qzs, ARRAY_SIZE(nav1.ion_qzs), ARRAY_SIZE(nav2.ion_qzs)))
-    return false;
-  if (!equalArray<double>(nav1.ion_cmp, nav2.ion_cmp, ARRAY_SIZE(nav1.ion_cmp), ARRAY_SIZE(nav2.ion_cmp)))
-    return false;
-  if (!equalArray<double>(nav1.ion_irn, nav2.ion_irn, ARRAY_SIZE(nav1.ion_irn), ARRAY_SIZE(nav2.ion_irn)))
-    return false;
-
-  if (nav1.leaps != nav2.leaps)
-    return false;
+bool operator==(const seph_t& seph1, const seph_t& seph2)
+{
+  return seph1.sat == seph2.sat && seph1.t0 == seph2.t0 && seph1.tof == seph2.tof && seph1.sva == seph2.sva &&
+         seph1.svh == seph2.svh &&
+         GnssUtils::equalArray<double>(seph1.pos, seph2.pos, ARRAY_SIZE(seph1.pos), ARRAY_SIZE(seph2.pos)) &&
+         GnssUtils::equalArray<double>(seph1.vel, seph2.vel, ARRAY_SIZE(seph1.vel), ARRAY_SIZE(seph2.vel)) &&
+         GnssUtils::equalArray<double>(seph1.acc, seph2.acc, ARRAY_SIZE(seph1.acc), ARRAY_SIZE(seph2.acc)) &&
+         seph1.af0 == seph2.af0 && seph1.af1 == seph2.af1;
+}
+bool operator!=(const seph_t& seph1, const seph_t& seph2)
+{
+  return not(seph1 == seph2);
+}
 
-  if (!equalArray2d<double>(&nav1.lam[0][0],
-                            &nav2.lam[0][0],
-                            ARRAY2D_NROWS(nav1.lam),
-                            ARRAY2D_NCOLS(nav1.lam),
-                            ARRAY2D_NROWS(nav2.lam),
-                            ARRAY2D_NCOLS(nav2.lam)))
-    return false;
-  if (!equalArray2d<double>(&nav1.cbias[0][0],
-                            &nav2.cbias[0][0],
-                            ARRAY2D_NROWS(nav1.cbias),
-                            ARRAY2D_NCOLS(nav1.cbias),
-                            ARRAY2D_NROWS(nav2.cbias),
-                            ARRAY2D_NCOLS(nav2.cbias)))
-    return false;
-  if (!equalArray3d<double>(&nav1.rbias[0][0][0], &nav2.rbias[0][0][0], MAXRCV, 2, 3, MAXRCV, 2, 3))
-    return false;
-  if (!equalArray<double>(nav1.wlbias, nav2.wlbias, ARRAY_SIZE(nav1.wlbias), ARRAY_SIZE(nav2.wlbias)))
-    return false;
-  if (!equalArray<double>(nav1.glo_cpbias, nav2.glo_cpbias, ARRAY_SIZE(nav1.glo_cpbias), ARRAY_SIZE(nav2.glo_cpbias)))
-    return false;
-  if (!equalArray<char>(nav1.glo_fcn, nav2.glo_fcn, ARRAY_SIZE(nav1.glo_fcn), ARRAY_SIZE(nav2.glo_fcn)))
-    return false;
+bool operator==(const peph_t& peph1, const peph_t& peph2)
+{
+  return peph1.time == peph2.time && peph1.index == peph2.index &&
+         GnssUtils::equalArray2d<double>(&peph1.pos[0][0],
+                                         &peph2.pos[0][0],
+                                         ARRAY2D_NROWS(peph1.pos),
+                                         ARRAY2D_NCOLS(peph1.pos),
+                                         ARRAY2D_NROWS(peph2.pos),
+                                         ARRAY2D_NCOLS(peph2.pos)) &&
+         GnssUtils::equalArray2d<float>(&peph1.std[0][0],
+                                        &peph2.std[0][0],
+                                        ARRAY2D_NROWS(peph1.std),
+                                        ARRAY2D_NCOLS(peph1.std),
+                                        ARRAY2D_NROWS(peph2.std),
+                                        ARRAY2D_NCOLS(peph2.std)) &&
+         GnssUtils::equalArray2d<double>(&peph1.vel[0][0],
+                                         &peph2.vel[0][0],
+                                         ARRAY2D_NROWS(peph1.vel),
+                                         ARRAY2D_NCOLS(peph1.vel),
+                                         ARRAY2D_NROWS(peph2.vel),
+                                         ARRAY2D_NCOLS(peph2.vel)) &&
+         GnssUtils::equalArray2d<float>(&peph1.vst[0][0],
+                                        &peph2.vst[0][0],
+                                        ARRAY2D_NROWS(peph1.vst),
+                                        ARRAY2D_NCOLS(peph1.vst),
+                                        ARRAY2D_NROWS(peph2.vst),
+                                        ARRAY2D_NCOLS(peph2.vst)) &&
+         GnssUtils::equalArray2d<float>(&peph1.cov[0][0],
+                                        &peph2.cov[0][0],
+                                        ARRAY2D_NROWS(peph1.cov),
+                                        ARRAY2D_NCOLS(peph1.cov),
+                                        ARRAY2D_NROWS(peph2.cov),
+                                        ARRAY2D_NCOLS(peph2.cov)) &&
+         GnssUtils::equalArray2d<float>(&peph1.vco[0][0],
+                                        &peph2.vco[0][0],
+                                        ARRAY2D_NROWS(peph1.vco),
+                                        ARRAY2D_NCOLS(peph1.vco),
+                                        ARRAY2D_NROWS(peph2.vco),
+                                        ARRAY2D_NCOLS(peph2.vco));
+}
+bool operator!=(const peph_t& peph1, const peph_t& peph2)
+{
+  return not(peph1 == peph2);
 }
-}  // namespace GnssUtils
 
-bool operator==(const gtime_t& time1, const gtime_t& time2)
+bool operator==(const pclk_t& pclk1, const pclk_t& pclk2)
 {
-  return (difftime(time1.time, time2.time) == 0.0 && time1.sec == time2.sec);
+  return pclk1.time == pclk2.time && pclk1.index == pclk2.index &&
+         GnssUtils::equalArray2d<double>(&pclk1.clk[0][0],
+                                         &pclk2.clk[0][0],
+                                         ARRAY2D_NROWS(pclk1.clk),
+                                         ARRAY2D_NCOLS(pclk1.clk),
+                                         ARRAY2D_NROWS(pclk2.clk),
+                                         ARRAY2D_NCOLS(pclk2.clk)) &&
+         GnssUtils::equalArray2d<float>(&pclk1.std[0][0],
+                                        &pclk2.std[0][0],
+                                        ARRAY2D_NROWS(pclk1.std),
+                                        ARRAY2D_NCOLS(pclk1.std),
+                                        ARRAY2D_NROWS(pclk2.std),
+                                        ARRAY2D_NCOLS(pclk2.std));
+}
+bool operator!=(const pclk_t& pclk1, const pclk_t& pclk2)
+{
+  return not(pclk1 == pclk2);
 }
 
-bool operator!=(const gtime_t& time1, const gtime_t& time2)
+bool operator==(const alm_t& alm1, const alm_t& alm2)
 {
-  return not(time1 == time2);
+  return alm1.sat == alm2.sat && alm1.svh == alm2.svh && alm1.svconf == alm2.svconf && alm1.week == alm2.week &&
+         alm1.toa == alm2.toa && alm1.A == alm2.A && alm1.e == alm2.e && alm1.i0 == alm2.i0 && alm1.OMG0 == alm2.OMG0 &&
+         alm1.omg == alm2.omg && alm1.M0 == alm2.M0 && alm1.OMGd == alm2.OMGd && alm1.toas == alm2.toas &&
+         alm1.f0 == alm2.f0 && alm1.f1 == alm2.f1;
+}
+bool operator!=(const alm_t& alm1, const alm_t& alm2)
+{
+  return not(alm1 == alm2);
 }
 
-bool operator==(const obsd_t& obs1, const obsd_t& obs2)
+bool operator==(const tec_t& tec1, const tec_t& tec2)
 {
-  return obs1.time == obs2.time && obs1.eventime == obs2.eventime && obs1.timevalid == obs2.timevalid &&
-         obs1.sat == obs2.sat && obs1.rcv == obs2.rcv && memcmp(obs1.SNR, obs2.SNR, sizeof(obs1.SNR)) == 0 &&
-         memcmp(obs1.LLI, obs2.LLI, sizeof(obs1.LLI)) == 0 && memcmp(obs1.code, obs2.code, sizeof(obs1.code)) == 0 &&
-         memcmp(obs1.qualL, obs2.qualL, sizeof(obs1.qualL)) == 0 &&
-         memcmp(obs1.qualP, obs2.qualP, sizeof(obs1.qualP)) == 0 && obs1.freq == obs2.freq &&
-         GnssUtils::equalArray<double>(
-             obs1.L, obs2.L, sizeof(obs1.L) / sizeof(obs1.L[0]), sizeof(obs2.L) / sizeof(obs2.L[0])) &&
-         GnssUtils::equalArray<double>(
-             obs1.P, obs2.P, sizeof(obs1.P) / sizeof(obs1.P[0]), sizeof(obs2.P) / sizeof(obs2.P[0])) &&
-         GnssUtils::equalArray<float>(
-             obs1.D, obs2.D, sizeof(obs1.D) / sizeof(obs1.D[0]), sizeof(obs2.D) / sizeof(obs2.D[0]));
+  return tec1.time == tec2.time &&
+         GnssUtils::equalArray<int>(tec1.ndata, tec2.ndata, ARRAY_SIZE(tec1.ndata), ARRAY_SIZE(tec2.ndata)) &&
+         tec1.rb == tec2.rb &&
+         GnssUtils::equalArray<double>(tec1.lats, tec2.lats, ARRAY_SIZE(tec1.lats), ARRAY_SIZE(tec2.lats)) &&
+         GnssUtils::equalArray<double>(tec1.lons, tec2.lons, ARRAY_SIZE(tec1.lons), ARRAY_SIZE(tec2.lons)) &&
+         GnssUtils::equalArray<double>(tec1.hgts, tec2.hgts, ARRAY_SIZE(tec1.hgts), ARRAY_SIZE(tec2.hgts));
+  // TODO: *data and *rms
+}
+bool operator!=(const tec_t& tec1, const tec_t& tec2)
+{
+  return not(tec1 == tec2);
 }
 
-bool operator!=(const obsd_t& obs1, const obsd_t& obs2)
+bool operator==(const fcbd_t& fcbd1, const fcbd_t& fcbd2)
 {
-  return not(obs1 == obs2);
+  return fcbd1.ts == fcbd2.ts && fcbd1.te == fcbd2.te &&
+         GnssUtils::equalArray2d<double>(&fcbd1.bias[0][0],
+                                         &fcbd2.bias[0][0],
+                                         ARRAY2D_NROWS(fcbd1.bias),
+                                         ARRAY2D_NCOLS(fcbd1.bias),
+                                         ARRAY2D_NROWS(fcbd2.bias),
+                                         ARRAY2D_NCOLS(fcbd2.bias)) &&
+         GnssUtils::equalArray2d<double>(&fcbd1.std[0][0],
+                                         &fcbd2.std[0][0],
+                                         ARRAY2D_NROWS(fcbd1.std),
+                                         ARRAY2D_NCOLS(fcbd1.std),
+                                         ARRAY2D_NROWS(fcbd2.std),
+                                         ARRAY2D_NCOLS(fcbd2.std));
+}
+bool operator!=(const fcbd_t& fcbd1, const fcbd_t& fcbd2)
+{
+  return not(fcbd1 == fcbd2);
 }
 
-bool operator==(const obs_t& obs1, const obs_t& obs2)
+bool operator==(const erp_t& erp1, const erp_t& erp2)
 {
-  return obs1.n == obs2.n && obs1.nmax == obs2.nmax && obs1.flag == obs2.flag && obs1.rcvcount == obs2.rcvcount &&
-         obs1.tmcount == obs2.tmcount && *(obs1.data) == *(obs2.data);
+  // TODO
+  return true;
+}
+bool operator!=(const erp_t& erp1, const erp_t& erp2)
+{
+  return not(erp1 == erp2);
 }
 
-bool operator!=(const obs_t& obs1, const obs_t& obs2)
+bool operator==(const nav_t& nav1, const nav_t& nav2)
 {
-  return not(obs1 == obs2);
+  return nav1.n == nav2.n && nav1.nmax == nav2.nmax && nav1.ng == nav2.ng && nav1.ngmax == nav2.ngmax &&
+         nav1.ns == nav2.ns && nav1.nsmax == nav2.nsmax && nav1.ne == nav2.ne && nav1.nemax == nav2.nemax &&
+         nav1.nc == nav2.nc && nav1.ncmax == nav2.ncmax && nav1.na == nav2.na && nav1.namax == nav2.namax &&
+         nav1.nt == nav2.nt && nav1.ntmax == nav2.ntmax && nav1.nf == nav2.nf && nav1.nfmax == nav2.nfmax &&
+         *nav1.eph == *nav2.eph && *nav1.geph == *nav2.geph && *nav1.seph == *nav2.seph && *nav1.peph == *nav2.peph &&
+         *nav1.pclk == *nav2.pclk && *nav1.alm == *nav2.alm && *nav1.tec == *nav2.tec && *nav1.fcb == *nav2.fcb &&
+         nav1.erp == nav2.erp &&
+         GnssUtils::equalArray<double>(
+             nav1.utc_gps, nav2.utc_gps, ARRAY_SIZE(nav1.utc_gps), ARRAY_SIZE(nav2.utc_gps)) &&
+         GnssUtils::equalArray<double>(
+             nav1.utc_glo, nav2.utc_glo, ARRAY_SIZE(nav1.utc_glo), ARRAY_SIZE(nav2.utc_glo)) &&
+         GnssUtils::equalArray<double>(
+             nav1.utc_gal, nav2.utc_gal, ARRAY_SIZE(nav1.utc_gal), ARRAY_SIZE(nav2.utc_gal)) &&
+         GnssUtils::equalArray<double>(
+             nav1.utc_qzs, nav2.utc_qzs, ARRAY_SIZE(nav1.utc_qzs), ARRAY_SIZE(nav2.utc_qzs)) &&
+         GnssUtils::equalArray<double>(
+             nav1.utc_cmp, nav2.utc_cmp, ARRAY_SIZE(nav1.utc_cmp), ARRAY_SIZE(nav2.utc_cmp)) &&
+         GnssUtils::equalArray<double>(
+             nav1.utc_irn, nav2.utc_irn, ARRAY_SIZE(nav1.utc_irn), ARRAY_SIZE(nav2.utc_irn)) &&
+         GnssUtils::equalArray<double>(
+             nav1.utc_sbs, nav2.utc_sbs, ARRAY_SIZE(nav1.utc_sbs), ARRAY_SIZE(nav2.utc_sbs)) &&
+         GnssUtils::equalArray<double>(
+             nav1.ion_gps, nav2.ion_gps, ARRAY_SIZE(nav1.ion_gps), ARRAY_SIZE(nav2.ion_gps)) &&
+         GnssUtils::equalArray<double>(
+             nav1.ion_gal, nav2.ion_gal, ARRAY_SIZE(nav1.ion_gal), ARRAY_SIZE(nav2.ion_gal)) &&
+         GnssUtils::equalArray<double>(
+             nav1.ion_qzs, nav2.ion_qzs, ARRAY_SIZE(nav1.ion_qzs), ARRAY_SIZE(nav2.ion_qzs)) &&
+         GnssUtils::equalArray<double>(
+             nav1.ion_cmp, nav2.ion_cmp, ARRAY_SIZE(nav1.ion_cmp), ARRAY_SIZE(nav2.ion_cmp)) &&
+         GnssUtils::equalArray<double>(
+             nav1.ion_irn, nav2.ion_irn, ARRAY_SIZE(nav1.ion_irn), ARRAY_SIZE(nav2.ion_irn)) &&
+         nav1.leaps == nav2.leaps &&
+         GnssUtils::equalArray2d<double>(&nav1.lam[0][0],
+                                         &nav2.lam[0][0],
+                                         ARRAY2D_NROWS(nav1.lam),
+                                         ARRAY2D_NCOLS(nav1.lam),
+                                         ARRAY2D_NROWS(nav2.lam),
+                                         ARRAY2D_NCOLS(nav2.lam)) &&
+         GnssUtils::equalArray2d<double>(&nav1.cbias[0][0],
+                                         &nav2.cbias[0][0],
+                                         ARRAY2D_NROWS(nav1.cbias),
+                                         ARRAY2D_NCOLS(nav1.cbias),
+                                         ARRAY2D_NROWS(nav2.cbias),
+                                         ARRAY2D_NCOLS(nav2.cbias)) &&
+         GnssUtils::equalArray3d<double>(&nav1.rbias[0][0][0], &nav2.rbias[0][0][0], MAXRCV, 2, 3, MAXRCV, 2, 3) &&
+         GnssUtils::equalArray<double>(nav1.wlbias, nav2.wlbias, ARRAY_SIZE(nav1.wlbias), ARRAY_SIZE(nav2.wlbias)) &&
+         GnssUtils::equalArray<double>(
+             nav1.glo_cpbias, nav2.glo_cpbias, ARRAY_SIZE(nav1.glo_cpbias), ARRAY_SIZE(nav2.glo_cpbias)) &&
+         GnssUtils::equalArray<char>(nav1.glo_fcn, nav2.glo_fcn, ARRAY_SIZE(nav1.glo_fcn), ARRAY_SIZE(nav2.glo_fcn));
 }
+bool operator!=(const nav_t& nav1, const nav_t& nav2)
+{
+  return not(nav1 == nav2);
+}
\ No newline at end of file
-- 
GitLab