[libdazzle] intpair: add a pointer-stashed int pair with 32-bit fallback



commit f9264b5197bc7591be60dfd320b9f14ba43a797d
Author: Christian Hergert <chergert redhat com>
Date:   Thu Jun 8 15:38:13 2017 -0700

    intpair: add a pointer-stashed int pair with 32-bit fallback
    
    If we are on 64-bit, we can stash two uint's in the pointer (or two signed
    ints). This can be useful when working with small structures that want to
    avoid allocations when possible.

 src/dazzle.h            |    1 +
 src/util/dzl-int-pair.h |  161 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/meson.build       |    6 ++
 tests/test-int-pair.c   |   79 +++++++++++++++++++++++
 4 files changed, 247 insertions(+), 0 deletions(-)
---
diff --git a/src/dazzle.h b/src/dazzle.h
index 609b75a..2c2b406 100644
--- a/src/dazzle.h
+++ b/src/dazzle.h
@@ -122,6 +122,7 @@ G_BEGIN_DECLS
 #include "util/dzl-gdk.h"
 #include "util/dzl-gtk.h"
 #include "util/dzl-heap.h"
+#include "util/dzl-int-pair.h"
 #include "util/dzl-pango.h"
 #include "util/dzl-rgba.h"
 #include "util/dzl-ring.h"
diff --git a/src/util/dzl-int-pair.h b/src/util/dzl-int-pair.h
new file mode 100644
index 0000000..8ced907
--- /dev/null
+++ b/src/util/dzl-int-pair.h
@@ -0,0 +1,161 @@
+/* dzl-int-pair.h
+ *
+ * Copyright (C) 2017 Christian Hergert <chergert redhat com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DZL_INT_PAIR_H
+#define DZL_INT_PAIR_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#if __WORDSIZE >= 64
+
+typedef union
+{
+  /*< private >*/
+  struct {
+    gint first;
+    gint second;
+  };
+  gpointer ptr;
+} DzlIntPair;
+
+typedef union
+{
+  /*< private >*/
+  struct {
+    guint first;
+    guint second;
+  };
+  gpointer ptr;
+} DzlUIntPair;
+
+#else
+
+typedef struct
+{
+  /*< private >*/
+  gint first;
+  gint second;
+} DzlIntPair;
+
+typedef struct
+{
+  /*< private >*/
+  guint first;
+  guint second;
+} DzlUIntPair;
+
+#endif
+
+G_STATIC_ASSERT (sizeof (DzlIntPair) == 8);
+G_STATIC_ASSERT (sizeof (DzlUIntPair) == 8);
+
+static inline DzlIntPair *
+dzl_int_pair_new (gint first, gint second)
+{
+  DzlIntPair pair = { .first = first, .second = second };
+#if __WORDSIZE >= 64
+  return pair.ptr;
+#else
+  return g_slice_copy (sizeof (DzlIntPair), &pair);
+#endif
+}
+
+static inline DzlUIntPair *
+dzl_uint_pair_new (guint first, guint second)
+{
+  DzlUIntPair pair = { .first = first, .second = second };
+#if __WORDSIZE >= 64
+  return pair.ptr;
+#else
+  return g_slice_copy (sizeof (DzlUIntPair), &pair);
+#endif
+}
+
+static inline gint
+dzl_int_pair_first (DzlIntPair *pair)
+{
+  DzlIntPair p;
+#if __WORDSIZE >= 64
+  p.ptr = pair;
+#else
+  p = *pair;
+#endif
+  return p.first;
+}
+
+static inline gint
+dzl_int_pair_second (DzlIntPair *pair)
+{
+  DzlIntPair p;
+#if __WORDSIZE >= 64
+  p.ptr = pair;
+#else
+  p = *pair;
+#endif
+  return p.second;
+}
+
+static inline guint
+dzl_uint_pair_first (DzlUIntPair *pair)
+{
+  DzlUIntPair p;
+#if __WORDSIZE >= 64
+  p.ptr = pair;
+#else
+  p = *pair;
+#endif
+  return p.first;
+}
+
+static inline guint
+dzl_uint_pair_second (DzlUIntPair *pair)
+{
+  DzlUIntPair p;
+#if __WORDSIZE >= 64
+  p.ptr = pair;
+#else
+  p = *pair;
+#endif
+  return p.second;
+}
+
+static inline void
+dzl_int_pair_free (DzlIntPair *pair)
+{
+#if __WORDSIZE >= 64
+  /* Do Nothing */
+#else
+  g_slice_free (DzlIntPair, pair);
+#endif
+}
+
+static inline void
+dzl_uint_pair_free (DzlUIntPair *pair)
+{
+#if __WORDSIZE >= 64
+  /* Do Nothing */
+#else
+  g_slice_free (DzlUIntPair, pair);
+#endif
+}
+
+G_END_DECLS
+
+#endif /* DZL_INT_PAIR_H */
diff --git a/tests/meson.build b/tests/meson.build
index 923e554..ba1b813 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -238,3 +238,9 @@ test_preferences = executable('test-preferences', 'test-preferences.c',
      link_args: test_link_args,
   dependencies: libdazzle_deps + [libdazzle_dep],
 )
