Browse Source

arraynd: replacing array2d and array3d by templated arraynd.

undefined
Guillaume Bittoun Sam Hocevar <sam@hocevar.net> 10 years ago
parent
commit
2f056e0133
5 changed files with 16 additions and 421 deletions
  1. +0
    -2
      src/lol/math/all.h
  2. +0
    -178
      src/lol/math/array2d.h
  3. +0
    -228
      src/lol/math/array3d.h
  4. +14
    -11
      src/lol/math/arraynd.h
  5. +2
    -2
      test/unit/arraynd.cpp

+ 0
- 2
src/lol/math/all.h View File

@@ -20,8 +20,6 @@
#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>
#include <lol/math/interp.h>
#include <lol/math/rand.h>


+ 0
- 178
src/lol/math/array2d.h View File

@@ -1,178 +0,0 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net>
// (c) 2013-2014 Benjamin "Touky" Huet <huet.benjamin@gmail.com>
// This program is free software; you can redistribute it and/or
// modify it under the terms of the Do What The Fuck You Want To
// Public License, Version 2, as published by Sam Hocevar. See
// http://www.wtfpl.net/ for more details.
//

//
// The array2d class
// -----------------
// A very simple 2D array class allowing var[i][j] indexing, with some nice
// additional features, eg. array2d<int,float> for automatic arrays of tuples.
//

//
// FIXME: This file is in lol/math/ instead of lol/base/ because it
// uses ivec2.
//

#if !defined __LOL_MATH_ARRAY2D_H__
#define __LOL_MATH_ARRAY2D_H__

#include <lol/base/array.h>
#include <lol/base/assert.h>

namespace lol
{

template<typename... T>
class array2d : protected array<T...>
{
public:
typedef array<T...> super;
typedef typename super::element_t element_t;

inline array2d()
: m_size(0, 0)
{
}

inline array2d(std::initializer_list<
std::initializer_list<element_t>> const &list)
: m_size(list.size() ? (int)(*list.begin()).size() : 0,
(int)list.size())
{
super::Reserve(m_size.x * m_size.y);
for (auto l : list)
for (auto elem : l)
super::Push(elem);
}

inline array2d(int w, int h)
{
SetSize(ivec2(w, h));
}

inline array2d(ivec2 size)
{
SetSize(size);
}

/* Access elements directly using an ivec2 index */
inline element_t const &operator [](ivec2 pos) const
{
ASSERT(pos.x >= 0);
ASSERT(pos.y >= 0);
ASSERT(pos.x < m_size.x);
ASSERT(pos.y < m_size.y);

ptrdiff_t n = pos.y * m_size.x + pos.x;
ASSERT(n >= 0);
ASSERT(n < this->m_count);

return this->m_data[n];
}

inline element_t &operator [](ivec2 pos)
{
ASSERT(pos.x >= 0);
ASSERT(pos.y >= 0);
ASSERT(pos.x < m_size.x);
ASSERT(pos.y < m_size.y);

ptrdiff_t n = pos.y * m_size.x + pos.x;
ASSERT(n >= 0);
ASSERT(n < this->m_count);

return this->m_data[n];
}

class Column
{
public:
inline Column(array2d &array, ptrdiff_t i)
: m_array(array),
m_column(i)
{
}

inline element_t &operator [](ptrdiff_t j)
{
ASSERT(j >= 0);
ASSERT(j < m_array.m_size.y);
return m_array[ivec2(m_column, j)];
}

private:
array2d<T...> &m_array;
ptrdiff_t m_column;
};

class ConstColumn
{
public:
inline ConstColumn(array2d const &array, ptrdiff_t i)
: m_array(array),
m_column(i)
{
}

inline element_t const &operator [](ptrdiff_t j) const
{
ASSERT(j >= 0);
ASSERT(j < m_array.m_size.y);
return m_array[ivec2(m_column, j)];
}

private:
array2d<T...> const &m_array;
ptrdiff_t m_column;
};

/* Access addressable columns, allowing for array[i][j] syntax. */
inline class Column operator [](ptrdiff_t i)
{
ASSERT(i >= 0);
ASSERT(i < m_size.x);
return Column(*this, i);
}

inline class ConstColumn operator [](ptrdiff_t i) const
{
ASSERT(i >= 0);
ASSERT(i < m_size.x);
return ConstColumn(*this, i);
}

/* Resize the array.
* FIXME: data gets scrambled; should we care? */
inline void SetSize(ivec2 size, element_t e = element_t())
{
this->Resize(size.x * size.y, e);
m_size = size;
}

inline ivec2 GetSize() const
{
return m_size;
}

public:
inline element_t *Data() { return super::Data(); }
inline element_t const *Data() const { return super::Data(); }
inline ptrdiff_t Count() const { return super::Count(); }
inline ptrdiff_t Bytes() const { return super::Bytes(); }

private:
ivec2 m_size;
};

} /* namespace lol */

