Add a mechanism to check whether an array handle is valid

Use this mechanism in the dynamic array handle to skip over trying
invalid array handle types (and thereby incurring a compiler error even
though we never intended to use these classes).
This commit is contained in:
Kenneth Moreland 2014-04-03 14:08:53 -06:00
parent d309fa7ae5
commit c4ecdbada8
3 changed files with 60 additions and 6 deletions

@ -28,6 +28,8 @@
#define VTKM_ARRAY_CONTAINER_CONTROL VTKM_ARRAY_CONTAINER_CONTROL_BASIC
#endif
#include <boost/static_assert.hpp>
namespace vtkm {
namespace cont {
@ -62,13 +64,35 @@ struct ArrayContainerControlTag___ { };
namespace internal {
struct UndefinedArrayContainerControl { };
namespace detail {
// This class should never be used. It is used as a placeholder for undefined
// ArrayContainerControl objects. If you get a compiler error involving this
// object, then it probably comes from trying to use an ArrayHandle with bad
// template arguments.
template<typename T>
struct UndefinedArrayPortal {
BOOST_STATIC_ASSERT(sizeof(T) == -1);
};
} // namespace detail
/// This templated class must be partially specialized for each
/// ArrayContainerControlTag created, which will define the implementation for
/// that tag.
///
template<typename T, class ArrayContainerControlTag>
class ArrayContainerControl
#ifdef VTKM_DOXYGEN_ONLY
#ifndef VTKM_DOXYGEN_ONLY
: public vtkm::cont::internal::UndefinedArrayContainerControl
{
public:
typedef vtkm::cont::internal::detail::UndefinedArrayPortal<T> PortalType;
typedef vtkm::cont::internal::detail::UndefinedArrayPortal<T> PortalConstType;
};
#else //VTKM_DOXYGEN_ONLY
{
public:
@ -133,8 +157,6 @@ public:
VTKM_CONT_EXPORT
void ReleaseResources();
};
#else // VTKM_DOXYGEN_ONLY
;
#endif // VTKM_DOXYGEN_ONLY
} // namespace internal

@ -30,16 +30,35 @@
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <boost/concept_check.hpp>
#include <boost/mpl/not.hpp>
#include <boost/smart_ptr/scoped_ptr.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <vector>
namespace vtkm {
namespace cont {
// Forward declaration
namespace internal { class ArrayHandleAccess; }
namespace internal {
/// Checks to see if the given type and container can form a valid array handle
/// (some containers cannot support all types). This check is compatable with
/// the Boost meta-template programming library (MPL). It contains a typedef
/// named type that is either boost::mpl::true_ or boost::mpl::false_. Both of
/// these have a typedef named value with the respective boolean value.
///
template<typename T, typename ArrayContainerControlTag>
struct IsValidArrayHandle {
typedef typename boost::mpl::not_<
typename boost::is_base_of<
vtkm::cont::internal::UndefinedArrayContainerControl,
vtkm::cont::internal::ArrayContainerControl<T,ArrayContainerControlTag>
>::type
>::type type;
};
} // namespace internal
/// \brief Manages an array-worth of data.
///

@ -29,6 +29,7 @@
#include <vtkm/cont/internal/SimplePolymorphicContainer.h>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/utility/enable_if.hpp>
namespace vtkm {
namespace cont {
@ -174,7 +175,10 @@ struct DynamicArrayHandleTryContainer {
template<typename Container>
VTKM_CONT_EXPORT
void operator()(Container) {
typename boost::enable_if<
typename vtkm::cont::internal::IsValidArrayHandle<Type,Container>::type
>::type
operator()(Container) {
if (!this->FoundCast &&
this->Array.IsTypeAndContainer(Type(), Container()))
{
@ -182,6 +186,15 @@ struct DynamicArrayHandleTryContainer {
this->FoundCast = true;
}
}
template<typename Container>
VTKM_CONT_EXPORT
typename boost::disable_if<
typename vtkm::cont::internal::IsValidArrayHandle<Type,Container>::type
>::type
operator()(Container) {
// This type of array handle cannot exist, so do nothing.
}
};
template<typename Functor, typename ContainerList>