Browse Source

Rename arraynd to old_arraynd and create new lol::narray implementation.

pull/1/head
Sam Hocevar 4 years ago
parent
commit
e073082150
3 changed files with 179 additions and 20 deletions
  1. +18
    -0
      include/lol/narray
  2. +141
    -0
      include/lol/private/base/narray.h
  3. +20
    -20
      legacy/lol/math/arraynd.h

+ 18
- 0
include/lol/narray View File

@@ -0,0 +1,18 @@
//
// Lol Engine
//
// Copyright © 2010—2020 Sam Hocevar <sam@hocevar.net>
//
// Lol Engine is free software. It comes without any warranty, to
// the extent permitted by applicable law. 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 the WTFPL Task Force.
// See http://www.wtfpl.net/ for more details.
//

#pragma once

#include "private/push_macros.h"
#include "private/base/narray.h"
#include "private/pop_macros.h"


+ 141
- 0
include/lol/private/base/narray.h View File

@@ -0,0 +1,141 @@
//
// Lol Engine
//
// Copyright © 2010—2020 Sam Hocevar <sam@hocevar.net>
//
// Lol Engine is free software. It comes without any warranty, to
// the extent permitted by applicable law. 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 the WTFPL Task Force.
// See http://www.wtfpl.net/ for more details.
//

#pragma once

//
// The narray class
// ————————————————
// An N-dimensional row-major array template class
//

#include <lol/vector> // lol::vec_t
#include <vector> // std::vector

namespace lol
{

template<typename T, size_t N>
class [[nodiscard]] narray
{
public:
typedef T value_type;

inline narray() = default;
inline ~narray() = default;

// Construct array with args: size1, size2, ..., sizen
template<typename... I> inline narray(I... sizes)
{
static_assert(N == sizeof...(I));
resize(sizes...);
}

// Construct array with integer vec_t arg:
inline narray(vec_t<int, N> const &sizes)
{
resize(sizes);
}

// Empty array
inline void clear() { resize(vec_t<size_t, N>(0)); }

// Access element i
inline value_type &operator[](size_t i)
{
return m_data[i];
}

inline value_type const &operator[](size_t i) const
{
return m_data[i];
}

// Access element (i, j, .., z) in row-major fashion
template<typename... I>
inline value_type &operator()(I... indices)
{
static_assert(N == sizeof...(I));
return m_data[offset(indices...)];
}

template<typename... I>
inline value_type const &operator()(I... indices) const
{
static_assert(N == sizeof...(I));
return m_data[offset(indices...)];
}

inline value_type &operator()(vec_t<int, N> const &indices)
{
return m_data[offset_helper(indices, std::make_index_sequence<N>{})];
}

inline value_type const &operator()(vec_t<int, N> const &indices) const
{
return m_data[offset_helper(indices, std::make_index_sequence<N>{})];
}

// Resize array with a list of sizes (size1, size2, ..., sizen)
template<typename... I>
inline void resize(I... sizes)
{
static_assert(N == sizeof...(I));
m_data.resize((size_t(sizes) * ... * 1));
m_sizes = { size_t(sizes)... };
}

inline void resize(vec_t<int, N> const &sizes)
{
resize_helper(sizes, std::make_index_sequence<N>{});
}

// Return sizes of each dimension
inline vec_t<int, N> sizes() const
{
return vec_t<int, N>(this->m_sizes);
}

inline value_type *data() { return m_data.data(); }
inline value_type const *data() const { return m_data.data(); }
inline size_t size() const { return m_data.size(); }
inline size_t bytes() const { return size() * sizeof(value_type); }

private:
template<typename... I> size_t offset(size_t i, I... indices) const
{
if constexpr(sizeof...(I) > 0)
i += m_sizes[N - sizeof...(I) - 1] * offset(indices...);
return i;
}

template <std::size_t... I>
size_t offset_helper(vec_t<int, N> const &sizes, std::index_sequence<I...>) const
{
return offset(size_t(sizes[I])...);
}

template <std::size_t... I>
void resize_helper(vec_t<int, N> const &sizes, std::index_sequence<I...>)
{
resize(sizes[I]...);
}

vec_t<size_t, N> m_sizes { 0 };
std::vector<T> m_data;
};

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

} // namespace lol