#endif // __LOL_MATH_ARRAY2D_H__


+ 0
- 228
src/lol/math/array3d.h View File

@@ -1,228 +0,0 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net>
// (c) 2013-2014 Benjamin "Touky" Huet <huet.benjamin@gmail.com>
// This program is free software; you can redistribute it and/or
// modify it under the terms of the Do What The Fuck You Want To
// Public License, Version 2, as published by Sam Hocevar. See
// http://www.wtfpl.net/ for more details.
//

//
// The array3d class
// -----------------
// A very simple 3D array class allowing var[i][j][k] indexing, with some nice
// additional features, eg. array3d<int,float> for automatic arrays of tuples.
//

//
// FIXME: This file is in lol/math/ instead of lol/base/ because it
// uses ivec3.
//

#if !defined __LOL_MATH_ARRAY3D_H__
#define __LOL_MATH_ARRAY3D_H__

#include <lol/base/array.h>
#include <lol/base/assert.h>

namespace lol
{

template<typename... T>
class array3d : protected array<T...>
{
public:
typedef array<T...> super;
typedef typename super::element_t element_t;

inline array3d()
: m_size(0, 0, 0)
{
}

inline array3d(std::initializer_list<
std::initializer_list<
std::initializer_list<element_t>>> const &list)
: m_size(list.size() && (*list.begin()).size() ?
(int)(*(*list.begin()).begin()).size() : 0,
list.size() ? (int)(*list.begin()).size() : 0,
(int)list.size())
{
super::Reserve(m_size.x * m_size.y * m_size.z);
for (auto ll : list)
for (auto l : ll)
for (auto elem : l)
super::Push(elem);
}

inline array3d(int w, int h, int d)
{
SetSize(ivec3(w, h, d));
}

inline array3d(ivec3 size)
{
SetSize(size);
}

/* Access elements directly using an ivec3 index */
inline element_t const &operator [](ivec3 pos) const
{
ASSERT(pos.x >= 0);
ASSERT(pos.y >= 0);
ASSERT(pos.z >= 0);
ASSERT(pos.x < m_size.x);
ASSERT(pos.y < m_size.y);
ASSERT(pos.z < m_size.z);

ptrdiff_t n = (pos.z * m_size.y + pos.y) * m_size.x + pos.x;
ASSERT(n >= 0);
ASSERT(n < this->m_count);

return this->m_data[n];
}

inline element_t &operator [](ivec3 pos)
{
ASSERT(pos.x >= 0);
ASSERT(pos.y >= 0);
ASSERT(pos.z >= 0);
ASSERT(pos.x < m_size.x);
ASSERT(pos.y < m_size.y);
ASSERT(pos.z < m_size.z);

ptrdiff_t n = (pos.z * m_size.y + pos.y) * m_size.x + pos.x;
ASSERT(n >= 0);
ASSERT(n < this->m_count);

return this->m_data[n];
}

class Slice
{
public:
inline Slice(array3d &array, ptrdiff_t i)
: m_array(array),
m_slice(i)
{
}

class Line
{
public:
inline Line(array3d &array, ivec2 ij)
: m_array(array),
m_line(ij)
{
}

inline element_t &operator [](ptrdiff_t k)
{
ASSERT(k >= 0);
ASSERT(k < m_array.m_size.z);
return m_array[ivec3(m_line, k)];
}

private:
array3d<T...> &m_array;
ivec2 m_line;
};

inline class Line operator [](ptrdiff_t j)
{
ASSERT(j >= 0);
ASSERT(j < m_array.m_size.y);
return Line(m_array, ivec2(m_slice, j));
}

private:
array3d<T...> &m_array;
ptrdiff_t m_slice;
};

class ConstSlice
{
public:
inline ConstSlice(array3d const &array, ptrdiff_t i)
: m_array(array),
m_slice(i)
{
}

class Line
{
public:
inline Line(array3d const &array, ivec2 ij)
: m_array(array),
m_line(ij)
{
}

inline element_t const &operator [](ptrdiff_t k) const
{
ASSERT(k >= 0);
ASSERT(k < m_array.m_size.z);
return m_array[ivec3(m_line, k)];
}

private:
array3d<T...> const &m_array;
ivec2 m_line;
};

inline class Line operator [](ptrdiff_t j) const
{
ASSERT(j >= 0);
ASSERT(j < m_array.m_size.y);
return Line(m_array, ivec2(m_slice, j));
}

private:
array3d<T...> const &m_array;
ptrdiff_t m_slice;
};

/* Access addressable slices, allowing for array[i][j][k] syntax. */
inline class Slice operator [](ptrdiff_t i)
{
ASSERT(i >= 0);
ASSERT(i < m_size.x);
return Slice(*this, i);
}

inline class ConstSlice operator [](ptrdiff_t i) const
{
ASSERT(i >= 0);
ASSERT(i < m_size.x);
return ConstSlice(*this, i);
}

/* Resize the array.
* FIXME: data gets scrambled; should we care? */
inline void SetSize(ivec3 size, element_t e = element_t())
{
this->Resize(size.x * size.y * size.z, e);
m_size = size;
}

inline ivec3 GetSize() const
{
return m_size;
}

public:
inline element_t *Data() { return super::Data(); }
inline element_t const *Data() const { return super::Data(); }
inline ptrdiff_t Count() const { return super::Count(); }
inline ptrdiff_t Bytes() const { return super::Bytes(); }

private:
ivec3 m_size;
};

} /* namespace lol */

