3

I made a mathematical multi-dimensional data structure, consider the following code:

template <class T, size_t ... Dims>
class ZAMultiDimTable
{
public:
    static constexpr size_t nDims = sizeof...(Dims);
    static constexpr size_t nElements = (... * Dims);
    static constexpr std::array<size_t, nDims> _indices = {Dims...};

    static size_t addIndices(size_t ind1,size_t ind2)
    {
        size_t ret = 0;
        size_t mul = 1;
        for (size_t i=0; i< nDims;++i)
        {
            ret+=mul*((ind1+ind2)%_indices[i]);
            ind1/=_indices[i];
            ind2/=_indices[i];
            mul*=_indices[i];
        }
        return ret;

    }

    friend inline const ZAMultiDimTable<T, Dims...>  operator*(const ZAMultiDimTable<T, Dims...>& l,const ZAMultiDimTable<T, Dims...>& r)
    {
        ZAMultiDimTable<T, Dims...> m;
        for(size_t i=0; i < nElements; ++i)
        {
            for (size_t j = 0; j < nElements; ++j)
            {
                m._table[addIndices(i,j)]+=l._table[i]*r._table[j];
            }
        }
        return m;
    }


private:
    std::array<T, nElements > _table;
};

the function addIndices() breaks two combined indices to the representation of multi-dimensions, and then add them.

Now, I want to create a static 2d array with size [nElements][nElements] that will replace the function addIndices(). How do I do that in an elegant way at compile time?

3
  • 1
    did you consider making a 1d array with nElements² elements and just calculating the index by x + y * nElements Commented May 21, 2019 at 19:37
  • Even in that way, I don't know how make that in templates. but 2dim is more elegant, and I think also that it's faster Commented May 21, 2019 at 19:43
  • 2d will not be faster. your overengineering a quite simple problem. maybe just consider std::vector, also the compiletime size will not give you a relevant performance improvement in most cases Commented May 21, 2019 at 19:50

1 Answer 1

4

I want to create a static 2d array with size [nElements][nElements] that will replace the function "addIndices". How do I do that in an elegant way at compile time?

Suggestion: avoid C-style arrays and use (this time) std::array instead.

Following this suggestion, I propose

1) make getIndices() a constexpr method

2) define the following using (just to simplify your life in following points) or something similar (maybe with a better name)

using arr2D = std::array<std::array<std::size_t, nElements>, nElements>;

3) define the following static constexpr method

static constexpr arr2D getIndices ()
 {
   arr2D  ret;

   for ( auto i = 0u ; i < nElements; ++i )
      for ( auto j = 0u ; j < nElements; ++j )
         ret[i][j] = addIndices(i, j);

   return ret;
 }

4) add the following static constexpr member in the class (initialized as follows)

static constexpr arr2D inds { getIndices() };

Now you have your indices in a constexpr member that is initialized compile-time.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.