@@@ mostly bench docs
[mLib] / struct / buf-float.c
index 5b5b625..e163ff7 100644 (file)
 #include "bits.h"
 #include "buf.h"
 #include "fltfmt.h"
+#include "macros.h"
 
-/*----- External functions ------------------------------------------------*/
+/*----- Constants ---------------------------------------------------------*/
+
+/* Tolerable errors.  These aren't great, and all of them imply a failure to
+ * faithfully pass the value on, but they're also the inevitable consequence
+ * of having different floating-point systems.
+ */
+#define IGNERR (FLTERR_INEXACT | FLTERR_OFLOW | FLTERR_UFLOW)
+
+/*----- Main code ---------------------------------------------------------*/
+
+#define FORMATS(_)                                                     \
+  _(flt, float, f32, 4)                                                        \
+  _(dbl, double, f64, 8)
 
 /* --- @buf_getf{32,64}{,l,b} --- *
  *
  *             the usual round-to-nearest/ties-to-even rounding mode.
  */
 
-int buf_getf32(buf *b, float *x_out)
-{
-  const octet *p;
-
-  p = buf_get(b, 4); if (!p) return (-1);
-  fltfmt_f32btoflt(x_out, p, FLTRND_NEAREVEN); return (0);
-}
-
-int buf_getf32l(buf *b, float *x_out)
-{
-  const octet *p;
-
-  p = buf_get(b, 4); if (!p) return (-1);
-  fltfmt_f32ltoflt(x_out, p, FLTRND_NEAREVEN); return (0);
-}
-
-int buf_getf32b(buf *b, float *x_out)
-{
-  const octet *p;
-
-  p = buf_get(b, 4); if (!p) return (-1);
-  fltfmt_f32ltoflt(x_out, p, FLTRND_NEAREVEN); return (0);
-}
-
-int (dbuf_getf32)(dbuf *db, float *x_out)
-  { return (dbuf_getf32(db, x_out)); }
-int (dbuf_getf32l)(dbuf *db, float *x_out)
-  { return (dbuf_getf32l(db, x_out)); }
-int (dbuf_getf32b)(dbuf *db, float *x_out)
-  { return (dbuf_getf32b(db, x_out)); }
-
-int buf_getf64(buf *b, double *x_out)
-{
-  const octet *p;
-
-  p = buf_get(b, 8); if (!p) return (-1);
-  fltfmt_f64btodbl(x_out, p, FLTRND_NEAREVEN); return (0);
-}
-
-int buf_getf64l(buf *b, double *x_out)
-{
-  const octet *p;
-
-  p = buf_get(b, 8); if (!p) return (-1);
-  fltfmt_f64ltodbl(x_out, p, FLTRND_NEAREVEN); return (0);
-}
-
-int buf_getf64b(buf *b, double *x_out)
-{
-  const octet *p;
-
-  p = buf_get(b, 8); if (!p) return (-1);
-  fltfmt_f64ltodbl(x_out, p, FLTRND_NEAREVEN); return (0);
-}
-
-int (dbuf_getf64)(dbuf *db, double *x_out)
-  { return (dbuf_getf64(db, x_out)); }
-int (dbuf_getf64l)(dbuf *db, double *x_out)
-  { return (dbuf_getf64l(db, x_out)); }
-int (dbuf_getf64b)(dbuf *db, double *x_out)
-  { return (dbuf_getf64b(db, x_out)); }
+#define DEFGET1(ty, cty, fty, e, xe, w)                                        \
+  int GLUE3(buf_get, fty, xe)(buf *b, cty *x_out)                      \
+  {                                                                    \
+    const octet *p;                                                    \
+    unsigned err;                                                      \
+                                                                       \
+    p = buf_get(b, w); if (!p) return (-1);                            \
+    err = fltfmt_##fty##e##to##ty(x_out, p, FLTRND_NEAREVEN);          \
+      if (err&~IGNERR) { BBREAK(b); return (-1); }                     \
+    return (0);                                                                \
+  }                                                                    \
+  int (GLUE3(dbuf_get, fty, xe))(dbuf *db, cty *x_out)                 \
+    { return (GLUE3(dbuf_get, fty, xe)(db, x_out)); }
+
+#define DEFGET(ty, cty, fty, w)                                                \
+  DEFGET1(ty, cty, fty, b, EMPTY, w)                                   \
+  DEFGET1(ty, cty, fty, l, l, w)                                       \
+  DEFGET1(ty, cty, fty, b, b, w)
+
+FORMATS(DEFGET)
+
+#undef DEFGET1
+#undef DEFGET
 
 /* --- @buf_putf{32,64}{,l,b} --- *
  *
@@ -124,66 +99,28 @@ int (dbuf_getf64b)(dbuf *db, double *x_out)
  *             the usual round-to-nearest/ties-to-even rounding mode.
  */
 
