From e0730821501436dee4056a4a17f7e312ac9df249 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Wed, 24 Jun 2020 23:43:26 +0200 Subject: [PATCH] Rename arraynd to old_arraynd and create new lol::narray implementation. --- include/lol/narray | 18 ++++ include/lol/private/base/narray.h | 141 ++++++++++++++++++++++++++++++ legacy/lol/math/arraynd.h | 40 ++++----- 3 files changed, 179 insertions(+), 20 deletions(-) create mode 100644 include/lol/narray create mode 100644 include/lol/private/base/narray.h diff --git a/include/lol/narray b/include/lol/narray new file mode 100644 index 00000000..dacc6be1 --- /dev/null +++ b/include/lol/narray @@ -0,0 +1,18 @@ +// +// Lol Engine +// +// Copyright © 2010—2020 Sam Hocevar +// +// 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" + diff --git a/include/lol/private/base/narray.h b/include/lol/private/base/narray.h new file mode 100644 index 00000000..7f45b923 --- /dev/null +++ b/include/lol/private/base/narray.h @@ -0,0 +1,141 @@ +// +// Lol Engine +// +// Copyright © 2010—2020 Sam Hocevar +// +// 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::vec_t +#include // std::vector + +namespace lol +{ + +template +class [[nodiscard]] narray +{ +public: + typedef T value_type; + + inline narray() = default; + inline ~narray() = default; + + // Construct array with args: size1, size2, ..., sizen + template inline narray(I... sizes) + { + static_assert(N == sizeof...(I)); + resize(sizes...); + } + + // Construct array with integer vec_t arg: + inline narray(vec_t const &sizes) + { + resize(sizes); + } + + // Empty array + inline void clear() { resize(vec_t(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 + inline value_type &operator()(I... indices) + { + static_assert(N == sizeof...(I)); + return m_data[offset(indices...)]; + } + + template + inline value_type const &operator()(I... indices) const + { + static_assert(N == sizeof...(I)); + return m_data[offset(indices...)]; + } + + inline value_type &operator()(vec_t const &indices) + { + return m_data[offset_helper(indices, std::make_index_sequence{})]; + } + + inline value_type const &operator()(vec_t const &indices) const + { + return m_data[offset_helper(indices, std::make_index_sequence{})]; + } + + // Resize array with a list of sizes (size1, size2, ..., sizen) + template + 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 const &sizes) + { + resize_helper(sizes, std::make_index_sequence{}); + } + + // Return sizes of each dimension + inline vec_t sizes() const + { + return vec_t(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 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 + size_t offset_helper(vec_t const &sizes, std::index_sequence) const + { + return offset(size_t(sizes[I])...); + } + + template + void resize_helper(vec_t const &sizes, std::index_sequence) + { + resize(sizes[I]...); + } + + vec_t m_sizes { 0 }; + std::vector m_data; +}; + +template using array2d = narray; +template using array3d = narray; + +} // namespace lol + diff --git a/legacy/lol/math/arraynd.h b/legacy/lol/math/arraynd.h index 0c120ecb..f38a21a8 100644 --- a/legacy/lol/math/arraynd.h +++ b/legacy/lol/math/arraynd.h @@ -15,8 +15,8 @@ #pragma once // -// The arraynd class -// ----------------- +// The old_arraynd class +// ————————————————————— // A N-Dimensional array class allowing var[i][j][k]... indexing, // @@ -31,11 +31,11 @@ namespace lol { template -class arraynd_initializer +class old_arraynd_initializer { public: - arraynd_initializer(std::initializer_list > const & initializers) : + old_arraynd_initializer(std::initializer_list > const & initializers) : m_initializers(initializers) { } @@ -58,16 +58,16 @@ public: private: - std::initializer_list > const & m_initializers; + std::initializer_list > const & m_initializers; }; template -class arraynd_initializer +class old_arraynd_initializer { public: - arraynd_initializer(std::initializer_list const & initializers) : + old_arraynd_initializer(std::initializer_list const & initializers) : m_initializers(initializers) { } @@ -92,14 +92,14 @@ private: template -class [[nodiscard]] arraynd +class [[nodiscard]] old_arraynd { public: typedef T element_t; - inline arraynd() = default; + inline old_arraynd() = default; - inline arraynd(vec_t sizes, element_t e = element_t()) + inline old_arraynd(vec_t sizes, element_t e = element_t()) : m_sizes(sizes) { resize_data(e); @@ -107,13 +107,13 @@ public: /* Additional constructor if size_t != int */ template::value, int>::type> - inline arraynd(vec_t sizes, element_t e = element_t()) + inline old_arraynd(vec_t sizes, element_t e = element_t()) : m_sizes(vec_t(sizes)) { resize_data(e); } - inline arraynd(std::initializer_list > initializer) + inline old_arraynd(std::initializer_list > initializer) { m_sizes[N - 1] = initializer.size(); @@ -140,7 +140,7 @@ public: inline element_t & operator[](vec_t const &pos) { return const_cast( - const_cast const&>(*this)[pos]); + const_cast const&>(*this)[pos]); } /* If int != size_t, access elements directly using an ivec2, @@ -158,7 +158,7 @@ public: inline element_t & operator[](vec_t const &pos) { return const_cast( - const_cast const&>(*this)[pos]); + const_cast const&>(*this)[pos]); } /* Proxy to access slices */ @@ -213,14 +213,14 @@ public: }; /* Access addressable slices, allowing for array[i][j][...] syntax. */ - inline slice const> operator[](size_t pos) const + inline slice const> operator[](size_t pos) const { - return slice const>(*this, pos, m_sizes[0]); + return slice const>(*this, pos, m_sizes[0]); } - inline slice> operator[](size_t pos) + inline slice> operator[](size_t pos) { - return slice>(*this, pos, m_sizes[0]); + return slice>(*this, pos, m_sizes[0]); } /* Resize the array. @@ -266,8 +266,8 @@ private: vec_t m_sizes { 0 }; }; -template using array2d = arraynd<2, T>; -template using array3d = arraynd<3, T>; +template using old_array2d = old_arraynd<2, T>; +template using old_array3d = old_arraynd<3, T>; } /* namespace lol */