[beast] Move AlignedArray to Birnet public API.



commit a7f4e1fedf0f9ec9a775e6ba9acf2da3d02dfe61
Author: Stefan Westerfeld <stefan space twc de>
Date:   Fri May 14 17:59:28 2010 +0200

    Move AlignedArray to Birnet public API.
    
    * move class from Bse::Resampler to Birnet namespace
    * minor refactoring (unsigned int -> size_t)
    * added test for AlignedArray

 birnet/birnetutils.hh    |   60 +++++++++++++++++++++++++++++++++++++++++
 birnet/tests/Makefile.am |    3 ++
 birnet/tests/utils.cc    |   67 ++++++++++++++++++++++++++++++++++++++++++++++
 bse/bseresamplerimpl.hh  |   58 +---------------------------------------
 4 files changed, 131 insertions(+), 57 deletions(-)
---
diff --git a/birnet/birnetutils.hh b/birnet/birnetutils.hh
index 1d8b143..32b62e7 100644
--- a/birnet/birnetutils.hh
+++ b/birnet/birnetutils.hh
@@ -1,5 +1,6 @@
 /* Birnet
  * Copyright (C) 2005-2006 Tim Janik
+ * Copyright (C) 2010 Stefan Westerfeld
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,6 +19,7 @@
 #define __BIRNET_UTILS_XX_HH__
 
 #include <birnet/birnetcdefs.h>
+#include <glib.h> /* g_free */
 #include <string>
 #include <vector>
 #include <map>
@@ -553,6 +555,64 @@ public: /* generic data API */
   template<typename Type> inline void delete_data (DataKey<Type> *key)            { data_list.del (key); }
 };
 
+/* --- class to allocate aligned memory --- */
+template<class T, int ALIGN>
+class AlignedArray {
+  unsigned char *unaligned_mem;
+  T *data;
+  size_t n_elements;
+
+  void
+  allocate_aligned_data()
+  {
+    BIRNET_ASSERT ((ALIGN % sizeof (T)) == 0);
+    data = reinterpret_cast<T *> (malloc_aligned (n_elements * sizeof (T), ALIGN, &unaligned_mem));
+  }
+  /* no copy constructor and no assignment operator */
+  BIRNET_PRIVATE_CLASS_COPY (AlignedArray);
+public:
+  AlignedArray (const vector<T>& elements) :
+    n_elements (elements.size())
+  {
+    allocate_aligned_data();
+
+    for (size_t i = 0; i < n_elements; i++)
+      new (data + i) T (elements[i]);
+  }
+  AlignedArray (size_t n_elements) :
+    n_elements (n_elements)
+  {
+    allocate_aligned_data();
+
+    for (size_t i = 0; i < n_elements; i++)
+      new (data + i) T();
+  }
+  ~AlignedArray()
+  {
+    /* C++ destruction order: last allocated element is deleted first */
+    while (n_elements)
+      data[--n_elements].~T();
+
+    g_free (unaligned_mem);
+  }
+  T&
+  operator[] (size_t pos)
+  {
+    return data[pos];
+  }
+  const T&
+  operator[] (size_t pos) const
+  {
+    return data[pos];
+  }
+  size_t
+  size()
+  {
+    return n_elements;
+  }
+};
+
+
 /* --- implementation --- */
 void _birnet_init_threads (void);
 
diff --git a/birnet/tests/Makefile.am b/birnet/tests/Makefile.am
index 2b2a18a..fbac99d 100644
--- a/birnet/tests/Makefile.am
+++ b/birnet/tests/Makefile.am
@@ -35,3 +35,6 @@ sorting_LDADD	 = $(progs_ldadd)
 TESTS		+= datalist
 datalist_SOURCES = datalist.cc
 datalist_LDADD	 = $(progs_ldadd)
