|
|
@@ -3,6 +3,7 @@ |
|
|
|
// |
|
|
|
// Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net> |
|
|
|
// (c) 2013-2014 Benjamin "Touky" Huet <huet.benjamin@gmail.com> |
|
|
|
// (c) 2013-2014 Guillaume Bittoun <guillaume.bittoun@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 |
|
|
@@ -17,7 +18,7 @@ |
|
|
|
|
|
|
|
// |
|
|
|
// FIXME: This file is in lol/math/ instead of lol/base/ because it |
|
|
|
// uses ivec3. |
|
|
|
// uses vec_t. |
|
|
|
// |
|
|
|
|
|
|
|
#if !defined __LOL_MATH_ARRAYND_H__ |
|
|
@@ -85,6 +86,73 @@ private: |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
template<typename T, size_t L> |
|
|
|
class arraynd_initializer |
|
|
|
{ |
|
|
|
public: |
|
|
|
|
|
|
|
arraynd_initializer(std::initializer_list<arraynd_initializer<T, L - 1> > const & initializers) : |
|
|
|
m_initializers(initializers) |
|
|
|
{ |
|
|
|
} |
|
|
|
|
|
|
|
void FillSizes(size_t * sizes) |
|
|
|
{ |
|
|
|
*sizes = std::max(*sizes, m_initializers.size()); |
|
|
|
|
|
|
|
for (auto subinitializer : m_initializers) |
|
|
|
subinitializer.FillSizes(sizes + 1); |
|
|
|
} |
|
|
|
|
|
|
|
void FillValues(T * values, size_t * sizes, size_t accumulator) |
|
|
|
{ |
|
|
|
int pos = 0; |
|
|
|
|
|
|
|
for (auto subinitializer : m_initializers) |
|
|
|
{ |
|
|
|
subinitializer.FillValues(values + pos * accumulator, sizes + 1, accumulator * *sizes); |
|
|
|
++pos; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
std::initializer_list<arraynd_initializer<T, L - 1> > const & m_initializers; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
template<typename T> |
|
|
|
class arraynd_initializer<T, 1> |
|
|
|
{ |
|
|
|
public: |
|
|
|
|
|
|
|
arraynd_initializer(std::initializer_list<T> const & initializers) : |
|
|
|
m_initializers(initializers) |
|
|
|
{ |
|
|
|
} |
|
|
|
|
|
|
|
void FillSizes(size_t * sizes) |
|
|
|
{ |
|
|
|
*sizes = std::max(*sizes, m_initializers.size()); |
|
|
|
} |
|
|
|
|
|
|
|
void FillValues(T * values, size_t * sizes, size_t accumulator) |
|
|
|
{ |
|
|
|
int pos = 0; |
|
|
|
|
|
|
|
for (auto value : m_initializers) |
|
|
|
{ |
|
|
|
*(values + pos * accumulator) = value; |
|
|
|
++pos; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
std::initializer_list<T> const & m_initializers; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
template<size_t N, typename T1, typename T2 = void, typename T3 = void, |
|
|
|
typename T4 = void, typename T5 = void, typename T6 = void, |
|
|
|
typename T7 = void, typename T8 = void> |
|
|
@@ -93,7 +161,7 @@ class arraynd : protected array<T1, T2, T3, T4, T5, T6, T7, T8> |
|
|
|
public: |
|
|
|
typedef array<T1, T2, T3, T4, T5, T6, T7, T8> super; |
|
|
|
typedef typename super::element_t element_t; |
|
|
|
typedef arraynd_proxy<N, N, super> proxy; |
|
|
|
typedef arraynd_proxy<N, N - 1, super> proxy; |
|
|
|
|
|
|
|
inline arraynd() : |
|
|
|
super(), |
|
|
@@ -108,7 +176,16 @@ public: |
|
|
|
SetSize(m_sizes, e); |
|
|
|
} |
|
|
|
|
|
|
|
/* Access elements directly using an ivec3 index */ |
|
|
|
inline arraynd(arraynd_initializer<element_t, N> initializer) : |
|
|
|
super(), |
|
|
|
m_sizes() |
|
|
|
{ |
|
|
|
initializer.FillSizes(&m_sizes[0]); |
|
|
|
SetSize(m_sizes); |
|
|
|
initializer.FillValues(&super::operator[](0), &m_sizes[0], 1); |
|
|
|
} |
|
|
|
|
|
|
|
/* Access elements directly using index position */ |
|
|
|
inline proxy operator [](size_t pos) const |
|
|
|
{ |
|
|
|
return proxy(this, m_sizes, pos, m_sizes[0]); |
|
|
|