Revision control
++ // Copyright 2009-2021 Intel Corporation
++ // SPDX-License-Identifier: Apache-2.0
++
++ #pragma once
++
++ #include "platform.h"
++ #include "alloc.h"
++
++ namespace embree
++ {
++ /*! static array with static size */
++ template<typename T, size_t N>
++ class array_t
++ {
++ public:
++
++ /********************** Iterators ****************************/
++
++ __forceinline T* begin() const { return items; };
++ __forceinline T* end () const { return items+N; };
++
++
++ /********************** Capacity ****************************/
++
++ __forceinline bool empty () const { return N == 0; }
++ __forceinline size_t size () const { return N; }
++ __forceinline size_t max_size () const { return N; }
++
++
++ /******************** Element access **************************/
++
++ __forceinline T& operator[](size_t i) { assert(i < N); return items[i]; }
++ __forceinline const T& operator[](size_t i) const { assert(i < N); return items[i]; }
++
++ __forceinline T& at(size_t i) { assert(i < N); return items[i]; }
++ __forceinline const T& at(size_t i) const { assert(i < N); return items[i]; }
++
++ __forceinline T& front() const { assert(N > 0); return items[0]; };
++ __forceinline T& back () const { assert(N > 0); return items[N-1]; };
++
++ __forceinline T* data() { return items; };
++ __forceinline const T* data() const { return items; };
++
++ private:
++ T items[N];
++ };
++
++ /*! static array with dynamic size */
++ template<typename T, size_t N>
++ class darray_t
++ {
++ public:
++
++ __forceinline darray_t () : M(0) {}
++
++ __forceinline darray_t (const T& v) : M(0) {
++ for (size_t i=0; i<N; i++) items[i] = v;
++ }
++
++ /********************** Iterators ****************************/
++
++ __forceinline T* begin() const { return (T*)items; };
++ __forceinline T* end () const { return (T*)items+M; };
++
++
++ /********************** Capacity ****************************/
++
++ __forceinline bool empty () const { return M == 0; }
++ __forceinline size_t size () const { return M; }
++ __forceinline size_t capacity () const { return N; }
++ __forceinline size_t max_size () const { return N; }
++
++ void resize(size_t new_size) {
++ assert(new_size < max_size());
++ M = new_size;
++ }
++
++ /******************** Modifiers **************************/
++
++ __forceinline void push_back(const T& v)
++ {
++ assert(M+1 < max_size());
++ items[M++] = v;
++ }
++
++ __forceinline void pop_back()
++ {
++ assert(!empty());
++ M--;
++ }
++
++ __forceinline void clear() {
++ M = 0;
++ }
++
++ /******************** Element access **************************/
++
++ __forceinline T& operator[](size_t i) { assert(i < M); return items[i]; }
++ __forceinline const T& operator[](size_t i) const { assert(i < M); return items[i]; }
++
++ __forceinline T& at(size_t i) { assert(i < M); return items[i]; }
++ __forceinline const T& at(size_t i) const { assert(i < M); return items[i]; }
++
++ __forceinline T& front() { assert(M > 0); return items[0]; };
++ __forceinline T& back () { assert(M > 0); return items[M-1]; };
++
++ __forceinline T* data() { return items; };
++ __forceinline const T* data() const { return items; };
++
++ private:
++ size_t M;
++ T items[N];
++ };
++
++ /*! dynamic sized array that is allocated on the stack */
++ #define dynamic_large_stack_array(Ty,Name,N,max_stack_bytes) StackArray<Ty,max_stack_bytes> Name(N)
++ template<typename Ty, size_t max_stack_bytes>
++ struct __aligned(64) StackArray
++ {
++ __forceinline StackArray (const size_t N)
++ : N(N)
++ {
++ if (N*sizeof(Ty) <= max_stack_bytes)
++ data = &arr[0];
++ else
++ data = (Ty*) alignedMalloc(N*sizeof(Ty),64);
++ }
++
++ __forceinline ~StackArray () {
++ if (data != &arr[0]) alignedFree(data);
++ }
++
++ __forceinline operator Ty* () { return data; }
++ __forceinline operator const Ty* () const { return data; }
++
++ __forceinline Ty& operator[](const int i) { assert(i>=0 && i<N); return data[i]; }
++ __forceinline const Ty& operator[](const int i) const { assert(i>=0 && i<N); return data[i]; }
++
++ __forceinline Ty& operator[](const unsigned i) { assert(i<N); return data[i]; }
++ __forceinline const Ty& operator[](const unsigned i) const { assert(i<N); return data[i]; }
++
++ #if defined(__64BIT__) || defined(__EMSCRIPTEN__)
++ __forceinline Ty& operator[](const size_t i) { assert(i<N); return data[i]; }
++ __forceinline const Ty& operator[](const size_t i) const { assert(i<N); return data[i]; }
++ #endif
++
++ private:
++ Ty arr[max_stack_bytes/sizeof(Ty)];
++ Ty* data;
++ size_t N;
++
++ private:
++ StackArray (const StackArray& other) DELETED; // do not implement
++ StackArray& operator= (const StackArray& other) DELETED; // do not implement
++
++ };
++
++ /*! dynamic sized array that is allocated on the stack */
++ template<typename Ty, size_t max_stack_elements, size_t max_total_elements>
++ struct __aligned(64) DynamicStackArray
++ {
++ __forceinline DynamicStackArray ()
++ : data(&arr[0]) {}
++
++ __forceinline ~DynamicStackArray ()
++ {
++ if (!isStackAllocated())
++ delete[] data;
++ }
++
++ __forceinline bool isStackAllocated() const {
++ return data == &arr[0];
++ }
++
++ __forceinline size_t size() const
++ {
++ if (isStackAllocated()) return max_stack_elements;
++ else return max_total_elements;
++ }
++
++ __forceinline void resize(size_t M)
++ {
++ assert(M <= max_total_elements);
++ if (likely(M <= max_stack_elements)) return;
++ if (likely(!isStackAllocated())) return;
++
++ data = new Ty[max_total_elements];
++
++ for (size_t i=0; i<max_stack_elements; i++)
++ data[i] = arr[i];
++ }
++
++ __forceinline operator Ty* () { return data; }
++ __forceinline operator const Ty* () const { return data; }
++
++ __forceinline Ty& operator[](const int i) { assert(i>=0 && i<max_total_elements); resize(i+1); return data[i]; }
++ __forceinline Ty& operator[](const unsigned i) { assert(i<max_total_elements); resize(i+1); return data[i]; }
++
++ #if defined(__64BIT__) || defined(__EMSCRIPTEN__)
++ __forceinline Ty& operator[](const size_t i) { assert(i<max_total_elements); resize(i+1); return data[i]; }
++ #endif
++
++ __forceinline DynamicStackArray (const DynamicStackArray& other)
++ : data(&arr[0])
++ {
++ for (size_t i=0; i<other.size(); i++)
++ this->operator[] (i) = other[i];
++ }
++
++ DynamicStackArray& operator= (const DynamicStackArray& other)
++ {
++ for (size_t i=0; i<other.size(); i++)
++ this->operator[] (i) = other[i];
++
++ return *this;
++ }
++
++ private:
++ Ty arr[max_stack_elements];
++ Ty* data;
++ };
++ }