Переглянути джерело

math: activate arraynd and simplify some stuff in there.

undefined
Sam Hocevar 10 роки тому
джерело
коміт
47f7fabbd9
3 змінених файлів з 93 додано та 119 видалено
  1. +1
    -0
      src/lol/math/all.h
  2. +68
    -112
      src/lol/math/arraynd.h
  3. +24
    -7
      test/unit/arraynd.cpp

+ 1
- 0
src/lol/math/all.h Переглянути файл

@@ -19,6 +19,7 @@
#include <lol/math/vector.h>
#include <lol/math/matrix.h>
#include <lol/math/transform.h>
#include <lol/math/arraynd.h>
#include <lol/math/array2d.h>
#include <lol/math/array3d.h>
#include <lol/math/geometry.h>


+ 68
- 112
src/lol/math/arraynd.h Переглянути файл

@@ -27,63 +27,10 @@
#include <lol/base/array.h>
#include <lol/base/assert.h>

namespace lol
{

template<size_t N, size_t L, typename ARRAY_TYPE>
class arraynd_proxy
{
public:

typedef arraynd_proxy<N, L - 1, ARRAY_TYPE> subproxy;

inline arraynd_proxy(ARRAY_TYPE * array, vec_t<size_t, N> const & sizes, size_t index, size_t accumulator) :
m_array(array),
m_sizes(sizes),
m_index(index),
m_accumulator(accumulator)
{
}

inline subproxy operator[](size_t pos)
{
return subproxy(m_array, this->m_sizes, m_index + pos * m_accumulator, m_accumulator * m_sizes[N - L]);
}

private:

ARRAY_TYPE * m_array;
vec_t<size_t, N> const & m_sizes;
size_t m_index;
size_t m_accumulator;
};

#include <type_traits>

template<size_t N, typename ARRAY_TYPE>
class arraynd_proxy<N, 1, ARRAY_TYPE>
namespace lol
{
public:

inline arraynd_proxy(ARRAY_TYPE * array, vec_t<size_t, N> const & sizes, size_t index, size_t accumulator) :
m_array(array),
m_sizes(sizes),
m_index(index),
m_accumulator(accumulator)
{
}

inline typename ARRAY_TYPE::element_t & operator[](size_t pos)
{
return m_array[m_index + pos * m_accumulator];
}

private:

ARRAY_TYPE * m_array;
vec_t<size_t, N> const & m_sizes;
size_t m_index;
size_t m_accumulator;
};


template<typename T, size_t L>
@@ -159,7 +106,6 @@ class arraynd : protected array<T...>
public:
typedef array<T...> super;
typedef typename super::element_t element_t;
typedef arraynd_proxy<N, N - 1, super> proxy;

inline arraynd() :
super(),
@@ -183,86 +129,96 @@ public:
initializer.FillValues(&super::operator[](0), &m_sizes[0], 1);
}

/* Access elements directly using index position */
inline proxy operator[](size_t pos) const
/* Access elements directly using an ivec2, ivec3 etc. index */
inline element_t const & operator[](vec_t<int, N> const &pos) const
{
return proxy(this, m_sizes, pos, m_sizes[0]);
size_t n = pos[N - 1];
for (int i = N - 2; i >= 0; --i)
n = pos[i] + m_sizes[i + 1] * n;
return super::operator[](n);
}

/* Resize the array.
* FIXME: data gets scrambled; should we care? */
inline void SetSize(vec_t<size_t, N> sizes, element_t e = element_t())
inline element_t & operator[](vec_t<int, N> const &pos)
{
size_t total_size = 1;

for (auto size : sizes)
total_size *= size;

this->Resize(total_size, e);
return const_cast<element_t &>(
const_cast<arraynd<N, T...> const&>(*this)[pos]);
}

inline vec_t<size_t, N> GetSize() const
/* Proxy to access slices */
template<typename ARRAY_TYPE, size_t L = N - 1>
class slice
{
return this->m_sizes;
}
public:
typedef slice<ARRAY_TYPE, L - 1> subslice;

public:
inline element_t *Data() { return super::Data(); }
inline element_t const *Data() const { return super::Data(); }
inline int Count() const { return super::Count(); }
inline int Bytes() const { return super::Bytes(); }
inline slice(ARRAY_TYPE &array, size_t index, size_t accumulator)
: m_array(array),
m_index(index),
m_accumulator(accumulator)
{
}

private:
vec_t<size_t, N> m_sizes;
};
/* Accessors for the const version of the proxy */
template<bool V = L != 1 && std::is_const<ARRAY_TYPE>::value>
inline typename std::enable_if<V, subslice>::type
operator[](size_t pos) const
{
return subslice(m_array, m_index + pos * m_accumulator,
m_accumulator * m_array.m_sizes[N - L]);
}

template<bool V = L == 1 && std::is_const<ARRAY_TYPE>::value>
inline typename std::enable_if<V, typename ARRAY_TYPE::element_t>::type
const & operator[](size_t pos) const
{
return m_array.super::operator[](m_index + pos * m_accumulator);
}