+ 20
- 20
legacy/lol/math/arraynd.h View File

@@ -15,8 +15,8 @@
#pragma once #pragma once


// //
// The arraynd class
// -----------------
// The old_arraynd class
// —————————————————————
// A N-Dimensional array class allowing var[i][j][k]... indexing, // A N-Dimensional array class allowing var[i][j][k]... indexing,
// //


@@ -31,11 +31,11 @@ namespace lol
{ {


template<typename T, int L> template<typename T, int L>
class arraynd_initializer
class old_arraynd_initializer
{ {
public: public:


arraynd_initializer(std::initializer_list<arraynd_initializer<T, L - 1> > const & initializers) :
old_arraynd_initializer(std::initializer_list<old_arraynd_initializer<T, L - 1> > const & initializers) :
m_initializers(initializers) m_initializers(initializers)
{ {
} }
@@ -58,16 +58,16 @@ public:


private: private:


std::initializer_list<arraynd_initializer<T, L - 1> > const & m_initializers;
std::initializer_list<old_arraynd_initializer<T, L - 1> > const & m_initializers;
}; };




template<typename T> template<typename T>
class arraynd_initializer<T, 1>
class old_arraynd_initializer<T, 1>
{ {
public: public:


arraynd_initializer(std::initializer_list<T> const & initializers) :
old_arraynd_initializer(std::initializer_list<T> const & initializers) :
m_initializers(initializers) m_initializers(initializers)
{ {
} }
@@ -92,14 +92,14 @@ private:




template<int N, typename T> template<int N, typename T>
class [[nodiscard]] arraynd
class [[nodiscard]] old_arraynd
{ {
public: public:
typedef T element_t; typedef T element_t;


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


inline arraynd(vec_t<size_t, N> sizes, element_t e = element_t())
inline old_arraynd(vec_t<size_t, N> sizes, element_t e = element_t())
: m_sizes(sizes) : m_sizes(sizes)
{ {
resize_data(e); resize_data(e);
@@ -107,13 +107,13 @@ public:


/* Additional constructor if size_t != int */ /* 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> 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 old_arraynd(vec_t<T2, N> sizes, element_t e = element_t())
: m_sizes(vec_t<size_t, N>(sizes)) : m_sizes(vec_t<size_t, N>(sizes))
{ {
resize_data(e); resize_data(e);
} }


inline arraynd(std::initializer_list<arraynd_initializer<element_t, N - 1> > initializer)
inline old_arraynd(std::initializer_list<old_arraynd_initializer<element_t, N - 1> > initializer)
{ {
m_sizes[N - 1] = initializer.size(); m_sizes[N - 1] = initializer.size();


@@ -140,7 +140,7 @@ public:
inline element_t & operator[](vec_t<size_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<old_arraynd<N, T> const&>(*this)[pos]);
} }


/* If int != size_t, access elements directly using an ivec2, /* If int != size_t, access elements directly using an ivec2,
@@ -158,7 +158,7 @@ public:
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 &>(
const_cast<arraynd<N, T> const&>(*this)[pos]);
const_cast<old_arraynd<N, T> const&>(*this)[pos]);
} }


/* Proxy to access slices */ /* Proxy to access slices */
@@ -213,14 +213,14 @@ public:
}; };


/* 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[](size_t pos) const
inline slice<old_arraynd<N, T> const> operator[](size_t pos) const
{ {
return slice<arraynd<N, T> const>(*this, pos, m_sizes[0]);
return slice<old_arraynd<N, T> const>(*this, pos, m_sizes[0]);
} }


inline slice<arraynd<N, T>> operator[](size_t pos)
inline slice<old_arraynd<N, T>> operator[](size_t pos)
{ {
return slice<arraynd<N, T>>(*this, pos, m_sizes[0]);
return slice<old_arraynd<N, T>>(*this, pos, m_sizes[0]);
} }


/* Resize the array. /* Resize the array.
@@ -266,8 +266,8 @@ private:
vec_t<size_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 array3d = arraynd<3, T>;
template<typename T> using old_array2d = old_arraynd<2, T>;
template<typename T> using old_array3d = old_arraynd<3, T>;


} /* namespace lol */ } /* namespace lol */



Loading…
Cancel
Save