Browse Source

Refactor arraynd class.

Use size_t instead of ptrdiff_t and reduce header usage.
wip/core-clipp
Sam Hocevar 5 years ago
parent
commit
20f39ee086
1 changed files with 41 additions and 40 deletions
  1. +41
    -40
      legacy/lol/math/arraynd.h

+ 41
- 40
legacy/lol/math/arraynd.h View File

@@ -25,11 +25,12 @@
// //


#include <lol/base/array.h> #include <lol/base/array.h>
#include <../legacy/lol/base/assert.h>
#include <lol/math/vector.h> // vec_t


#include <cstddef>
#include <algorithm> // std::min
#include <cstring> // memset
#include <climits> #include <climits>
#include <type_traits>
#include <type_traits> // std::enable_if


namespace lol namespace lol
{ {
@@ -44,15 +45,15 @@ public:
{ {
} }


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


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


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


@@ -76,12 +77,12 @@ public:
{ {
} }


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


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


@@ -104,16 +105,16 @@ public:


inline arraynd() = default; inline arraynd() = default;


inline arraynd(vec_t<ptrdiff_t, N> sizes, element_t e = element_t())
inline arraynd(vec_t<size_t, N> sizes, element_t e = element_t())
: m_sizes(sizes) : m_sizes(sizes)
{ {
resize_data(e); resize_data(e);
} }


/* Additional constructor if ptrdiff_t != int */
template<typename T2 = int, typename T3 = typename std::enable_if<!std::is_same<ptrdiff_t, T2>::value, int>::type>
/* Additional constructor if size_t != int */
template<typename T2 = int, typename T3 = typename std::enable_if<!std::is_same<size_t, T2>::value, int>::type>
inline arraynd(vec_t<T2, N> sizes, element_t e = element_t()) inline arraynd(vec_t<T2, N> sizes, element_t e = element_t())
: m_sizes(vec_t<ptrdiff_t, N>(sizes))
: m_sizes(vec_t<size_t, N>(sizes))
{ {
resize_data(e); resize_data(e);
} }
@@ -133,33 +134,33 @@ public:
inner_initializer.fill_values(&super::operator[](0), pos++, &m_sizes[N - 2]); inner_initializer.fill_values(&super::operator[](0), pos++, &m_sizes[N - 2]);
} }


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


inline element_t & operator[](vec_t<ptrdiff_t, N> const &pos)
inline element_t & operator[](vec_t<size_t, N> const &pos)
{ {
return const_cast<element_t &>( return const_cast<element_t &>(
const_cast<arraynd<N, T...> const&>(*this)[pos]); const_cast<arraynd<N, T...> const&>(*this)[pos]);
} }


/* If int != ptrdiff_t, access elements directly using an ivec2,
/* If int != size_t, access elements directly using an ivec2,
* ivec3 etc. */ * ivec3 etc. */
template<typename T2 = int, typename T3 = typename std::enable_if<!std::is_same<ptrdiff_t, T2>::value, int>::type>
template<typename T2 = int, typename T3 = typename std::enable_if<!std::is_same<size_t, T2>::value, int>::type>
inline element_t const & operator[](vec_t<T2, N> const &pos) const inline element_t const & operator[](vec_t<T2, N> const &pos) const
{ {
ptrdiff_t n = pos[N - 1];
for (ptrdiff_t i = N - 2; i >= 0; --i)
n = pos[i] + m_sizes[i + 1] * n;
size_t n = pos[N - 1];
for (size_t i = N - 1; i > 0; --i)
n = pos[i - 1] + m_sizes[i] * n;
return super::operator[](n); return super::operator[](n);
} }


