/* * Copyright (c) 2014, Siemens AG. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #ifndef EMBB_CONTAINERS_INTERNAL_INDEXED_OBJECT_POOL_INL_H_ #define EMBB_CONTAINERS_INTERNAL_INDEXED_OBJECT_POOL_INL_H_ #include namespace embb { namespace containers { namespace internal { template template IndexedObjectPool:: IndexedObjectPool(RAI first, RAI last) : size_(static_cast(std::distance(first, last))), indexPool(internal::ReturningTrueIterator(0), internal::ReturningTrueIterator(size_)) { // use the allocator to allocate array of size dist elements = allocator.allocate(size_); // fill element pool with elements from the iteration int i = 0; for (RAI curIter(first); curIter != last; ++curIter, ++i) { // assign element from iteration elements[i] = *curIter; } } template IndexedObjectPool:: IndexedObjectPool(size_t size, const Type & defaultInstance) : size_(size), indexPool(internal::ReturningTrueIterator(0), internal::ReturningTrueIterator(size_)) { // use the allocator to allocate array of size dist elements = allocator.allocate(size); // fill element pool with elements from the iteration for (size_t i = 0; i < size_; ++i) { // initialize element from default constructor and // assignment operator elements[i] = defaultInstance; } } template IndexedObjectPool:: ~IndexedObjectPool() { allocator.deallocate(elements, size_); } template void IndexedObjectPool:: Free(int elementIndex) { // Call the referenced element's destructor: elements[elementIndex].~Type(); // Release index of the element for reuse: indexPool.Free(true, elementIndex); } template Type & IndexedObjectPool:: operator[](int elementIndex) { return elements[elementIndex]; } template int IndexedObjectPool::AllocateRaw( Type * & newElement) { newElement = NULL; // Reserve a pool index: bool val; int allocated_index = indexPool.Allocate(val); if (allocated_index >= 0) { // Return pointer to reserved element: Type * ret_pointer = &(elements[allocated_index]); newElement = ret_pointer; } return allocated_index; } template int IndexedObjectPool:: Allocate() { Type * raw_object = NULL; int element_index = AllocateRaw(raw_object); if (element_index >= 0 && raw_object != NULL) { new (raw_object)Type(); } return element_index; } template template int IndexedObjectPool::Allocate( Param1 const & param1) { Type * raw_object = NULL; int element_index = AllocateRaw(raw_object); if (element_index >= 0 && raw_object != NULL) { new (raw_object)Type(param1); } return element_index; } template template int IndexedObjectPool::Allocate( Param1 const & param1, Param2 const & param2) { Type * raw_object = NULL; int element_index = AllocateRaw(raw_object); if (element_index >= 0 && raw_object != NULL) { new (raw_object)Type(param1, param2); } return element_index; } template template int IndexedObjectPool::Allocate( Param1 const & param1, Param2 const & param2, Param3 const & param3) { Type * raw_object = NULL; int element_index = AllocateRaw(raw_object); if (element_index >= 0 && raw_object != NULL) { new (raw_object)Type(param1, param2, param3); } return element_index; } template template int IndexedObjectPool::Allocate( Param1 const & param1, Param2 const & param2, Param3 const & param3, Param4 const & param4) { Type * raw_object = NULL; int element_index = AllocateRaw(raw_object); if (element_index >= 0 && raw_object != NULL) { new (raw_object)Type(param1, param2, param3, param4); } return element_index; } } // namespace internal } // namespace containers } // namespace embb #endif // EMBB_CONTAINERS_INTERNAL_INDEXED_OBJECT_POOL_INL_H_