Remove special ArrayHandleMultiplexer template case

There was a special case for ArrayHandleMultiplexer where if you gave it
just one type it would treat that as a value type rather than an array
to support and instead provide a default list of types. However, GCC 4.8
is having trouble compiling the code to create the default list, the
semantics are confusing, and the more I think about it the less likely I
think we will need this functionality. So, just getting rid of that.
This commit is contained in:
Kenneth Moreland 2019-07-30 14:43:52 -06:00
parent 023e12b23a
commit eaf87e4519
4 changed files with 50 additions and 294 deletions

@ -306,12 +306,25 @@ template <typename ArrayHandleType>
using ArrayHandlePassThrough = using ArrayHandlePassThrough =
vtkm::cont::ArrayHandleTransform<ArrayHandleType, PassThroughFunctor, PassThroughFunctor>; vtkm::cont::ArrayHandleTransform<ArrayHandleType, PassThroughFunctor, PassThroughFunctor>;
template <typename ValueType, vtkm::IdComponent>
struct JunkArrayHandle : vtkm::cont::ArrayHandle<ValueType>
{
};
template <typename ArrayHandleType> template <typename ArrayHandleType>
using BMArrayHandleMultiplexer = using BMArrayHandleMultiplexer =
vtkm::ListTagApply<vtkm::ListTagAppend<vtkm::cont::internal::ArrayHandleMultiplexerDefaultArrays< vtkm::cont::ArrayHandleMultiplexer<ArrayHandleType,
typename ArrayHandleType::ValueType>, JunkArrayHandle<typename ArrayHandleType::ValueType, 0>,
ArrayHandlePassThrough<ArrayHandleType>>, JunkArrayHandle<typename ArrayHandleType::ValueType, 1>,
vtkm::cont::ArrayHandleMultiplexer>; JunkArrayHandle<typename ArrayHandleType::ValueType, 2>,
JunkArrayHandle<typename ArrayHandleType::ValueType, 3>,
JunkArrayHandle<typename ArrayHandleType::ValueType, 4>,
JunkArrayHandle<typename ArrayHandleType::ValueType, 5>,
JunkArrayHandle<typename ArrayHandleType::ValueType, 6>,
JunkArrayHandle<typename ArrayHandleType::ValueType, 7>,
JunkArrayHandle<typename ArrayHandleType::ValueType, 8>,
JunkArrayHandle<typename ArrayHandleType::ValueType, 9>,
ArrayHandlePassThrough<ArrayHandleType>>;
template <typename ArrayHandleType> template <typename ArrayHandleType>
BMArrayHandleMultiplexer<ArrayHandleType> make_ArrayHandleMultiplexer0(const ArrayHandleType& array) BMArrayHandleMultiplexer<ArrayHandleType> make_ArrayHandleMultiplexer0(const ArrayHandleType& array)

@ -96,47 +96,6 @@ indices = indicesInMemory;
All the code that uses `indices` will continue to work. All the code that uses `indices` will continue to work.
If `ArrayHandleMultiplexer` is created with only a single template
parameter, then the parameter is interpreted differently. Instead of being
interpreted as a type of array, it is interpreted as the `ValueType` of the
array. In this case, a default set of arrays will set for you. The basic
storage type array will always be part of this list.
``` cpp
vtkm::cont::ArrayHandleMultiplexer<vtkm::FloatDefault> multiplexerArray;
vtkm::cont::ArrayHandle<vtkm::FloatDefault> basicArray;
// Fill basicArray...
multiplexerArray = basicArray;
```
The default list of arrays includes `ArrayHandleCast` from pretty much any
basic type of the same vector length. This allows you to get an
`ArrayHandleMultiplexer` of some known type and then use it for other
types. For example, you can use an integer-based array in a place where you
expect a floating point field.
``` cpp
vtkm::cont::ArrayHandleMultiplexer<vtkm::FloatDefault> multiplexerArray;
vtkm::cont::ArrayHandle<vtkm::Int32> integerField;
// Fill integerField...
multiplexerArray = vtkm::cont::make_ArrayHandleCast<vtkm::FloatDefault>(integerField);
```
We (as developers) also have the option of putting in special storage types
for particular value types. For example, the default list of arrays for a
`Vec<FloatDefault,3>` include `ArrayHandleUniformPointCoordinates` (whereas
this array cannot be placed in other default lists).
``` cpp
vtkm::cont::ArrayHandleMultiplexer<vtkm::Vec<vtkm::FloatDefault, 3>> multiplexerArray;
multiplexerArray = vtkm::cont::ArrayHandleUniformPointCoordinates(vtkm::Id3(50));
```
## Variant ## Variant
To implement `ArrayHandleMultiplexer`, the class `vtkm::internal::Variant` To implement `ArrayHandleMultiplexer`, the class `vtkm::internal::Variant`

