glib/tests/bit-test.c
changeset 18 47c74d1534e1
child 34 5fae379060a7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/glib/tests/bit-test.c	Fri Apr 16 16:46:38 2010 +0300
@@ -0,0 +1,173 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+#include <glib.h>
+#ifdef __SYMBIAN32__
+#include "mrt2_glib2_test.h"
+#endif /*__SYMBIAN32__*/
+
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+# define TEST_BUILTINS 1
+#else
+# define TEST_BUILTINS 0
+#endif
+
+#if TEST_BUILTINS
+static gint
+builtin_bit_nth_lsf1 (gulong mask, gint nth_bit)
+{
+  if (nth_bit >= 0)
+    {
+      if (G_LIKELY (nth_bit < GLIB_SIZEOF_LONG * 8 - 1))
+	mask &= -(1UL<<(nth_bit+1));
+      else
+	mask = 0;
+    }
+  return __builtin_ffsl(mask) - 1;
+}
+
+static gint
+builtin_bit_nth_lsf2 (gulong mask, gint nth_bit)
+{
+  if (nth_bit >= 0)
+    {
+      if (G_LIKELY (nth_bit < GLIB_SIZEOF_LONG * 8 - 1))
+	mask &= -(1UL<<(nth_bit+1));
+      else
+	mask = 0;
+    }
+  return mask ? __builtin_ctzl(mask) : -1;
+}
+
+static gint
+builtin_bit_nth_msf (gulong mask, gint nth_bit)
+{
+  if (nth_bit >= 0 && nth_bit < GLIB_SIZEOF_LONG * 8)
+    mask &= (1UL<<nth_bit)-1;
+  return mask ? GLIB_SIZEOF_LONG * 8 - 1 - __builtin_clzl(mask) : -1;
+}
+
+
+static guint
+builtin_bit_storage (gulong number)
+{
+  return number ? GLIB_SIZEOF_LONG * 8 - __builtin_clzl(number) : 1;
+}
+#endif
+
+
+static gint
+naive_bit_nth_lsf (gulong mask, gint   nth_bit)
+{
+  if (G_UNLIKELY (nth_bit < -1))
+    nth_bit = -1;
+  while (nth_bit < ((GLIB_SIZEOF_LONG * 8) - 1))
+    {
+      nth_bit++;
+      if (mask & (1UL << nth_bit))
+	return nth_bit;
+    }
+  return -1;
+}
+
+static gint
+naive_bit_nth_msf (gulong mask, gint   nth_bit)
+{
+  if (nth_bit < 0 || G_UNLIKELY (nth_bit > GLIB_SIZEOF_LONG * 8))
+    nth_bit = GLIB_SIZEOF_LONG * 8;
+  while (nth_bit > 0)
+    {
+      nth_bit--;
+      if (mask & (1UL << nth_bit))
+	return nth_bit;
+    }
+  return -1;
+}
+
+static guint
+naive_bit_storage (gulong number)
+{
+  register guint n_bits = 0;
+  
+  do
+    {
+      n_bits++;
+      number >>= 1;
+    }
+  while (number);
+  return n_bits;
+}
+
+
+
+#define TEST(f1, f2, i) \
+	if (f1 (i) != f2 (i)) { \
+		g_error (G_STRINGIFY (f1) " (%lu) = %d; " \
+			 G_STRINGIFY (f2) " (%lu) = %d; ", \
+			 i, f1 (i), \
+			 i, f2 (i)); \
+		return 1; \
+	}
+#define TEST2(f1, f2, i, n) \
+	if (f1 (i, n) != f2 (i, n)) { \
+		g_error (G_STRINGIFY (f1) " (%lu, %d) = %d; " \
+			 G_STRINGIFY (f2) " (%lu, %d) = %d; ", \
+			 i, n, f1 (i, n), \
+			 i, n, f2 (i, n)); \
+		return 1; \
+	}
+
+int
+main (void)
+{
+  gulong i;
+  gint nth_bit;
+  #ifdef __SYMBIAN32__
+  g_log_set_handler (NULL,  G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, &mrtLogHandler, NULL);
+  g_set_print_handler(mrtPrintHandler);
+  #endif /*__SYMBIAN32__*/
+
+
+  /* we loop like this: 0, -1, 1, -2, 2, -3, 3, ... */
+  for (i = 0; (glong)i < 1500 ; i = -(i+((glong)i>=0))) {
+
+#if TEST_BUILTINS
+    TEST (naive_bit_storage, builtin_bit_storage, i);
+#endif
+    TEST (naive_bit_storage, g_bit_storage, i);
+
+    for (nth_bit = -3; nth_bit <= 2 + GLIB_SIZEOF_LONG * 8; nth_bit++) {
+
+#if TEST_BUILTINS
+      TEST2 (naive_bit_nth_lsf, builtin_bit_nth_lsf1, i, nth_bit);
+      TEST2 (naive_bit_nth_lsf, builtin_bit_nth_lsf2, i, nth_bit);
+#endif
+      TEST2 (naive_bit_nth_lsf, g_bit_nth_lsf, i, nth_bit);
+
+#if TEST_BUILTINS
+      TEST2 (naive_bit_nth_msf, builtin_bit_nth_msf, i, nth_bit);
+#endif
+      TEST2 (naive_bit_nth_msf, g_bit_nth_msf, i, nth_bit);
+
+    }
+  }
+  #ifdef __SYMBIAN32__
+  testResultXml("bit-test");
+  #endif /* EMULATOR */
+  
+  return 0;
+}