vtk-m/vtkm/cont/ArrayHandleCompositeVector.h

672 lines
24 KiB
C
Raw Normal View History

//============================================================================
// 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.
//============================================================================
#ifndef vtk_m_ArrayHandleCompositeVector_h
#define vtk_m_ArrayHandleCompositeVector_h
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/cont/ErrorInternal.h>
#include <vtkm/StaticAssert.h>
#include <vtkm/VecTraits.h>
#include <vtkm/internal/FunctionInterface.h>
#include <sstream>
2017-05-18 14:29:41 +00:00
namespace vtkm
{
namespace cont
{
2017-05-18 14:29:41 +00:00
namespace internal
{
2017-05-18 14:29:41 +00:00
namespace detail
{
2017-05-18 14:29:41 +00:00
template <typename ValueType>
struct VTKM_ALWAYS_EXPORT CompositeVectorSwizzleFunctor
{
2017-05-18 14:29:41 +00:00
static const vtkm::IdComponent NUM_COMPONENTS = vtkm::VecTraits<ValueType>::NUM_COMPONENTS;
typedef vtkm::Vec<vtkm::IdComponent, NUM_COMPONENTS> ComponentMapType;
// Caution! This is a reference.
2017-05-18 14:29:41 +00:00
const ComponentMapType& SourceComponents;
VTKM_EXEC_CONT
2017-05-18 14:29:41 +00:00
CompositeVectorSwizzleFunctor(const ComponentMapType& sourceComponents)
: SourceComponents(sourceComponents)
{
}
// Currently only supporting 1-4 components.
2017-05-18 14:29:41 +00:00
template <typename T1>
VTKM_EXEC_CONT ValueType operator()(const T1& p1) const
{
return ValueType(vtkm::VecTraits<T1>::GetComponent(p1, this->SourceComponents[0]));
}
2017-05-18 14:29:41 +00:00
template <typename T1, typename T2>
VTKM_EXEC_CONT ValueType operator()(const T1& p1, const T2& p2) const
{
return ValueType(vtkm::VecTraits<T1>::GetComponent(p1, this->SourceComponents[0]),
vtkm::VecTraits<T2>::GetComponent(p2, this->SourceComponents[1]));
}
2017-05-18 14:29:41 +00:00
template <typename T1, typename T2, typename T3>
VTKM_EXEC_CONT ValueType operator()(const T1& p1, const T2& p2, const T3& p3) const
{
return ValueType(vtkm::VecTraits<T1>::GetComponent(p1, this->SourceComponents[0]),
vtkm::VecTraits<T2>::GetComponent(p2, this->SourceComponents[1]),
vtkm::VecTraits<T3>::GetComponent(p3, this->SourceComponents[2]));
}
2017-05-18 14:29:41 +00:00
template <typename T1, typename T2, typename T3, typename T4>
VTKM_EXEC_CONT ValueType operator()(const T1& p1, const T2& p2, const T3& p3, const T4& p4) const
{
return ValueType(vtkm::VecTraits<T1>::GetComponent(p1, this->SourceComponents[0]),
vtkm::VecTraits<T2>::GetComponent(p2, this->SourceComponents[1]),
vtkm::VecTraits<T3>::GetComponent(p3, this->SourceComponents[2]),
vtkm::VecTraits<T4>::GetComponent(p4, this->SourceComponents[3]));
}
};
2017-05-18 14:29:41 +00:00
template <typename ReturnValueType>
struct VTKM_ALWAYS_EXPORT CompositeVectorPullValueFunctor
{
vtkm::Id Index;
VTKM_EXEC
2017-05-18 14:29:41 +00:00
CompositeVectorPullValueFunctor(vtkm::Id index)
: Index(index)
{
}
// This form is to pull values out of array arguments.
VTKM_SUPPRESS_EXEC_WARNINGS
2017-05-18 14:29:41 +00:00
template <typename PortalType>
VTKM_EXEC_CONT typename PortalType::ValueType operator()(const PortalType& portal) const
{
return portal.Get(this->Index);
}
// This form is an identity to pass the return value back.
VTKM_EXEC_CONT
2017-05-18 14:29:41 +00:00
const ReturnValueType& operator()(const ReturnValueType& value) const { return value; }
};
2017-05-18 14:29:41 +00:00
struct CompositeVectorArrayToPortalCont
{
template <typename ArrayHandleType, vtkm::IdComponent Index>
struct ReturnType
{
typedef typename ArrayHandleType::PortalConstControl type;
};
2017-05-18 14:29:41 +00:00
template <typename ArrayHandleType, vtkm::IdComponent Index>
VTKM_CONT typename ReturnType<ArrayHandleType, Index>::type operator()(
const ArrayHandleType& array, vtkm::internal::IndexTag<Index>) const
{
return array.GetPortalConstControl();
}
};
2017-05-18 14:29:41 +00:00
template <typename DeviceAdapterTag>
struct CompositeVectorArrayToPortalExec
{
template <typename ArrayHandleType, vtkm::IdComponent Index>
struct ReturnType
{
typedef typename ArrayHandleType::template ExecutionTypes<DeviceAdapterTag>::PortalConst type;
};
2017-05-18 14:29:41 +00:00
template <typename ArrayHandleType, vtkm::IdComponent Index>
VTKM_CONT typename ReturnType<ArrayHandleType, Index>::type operator()(
const ArrayHandleType& array, vtkm::internal::IndexTag<Index>) const
{
return array.PrepareForInput(DeviceAdapterTag());
}
};
2017-05-18 14:29:41 +00:00
struct CheckArraySizeFunctor
{
vtkm::Id ExpectedSize;
2017-05-18 14:29:41 +00:00
CheckArraySizeFunctor(vtkm::Id expectedSize)
: ExpectedSize(expectedSize)
{
}
2017-05-18 14:29:41 +00:00
template <typename T, vtkm::IdComponent Index>
void operator()(const T& a, vtkm::internal::IndexTag<Index>) const
{
if (a.GetNumberOfValues() != this->ExpectedSize)
{
std::stringstream message;
message << "All input arrays to ArrayHandleCompositeVector must be the same size.\n"
2017-05-18 14:29:41 +00:00
<< "Array " << Index - 1 << " has " << a.GetNumberOfValues() << ". Expected "
<< this->ExpectedSize << ".";
throw vtkm::cont::ErrorBadValue(message.str().c_str());
}
}
};
} // namespace detail
/// \brief A portal that gets values from components of other portals.
///
/// This is the portal used within ArrayHandleCompositeVector.
///
2017-05-18 14:29:41 +00:00
template <typename SignatureWithPortals>
class VTKM_ALWAYS_EXPORT ArrayPortalCompositeVector
{
typedef vtkm::internal::FunctionInterface<SignatureWithPortals> PortalTypes;
public:
typedef typename PortalTypes::ResultType ValueType;
2017-05-18 14:29:41 +00:00
static const vtkm::IdComponent NUM_COMPONENTS = vtkm::VecTraits<ValueType>::NUM_COMPONENTS;
// Used internally.
typedef vtkm::Vec<vtkm::IdComponent, NUM_COMPONENTS> ComponentMapType;
VTKM_STATIC_ASSERT(NUM_COMPONENTS == PortalTypes::ARITY);
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
2017-05-18 14:29:41 +00:00
ArrayPortalCompositeVector() {}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_CONT
2017-05-18 14:29:41 +00:00
ArrayPortalCompositeVector(const PortalTypes portals,
vtkm::Vec<vtkm::IdComponent, NUM_COMPONENTS> sourceComponents)
: Portals(portals)
, SourceComponents(sourceComponents)
{
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
2017-05-18 14:29:41 +00:00
vtkm::Id GetNumberOfValues() const
{
return this->Portals.template GetParameter<1>().GetNumberOfValues();
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
2017-05-18 14:29:41 +00:00
ValueType Get(vtkm::Id index) const
{
// This might be inefficient because we are copying all the portals only
// because they are coupled with the return value.
PortalTypes localPortals = this->Portals;
localPortals.InvokeExec(
2017-05-18 14:29:41 +00:00
detail::CompositeVectorSwizzleFunctor<ValueType>(this->SourceComponents),
detail::CompositeVectorPullValueFunctor<ValueType>(index));
return localPortals.GetReturnValue();
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
2017-05-18 14:29:41 +00:00
void Set(vtkm::Id vtkmNotUsed(index), const ValueType& vtkmNotUsed(value)) const
{
// There is no technical reason why this cannot be implemented. As of this
// writing no one has needed to write to a composite vector yet.
2017-05-18 14:29:41 +00:00
VTKM_ASSERT(false &&
"Set not yet implemented for composite vector. Do you volunteer to implement it?");
}
private:
PortalTypes Portals;
ComponentMapType SourceComponents;
};
2017-05-18 14:29:41 +00:00
template <typename SignatureWithArrays>
struct VTKM_ALWAYS_EXPORT StorageTagCompositeVector
{
};
/// A convenience class that provides a typedef to the appropriate tag for
/// a composite storage.
2017-05-18 14:29:41 +00:00
template <typename SignatureWithArrays>
struct ArrayHandleCompositeVectorTraits
{
2017-05-18 14:29:41 +00:00
typedef vtkm::cont::internal::StorageTagCompositeVector<SignatureWithArrays> Tag;
typedef typename vtkm::internal::FunctionInterface<SignatureWithArrays>::ResultType ValueType;
typedef vtkm::cont::internal::Storage<ValueType, Tag> StorageType;
typedef vtkm::cont::ArrayHandle<ValueType, Tag> Superclass;
};
// It may seem weird that this specialization throws an exception for
// everything, but that is because all the functionality is handled in the
// ArrayTransfer class.
2017-05-18 14:29:41 +00:00
template <typename SignatureWithArrays>
class Storage<typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::ValueType,
vtkm::cont::internal::StorageTagCompositeVector<SignatureWithArrays>>
{
2017-05-18 14:29:41 +00:00
typedef vtkm::internal::FunctionInterface<SignatureWithArrays> FunctionInterfaceWithArrays;
static const vtkm::IdComponent NUM_COMPONENTS = FunctionInterfaceWithArrays::ARITY;
typedef vtkm::Vec<vtkm::IdComponent, NUM_COMPONENTS> ComponentMapType;
typedef typename FunctionInterfaceWithArrays::template StaticTransformType<
2017-05-18 14:29:41 +00:00
detail::CompositeVectorArrayToPortalCont>::type FunctionInterfaceWithPortals;
typedef typename FunctionInterfaceWithPortals::Signature SignatureWithPortals;
public:
typedef ArrayPortalCompositeVector<SignatureWithPortals> PortalType;
typedef PortalType PortalConstType;
typedef typename PortalType::ValueType ValueType;
VTKM_CONT
2017-05-18 14:29:41 +00:00
Storage()
: Valid(false)
{
}
VTKM_CONT
2017-05-18 14:29:41 +00:00
Storage(const FunctionInterfaceWithArrays& arrays, const ComponentMapType& sourceComponents)
: Arrays(arrays)
, SourceComponents(sourceComponents)
, Valid(true)
{
2017-05-18 14:29:41 +00:00
arrays.ForEachCont(detail::CheckArraySizeFunctor(this->GetNumberOfValues()));
}
VTKM_CONT
2017-05-18 14:29:41 +00:00
PortalType GetPortal()
{
throw vtkm::cont::ErrorBadValue("Composite vector arrays are read only.");
}
VTKM_CONT
2017-05-18 14:29:41 +00:00
PortalConstType GetPortalConst() const
{
if (!this->Valid)
{
throw vtkm::cont::ErrorBadValue(
2017-05-18 14:29:41 +00:00
"Tried to use an ArrayHandleCompositeHandle without dependent arrays.");
}
2017-05-18 14:29:41 +00:00
return PortalConstType(
this->Arrays.StaticTransformCont(detail::CompositeVectorArrayToPortalCont()),
this->SourceComponents);
}
VTKM_CONT
2017-05-18 14:29:41 +00:00
vtkm::Id GetNumberOfValues() const
{
if (!this->Valid)
{
throw vtkm::cont::ErrorBadValue(
2017-05-18 14:29:41 +00:00
"Tried to use an ArrayHandleCompositeHandle without dependent arrays.");
}
return this->Arrays.template GetParameter<1>().GetNumberOfValues();
}
VTKM_CONT
2017-05-18 14:29:41 +00:00
void Allocate(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorInternal(
2017-05-18 14:29:41 +00:00
"The allocate method for the composite vector storage should never "
"have been called. The allocate is generally only called by the "
"execution array manager, and the array transfer for the composite "
"storage should prevent the execution array manager from being "
"directly used.");
}
VTKM_CONT
2017-05-18 14:29:41 +00:00
void Shrink(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorBadValue("Composite vector arrays are read-only.");
}
VTKM_CONT
2017-05-18 14:29:41 +00:00
void ReleaseResources()
{
if (this->Valid)
{
// TODO: Implement this.
}
}
VTKM_CONT
2017-05-18 14:29:41 +00:00
const FunctionInterfaceWithArrays& GetArrays() const
{
VTKM_ASSERT(this->Valid);
return this->Arrays;
}
VTKM_CONT
2017-05-18 14:29:41 +00:00
const ComponentMapType& GetSourceComponents() const
{
VTKM_ASSERT(this->Valid);
return this->SourceComponents;
}
private:
FunctionInterfaceWithArrays Arrays;
ComponentMapType SourceComponents;
bool Valid;
};
2017-05-18 14:29:41 +00:00
template <typename SignatureWithArrays, typename DeviceAdapterTag>
class ArrayTransfer<typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::ValueType,
vtkm::cont::internal::StorageTagCompositeVector<SignatureWithArrays>,
DeviceAdapterTag>
{
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
2017-05-18 14:29:41 +00:00
typedef typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::StorageType StorageType;
2017-05-18 14:29:41 +00:00
typedef vtkm::internal::FunctionInterface<SignatureWithArrays> FunctionWithArrays;
typedef typename FunctionWithArrays::template StaticTransformType<
2017-05-18 14:29:41 +00:00
detail::CompositeVectorArrayToPortalExec<DeviceAdapterTag>>::type FunctionWithPortals;
typedef typename FunctionWithPortals::Signature SignatureWithPortals;
public:
2017-05-18 14:29:41 +00:00
typedef typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::ValueType ValueType;
// These are not currently fully implemented.
typedef typename StorageType::PortalType PortalControl;
typedef typename StorageType::PortalConstType PortalConstControl;
typedef ArrayPortalCompositeVector<SignatureWithPortals> PortalExecution;
typedef ArrayPortalCompositeVector<SignatureWithPortals> PortalConstExecution;
VTKM_CONT
2017-05-18 14:29:41 +00:00
ArrayTransfer(StorageType* storage)
: Storage(storage)
{
}
VTKM_CONT
2017-05-18 14:29:41 +00:00
vtkm::Id GetNumberOfValues() const { return this->Storage->GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData)) const
{
2017-05-18 14:29:41 +00:00
return PortalConstExecution(this->Storage->GetArrays().StaticTransformCont(
detail::CompositeVectorArrayToPortalExec<DeviceAdapterTag>()),
this->Storage->GetSourceComponents());
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
{
// It may be the case a composite vector could be used for in place
// operations, but this is not implemented currently.
throw vtkm::cont::ErrorBadValue(
2017-05-18 14:29:41 +00:00
"Composite vector arrays cannot be used for output or in place.");
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues))
{
// It may be the case a composite vector could be used for output if you
// want the delegate arrays to be resized, but this is not implemented
// currently.
2017-05-18 14:29:41 +00:00
throw vtkm::cont::ErrorBadValue("Composite vector arrays cannot be used for output.");
}
VTKM_CONT
2017-05-18 14:29:41 +00:00
void RetrieveOutputData(StorageType* vtkmNotUsed(storage)) const
{
2017-05-18 14:29:41 +00:00
throw vtkm::cont::ErrorBadValue("Composite vector arrays cannot be used for output.");
}
VTKM_CONT
void Shrink(vtkm::Id vtkmNotUsed(numberOfValues))
{
2017-05-18 14:29:41 +00:00
throw vtkm::cont::ErrorBadValue("Composite vector arrays cannot be resized.");
}
VTKM_CONT
2017-05-18 14:29:41 +00:00
void ReleaseResources() { this->Storage->ReleaseResources(); }
private:
2017-05-18 14:29:41 +00:00
StorageType* Storage;
};
} // namespace internal
/// \brief An \c ArrayHandle that combines components from other arrays.
///
/// \c ArrayHandleCompositeVector is a specialization of \c ArrayHandle that
/// derives its content from other arrays. It takes up to 4 other \c
/// ArrayHandle objects and mimics an array that contains vectors with
/// components that come from these delegate arrays.
///
/// The easiest way to create and type an \c ArrayHandleCompositeVector is
/// to use the \c make_ArrayHandleCompositeVector functions.
///
2017-05-18 14:29:41 +00:00
template <typename Signature>
class ArrayHandleCompositeVector
2017-05-18 14:29:41 +00:00
: public internal::ArrayHandleCompositeVectorTraits<Signature>::Superclass
{
2017-05-18 14:29:41 +00:00
typedef typename internal::ArrayHandleCompositeVectorTraits<Signature>::StorageType StorageType;
typedef
typename internal::ArrayPortalCompositeVector<Signature>::ComponentMapType ComponentMapType;
public:
VTKM_ARRAY_HANDLE_SUBCLASS(
2017-05-18 14:29:41 +00:00
ArrayHandleCompositeVector, (ArrayHandleCompositeVector<Signature>),
(typename internal::ArrayHandleCompositeVectorTraits<Signature>::Superclass));
VTKM_CONT
2017-05-18 14:29:41 +00:00
ArrayHandleCompositeVector(const vtkm::internal::FunctionInterface<Signature>& arrays,
const ComponentMapType& sourceComponents)
: Superclass(StorageType(arrays, sourceComponents))
2017-05-18 14:29:41 +00:00
{
}
/// Template constructors for passing in types. You'll get weird compile
/// errors if the argument types do not actually match the types in the
/// signature.
///
2017-05-18 14:29:41 +00:00
template <typename ArrayHandleType1>
VTKM_CONT ArrayHandleCompositeVector(const ArrayHandleType1& array1,
vtkm::IdComponent sourceComponent1)
: Superclass(StorageType(vtkm::internal::make_FunctionInterface<ValueType>(array1),
ComponentMapType(sourceComponent1)))
{
}
template <typename ArrayHandleType1, typename ArrayHandleType2>
VTKM_CONT ArrayHandleCompositeVector(const ArrayHandleType1& array1,
vtkm::IdComponent sourceComponent1,
const ArrayHandleType2& array2,
vtkm::IdComponent sourceComponent2)
: Superclass(StorageType(vtkm::internal::make_FunctionInterface<ValueType>(array1, array2),
ComponentMapType(sourceComponent1, sourceComponent2)))
{
}
template <typename ArrayHandleType1, typename ArrayHandleType2, typename ArrayHandleType3>
VTKM_CONT ArrayHandleCompositeVector(const ArrayHandleType1& array1,
vtkm::IdComponent sourceComponent1,
const ArrayHandleType2& array2,
vtkm::IdComponent sourceComponent2,
const ArrayHandleType3& array3,
vtkm::IdComponent sourceComponent3)
: Superclass(
StorageType(vtkm::internal::make_FunctionInterface<ValueType>(array1, array2, array3),
ComponentMapType(sourceComponent1, sourceComponent2, sourceComponent3)))
{
}
template <typename ArrayHandleType1, typename ArrayHandleType2, typename ArrayHandleType3,
typename ArrayHandleType4>
VTKM_CONT ArrayHandleCompositeVector(
const ArrayHandleType1& array1, vtkm::IdComponent sourceComponent1,
const ArrayHandleType2& array2, vtkm::IdComponent sourceComponent2,
const ArrayHandleType3& array3, vtkm::IdComponent sourceComponent3,
const ArrayHandleType4& array4, vtkm::IdComponent sourceComponent4)
: Superclass(StorageType(
2017-05-18 14:29:41 +00:00
vtkm::internal::make_FunctionInterface<ValueType>(array1, array2, array3, array4),
ComponentMapType(sourceComponent1, sourceComponent2, sourceComponent3, sourceComponent4)))
{
}
};
/// \brief Get the type for an ArrayHandleCompositeVector
///
/// The ArrayHandleCompositeVector has a difficult template specification.
/// Use this helper template to covert a list of array handle types to a
/// composite vector of these array handles. Here is a simple example.
///
/// \code{.cpp}
/// typedef vtkm::cont::ArrayHandleCompositeVector<
/// vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
/// vtkm::cont::ArrayHandle<vtkm::FloatDefault> >::type OutArrayType;
/// OutArrayType outArray = vtkm::cont::make_ArrayHandleCompositeVector(a1,a2);
/// \endcode
///
2017-05-18 14:29:41 +00:00
template <typename ArrayHandleType1, typename ArrayHandleType2 = void,
typename ArrayHandleType3 = void, typename ArrayHandleType4 = void>
struct ArrayHandleCompositeVectorType
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType1);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType2);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType3);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType4);
2017-05-18 14:29:41 +00:00
private:
2017-05-18 14:29:41 +00:00
typedef
typename vtkm::VecTraits<typename ArrayHandleType1::ValueType>::ComponentType ComponentType;
typedef vtkm::Vec<ComponentType, 4> Signature(ArrayHandleType1, ArrayHandleType2,
ArrayHandleType3, ArrayHandleType4);
public:
typedef vtkm::cont::ArrayHandleCompositeVector<Signature> type;
};
2017-05-18 14:29:41 +00:00
template <typename ArrayHandleType1, typename ArrayHandleType2, typename ArrayHandleType3>
struct ArrayHandleCompositeVectorType<ArrayHandleType1, ArrayHandleType2, ArrayHandleType3>
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType1);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType2);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType3);
2017-05-18 14:29:41 +00:00
private:
2017-05-18 14:29:41 +00:00
typedef
typename vtkm::VecTraits<typename ArrayHandleType1::ValueType>::ComponentType ComponentType;
typedef vtkm::Vec<ComponentType, 3> Signature(ArrayHandleType1, ArrayHandleType2,
ArrayHandleType3);
public:
typedef vtkm::cont::ArrayHandleCompositeVector<Signature> type;
};
2017-05-18 14:29:41 +00:00
template <typename ArrayHandleType1, typename ArrayHandleType2>
struct ArrayHandleCompositeVectorType<ArrayHandleType1, ArrayHandleType2>
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType1);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType2);
2017-05-18 14:29:41 +00:00
private:
2017-05-18 14:29:41 +00:00
typedef
typename vtkm::VecTraits<typename ArrayHandleType1::ValueType>::ComponentType ComponentType;
typedef vtkm::Vec<ComponentType, 2> Signature(ArrayHandleType1, ArrayHandleType2);
public:
typedef vtkm::cont::ArrayHandleCompositeVector<Signature> type;
};
2017-05-18 14:29:41 +00:00
template <typename ArrayHandleType1>
struct ArrayHandleCompositeVectorType<ArrayHandleType1>
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType1);
2017-05-18 14:29:41 +00:00
private:
2017-05-18 14:29:41 +00:00
typedef
typename vtkm::VecTraits<typename ArrayHandleType1::ValueType>::ComponentType ComponentType;
typedef ComponentType Signature(ArrayHandleType1);
2017-05-18 14:29:41 +00:00
public:
typedef vtkm::cont::ArrayHandleCompositeVector<Signature> type;
};
2017-05-18 14:29:41 +00:00
// clang-format off
/// Create a composite vector array from other arrays.
///
2017-05-18 14:29:41 +00:00
template <typename ValueType1, typename Storage1>
VTKM_CONT
2017-05-18 14:29:41 +00:00
typename ArrayHandleCompositeVectorType<vtkm::cont::ArrayHandle<ValueType1, Storage1>>::type
make_ArrayHandleCompositeVector(const vtkm::cont::ArrayHandle<ValueType1, Storage1>& array1,
vtkm::IdComponent sourceComponent1)
{
2017-05-18 14:29:41 +00:00
return
typename ArrayHandleCompositeVectorType<vtkm::cont::ArrayHandle<ValueType1, Storage1>>::type(
array1, sourceComponent1);
}
2017-05-18 14:29:41 +00:00
// clang-format on
template <typename ArrayHandleType1>
VTKM_CONT typename ArrayHandleCompositeVectorType<ArrayHandleType1>::type
make_ArrayHandleCompositeVector(const ArrayHandleType1& array1, vtkm::IdComponent sourceComponent1)
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType1);
2017-05-18 14:29:41 +00:00
return typename ArrayHandleCompositeVectorType<ArrayHandleType1>::type(array1, sourceComponent1);
}
2017-05-18 14:29:41 +00:00
template <typename ArrayHandleType1, typename ArrayHandleType2>
VTKM_CONT typename ArrayHandleCompositeVectorType<ArrayHandleType1, ArrayHandleType2>::type
make_ArrayHandleCompositeVector(const ArrayHandleType1& array1, vtkm::IdComponent sourceComponent1,
const ArrayHandleType2& array2, vtkm::IdComponent sourceComponent2)
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType1);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType2);
2017-05-18 14:29:41 +00:00
return typename ArrayHandleCompositeVectorType<ArrayHandleType1, ArrayHandleType2>::type(
array1, sourceComponent1, array2, sourceComponent2);
}
2017-05-18 14:29:41 +00:00
template <typename ArrayHandleType1, typename ArrayHandleType2, typename ArrayHandleType3>
VTKM_CONT typename ArrayHandleCompositeVectorType<ArrayHandleType1, ArrayHandleType2,
ArrayHandleType3>::type
make_ArrayHandleCompositeVector(const ArrayHandleType1& array1, vtkm::IdComponent sourceComponent1,
const ArrayHandleType2& array2, vtkm::IdComponent sourceComponent2,
const ArrayHandleType3& array3, vtkm::IdComponent sourceComponent3)
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType1);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType2);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType3);
2017-05-18 14:29:41 +00:00
return typename ArrayHandleCompositeVectorType<ArrayHandleType1, ArrayHandleType2,
ArrayHandleType3>::type(array1, sourceComponent1,
array2, sourceComponent2,
array3, sourceComponent3);
}
2017-05-18 14:29:41 +00:00
template <typename ArrayHandleType1, typename ArrayHandleType2, typename ArrayHandleType3,
typename ArrayHandleType4>
VTKM_CONT typename ArrayHandleCompositeVectorType<ArrayHandleType1, ArrayHandleType2,
ArrayHandleType3, ArrayHandleType4>::type
make_ArrayHandleCompositeVector(const ArrayHandleType1& array1, vtkm::IdComponent sourceComponent1,
const ArrayHandleType2& array2, vtkm::IdComponent sourceComponent2,
const ArrayHandleType3& array3, vtkm::IdComponent sourceComponent3,
const ArrayHandleType4& array4, vtkm::IdComponent sourceComponent4)
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType1);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType2);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType3);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType4);
2017-05-18 14:29:41 +00:00
return
typename ArrayHandleCompositeVectorType<ArrayHandleType1, ArrayHandleType2, ArrayHandleType3,
ArrayHandleType4>::type(array1, sourceComponent1,
array2, sourceComponent2,
array3, sourceComponent3,
array4, sourceComponent4);
}
}
} // namespace vtkm::cont
#endif //vtk_m_ArrayHandleCompositeVector_h