@ -375,13 +375,18 @@ private:
namespace detail namespace detail
{ {
template <typename ValueType, typename... ArrayHandleTypes> template <typename... ArrayHandleTypes>
struct ArrayHandleMultiplexerTraits struct ArrayHandleMultiplexerTraits
{ {
// If there is a compile error in this group of lines, then the list tag given to using ArrayHandleType0 =
// ArrayHandleMultiplexer must contain an invalid ArrayHandle. That could mean that brigand::at<brigand::list<ArrayHandleTypes...>, std::integral_constant<vtkm::IdComponent, 0>>;
// it is not an ArrayHandle type or it could mean that the value type does not match VTKM_IS_ARRAY_HANDLE(ArrayHandleType0);
// the appropriate value type. using ValueType = typename ArrayHandleType0::ValueType;
// If there is a compile error in this group of lines, then one of the array types given to
// ArrayHandleMultiplexer must contain an invalid ArrayHandle. That could mean that it is not an
// ArrayHandle type or it could mean that the value type does not match the appropriate value
// type.
template <typename ArrayHandle> template <typename ArrayHandle>
struct CheckArrayHandleTransform struct CheckArrayHandleTransform
{ {
@ -409,154 +414,6 @@ struct ArrayHandleMultiplexerTraits
}; };
} }
/// \brief Base implementation of \c ArrayHandleMultiplexer.
///
/// This behavies the same as \c ArrayHandleMultiplexer, but the template parameters are
/// more explicit. The first template parameter must be the \c ValueType of the array.
/// The remaining template parameters are the array handles to support.
///
template <typename ValueType_, typename... ArrayHandleTypes>
class ArrayHandleMultiplexerBase
: public vtkm::cont::ArrayHandle<
ValueType_,
typename detail::ArrayHandleMultiplexerTraits<ValueType_, ArrayHandleTypes...>::StorageTag>
{
using Traits = detail::ArrayHandleMultiplexerTraits<ValueType_, ArrayHandleTypes...>;
public:
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleMultiplexerBase,
(ArrayHandleMultiplexerBase<ValueType_, ArrayHandleTypes...>),
(vtkm::cont::ArrayHandle<ValueType_, typename Traits::StorageTag>));
private:
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
public:
template <typename RealStorageTag>
VTKM_CONT ArrayHandleMultiplexerBase(
const vtkm::cont::ArrayHandle<ValueType, RealStorageTag>& src)
: Superclass(StorageType(src))
{
}
template <typename RealStorageTag>
VTKM_CONT ArrayHandleMultiplexerBase(vtkm::cont::ArrayHandle<ValueType, RealStorageTag>&& rhs)
: Superclass(StorageType(std::move(rhs)))
{
}
};
namespace internal
{
namespace detail
{
template <typename ValueType>
struct MakeArrayListFromStorage
{
template <typename S>
using Transform = vtkm::cont::ArrayHandle<ValueType, S>;
};
template <typename ValueType>
struct SupportedArrays
: vtkm::ListTagTransform<vtkm::cont::StorageListTagSupported,
MakeArrayListFromStorage<ValueType>::template Transform>
{
};
template <typename DestType, typename SrcTypeList>
struct MakeCastArrayListImpl
{
using TypeStoragePairs = vtkm::ListCrossProduct<SrcTypeList, vtkm::cont::StorageListTagSupported>;
template <typename Pair>
struct PairToCastArrayImpl;
template <typename T, typename S>
struct PairToCastArrayImpl<brigand::list<T, S>>
{
using Type = vtkm::cont::ArrayHandleCast<DestType, vtkm::cont::ArrayHandle<T, S>>;
};
template <typename Pair>
using PairToCastArray = typename PairToCastArrayImpl<Pair>::Type;
using Type = vtkm::ListTagTransform<TypeStoragePairs, PairToCastArray>;
};
template <typename DestType>
struct MakeCastArrayList
{
using Type = typename MakeCastArrayListImpl<DestType, vtkm::TypeListTagScalarAll>::Type;
};
template <typename ComponentType, vtkm::IdComponent N>
struct MakeCastArrayList<vtkm::Vec<ComponentType, N>>
{
template <typename T>
using ScalarToVec = vtkm::Vec<T, N>;
using SourceTypes = vtkm::ListTagTransform<vtkm::TypeListTagScalarAll, ScalarToVec>;
using Type = typename MakeCastArrayListImpl<vtkm::Vec<ComponentType, N>, SourceTypes>::Type;
};
template <typename T>
struct ArrayHandleMultiplexerDefaultArraysBase
: vtkm::ListTagJoin<SupportedArrays<T>, typename MakeCastArrayList<T>::Type>
{
};
} // namespace detail
template <typename T>
struct ArrayHandleMultiplexerDefaultArrays : detail::ArrayHandleMultiplexerDefaultArraysBase<T>
{
};
template <>
struct ArrayHandleMultiplexerDefaultArrays<vtkm::Vec<vtkm::FloatDefault, 3>>
: vtkm::ListTagJoin<
detail::ArrayHandleMultiplexerDefaultArraysBase<vtkm::Vec<vtkm::FloatDefault, 3>>,
vtkm::ListTagBase<
#if 1
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>,
#endif
vtkm::cont::ArrayHandleUniformPointCoordinates>>
{
};
} // namespace internal
namespace detail
{
template <typename ValueType, typename ListTagArrays>
struct ArrayHandleMultiplexerChooseBaseImpl
{
VTKM_IS_LIST_TAG(ListTagArrays);
template <typename BrigandListArrays>
struct BrigandListArraysToArrayHandleMultiplexerBase;
template <typename... ArrayHandleTypes>
struct BrigandListArraysToArrayHandleMultiplexerBase<brigand::list<ArrayHandleTypes...>>
{
using Type = vtkm::cont::ArrayHandleMultiplexerBase<ValueType, ArrayHandleTypes...>;
};
using Type = typename BrigandListArraysToArrayHandleMultiplexerBase<
vtkm::internal::ListTagAsBrigandList<ListTagArrays>>::Type;
};
template <typename ValueType>
using ArrayHandleMultiplexerChooseBase = typename ArrayHandleMultiplexerChooseBaseImpl<
ValueType,
internal::ArrayHandleMultiplexerDefaultArrays<ValueType>>::Type;
} // namespace detail
/// \brief An ArrayHandle that can behave like several other handles. /// \brief An ArrayHandle that can behave like several other handles.
/// ///
/// An \c ArrayHandleMultiplexer simply redirects its calls to another \c ArrayHandle. However /// An \c ArrayHandleMultiplexer simply redirects its calls to another \c ArrayHandle. However
@ -568,58 +425,41 @@ using ArrayHandleMultiplexerChooseBase = typename ArrayHandleMultiplexerChooseBa
/// see which type of array is currently stored in it. It then redirects to the \c ArrayHandle /// see which type of array is currently stored in it. It then redirects to the \c ArrayHandle
/// of the appropriate type. /// of the appropriate type.
/// ///
/// The \c ArrayHandleMultiplexer template parameters are all the ArrayHandle types it
/// should support.
///
/// If only one template parameter is given, it is assumed to be the \c ValueType of the /// If only one template parameter is given, it is assumed to be the \c ValueType of the
/// array. A default list of supported arrays is supported (see /// array. A default list of supported arrays is supported (see
/// \c vtkm::cont::internal::ArrayHandleMultiplexerDefaultArrays.) If multiple template /// \c vtkm::cont::internal::ArrayHandleMultiplexerDefaultArrays.) If multiple template
/// parameters are given, they are all considered possible \c ArrayHandle types. /// parameters are given, they are all considered possible \c ArrayHandle types.
/// ///
template <typename... Ts> template <typename... ArrayHandleTypes>
class ArrayHandleMultiplexer; class ArrayHandleMultiplexer
: public vtkm::cont::ArrayHandle<
template <typename ValueType_> typename detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>::ValueType,
class ArrayHandleMultiplexer<ValueType_> typename detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>::StorageTag>
: public detail::ArrayHandleMultiplexerChooseBase<ValueType_>
{ {
using Traits = detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>;
public: public:
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleMultiplexer, VTKM_ARRAY_HANDLE_SUBCLASS(
(ArrayHandleMultiplexer<ValueType_>), ArrayHandleMultiplexer,
(detail::ArrayHandleMultiplexerChooseBase<ValueType_>)); (ArrayHandleMultiplexer<ArrayHandleTypes...>),
(vtkm::cont::ArrayHandle<typename Traits::ValueType, typename Traits::StorageTag>));
template <typename RealT, typename RealStorageTag> private:
VTKM_CONT ArrayHandleMultiplexer(const vtkm::cont::ArrayHandle<RealT, RealStorageTag>& src) using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
: Superclass(src)
{
}
template <typename RealT, typename RealStorageTag>
VTKM_CONT ArrayHandleMultiplexer(vtkm::cont::ArrayHandle<RealT, RealStorageTag>&& rhs)
: Superclass(std::move(rhs))
{
}
};
template <typename ArrayType0, typename... ArrayTypes>
class ArrayHandleMultiplexer<ArrayType0, ArrayTypes...>
: public vtkm::cont::ArrayHandleMultiplexerBase<typename ArrayType0::ValueType,
ArrayType0,
ArrayTypes...>
{
public: public:
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleMultiplexer, template <typename RealStorageTag>
(ArrayHandleMultiplexer<ArrayType0, ArrayTypes...>), VTKM_CONT ArrayHandleMultiplexer(const vtkm::cont::ArrayHandle<ValueType, RealStorageTag>& src)
(vtkm::cont::ArrayHandleMultiplexerBase<typename ArrayType0::ValueType, : Superclass(StorageType(src))
ArrayType0,
ArrayTypes...>));
template <typename RealT, typename RealStorageTag>
VTKM_CONT ArrayHandleMultiplexer(const vtkm::cont::ArrayHandle<RealT, RealStorageTag>& src)
: Superclass(src)
{ {
} }
template <typename RealT, typename RealStorageTag> template <typename RealStorageTag>
VTKM_CONT ArrayHandleMultiplexer(vtkm::cont::ArrayHandle<RealT, RealStorageTag>&& rhs) VTKM_CONT ArrayHandleMultiplexer(vtkm::cont::ArrayHandle<ValueType, RealStorageTag>&& rhs)
: Superclass(std::move(rhs)) : Superclass(StorageType(std::move(rhs)))
{ {
} }
}; };

