//============================================================================ // Copyright (c) Kitware, Inc. // All rights reserved. // See LICENSE.txt for details. // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. // // Copyright 2014 Sandia Corporation. // Copyright 2014 UT-Battelle, LLC. // Copyright 2014 Los Alamos National Security. // // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. // // Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National // Laboratory (LANL), the U.S. Government retains certain rights in // this software. //============================================================================ namespace vtkm { namespace cont { namespace internal { template Storage::Storage(const T *array, vtkm::Id numberOfValues) : Array(const_cast(array)), NumberOfValues(numberOfValues), AllocatedSize(numberOfValues), DeallocateOnRelease(false), UserProvidedMemory( array == nullptr ? false : true) { } template Storage::~Storage() { this->ReleaseResources(); } template Storage::Storage(const Storage &src) : Array(src.Array), NumberOfValues(src.NumberOfValues), AllocatedSize(src.AllocatedSize), DeallocateOnRelease(false), UserProvidedMemory(src.UserProvidedMemory) { if (src.DeallocateOnRelease) { throw vtkm::cont::ErrorBadValue( "Attempted to copy a storage array that needs deallocation. " "This is disallowed to prevent complications with deallocation."); } } template Storage& Storage::operator=(const Storage &src) { if (src.DeallocateOnRelease) { throw vtkm::cont::ErrorBadValue( "Attempted to copy a storage array that needs deallocation. " "This is disallowed to prevent complications with deallocation."); } this->ReleaseResources(); this->Array = src.Array; this->NumberOfValues = src.NumberOfValues; this->AllocatedSize = src.AllocatedSize; this->DeallocateOnRelease = src.DeallocateOnRelease; this->UserProvidedMemory = src.UserProvidedMemory; return *this; } template void Storage::ReleaseResources() { if (this->NumberOfValues > 0) { VTKM_ASSERT(this->Array != nullptr); if (this->DeallocateOnRelease) { AllocatorType allocator; allocator.deallocate(this->Array, static_cast(this->AllocatedSize) ); } this->Array = nullptr; this->NumberOfValues = 0; this->AllocatedSize = 0; } else { VTKM_ASSERT(this->Array == nullptr); } } template void Storage::Allocate(vtkm::Id numberOfValues) { if (numberOfValues <= this->AllocatedSize) { this->NumberOfValues = numberOfValues; return; } if(this->UserProvidedMemory) { throw vtkm::cont::ErrorBadValue( "User allocated arrays cannot be reallocated."); } this->ReleaseResources(); try { if (numberOfValues > 0) { AllocatorType allocator; this->Array = allocator.allocate(static_cast(numberOfValues)); this->AllocatedSize = numberOfValues; this->NumberOfValues = numberOfValues; } else { // ReleaseResources should have already set AllocatedSize to 0. VTKM_ASSERT(this->AllocatedSize == 0); } } catch (std::bad_alloc err) { // Make sureour state is OK. this->Array = nullptr; this->NumberOfValues = 0; this->AllocatedSize = 0; throw vtkm::cont::ErrorBadAllocation( "Could not allocate basic control array."); } this->DeallocateOnRelease = true; this->UserProvidedMemory = false; } template void Storage::Shrink(vtkm::Id numberOfValues) { if (numberOfValues > this->GetNumberOfValues()) { throw vtkm::cont::ErrorBadValue( "Shrink method cannot be used to grow array."); } this->NumberOfValues = numberOfValues; } template T* Storage::StealArray() { T *saveArray = this->Array; this->Array = nullptr; this->NumberOfValues = 0; this->AllocatedSize = 0; return saveArray; } } // namespace internal } } // namespace vtkm::cont