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 =
vtkm::cont::ArrayHandleTransform<ArrayHandleType, PassThroughFunctor, PassThroughFunctor>;
template <typename ValueType, vtkm::IdComponent>
struct JunkArrayHandle : vtkm::cont::ArrayHandle<ValueType>
{
};
template <typename ArrayHandleType>
using BMArrayHandleMultiplexer =
vtkm::ListTagApply<vtkm::ListTagAppend<vtkm::cont::internal::ArrayHandleMultiplexerDefaultArrays<
typename ArrayHandleType::ValueType>,
ArrayHandlePassThrough<ArrayHandleType>>,
vtkm::cont::ArrayHandleMultiplexer>;
vtkm::cont::ArrayHandleMultiplexer<ArrayHandleType,
JunkArrayHandle<typename ArrayHandleType::ValueType, 0>,
JunkArrayHandle<typename ArrayHandleType::ValueType, 1>,
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>
BMArrayHandleMultiplexer<ArrayHandleType> make_ArrayHandleMultiplexer0(const ArrayHandleType& array)

@ -96,47 +96,6 @@ indices = indicesInMemory;
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
To implement `ArrayHandleMultiplexer`, the class `vtkm::internal::Variant`

@ -375,13 +375,18 @@ private:
namespace detail
{
template <typename ValueType, typename... ArrayHandleTypes>
template <typename... ArrayHandleTypes>
struct ArrayHandleMultiplexerTraits
{
// If there is a compile error in this group of lines, then the list tag 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.
using ArrayHandleType0 =
brigand::at<brigand::list<ArrayHandleTypes...>, std::integral_constant<vtkm::IdComponent, 0>>;
VTKM_IS_ARRAY_HANDLE(ArrayHandleType0);
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>
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.
///
/// 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
/// 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
/// array. A default list of supported arrays is supported (see
/// \c vtkm::cont::internal::ArrayHandleMultiplexerDefaultArrays.) If multiple template
/// parameters are given, they are all considered possible \c ArrayHandle types.
///
template <typename... Ts>
class ArrayHandleMultiplexer;
template <typename ValueType_>
class ArrayHandleMultiplexer<ValueType_>
: public detail::ArrayHandleMultiplexerChooseBase<ValueType_>
template <typename... ArrayHandleTypes>
class ArrayHandleMultiplexer
: public vtkm::cont::ArrayHandle<
typename detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>::ValueType,
typename detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>::StorageTag>
{
using Traits = detail::ArrayHandleMultiplexerTraits<ArrayHandleTypes...>;
public:
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleMultiplexer,
(ArrayHandleMultiplexer<ValueType_>),
(detail::ArrayHandleMultiplexerChooseBase<ValueType_>));
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandleMultiplexer,
(ArrayHandleMultiplexer<ArrayHandleTypes...>),
(vtkm::cont::ArrayHandle<typename Traits::ValueType, typename Traits::StorageTag>));
template <typename RealT, typename RealStorageTag>
VTKM_CONT ArrayHandleMultiplexer(const vtkm::cont::ArrayHandle<RealT, RealStorageTag>& src)
: Superclass(src)
{
}
private:
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
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:
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleMultiplexer,
(ArrayHandleMultiplexer<ArrayType0, ArrayTypes...>),
(vtkm::cont::ArrayHandleMultiplexerBase<typename ArrayType0::ValueType,
ArrayType0,
ArrayTypes...>));
template <typename RealT, typename RealStorageTag>
VTKM_CONT ArrayHandleMultiplexer(const vtkm::cont::ArrayHandle<RealT, RealStorageTag>& src)
: Superclass(src)
template <typename RealStorageTag>
VTKM_CONT ArrayHandleMultiplexer(const vtkm::cont::ArrayHandle<ValueType, RealStorageTag>& src)
: Superclass(StorageType(src))
{
}
template <typename RealT, typename RealStorageTag>
VTKM_CONT ArrayHandleMultiplexer(vtkm::cont::ArrayHandle<RealT, RealStorageTag>&& rhs)
: Superclass(std::move(rhs))
template <typename RealStorageTag>
VTKM_CONT ArrayHandleMultiplexer(vtkm::cont::ArrayHandle<ValueType, RealStorageTag>&& rhs)
: Superclass(StorageType(std::move(rhs)))
{
}
};

@ -86,63 +86,7 @@ class TestingArrayHandleMultiplexer
CheckArray(multiplexer, array3);
}
static void DefaultScalar()
{
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();
}
static void TestAll() { BasicSwitch(); }
public:
static int Run(int argc, char* argv[])