#endif // __LOL_MATH_ARRAY3D_H__


+ 14
- 11
src/lol/math/arraynd.h View File

@@ -43,15 +43,15 @@ public:
{
}

void FillSizes(ptrdiff_t * sizes)
void FillSizes(int * sizes)
{
*sizes = std::max(*sizes, (ptrdiff_t)(m_initializers.size()));
*sizes = std::max((ptrdiff_t)*sizes, (ptrdiff_t)(m_initializers.size()));

for (auto subinitializer : m_initializers)
subinitializer.FillSizes(sizes - 1);
}

void FillValues(T * origin, ptrdiff_t prev, ptrdiff_t * sizes)
void FillValues(T * origin, ptrdiff_t prev, int * sizes)
{
ptrdiff_t pos = 0;

@@ -75,12 +75,12 @@ public:
{
}

void FillSizes(ptrdiff_t * sizes)
void FillSizes(int * sizes)
{
*sizes = std::max(*sizes, (ptrdiff_t)(m_initializers.size()));
*sizes = std::max((ptrdiff_t)*sizes, (ptrdiff_t)(m_initializers.size()));
}

void FillValues(T * origin, ptrdiff_t prev, ptrdiff_t * sizes)
void FillValues(T * origin, ptrdiff_t prev, int * sizes)
{
UNUSED(sizes);

@@ -107,7 +107,7 @@ public:
{
}

inline arraynd(vec_t<ptrdiff_t, N> sizes, element_t e = element_t())
inline arraynd(vec_t<int, N> sizes, element_t e = element_t())
: m_sizes(sizes)
{
FixSizes(e);
@@ -137,7 +137,7 @@ public:
return super::operator[](n);
}

inline element_t & operator[](vec_t<ptrdiff_t, N> const &pos)
inline element_t & operator[](vec_t<int, N> const &pos)
{
return const_cast<element_t &>(
const_cast<arraynd<N, T...> const&>(*this)[pos]);
@@ -207,13 +207,13 @@ public:

/* Resize the array.
* FIXME: data gets scrambled; should we care? */
inline void SetSize(vec_t<ptrdiff_t, N> sizes, element_t e = element_t())
inline void SetSize(vec_t<int, N> sizes, element_t e = element_t())
{
m_sizes = sizes;
FixSizes(e);
}

inline vec_t<ptrdiff_t, N> GetSize() const
inline vec_t<int, N> GetSize() const
{
return this->m_sizes;
}
@@ -235,9 +235,12 @@ private:
this->Resize(total_size, e);
}

vec_t<ptrdiff_t, N> m_sizes;
vec_t<int, N> m_sizes;
};

template<typename... T> using array2d = arraynd<2, T...>;
template<typename... T> using array3d = arraynd<3, T...>;

} /* namespace lol */

#endif // __LOL_MATH_ARRAYND_H__


+ 2
- 2
test/unit/arraynd.cpp View File

@@ -29,7 +29,7 @@ LOLUNIT_FIXTURE(ArrayNDTest)
LOLUNIT_TEST(Array2D)
{
arraynd<2, int> a;
a.SetSize(vec_t<ptrdiff_t, 2>(2, 2));
a.SetSize(vec_t<int, 2>(2, 2));

/* Non-const accessors */
a[0][0] = 1;
@@ -98,7 +98,7 @@ LOLUNIT_FIXTURE(ArrayNDTest)
LOLUNIT_TEST(ArrayNDInit)
{
int const NDIM = 8;
vec_t<ptrdiff_t, NDIM> size;
vec_t<int, NDIM> size;
for (int i = 0; i < NDIM; ++i)
size[i] = 5;



Loading…
Cancel
Save