25 : dimensions(dimensions) {
30 return data[map(idxs)];
34 return data[map(idxs)];
46 return dimensions[
X] * dimensions[
Y] * dimensions[
Z];
62 return idxs[
X] * dimensions[
Y] * dimensions[
Z] + idxs[
Y] * dimensions[
Z] + idxs[
Z];
82 tieToTuple(code, childIdxs) = this->getCodeAndChildIdxs(idxs, dim);
85 if (!children[code]) {
86 children[code] = makeAuto<OctreeNode>();
88 return children[code]->create(childIdxs, dim / 2, value);
97 SPH_ASSERT(idxs[
X] >= 0 && idxs[
X] <
int(dim), idxs, dim);
98 SPH_ASSERT(idxs[
Y] >= 0 && idxs[
Y] <
int(dim), idxs, dim);
99 SPH_ASSERT(idxs[
Z] >= 0 && idxs[
Z] <
int(dim), idxs, dim);
101 return std::addressof(data.template get<T>());
105 tieToTuple(code, childIdxs) = this->getCodeAndChildIdxs(idxs, dim);
108 if (children[code]) {
109 return children[code]->find(childIdxs, dim / 2);
111 return Hint{
this, dim };
118 if (value.template has<T*>()) {
119 return static_cast<const T*
>(value.template get<T*>());
121 return value.template get<Hint>();
125 template <
typename TFunctor>
129 functor(data.template get<T>(), from);
134 for (
Size code = 0; code < 8; ++code) {
135 if (!children[code]) {
138 const Indices size((to[
X] - from[
X]) / 2, (to[
Y] - from[
Y]) / 2, (to[
Z] - from[
Z]) / 2);
155 children[code]->iterate(n1, n2, functor);
160 return data.template has<T>();
166 const int half = int(dim / 2);
169 if (idxs[
X] >= half) {
173 if (idxs[
Y] >= half) {
177 if (idxs[
Z] >= half) {
182 return { code, child };
186 template <
typename T>
198 : dimensions(dimensions)
199 , defaultValue(value) {
205 if (ptrOrHint.template has<T*>()) {
206 return *ptrOrHint.template get<T*>();
215 if (ptrOrHint.template has<const T*>()) {
216 return *ptrOrHint.template get<const T*>();
222 template <
typename TFunctor>
232 return dimensions == 0;
236 const uint64_t d = dimensions;
Generic dynamically allocated resizable storage.
#define SPH_ASSERT(x,...)
Simplified implementation of std::unique_ptr, using only default deleter.
uint32_t Size
Integral type used to index arrays (by default).
Vectorized computations with integral numbers.
INLINE bool all(const Indices &i)
INLINE Float root(const Float f)
constexpr INLINE bool isPower2(const Size n) noexcept
Returns true if given n is a power of 2. N must at least 1.
#define INLINE
Macros for conditional compilation based on selected compiler.
#define NAMESPACE_SPH_END
INLINE Tuple< TArgs &... > tieToTuple(TArgs &... args)
Creates a tuple of l-value references. Use IGNORE placeholder to omit one or more parameters.
Object capable of storing values of different types.
INLINE Iterator< StorageType > end() noexcept
INLINE bool empty() const noexcept
void resizeAndSet(const TCounter newSize, const T &value)
Resizes the array to new size and assigns a given value to all newly created elements.
INLINE Iterator< StorageType > begin() noexcept
INLINE T & operator[](const Indices &idxs)
INLINE const T & operator[](const Indices &idxs) const
INLINE bool empty() const
INLINE Indices size() const
INLINE uint64_t voxelCount() const
Grid(const Indices &dimensions, const T &value=T())
Helper object for storing three (possibly four) int or bool values.
Simple (forward) iterator over continuous array of objects of type T.
Variant< const T *, Hint > find(const Indices &idxs, const Size dim) const
void iterate(const Indices &from, const Indices &to, const TFunctor &functor)
Variant< T *, Hint > find(const Indices &idxs, const Size dim)
T & create(const Indices &idxs, const Size dim, const T &value)
INLINE T & operator[](const Indices &idxs)
INLINE const T & operator[](const Indices &idxs) const
INLINE uint64_t voxelCount() const
void iterate(const TFunctor &functor)
INLINE bool empty() const
SparseGrid(const Size dimensions, const T &value=T())
Array with fixed number of allocated elements.
Heterogeneous container capable of storing a fixed number of values.
Variant, an implementation of type-safe union, similar to std::variant or boost::variant.