1 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
2 
3 #ifndef SPECTMORPH_ALIGNED_ARRAY_HH
4 #define SPECTMORPH_ALIGNED_ARRAY_HH
5 
6 #include <glib.h>
7 #include "smutils.hh"
8 
9 namespace SpectMorph
10 {
11 
12 /* --- memory utils --- */
13 void* malloc_aligned            (size_t                total_size,
14                                  size_t                alignment,
15                                  uint8               **free_pointer);
16 
17 template<class T, int ALIGN>
18 class AlignedArray {
19   unsigned char *unaligned_mem;
20   T *data;
21   size_t n_elements;
22   void
allocate_aligned_data()23   allocate_aligned_data()
24   {
25     g_assert ((ALIGN % sizeof (T)) == 0);
26     data = reinterpret_cast<T *> (malloc_aligned (n_elements * sizeof (T), ALIGN, &unaligned_mem));
27   }
28 public:
AlignedArray(size_t n_elements)29   AlignedArray (size_t n_elements) :
30     n_elements (n_elements)
31   {
32     allocate_aligned_data();
33     for (size_t i = 0; i < n_elements; i++)
34       new (data + i) T();
35   }
~AlignedArray()36   ~AlignedArray()
37   {
38     /* C++ destruction order: last allocated element is deleted first */
39     while (n_elements)
40       data[--n_elements].~T();
41     g_free (unaligned_mem);
42   }
43   T&
operator [](size_t pos)44   operator[] (size_t pos)
45   {
46     return data[pos];
47   }
48   const T&
operator [](size_t pos) const49   operator[] (size_t pos) const
50   {
51     return data[pos];
52   }
size() const53   size_t size () const
54   {
55     return n_elements;
56   }
57 };
58 
59 }
60 
61 #endif /* SPECTMORPH_ALIGNED_ARRAY_HH */
62