-int buf_putf32(buf *b, float x)
-{
-  octet *p;
-
-  p = buf_get(b, 4); if (!p) return (-1);
-  fltfmt_flttof32b(p, x, FLTRND_NEAREVEN); return (0);
-}
-
-int buf_putf32l(buf *b, float x)
-{
-  octet *p;
-
-  p = buf_get(b, 4); if (!p) return (-1);
-  fltfmt_flttof32l(p, x, FLTRND_NEAREVEN); return (0);
-}
-
-int buf_putf32b(buf *b, float x)
-{
-  octet *p;
-
-  p = buf_get(b, 4); if (!p) return (-1);
-  fltfmt_flttof32b(p, x, FLTRND_NEAREVEN); return (0);
-}
-
-int (dbuf_putf32)(dbuf *db, float x)
-  { return (dbuf_putf32(db, x)); }
-int (dbuf_putf32l)(dbuf *db, float x)
-  { return (dbuf_putf32l(db, x)); }
-int (dbuf_putf32b)(dbuf *db, float x)
-  { return (dbuf_putf32b(db, x)); }
-
-int buf_putf64(buf *b, double x)
-{
-  octet *p;
-
-  p = buf_get(b, 8); if (!p) return (-1);
-  fltfmt_dbltof64b(p, x, FLTRND_NEAREVEN); return (0);
-}
-
-int buf_putf64l(buf *b, double x)
-{
-  octet *p;
-
-  p = buf_get(b, 8); if (!p) return (-1);
-  fltfmt_dbltof64l(p, x, FLTRND_NEAREVEN); return (0);
-}
-
-int buf_putf64b(buf *b, double x)
-{
-  octet *p;
-
-  p = buf_get(b, 8); if (!p) return (-1);
-  fltfmt_dbltof64b(p, x, FLTRND_NEAREVEN); return (0);
-}
-
-int (dbuf_putf64)(dbuf *db, double x)
-  { return (dbuf_putf64(db, x)); }
-int (dbuf_putf64l)(dbuf *db, double x)
-  { return (dbuf_putf64l(db, x)); }
-int (dbuf_putf64b)(dbuf *db, double x)
-  { return (dbuf_putf64b(db, x)); }
+#define DEFPUT1(ty, cty, fty, e, xe, w)                                        \
+  int GLUE3(buf_put, fty, xe)(buf *b, cty x)                           \
+  {                                                                    \
+    octet *p;                                                          \
+    unsigned err;                                                      \
+                                                                       \
+    p = buf_get(b, w); if (!p) return (-1);                            \
+    err = fltfmt_##ty##to##fty##e(p, x, FLTRND_NEAREVEN);              \
+      if (err&~IGNERR) { BBREAK(b); return (-1); }                     \
+    return (0);                                                                \
+  }                                                                    \
+  int (GLUE3(dbuf_put, fty, xe))(dbuf *db, cty x)                      \
+    { return (GLUE3(dbuf_put, fty, xe)(db, x)); }
+
+#define DEFPUT(ty, cty, fty, w)                                                \
+  DEFPUT1(ty, cty, fty, b, EMPTY, w)                                   \
+  DEFPUT1(ty, cty, fty, l, l, w)                                       \
+  DEFPUT1(ty, cty, fty, b, b, w)
+
+FORMATS(DEFPUT)
+
+#undef DEFPUT1
+#undef DEFPUT
 
 /*----- That's all, folks -------------------------------------------------*/