2016-12-19 13:58:12 +00:00
|
|
|
//============================================================================
|
|
|
|
// 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.
|
|
|
|
//
|
2017-09-20 21:33:44 +00:00
|
|
|
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
2016-12-19 13:58:12 +00:00
|
|
|
// Copyright 2014 UT-Battelle, LLC.
|
|
|
|
// Copyright 2014 Los Alamos National Security.
|
|
|
|
//
|
2017-09-20 21:33:44 +00:00
|
|
|
// Under the terms of Contract DE-NA0003525 with NTESS,
|
2016-12-19 13:58:12 +00:00
|
|
|
// 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.
|
|
|
|
//============================================================================
|
|
|
|
|
2017-06-23 13:33:28 +00:00
|
|
|
#include <vtkm/cont/StorageBasic.h>
|
|
|
|
|
|
|
|
#include <limits>
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace cont
|
|
|
|
{
|
|
|
|
namespace internal
|
|
|
|
{
|
|
|
|
|
2017-08-17 12:43:39 +00:00
|
|
|
template <typename T>
|
|
|
|
Storage<T, vtkm::cont::StorageTagBasic>::Storage()
|
|
|
|
: Array(nullptr)
|
|
|
|
, NumberOfValues(0)
|
|
|
|
, AllocatedSize(0)
|
|
|
|
, DeallocateOnRelease(true)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
|
|
|
Storage<T, vtkm::cont::StorageTagBasic>::Storage(const T* array, vtkm::Id numberOfValues)
|
|
|
|
: Array(const_cast<T*>(array))
|
|
|
|
, NumberOfValues(numberOfValues)
|
|
|
|
, AllocatedSize(numberOfValues)
|
2017-08-17 12:43:39 +00:00
|
|
|
, DeallocateOnRelease(array == nullptr ? true : false)
|
2016-12-19 13:58:12 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
2016-12-19 13:58:12 +00:00
|
|
|
Storage<T, vtkm::cont::StorageTagBasic>::~Storage()
|
|
|
|
{
|
|
|
|
this->ReleaseResources();
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
|
|
|
Storage<T, vtkm::cont::StorageTagBasic>::Storage(const Storage<T, StorageTagBasic>& src)
|
|
|
|
: Array(src.Array)
|
|
|
|
, NumberOfValues(src.NumberOfValues)
|
|
|
|
, AllocatedSize(src.AllocatedSize)
|
2017-08-17 12:43:39 +00:00
|
|
|
, DeallocateOnRelease(src.DeallocateOnRelease)
|
2016-12-19 13:58:12 +00:00
|
|
|
{
|
|
|
|
if (src.DeallocateOnRelease)
|
|
|
|
{
|
2017-01-09 21:15:32 +00:00
|
|
|
throw vtkm::cont::ErrorBadValue(
|
2017-05-18 14:29:41 +00:00
|
|
|
"Attempted to copy a storage array that needs deallocation. "
|
|
|
|
"This is disallowed to prevent complications with deallocation.");
|
2016-12-19 13:58:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
|
|
|
Storage<T, vtkm::cont::StorageTagBasic>& Storage<T, vtkm::cont::StorageTagBasic>::operator=(
|
|
|
|
const Storage<T, StorageTagBasic>& src)
|
2016-12-19 13:58:12 +00:00
|
|
|
{
|
|
|
|
if (src.DeallocateOnRelease)
|
|
|
|
{
|
2017-01-09 21:15:32 +00:00
|
|
|
throw vtkm::cont::ErrorBadValue(
|
2017-05-18 14:29:41 +00:00
|
|
|
"Attempted to copy a storage array that needs deallocation. "
|
|
|
|
"This is disallowed to prevent complications with deallocation.");
|
2016-12-19 13:58:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
this->ReleaseResources();
|
|
|
|
this->Array = src.Array;
|
|
|
|
this->NumberOfValues = src.NumberOfValues;
|
|
|
|
this->AllocatedSize = src.AllocatedSize;
|
|
|
|
this->DeallocateOnRelease = src.DeallocateOnRelease;
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
2016-12-19 13:58:12 +00:00
|
|
|
void Storage<T, vtkm::cont::StorageTagBasic>::ReleaseResources()
|
|
|
|
{
|
|
|
|
if (this->NumberOfValues > 0)
|
|
|
|
{
|
|
|
|
VTKM_ASSERT(this->Array != nullptr);
|
|
|
|
if (this->DeallocateOnRelease)
|
|
|
|
{
|
|
|
|
AllocatorType allocator;
|
2017-05-18 14:29:41 +00:00
|
|
|
allocator.deallocate(this->Array, static_cast<std::size_t>(this->AllocatedSize));
|
2016-12-19 13:58:12 +00:00
|
|
|
}
|
|
|
|
this->Array = nullptr;
|
|
|
|
this->NumberOfValues = 0;
|
|
|
|
this->AllocatedSize = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
VTKM_ASSERT(this->Array == nullptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
2016-12-19 13:58:12 +00:00
|
|
|
void Storage<T, vtkm::cont::StorageTagBasic>::Allocate(vtkm::Id numberOfValues)
|
|
|
|
{
|
2017-06-23 13:33:28 +00:00
|
|
|
if (numberOfValues < 0)
|
|
|
|
{
|
|
|
|
throw vtkm::cont::ErrorBadAllocation("Cannot allocate an array with negative size.");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that the number of bytes won't be more than a size_t can hold.
|
|
|
|
const size_t maxNumValues = std::numeric_limits<size_t>::max() / sizeof(T);
|
|
|
|
if (static_cast<vtkm::UInt64>(numberOfValues) > static_cast<vtkm::UInt64>(maxNumValues))
|
|
|
|
{
|
|
|
|
throw ErrorBadAllocation("Requested allocation exceeds size_t capacity.");
|
|
|
|
}
|
2017-09-18 17:03:26 +00:00
|
|
|
this->AllocateBytes(static_cast<vtkm::UInt64>(numberOfValues) *
|
|
|
|
static_cast<vtkm::UInt64>(sizeof(T)));
|
2017-06-23 13:33:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2017-09-18 17:03:26 +00:00
|
|
|
void Storage<T, vtkm::cont::StorageTagBasic>::AllocateBytes(vtkm::UInt64 numberOfBytes)
|
2017-06-23 13:33:28 +00:00
|
|
|
{
|
2017-09-18 17:03:26 +00:00
|
|
|
const vtkm::Id numberOfValues =
|
|
|
|
static_cast<vtkm::Id>(numberOfBytes / static_cast<vtkm::UInt64>(sizeof(T)));
|
2017-06-23 13:33:28 +00:00
|
|
|
|
2017-03-08 23:49:03 +00:00
|
|
|
// If we are allocating less data, just shrink the array.
|
|
|
|
// (If allocation empty, drop down so we can deallocate memory.)
|
2017-05-18 14:29:41 +00:00
|
|
|
if ((numberOfValues <= this->AllocatedSize) && (numberOfValues > 0))
|
2016-12-19 13:58:12 +00:00
|
|
|
{
|
|
|
|
this->NumberOfValues = numberOfValues;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-08-17 12:43:39 +00:00
|
|
|
if (!this->DeallocateOnRelease)
|
2016-12-19 13:58:12 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
throw vtkm::cont::ErrorBadValue("User allocated arrays cannot be reallocated.");
|
2016-12-19 13:58:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
this->ReleaseResources();
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (numberOfValues > 0)
|
|
|
|
{
|
|
|
|
AllocatorType allocator;
|
|
|
|
this->Array = allocator.allocate(static_cast<std::size_t>(numberOfValues));
|
2017-05-18 14:29:41 +00:00
|
|
|
this->AllocatedSize = numberOfValues;
|
2016-12-19 13:58:12 +00:00
|
|
|
this->NumberOfValues = numberOfValues;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// ReleaseResources should have already set AllocatedSize to 0.
|
|
|
|
VTKM_ASSERT(this->AllocatedSize == 0);
|
|
|
|
}
|
|
|
|
}
|
2017-02-23 15:13:30 +00:00
|
|
|
catch (std::bad_alloc&)
|
2016-12-19 13:58:12 +00:00
|
|
|
{
|
|
|
|
// Make sureour state is OK.
|
|
|
|
this->Array = nullptr;
|
|
|
|
this->NumberOfValues = 0;
|
|
|
|
this->AllocatedSize = 0;
|
2017-05-18 14:29:41 +00:00
|
|
|
throw vtkm::cont::ErrorBadAllocation("Could not allocate basic control array.");
|
2016-12-19 13:58:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
this->DeallocateOnRelease = true;
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
2016-12-19 13:58:12 +00:00
|
|
|
void Storage<T, vtkm::cont::StorageTagBasic>::Shrink(vtkm::Id numberOfValues)
|
|
|
|
{
|
2017-09-18 17:03:26 +00:00
|
|
|
this->ShrinkBytes(static_cast<vtkm::UInt64>(numberOfValues) *
|
|
|
|
static_cast<vtkm::UInt64>(sizeof(T)));
|
2017-06-23 13:33:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
2017-09-18 17:03:26 +00:00
|
|
|
void Storage<T, vtkm::cont::StorageTagBasic>::ShrinkBytes(vtkm::UInt64 numberOfBytes)
|
2017-06-23 13:33:28 +00:00
|
|
|
{
|
|
|
|
if (numberOfBytes > this->GetNumberOfBytes())
|
2016-12-19 13:58:12 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
throw vtkm::cont::ErrorBadValue("Shrink method cannot be used to grow array.");
|
2016-12-19 13:58:12 +00:00
|
|
|
}
|
|
|
|
|
2017-09-18 17:03:26 +00:00
|
|
|
this->NumberOfValues =
|
|
|
|
static_cast<vtkm::Id>(numberOfBytes / static_cast<vtkm::UInt64>(sizeof(T)));
|
2016-12-19 13:58:12 +00:00
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
2016-12-19 13:58:12 +00:00
|
|
|
T* Storage<T, vtkm::cont::StorageTagBasic>::StealArray()
|
|
|
|
{
|
2017-08-17 12:43:39 +00:00
|
|
|
this->DeallocateOnRelease = false;
|
|
|
|
return this->Array;
|
2016-12-19 13:58:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace internal
|
|
|
|
}
|
|
|
|
} // namespace vtkm::cont
|