template<typename T2 = int, typename T3 = typename std::enable_if<!std::is_same<ptrdiff_t, T2>::value, int>::type>
template<typename T2 = int, typename T3 = typename std::enable_if<!std::is_same<size_t, T2>::value, int>::type>
inline element_t & operator[](vec_t<T2, N> const &pos) inline element_t & operator[](vec_t<T2, N> const &pos)
{ {
return const_cast<element_t &>( return const_cast<element_t &>(
@@ -173,7 +174,7 @@ public:
public: public:
typedef slice<ARRAY_TYPE, L - 1> subslice; typedef slice<ARRAY_TYPE, L - 1> subslice;


inline slice(ARRAY_TYPE &array, ptrdiff_t index, ptrdiff_t accumulator)
inline slice(ARRAY_TYPE &array, size_t index, size_t accumulator)
: m_array(array), : m_array(array),
m_index(index), m_index(index),
m_accumulator(accumulator) m_accumulator(accumulator)
@@ -183,7 +184,7 @@ public:
/* Accessors for the const version of the proxy */ /* Accessors for the const version of the proxy */
template<bool V = L != 1 && std::is_const<ARRAY_TYPE>::value> template<bool V = L != 1 && std::is_const<ARRAY_TYPE>::value>
inline typename std::enable_if<V, subslice>::type inline typename std::enable_if<V, subslice>::type
operator[](ptrdiff_t pos) const
operator[](size_t pos) const
{ {
return subslice(m_array, m_index + pos * m_accumulator, return subslice(m_array, m_index + pos * m_accumulator,
m_accumulator * m_array.m_sizes[N - L]); m_accumulator * m_array.m_sizes[N - L]);
@@ -191,7 +192,7 @@ public:


template<bool V = L == 1 && std::is_const<ARRAY_TYPE>::value> template<bool V = L == 1 && std::is_const<ARRAY_TYPE>::value>
inline typename std::enable_if<V, typename ARRAY_TYPE::element_t>::type inline typename std::enable_if<V, typename ARRAY_TYPE::element_t>::type
const & operator[](ptrdiff_t pos) const
const & operator[](size_t pos) const
{ {
return m_array.super::operator[](m_index + pos * m_accumulator); return m_array.super::operator[](m_index + pos * m_accumulator);
} }
@@ -199,7 +200,7 @@ public:
/* Accessors for the non-const version of the proxy */ /* Accessors for the non-const version of the proxy */
template<bool V = L != 1 && !std::is_const<ARRAY_TYPE>::value> template<bool V = L != 1 && !std::is_const<ARRAY_TYPE>::value>
inline typename std::enable_if<V, subslice>::type inline typename std::enable_if<V, subslice>::type
operator[](ptrdiff_t pos)
operator[](size_t pos)
{ {
return subslice(m_array, m_index + pos * m_accumulator, return subslice(m_array, m_index + pos * m_accumulator,
m_accumulator * m_array.m_sizes[N - L]); m_accumulator * m_array.m_sizes[N - L]);
@@ -207,23 +208,23 @@ public:


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


private: private:
ARRAY_TYPE &m_array; ARRAY_TYPE &m_array;
ptrdiff_t m_index, m_accumulator;
size_t m_index, m_accumulator;
}; };


/* Access addressable slices, allowing for array[i][j][...] syntax. */ /* Access addressable slices, allowing for array[i][j][...] syntax. */
inline slice<arraynd<N, T...> const> operator[](ptrdiff_t pos) const
inline slice<arraynd<N, T...> const> operator[](size_t pos) const
{ {
return slice<arraynd<N, T...> const>(*this, pos, m_sizes[0]); return slice<arraynd<N, T...> const>(*this, pos, m_sizes[0]);
} }


inline slice<arraynd<N, T...>> operator[](ptrdiff_t pos)
inline slice<arraynd<N, T...>> operator[](size_t pos)
{ {
return slice<arraynd<N, T...>>(*this, pos, m_sizes[0]); return slice<arraynd<N, T...>>(*this, pos, m_sizes[0]);
} }
@@ -232,10 +233,10 @@ public:
* FIXME: data gets scrambled; should we care? */ * FIXME: data gets scrambled; should we care? */
inline void resize(vec_t<int, N> sizes, element_t e = element_t()) inline void resize(vec_t<int, N> sizes, element_t e = element_t())
{ {
resize_s(vec_t<ptrdiff_t, N>(sizes), e);
resize_s(vec_t<size_t, N>(sizes), e);
} }


inline void resize_s(vec_t<ptrdiff_t, N> sizes, element_t e = element_t())
inline void resize_s(vec_t<size_t, N> sizes, element_t e = element_t())
{ {
m_sizes = sizes; m_sizes = sizes;
resize_data(e); resize_data(e);
@@ -246,7 +247,7 @@ public:
return vec_t<int, N>(this->m_sizes); return vec_t<int, N>(this->m_sizes);
} }


inline vec_t<ptrdiff_t, N> size_s() const
inline vec_t<size_t, N> size_s() const
{ {
return this->m_sizes; return this->m_sizes;
} }
@@ -256,13 +257,13 @@ public:
inline element_t const *data() const { return super::data(); } inline element_t const *data() const { return super::data(); }
inline int count() const { return super::count(); } inline int count() const { return super::count(); }
inline int bytes() const { return super::bytes(); } inline int bytes() const { return super::bytes(); }
inline ptrdiff_t count_s() const { return super::count_s(); }
inline ptrdiff_t bytes_s() const { return super::bytes_s(); }
inline size_t count_s() const { return super::count_s(); }
inline size_t bytes_s() const { return super::bytes_s(); }


private: private:
inline void resize_data(element_t e = element_t()) inline void resize_data(element_t e = element_t())
{ {
ptrdiff_t total_size = 1;
size_t total_size = 1;


/* HACK: we can't use for (auto s : m_sizes) because of an ICE in /* HACK: we can't use for (auto s : m_sizes) because of an ICE in
* the Visual Studio compiler. */ * the Visual Studio compiler. */
@@ -272,7 +273,7 @@ private:
this->array<T...>::resize(total_size, e); this->array<T...>::resize(total_size, e);
} }


vec_t<ptrdiff_t, N> m_sizes { 0 };
vec_t<size_t, N> m_sizes { 0 };
}; };


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


Loading…
Cancel
Save