+
+test_int_pair = executable('test-int-pair', 'test-int-pair.c',
+        c_args: test_cflags,
+     link_args: test_link_args,
+  dependencies: libdazzle_deps + [libdazzle_dep],
+)
diff --git a/tests/test-int-pair.c b/tests/test-int-pair.c
new file mode 100644
index 0000000..1dd9e15
--- /dev/null
+++ b/tests/test-int-pair.c
@@ -0,0 +1,79 @@
+#include <dazzle.h>
+
+static void
+test_intpair_basic (void)
+{
+  DzlIntPair *p;
+
+  p = dzl_int_pair_new (0, 0);
+#if __WORDSIZE >= 64
+  /* Technically not ANSI as NULL is allowed to be non-zero, but all the
+   * platforms we support, this is the case.
+   */
+  g_assert (p == NULL);
+#else
+  g_assert (p != NULL);
+#endif
+
+  p = dzl_int_pair_new (4, 5);
+  g_assert (p != NULL);
+  g_assert_cmpint (dzl_int_pair_first (p), ==, 4);
+  g_assert_cmpint (dzl_int_pair_second (p), ==, 5);
+  dzl_int_pair_free (p);
+
+  p = dzl_int_pair_new (G_MAXINT, G_MAXINT-1);
+  g_assert (p != NULL);
+  g_assert_cmpint (dzl_int_pair_first (p), ==, G_MAXINT);
+  g_assert_cmpint (dzl_int_pair_second (p), ==, G_MAXINT-1);
+  dzl_int_pair_free (p);
+
+  p = dzl_int_pair_new (G_MAXINT-1, G_MAXINT);
+  g_assert (p != NULL);
+  g_assert_cmpint (dzl_int_pair_first (p), ==, G_MAXINT-1);
+  g_assert_cmpint (dzl_int_pair_second (p), ==, G_MAXINT);
+  dzl_int_pair_free (p);
+}
+
+static void
+test_uintpair_basic (void)
+{
+  DzlUIntPair *p;
+
+  p = dzl_uint_pair_new (0, 0);
+#if __WORDSIZE >= 64
+  /* Technically not ANSI as NULL is allowed to be non-zero, but all the
+   * platforms we support, this is the case.
+   */
+  g_assert (p == NULL);
+#else
+  g_assert (p != NULL);
+#endif
+
+  p = dzl_uint_pair_new (4, 5);
+  g_assert (p != NULL);
+  g_assert_cmpuint (dzl_uint_pair_first (p), ==, 4);
+  g_assert_cmpuint (dzl_uint_pair_second (p), ==, 5);
+  dzl_uint_pair_free (p);
+
+  p = dzl_uint_pair_new (G_MAXUINT, G_MAXUINT-1);
+  g_assert (p != NULL);
+  g_assert_cmpuint (dzl_uint_pair_first (p), ==, G_MAXUINT);
+  g_assert_cmpuint (dzl_uint_pair_second (p), ==, G_MAXUINT-1);
+  dzl_uint_pair_free (p);
+
+  p = dzl_uint_pair_new (G_MAXUINT-1, G_MAXUINT);
+  g_assert (p != NULL);
+  g_assert_cmpuint (dzl_uint_pair_first (p), ==, G_MAXUINT-1);
+  g_assert_cmpuint (dzl_uint_pair_second (p), ==, G_MAXUINT);
+  dzl_uint_pair_free (p);
+}
+
+gint
+main (gint argc,
+      gchar *argv[])
+{
+  g_test_init (&argc, &argv, NULL);
+  g_test_add_func ("/Dazzle/IntPair/basic", test_intpair_basic);
+  g_test_add_func ("/Dazzle/UIntPair/basic", test_uintpair_basic);
+  return g_test_run ();
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]