template<typename... T>
class arraynd<1, T...> : protected array<T...>
{
public:
typedef array<T...> super;
typedef typename super::element_t element_t;
/* Accessors for the non-const version of the proxy */
template<bool V = L != 1 && !std::is_const<ARRAY_TYPE>::value>
inline typename std::enable_if<V, subslice>::type
operator[](size_t pos)
{
return subslice(m_array, m_index + pos * m_accumulator,
m_accumulator * m_array.m_sizes[N - L]);
}

inline arraynd() :
super(),
m_sizes()
{
}
template<bool V = L == 1 && !std::is_const<ARRAY_TYPE>::value>
inline typename std::enable_if<V, typename ARRAY_TYPE::element_t>::type
& operator[](size_t pos)
{
return m_array.super::operator[](m_index + pos * m_accumulator);
}

inline arraynd(vec_t<size_t, 1> sizes, element_t e = element_t()) :
super(),
m_sizes(sizes)
{
SetSize(m_sizes, e);
}
private:
ARRAY_TYPE &m_array;
size_t m_index, m_accumulator;
};

inline arraynd(std::initializer_list<element_t> initializer) :
super(),
m_sizes()
/* Access addressable slices, allowing for array[i][j][...] syntax. */
inline slice<arraynd<N, T...> const> operator[](size_t pos) const
{
m_sizes[0] = initializer.size();
SetSize(m_sizes[0]);

size_t pos = 0;
for (auto element : initializer)
(*this)[pos++] = element;
return slice<arraynd<N, T...> const>(*this, pos, m_sizes[0]);
}

/* Access elements directly using index position */
inline element_t & operator[](size_t pos) const
inline slice<arraynd<N, T...>> operator[](size_t pos)
{
return super::operator[](pos);
return slice<arraynd<N, T...>>(*this, pos, m_sizes[0]);
}

/* Resize the array.
* FIXME: data gets scrambled; should we care? */
inline void SetSize(vec_t<size_t, 1> sizes, element_t e = element_t())
inline void SetSize(vec_t<size_t, N> sizes, element_t e = element_t())
{
this->Resize(m_sizes[0], e);
size_t total_size = 1;

for (auto size : sizes)
total_size *= size;

this->Resize(total_size, e);
}

inline vec_t<size_t, 1> GetSize() const
inline vec_t<size_t, N> GetSize() const
{
return this->m_sizes;
}
@@ -274,7 +230,7 @@ public:
inline int Bytes() const { return super::Bytes(); }

private:
vec_t<size_t, 1> m_sizes;
vec_t<size_t, N> m_sizes;
};

} /* namespace lol */


+ 24
- 7
test/unit/arraynd.cpp Переглянути файл

@@ -24,7 +24,21 @@ LOLUNIT_FIXTURE(ArrayNDTest)

void TearDown() {}

#if 0
LOLUNIT_TEST(Array2D)
{
arraynd<2, int> a;
a.SetSize(vec_t<size_t, 2>(1, 2));

a[0][0] = 1;
a[0][1] = 2;
LOLUNIT_ASSERT_EQUAL(a[0][0], 1);
LOLUNIT_ASSERT_EQUAL(a[0][1], 2);

arraynd<2, int> const &b = a;
LOLUNIT_ASSERT_EQUAL(b[0][0], 1);
LOLUNIT_ASSERT_EQUAL(b[0][1], 2);
}

LOLUNIT_TEST(ArrayNDCreate)
{
arraynd<10, int> a;
@@ -35,23 +49,26 @@ LOLUNIT_FIXTURE(ArrayNDTest)

LOLUNIT_TEST(ArrayNDInit)
{
int const dimension = 8;
vec_t<size_t, dimension> size;
for (int i = 0; i < dimension; ++i)
int const NDIM = 8;
vec_t<size_t, NDIM> size;
for (int i = 0; i < NDIM; ++i)
size[i] = 5;

arraynd<dimension, uint8_t> a(size);
arraynd<NDIM, uint8_t> a(size);
memset(a.Data(), 0, a.Bytes());
LOLUNIT_ASSERT_EQUAL(a[2][3][2][0][1][4][0][1], 0x00);

vec_t<int, dimension> v{ 2, 3, 2, 0, 1, 4, 0, 1 };
vec_t<int, NDIM> v = { 2, 3, 2, 0, 1, 4, 0, 1 };
LOLUNIT_ASSERT_EQUAL(a[v], 0x00);

a[2][3][2][0][1][4][0][1] = 0xcd;
LOLUNIT_ASSERT_EQUAL(a[2][3][2][0][1][4][0][1], 0xcd);
LOLUNIT_ASSERT_EQUAL(a[v], 0xcd);

arraynd<NDIM, uint8_t> const &b = a;
LOLUNIT_ASSERT_EQUAL(b[2][3][2][0][1][4][0][1], 0xcd);
LOLUNIT_ASSERT_EQUAL(b[v], 0xcd);
}
#endif
};

} /* namespace lol */


Завантаження…
Відмінити
Зберегти