+TESTS		+= utils
+utils_SOURCES    = utils.cc
+utils_LDADD	 = $(progs_ldadd)
diff --git a/birnet/tests/utils.cc b/birnet/tests/utils.cc
new file mode 100644
index 0000000..96ace49
--- /dev/null
+++ b/birnet/tests/utils.cc
@@ -0,0 +1,67 @@
+/* Birnet
+ * Copyright (C) 2010 Stefan Westerfeld
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * A copy of the GNU Lesser General Public License should ship along
+ * with this library; if not, see http://www.gnu.org/copyleft/.
+ */
+#include <birnet/birnettests.h>
+
+using namespace Birnet;
+
+struct Foo
+{
+  static int destructor_calls;
+  int value;
+  Foo()
+  {
+    value = 42;
+  }
+  ~Foo()
+  {
+    TASSERT (value == 42);
+    value = 0;
+    destructor_calls++;
+  }
+};
+
+int Foo::destructor_calls = 0;
+
+static void
+test_aligned_array (void)
+{
+  TSTART ("AlignedArray");
+  TOK();
+  AlignedArray<int, 65540> array (3);      // choose an alignment that is unlikely to occur by chance
+  TASSERT (array[0] == 0);
+  TASSERT (array[1] == 0);
+  TASSERT (array[2] == 0);
+  TASSERT (size_t (&array[0]) % 65540 == 0);
+    {
+      AlignedArray<Foo, 40> foo_array (5);
+      TASSERT (size_t (&foo_array[0]) % 40 == 0);
+      for (size_t i = 0; i < foo_array.size(); i++)
+        TASSERT (foo_array[i].value == 42);
+    }
+  TASSERT (Foo::destructor_calls == 5);   // check that all elements have been destructed
+  TOK();
+  TDONE();
+}
+
+int
+main (int   argc,
+      char *argv[])
+{
+  birnet_init_test (&argc, &argv);
+
+  test_aligned_array();
+}
diff --git a/bse/bseresamplerimpl.hh b/bse/bseresamplerimpl.hh
index d9739ab..cffc085 100644
--- a/bse/bseresamplerimpl.hh
+++ b/bse/bseresamplerimpl.hh
@@ -34,6 +34,7 @@ using std::vector;
 using std::min;
 using std::max;
 using std::copy;
+using Birnet::AlignedArray;
 
 /* see: http://ds9a.nl/gcc-simd/ */
 union F4Vector 
@@ -152,63 +153,6 @@ fir_compute_sse_taps (const vector<float>& taps)
   return sse_taps;
 }
 
-/* Helper class to allocate aligned memory */
-template<class T, int ALIGN>
-class AlignedArray {
-  unsigned char *unaligned_mem;
-  T *data;
-  unsigned int n_elements;
-  
-  void
-  allocate_aligned_data()
-  {
-    g_assert ((ALIGN % sizeof (T)) == 0);
-    data = reinterpret_cast<T *> (Birnet::malloc_aligned (n_elements * sizeof (T), ALIGN, &unaligned_mem));
-  }
-  /* no copy constructor and no assignment operator */
-  BIRNET_PRIVATE_CLASS_COPY (AlignedArray);
-public:
-  AlignedArray (const vector<T>& elements) :
-    n_elements (elements.size())
-  {
-    allocate_aligned_data();
-    
-    for (unsigned int i = 0; i < n_elements; i++)
-      new (data + i) T(elements[i]);
-  }
-  AlignedArray (unsigned int n_elements) :
-    n_elements (n_elements)
-  {
-    allocate_aligned_data();
-    
-    for (unsigned int i = 0; i < n_elements; i++)
-      new (data + i) T();
-  }
-  ~AlignedArray()
-  {
-    /* C++ destruction order: last allocated element is deleted first */
-    while (n_elements)
-      data[--n_elements].~T();
-    
-    g_free (unaligned_mem);
-  }
-  T&
-  operator[] (unsigned int pos)
-  {
-    return data[pos];
-  }
-  const T&
-  operator[] (unsigned int pos) const
-  {
-    return data[pos];
-  }
-  unsigned int
-  size()
-  {
-    return n_elements;
-  }
-};
-
 /**
  * This function tests the SSEified FIR filter code (that is, the reordering
  * done by fir_compute_sse_taps and the actual computation implemented in



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