Commit c026d14b authored by Robert Maynard's avatar Robert Maynard
Browse files

DynamicArrayHandle prunes invalid Value/Storage set before cast and call

By pruning the invalid combinations first we reduce the amount of work
the compiler has to do. Additionally it makes for smaller callstacks when
the compiler errors out during a CastAndCall.
parent d3fe1a6b
......@@ -58,20 +58,28 @@ class VTKM_CONT_EXPORT ArrayHandleBase
{
};
/// Checks to see if the given type and storage can form a valid array handle
/// Checks to see if the given type and storage forms a valid array handle
/// (some storage objects cannot support all types). This check is compatible
/// with C++11 type_traits. It contains a
/// typedef named type that is either std::true_type or std::false_type.
/// Both of these have a typedef named value with the respective boolean value.
/// with C++11 type_traits.
///
template <typename T, typename StorageTag>
struct IsValidArrayHandle
{
//need to add the not
using type =
std::integral_constant<bool,
: std::integral_constant<bool,
!(std::is_base_of<vtkm::cont::internal::UndefinedStorage,
vtkm::cont::internal::Storage<T, StorageTag>>::value)>;
vtkm::cont::internal::Storage<T, StorageTag>>::value)>
{
};
/// Checks to see if the given type and storage forms a invalid array handle
/// (some storage objects cannot support all types). This check is compatible
/// with C++11 type_traits.
///
template <typename T, typename StorageTag>
struct IsInValidArrayHandle
: std::integral_constant<bool,
(std::is_base_of<vtkm::cont::internal::UndefinedStorage,
vtkm::cont::internal::Storage<T, StorageTag>>::value)>
{
};
/// Checks to see if the ArrayHandle for the given DeviceAdatper allows
......@@ -97,6 +105,7 @@ private:
public:
using type = std::integral_constant<bool, !IsVoidType::value>;
static constexpr bool value = !IsVoidType::value;
};
/// Checks to see if the given object is an array handle. This check is
......
......@@ -29,6 +29,7 @@
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/cont/StorageListTag.h>
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/internal/DynamicTransform.h>
namespace vtkm
......@@ -408,26 +409,17 @@ namespace detail
struct DynamicArrayHandleTry
{
DynamicArrayHandleTry(const PolymorphicArrayHandleContainerBase* const c)
: Container(c)
{
}
template <typename T, typename U, typename... Args>
void operator()(brigand::list<T, U>, Args&&... args) const
{
using storage = vtkm::cont::internal::Storage<T, U>;
using invalid = typename std::is_base_of<vtkm::cont::internal::UndefinedStorage, storage>::type;
this->run<T, U>(invalid{}, args...);
}
template <typename T, typename U, typename Functor, typename... Args>
void run(std::false_type, Functor&& f, bool& called, Args&&... args) const
void operator()(brigand::list<T, U>,
Functor&& f,
bool& called,
const PolymorphicArrayHandleContainerBase* const container,
Args&&... args) const
{
if (!called)
{
using downcastType = const vtkm::cont::detail::PolymorphicArrayHandleContainer<T, U>* const;
downcastType downcastContainer = dynamic_cast<downcastType>(this->Container);
downcastType downcastContainer = dynamic_cast<downcastType>(container);
if (downcastContainer)
{
f(downcastContainer->Array, std::forward<Args>(args)...);
......@@ -435,13 +427,6 @@ struct DynamicArrayHandleTry
}
}
}
template <typename T, typename U, typename... Args>
void run(std::true_type, Args&&...) const
{
}
const PolymorphicArrayHandleContainerBase* const Container;
};
VTKM_CONT_EXPORT void ThrowCastAndCallException(PolymorphicArrayHandleContainerBase*,
......@@ -449,6 +434,25 @@ VTKM_CONT_EXPORT void ThrowCastAndCallException(PolymorphicArrayHandleContainerB
const std::type_info*);
} // namespace detail
template <typename T>
struct IsUndefinedStorage
{
};
template <typename T, typename U>
struct IsUndefinedStorage<brigand::list<T, U>> : vtkm::cont::internal::IsInValidArrayHandle<T, U>
{
};
template <typename TypeList, typename StorageList>
struct ListTagDynamicTypes : vtkm::detail::ListRoot
{
using crossProduct = typename vtkm::ListCrossProduct<TypeList, StorageList>;
// using list = typename crossProduct::list;
using list = ::brigand::remove_if<typename crossProduct::list, IsUndefinedStorage<brigand::_1>>;
};
template <typename TypeList, typename StorageList>
template <typename Functor, typename... Args>
VTKM_CONT void DynamicArrayHandleBase<TypeList, StorageList>::CastAndCall(Functor&& f,
......@@ -456,14 +460,15 @@ VTKM_CONT void DynamicArrayHandleBase<TypeList, StorageList>::CastAndCall(Functo
{
//For optimizations we should compile once the cross product for the default types
//and make it extern
using crossProduct = typename vtkm::ListCrossProduct<TypeList, StorageList>;
using crossProduct = ListTagDynamicTypes<TypeList, StorageList>;
bool called = false;
auto* ptr = this->ArrayContainer.get();
vtkm::ListForEach(detail::DynamicArrayHandleTry(ptr),
vtkm::ListForEach(detail::DynamicArrayHandleTry{},
crossProduct{},
std::forward<Functor>(f),
called,
ptr,
std::forward<Args>(args)...);
if (!called)
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment