From cd32a1c515834345d398724224aac50831177427 Mon Sep 17 00:00:00 2001 From: Irlan <> Date: Sat, 25 Nov 2017 13:16:40 -0200 Subject: [PATCH] restored a file from 81f744b805ce4207cb69863b74edf1a817c44fb7 --- include/bounce/common/template/object_array.h | 283 ++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 include/bounce/common/template/object_array.h diff --git a/include/bounce/common/template/object_array.h b/include/bounce/common/template/object_array.h new file mode 100644 index 0000000..9360f49 --- /dev/null +++ b/include/bounce/common/template/object_array.h @@ -0,0 +1,283 @@ +/* +* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. +*/ + +#ifndef B3_OBJECT_ARRAY_H +#define B3_OBJECT_ARRAY_H + +#include + +// An array for objects. +template +class b3ObjectArray +{ +public: + const T& operator[](u32 i) const + { + B3_ASSERT(i < m_count); + return m_elements[i]; + } + + T& operator[](u32 i) + { + B3_ASSERT(i < m_count); + return m_elements[i]; + } + + const T* Get(u32 i) const + { + B3_ASSERT(i < m_count); + return m_elements + i; + } + + T* Get(u32 i) + { + B3_ASSERT(i < m_count); + return m_elements + i; + } + + const T* Elements() const + { + return m_elements; + } + + T* Elements() + { + return m_elements; + } + + void PushBack(const T& ele) + { + if (m_count == m_capacity) + { + // There is no capacity for one more element. + T* oldElements = m_elements; + m_capacity *= 2; + m_elements = (T*)b3Alloc(m_capacity * sizeof(T)); + + for (u32 i = 0; i < m_count; ++i) + { + T* old = oldElements + i; + T* e = m_elements + i; + new (e) T(*old); + old->~T(); + } + + if (oldElements != m_localElements) + { + b3Free(oldElements); + } + } + + B3_ASSERT(m_count < m_capacity); + T* e = m_elements + m_count; + new(e) T(ele); + ++m_count; + } + + void PopBack() + { + B3_ASSERT(m_count > 0); + --m_count; + } + + const T& Back() const + { + B3_ASSERT(m_count > 0); + return m_elements[m_count - 1]; + } + + T& Back() + { + B3_ASSERT(m_count > 0); + return m_elements[m_count - 1]; + } + + u32 Count() const + { + return m_count; + } + + bool Empty() const + { + return m_count == 0; + } + + void Resize(u32 size) + { + if (m_capacity < size) + { + // There is no capacity for the requested size. + T* oldElements = m_elements; + m_capacity = 2 * size; + m_elements = (T*)b3Alloc(m_capacity * sizeof(T)); + + // Construct and copy objects. + for (u32 i = 0; i < m_count; ++i) + { + T* old = oldElements + i; + T* e = m_elements + i; + new (e) T(*old); + old->~T(); + } + + // Construct objects up to the requested size. + for (u32 i = m_count; i < size; ++i) + { + T* e = m_elements + i; + new (e) T(); + } + + if (oldElements != m_localElements) + { + b3Free(oldElements); + } + + m_count = size; + return; + } + + B3_ASSERT(m_capacity >= size); + if (size < m_count) + { + // Destroy objects beyond the requested size. + for (u32 i = size; i < m_count; ++i) + { + T* e = m_elements + i; + e->~T(); + } + } + else + { + // Construct objects up to the requested size. + for (u32 i = m_count; i < size; ++i) + { + T* e = m_elements + i; + new (e) T(); + } + } + + m_count = size; + } + + void Swap(const b3ObjectArray& other) + { + if (m_elements == other.m_elements) + { + return; + } + + // Destroy all objects. + for (u32 i = 0; i < m_count; ++i) + { + T* e = m_elements + i; + e->~T(); + } + + // Ensure sufficient capacity for a copy. + if (m_capacity < other.m_count) + { + if (m_elements != m_localElements) + { + b3Free(m_elements); + } + m_capacity = 2 * other.m_count; + m_elements = (T*)b3Alloc(m_capacity * sizeof(T)); + } + + // Copy. + B3_ASSERT(m_capacity >= other.m_count); + for (u32 i = 0; i < other.m_count; ++i) + { + T* e2 = other.m_elements + i; + T* e1 = m_elements + i; + new (e1) T(*e2); + } + m_count = other.m_count; + } +protected: + b3ObjectArray(T* elements, u32 N) + { + B3_ASSERT(N > 0); + m_localElements = elements; + m_capacity = N; + m_elements = m_localElements; + m_count = 0; + } + + b3ObjectArray(const b3ObjectArray& other) + { + Swap(other); + } + + ~b3ObjectArray() + { + if (m_elements != m_localElements) + { + for (u32 i = 0; i < m_count; ++i) + { + T* e = m_elements + i; + e->~T(); + } + b3Free(m_elements); + } + } + + void operator=(const b3ObjectArray& other) + { + Swap(other); + } + + u32 m_capacity; + T* m_elements; + u32 m_count; + T* m_localElements; +}; + +template +class b3StackObjectArray : public b3ObjectArray +{ +public: + b3StackObjectArray() : b3ObjectArray(m_stackElements, N) + { + } + + b3StackObjectArray(const b3StackObjectArray& other) : b3ObjectArray(other) + { + } + + b3StackObjectArray(const b3ObjectArray& other) : b3ObjectArray(other) + { + } + + void operator=(const b3StackObjectArray& other) + { + Swap(other); + } + + void operator=(const b3ObjectArray& other) + { + Swap(other); + } + +protected: + //@todo + // u8 m_bytes[N * sizeof(T)]; + T m_stackElements[N]; +}; + +#endif