@ -86,63 +86,7 @@ class TestingArrayHandleMultiplexer
CheckArray(multiplexer, array3); CheckArray(multiplexer, array3);
} }
static void DefaultScalar() static void TestAll() { BasicSwitch(); }
{
std::cout << std::endl << "--- Default list for scalars" << std::endl;
using ValueType = vtkm::FloatDefault;
vtkm::cont::ArrayHandleMultiplexer<ValueType> multiplexer;
std::cout << "Basic array type." << std::endl;
vtkm::cont::ArrayHandle<ValueType> baseArray;
baseArray.Allocate(ARRAY_SIZE);
SetPortal(baseArray.GetPortalControl());
multiplexer = baseArray;
CheckArray(multiplexer, baseArray);
std::cout << "Cast array type." << std::endl;
vtkm::cont::ArrayHandle<vtkm::UInt8> castArray;
castArray.Allocate(ARRAY_SIZE);
SetPortal(castArray.GetPortalControl());
multiplexer = vtkm::cont::make_ArrayHandleCast<ValueType>(castArray);
CheckArray(multiplexer, castArray);
}
static void DefaultVec3()
{
std::cout << std::endl << "--- Default list for Vec3" << std::endl;
using ValueType = vtkm::Vec<vtkm::FloatDefault, 3>;
vtkm::cont::ArrayHandleMultiplexer<ValueType> multiplexer;
std::cout << "Basic array type." << std::endl;
vtkm::cont::ArrayHandle<ValueType> baseArray;
baseArray.Allocate(ARRAY_SIZE);
SetPortal(baseArray.GetPortalControl());
multiplexer = baseArray;
CheckArray(multiplexer, baseArray);
std::cout << "Cast array type." << std::endl;
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 3>> castArray;
castArray.Allocate(ARRAY_SIZE);
SetPortal(castArray.GetPortalControl());
multiplexer = vtkm::cont::make_ArrayHandleCast<ValueType>(castArray);
CheckArray(multiplexer, castArray);
std::cout << "Uniform point coordinates" << std::endl;
vtkm::cont::ArrayHandleUniformPointCoordinates uniformCoords(vtkm::Id3(3));
multiplexer = uniformCoords;
CheckArray(multiplexer, uniformCoords);
}
static void TestAll()
{
BasicSwitch();
DefaultScalar();
DefaultVec3();
}
public: public:
static int Run(int argc, char* argv[]) static int Run(int argc, char* argv[])