Getting the number of components (or the number of flattened components)
from an `ArrayHandle` is usually trivial. However, if the `ArrayHandle` is
special in that the number of components is specified at runtime, then it
becomes much more difficult to determine.
Getting the number of components is most important when extracting
component arrays (or reconstructions using component arrays) with
`UnknownArrayHandle`. Previously, `UnknownArrayHandle` used a hack to get
the number of components, which mostly worked but broke down when wrapping
a runtime array inside another array such as `ArrayHandleView`.
To prevent this issue, the ability to get the number of components has been
added to `ArrayHandle` proper. All `Storage` objects for `ArrayHandle`s now
need a method named `GetNumberOfComponentsFlat`. The implementation of this
method is usually trivial. The `ArrayHandle` template now also provides a
`GetNumberOfComponentsFlat` method that gets this information from the
`Storage`. This provides an easy access point for the `UnknownArrayHandle`
to pull this information.
Previously, `ArrayHandleConstant` did not really support component
extraction. Instead, it let a fallback operation create a full array on
the CPU.
Component extraction is now quite efficient for `ArrayHandleConstant`. It
creates a basic `ArrayHandle` with one entry and sets a modulo on the
`ArrayHandleStride` to access that value for all indices.
StorageType is public in vtkm::cont::ArrayHandle, but some subclasses
re-declare it as private. Having it public provides a convenient way to
get the storage type of an ArrayHandle, otherwise it is quite verbose.
Addresses: #314
This feature enables the ability to anonomously create an array (such as
with `UnknownArrayHandle::NewInstance()`) and then use that as an output
array. Although resizing `ArrayHandleStride` is a little wonky, it
allows worklets to resize them after creation rather than having to know
what size to make and allocating the array.
Previously, the number of buffers held by an `ArrayHandle` had to be
determined statically at compile time by the storage. Most of the time
this is fine. However, there are some exceptions where the number of
buffers need to be selected at runtime. For example, the
`ArrayHandleRecombineVec` does not specify the number of components it
uses, and it needed a hack where it stored buffers in the metadata of
another buffer, which is bad.
This change allows the number of buffers to vary at runtime (at least at
construction). The buffers were already managed in a `std::vector`. It
now no longer forces the vector to be a specific size.
`GetNumberOfBuffers` was removed from the `Storage`. Instead, if the
number of buffers was not specified at construction, an allocation of
size 0 is done to create default buffers.
The biggest change is to the interface of the storage object methods,
which now take `std::vector` instead of pointers to `Buffer` objects.
This adds a little hastle in having to copy subsets of this `vector`
when a storage object has multiple sub-arrays. But it does simplify some
of the templating.
What was previously declared as `ArrayHandleNewStyle` is now just the
implementation of `ArrayHandle`. The old implementation of `ArrayHandle`
has been moved to `ArrayHandleDeprecated`, and `ArrayHandle`s still
using this implementation must declare `VTKM_ARRAY_HANDLE_DEPRECATED` to
use it.
The primary purpose of `ArrayHandleRecombineVec` is to take arrays
returned from `ArrayExtractComponent` and recombine them again into a
single `ArrayHandle` that has `Vec` values.
The typical use case of `ArrayHandleStride` is to flexibly point into
another array, often looking at a single component in an array. It is
typical that multiple things will be accessing the same array, and bad
things could happen as they all try to resize. There was some code to
try to figure out what the size of the original array was, but it was
fragile.
It is safer for now to disable the behavior altogether. If a use case
pops up, we can reintroduce the code.
`ArrayExtractComponent` allows you to get a component of an array.
Unlike `ArrayHandleExtractComponent`, the type you get is always the
same: an `ArrayHandleStride`. This way, you can get an array that
contains the data of an extracted component with less templating and
potentially dramatically reduce the amount of code generated (although
some runtime integer arithmetic is added).