Merge topic 'use_brigand_over_boost_mpl'

ba8c8586 Get IntegerSequence to work correctly with MSVC.
377532c7 Update brigand to get a chunk of msvc2013 fixes.
a7f7cfe4 Update brigand.hpp to get corrections for MSVC2013.
a931b8e2 FunctionInterface and DispatcherBase don't require boost now.
ac0929a1 Add fast tracks for ListTag operations on size <= 4.
7ad88b6e Use c++11 variadic templates as storage of ListTags.

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !559
This commit is contained in:
Robert Maynard 2016-09-28 08:41:25 -04:00 committed by Kitware Robot
commit 70abe603c5
17 changed files with 3053 additions and 1709 deletions

@ -76,3 +76,4 @@ CMake/FindTBB.cmake
CMake/FindGLEW.cmake
vtkm/cont/tbb/internal/parallel_sort.h
vtkm/testing/OptionParser.h
vtkm/internal/brigand.hpp

@ -32,7 +32,7 @@ namespace vtkm {
namespace internal {
template<typename ListTag>
struct ListTagCheck
struct ListTagCheck : std::is_base_of<vtkm::detail::ListRoot,ListTag>
{
static VTKM_CONSTEXPR bool Valid = std::is_base_of<vtkm::detail::ListRoot,
ListTag>::value;
@ -47,57 +47,23 @@ struct ListTagCheck
///
#define VTKM_IS_LIST_TAG(tag) \
VTKM_STATIC_ASSERT_MSG( \
(::vtkm::internal::ListTagCheck<tag>::Valid), \
(::vtkm::internal::ListTagCheck<tag>::value), \
"Provided type is not a valid VTK-m list tag.")
namespace detail {
template<typename ListTag1, typename ListTag2>
struct ListJoin { };
} // namespace detail
/// A special tag for an empty list.
///
struct ListTagEmpty : detail::ListRoot {
typedef detail::ListBase<void()> List;
using list = vtkm::detail::ListBase<>;
};
/// A tag that is a construction of two other tags joined together. This struct
/// can be subclassed and still behave like a list tag.
template<typename ListTag1, typename ListTag2>
struct ListTagJoin : detail::ListRoot {
typedef detail::ListJoin<ListTag1, ListTag2> List;
using list = typename detail::ListJoin<ListTag1,ListTag2>::type;
};
template<typename Functor, typename ListTag>
VTKM_CONT_EXPORT
void ListForEach(Functor &f, ListTag);
template<typename Functor, typename ListTag>
VTKM_CONT_EXPORT
void ListForEach(const Functor &f, ListTag);
namespace detail {
template<typename Functor, typename ListTag1, typename ListTag2>
VTKM_CONT_EXPORT
void ListForEachImpl(Functor &f, ListJoin<ListTag1, ListTag2>)
{
vtkm::ListForEach(f, ListTag1());
vtkm::ListForEach(f, ListTag2());
}
template<typename Functor, typename ListTag1, typename ListTag2>
VTKM_CONT_EXPORT
void ListForEachImpl(const Functor &f, ListJoin<ListTag1, ListTag2>)
{
vtkm::ListForEach(f, ListTag1());
vtkm::ListForEach(f, ListTag2());
}
} // namespace detail
/// For each typename represented by the list tag, call the functor with a
/// default instance of that type.
///
@ -106,7 +72,7 @@ VTKM_CONT_EXPORT
void ListForEach(Functor &f, ListTag)
{
VTKM_IS_LIST_TAG(ListTag);
detail::ListForEachImpl(f, typename ListTag::List());
detail::ListForEachImpl(f, typename ListTag::list());
}
/// For each typename represented by the list tag, call the functor with a
@ -117,7 +83,7 @@ VTKM_CONT_EXPORT
void ListForEach(const Functor &f, ListTag)
{
VTKM_IS_LIST_TAG(ListTag);
detail::ListForEachImpl(f, typename ListTag::List());
detail::ListForEachImpl(f, typename ListTag::list());
}
/// Checks to see if the given \c Type is in the list pointed to by \c ListTag.
@ -128,20 +94,10 @@ template<typename ListTag, typename Type>
struct ListContains
{
VTKM_IS_LIST_TAG(ListTag);
static const bool value =
detail::ListContainsImpl<typename ListTag::List,Type>::value;
static VTKM_CONSTEXPR bool value =
detail::ListContainsImpl<Type,typename ListTag::list>::value;
};
namespace detail {
template<typename Type, typename ListTag1, typename ListTag2>
struct ListContainsImpl<ListJoin<ListTag1,ListTag2>, Type>
{
static const bool value = (vtkm::ListContains<ListTag1,Type>::value ||
vtkm::ListContains<ListTag2,Type>::value);
};
} // namespace detail
} // namespace vtkm

@ -62,15 +62,15 @@ typedef vtkm::cont::ArrayHandleCompositeVectorType<
/// by default (unless it is defined before including VTK-m headers.
///
struct StorageListTagCoordinateSystemDefault
: vtkm::ListTagJoin<
VTKM_DEFAULT_STORAGE_LIST_TAG,
vtkm::ListTagBase<vtkm::cont::ArrayHandleUniformPointCoordinates::StorageTag,
: vtkm::ListTagBase<
vtkm::cont::StorageTagBasic,
vtkm::cont::ArrayHandleUniformPointCoordinates::StorageTag,
detail::ArrayHandleCompositeVectorFloat32_3Default::StorageTag,
detail::ArrayHandleCompositeVectorFloat64_3Default::StorageTag,
vtkm::cont::ArrayHandleCartesianProduct<
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault> >::StorageTag > >
vtkm::cont::ArrayHandle<vtkm::FloatDefault> >::StorageTag >
{ };
typedef vtkm::cont::DynamicArrayHandleBase<

@ -471,6 +471,7 @@ struct DynamicArrayHandleTryType {
typedef DynamicArrayHandleTryStorage<Functor, Type> TryStorageType;
TryStorageType tryStorage =
TryStorageType(*this->Array, this->Function);
vtkm::ListForEach(tryStorage, StorageList());
if (tryStorage.FoundCast)
{
@ -524,6 +525,7 @@ void DynamicArrayHandleBase<VTKM_DEFAULT_TYPE_LIST_TAG,
// the default one, and no reason to do an atomic increment and increase
// library size, and reduce performance
TryTypeType tryType = TryTypeType(*this, f);
vtkm::ListForEach(tryType, VTKM_DEFAULT_TYPE_LIST_TAG());
if (!tryType.FoundCast)
{

@ -337,6 +337,7 @@ void DynamicCellSetBase<CellSetList>::CastAndCall(const Functor &f) const
{
typedef detail::DynamicCellSetTryCellSet<Functor> TryCellSetType;
TryCellSetType tryCellSet = TryCellSetType(this->CellSetContainer.get(), f);
vtkm::ListForEach(tryCellSet, CellSetList());
if (!tryCellSet.FoundCast)
{

@ -58,6 +58,7 @@ set(headers
FunctionInterfaceDetailPost.h
FunctionInterfaceDetailPre.h
IndexTag.h
IntegerSequence.h
Invocation.h
ListTagDetail.h
)
@ -66,7 +67,6 @@ vtkm_declare_headers(${headers})
vtkm_pyexpander_generated_file(FunctionInterfaceDetailPre.h)
vtkm_pyexpander_generated_file(FunctionInterfaceDetailPost.h)
vtkm_pyexpander_generated_file(ListTagDetail.h)
add_subdirectory(testing)

@ -23,27 +23,6 @@
#include <vtkm/Types.h>
#include <vtkm/internal/IndexTag.h>
VTKM_THIRDPARTY_PRE_INCLUDE
#include <boost/function_types/components.hpp>
#include <boost/function_types/function_arity.hpp>
#include <boost/function_types/function_type.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/mpl/advance.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/erase.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/less.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/joint_view.hpp>
#include <boost/mpl/single_view.hpp>
VTKM_THIRDPARTY_POST_INCLUDE
#include <vtkm/internal/FunctionInterfaceDetailPre.h>
namespace vtkm {
@ -252,24 +231,23 @@ public:
}
// the number of parameters as a boost mpl integral constant
typedef boost::function_types::function_arity<FunctionSignature> SignatureArity;
typedef typename boost::function_types::result_type<FunctionSignature>::type
ResultType;
typedef typename boost::function_types::components<FunctionSignature> FunctionSignatureComponents;
// the number of parameters as an integral constant
typedef detail::FunctionSigInfo<FunctionSignature> SigInfo;
typedef typename SigInfo::ArityType SignatureArity;
typedef typename SigInfo::ResultType ResultType;
typedef typename SigInfo::Components ComponentSig;
typedef typename SigInfo::Parameters ParameterSig;
template<vtkm::IdComponent ParameterIndex>
struct ParameterType {
typedef typename detail::AtType<FunctionSignature, ParameterIndex>::type type;
typedef typename detail::AtType<ParameterIndex,FunctionSignature>::type type;
};
static const bool RETURN_VALID = FunctionInterfaceReturnContainer<ResultType>::VALID;
/// The number of parameters in this \c Function Interface.
///
static const vtkm::IdComponent ARITY = SignatureArity::value;
static const vtkm::IdComponent ARITY = SigInfo::Arity;
/// Returns the number of parameters held in this \c FunctionInterface. The
/// return value is the same as \c ARITY.
@ -481,17 +459,6 @@ public:
detail::DoInvokeExec(f, this->Parameters, this->Result, transform);
}
template<typename NewType>
struct AppendType {
private:
typedef boost::mpl::single_view<NewType> NewTypeSeq;
typedef boost::mpl::joint_view<FunctionSignatureComponents, NewTypeSeq> JointType;
typedef boost::function_types::function_type<JointType> FuntionType;
public:
typedef FunctionInterface< typename FuntionType::type > type;
};
/// Returns a new \c FunctionInterface with all the parameters of this \c
/// FunctionInterface and the given method argument appended to these
/// parameters. The return type can be determined with the \c AppendType
@ -499,28 +466,17 @@ public:
///
template<typename NewType>
VTKM_CONT_EXPORT
typename AppendType<NewType>::type
FunctionInterface < typename detail::AppendType<ComponentSig,NewType>::type >
Append(const NewType& newParameter) const
{
typedef typename AppendType<NewType>::type AppendInterfaceType;
typedef typename detail::AppendType<ComponentSig,NewType>::type AppendSignature;
AppendInterfaceType appendedFuncInterface;
FunctionInterface< AppendSignature > appendedFuncInterface;
appendedFuncInterface.Copy(*this);
appendedFuncInterface.template SetParameter<ARITY+1>(newParameter);
return appendedFuncInterface;
}
template<vtkm::IdComponent ParameterIndex, typename NewType>
class ReplaceType {
typedef typename boost::mpl::advance_c<typename boost::mpl::begin<FunctionSignatureComponents>::type, ParameterIndex>::type ToRemovePos;
typedef typename boost::mpl::erase<FunctionSignatureComponents, ToRemovePos>::type ComponentRemoved;
typedef typename boost::mpl::advance_c<typename boost::mpl::begin<ComponentRemoved>::type, ParameterIndex>::type ToInsertPos;
typedef typename boost::mpl::insert<ComponentRemoved, ToInsertPos, NewType>::type ComponentInserted;
typedef typename boost::function_types::function_type<ComponentInserted>::type NewSignature;
public:
typedef FunctionInterface<NewSignature> type;
};
/// Returns a new \c FunctionInterface with all the parameters of this \c
/// FunctionInterface except that the parameter indexed at the template
/// parameter \c ParameterIndex (also specified with the optional second
@ -560,13 +516,14 @@ public:
///
template<vtkm::IdComponent ParameterIndex, typename NewType>
VTKM_CONT_EXPORT
typename ReplaceType<ParameterIndex, NewType>::type
FunctionInterface < typename detail::ReplaceType<ComponentSig,ParameterIndex, NewType>::type >
Replace(const NewType& newParameter,
vtkm::internal::IndexTag<ParameterIndex> =
vtkm::internal::IndexTag<ParameterIndex>()) const
{
typename ReplaceType<ParameterIndex, NewType>::type replacedFuncInterface;
typedef typename detail::ReplaceType<ComponentSig,ParameterIndex, NewType>::type ReplaceSigType;
FunctionInterface< ReplaceSigType > replacedFuncInterface;
detail::FunctionInterfaceCopyParameters<ParameterIndex-1>::
Copy(replacedFuncInterface.Parameters, this->Parameters);
@ -804,22 +761,20 @@ public:
VTKM_CONT_EXPORT
void operator()(const T& newParameter) const
{
typedef typename FunctionInterface<NewFunction>::FunctionSignatureComponents NewFSigComp;
typedef typename FunctionInterface<NewFunction>::ComponentSig NewFSigComp;
typedef boost::mpl::single_view<T> NewTypeSeq;
typedef boost::mpl::joint_view<NewFSigComp, NewTypeSeq> JointType;
typedef boost::function_types::function_type<JointType> FuntionType;
typedef FunctionInterface< typename FuntionType::type > NextInterfaceType;
//Determine if we should do the next transform
using appended = brigand::push_back<NewFSigComp,T>;
using interfaceSig = typename detail::AsSigType<appended>::type;
using NextInterfaceType = FunctionInterface< interfaceSig >;
//Determine if we should do the next transform, and if so convert from
//boost mpl to std::true_type/false_type ( for readability of sigs )
typedef typename boost::mpl::less<
typename NextInterfaceType::SignatureArity,
typename vtkm::internal::FunctionInterface<OriginalFunction>::SignatureArity
>::type IsLessType;
typedef std::integral_constant<bool, IsLessType::value > ShouldDoNextTransformType;
static VTKM_CONSTEXPR std::size_t newArity = NextInterfaceType::ARITY;
static VTKM_CONSTEXPR std::size_t oldArity = detail::FunctionSigInfo<OriginalFunction>::Arity;
typedef std::integral_constant<bool,
(newArity < oldArity ) > ShouldDoNextTransformType;
NextInterfaceType nextInterface = this->NewInterface.Append(newParameter);
this->DoNextTransform(nextInterface, ShouldDoNextTransformType());
this->NewInterface.GetReturnValueSafe()
= nextInterface.GetReturnValueSafe();

@ -30,10 +30,9 @@
#include <vtkm/Types.h>
#include <vtkm/internal/IndexTag.h>
VTKM_THIRDPARTY_PRE_INCLUDE
#include <boost/function_types/function_type.hpp>
#include <boost/mpl/at.hpp>
VTKM_THIRDPARTY_POST_INCLUDE
#include <type_traits>
#include <vtkm/internal/brigand.hpp>
#define VTKM_MAX_FUNCTION_PARAMETERS 10
@ -48,13 +47,13 @@ namespace internal {
template<typename T>
struct FunctionInterfaceReturnContainer {
T Value;
static const bool VALID = true;
static VTKM_CONSTEXPR bool VALID = true;
};
template<>
struct FunctionInterfaceReturnContainer<void> {
// Nothing to store for void return.
static const bool VALID = false;
static VTKM_CONSTEXPR bool VALID = false;
};
namespace detail {
@ -223,11 +222,51 @@ struct ParameterContainer<R(P1,P2,P3,P4,P5,P6,P7,P8,P9,P10)> {
//============================================================================
template< typename FS, int Index>
struct AtType
template<typename> struct FunctionSigInfo;
template<typename R, typename... ArgTypes>
struct FunctionSigInfo<R(ArgTypes...)>
{
typedef boost::function_types::components<FS> ParamterTypes;
typedef typename boost::mpl::at_c<ParamterTypes, Index>::type type;
static VTKM_CONSTEXPR std::size_t Arity = sizeof...(ArgTypes);
using ArityType = std::integral_constant<int, Arity>;
using ResultType = R;
using Components = brigand::list<R,ArgTypes...>;
using Parameters = brigand::list<ArgTypes...>;
};
template<int, typename> struct AtType;
template<int Index, typename R, typename... ArgTypes>
struct AtType<Index, R(ArgTypes...)>
{
using type = brigand::at_c< brigand::list<R,ArgTypes...>, Index>;
};
template<typename Collection, typename NewType> struct AppendType;
template<template<typename...> class L, typename T, typename NT, typename... U>
struct AppendType<L<T, U...>, NT>
{
typedef T type(U...,NT);
};
template<typename Collection> struct AsSigType;
template<template<typename...> class L, typename T, typename... U>
struct AsSigType< L<T, U...> >
{
typedef T type(U...);
};
template< typename Components,
vtkm::IdComponent ParameterIndex,
typename NewType >
class ReplaceType {
typedef std::integral_constant<std::size_t, (std::size_t)ParameterIndex> Index;
using split = brigand::split_at<Components, Index>;
using front = brigand::push_back< brigand::front<split>, NewType >;
using back = brigand::pop_front< brigand::back<split> >;
using replaced = brigand::append< front, back >;
public:
using type = typename AsSigType< replaced >::type;
};
@ -242,7 +281,7 @@ struct ParameterContainerAccess<1> {
VTKM_SUPPRESS_EXEC_WARNINGS
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
const typename AtType<FunctionSignature, 1>::type &
const typename AtType<1, FunctionSignature>::type &
Get(const ParameterContainer<FunctionSignature> &parameters) {
return parameters.Parameter1;
}
@ -251,7 +290,7 @@ struct ParameterContainerAccess<1> {
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
void Set(ParameterContainer<FunctionSignature> &parameters,
const typename AtType<FunctionSignature, 1>::type &value) {
const typename AtType<1, FunctionSignature>::type &value) {
parameters.Parameter1 = value;
}
};
@ -262,7 +301,7 @@ struct ParameterContainerAccess<2> {
VTKM_SUPPRESS_EXEC_WARNINGS
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
const typename AtType<FunctionSignature, 2>::type &
const typename AtType<2, FunctionSignature>::type &
Get(const ParameterContainer<FunctionSignature> &parameters) {
return parameters.Parameter2;
}
@ -271,7 +310,7 @@ struct ParameterContainerAccess<2> {
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
void Set(ParameterContainer<FunctionSignature> &parameters,
const typename AtType<FunctionSignature, 2>::type &value) {
const typename AtType<2, FunctionSignature>::type &value) {
parameters.Parameter2 = value;
}
};
@ -282,7 +321,7 @@ struct ParameterContainerAccess<3> {
VTKM_SUPPRESS_EXEC_WARNINGS
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
const typename AtType<FunctionSignature, 3>::type &
const typename AtType<3, FunctionSignature>::type &
Get(const ParameterContainer<FunctionSignature> &parameters) {
return parameters.Parameter3;
}
@ -291,7 +330,7 @@ struct ParameterContainerAccess<3> {
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
void Set(ParameterContainer<FunctionSignature> &parameters,
const typename AtType<FunctionSignature, 3>::type &value) {
const typename AtType<3, FunctionSignature>::type &value) {
parameters.Parameter3 = value;
}
};
@ -302,7 +341,7 @@ struct ParameterContainerAccess<4> {
VTKM_SUPPRESS_EXEC_WARNINGS
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
const typename AtType<FunctionSignature, 4>::type &
const typename AtType<4, FunctionSignature>::type &
Get(const ParameterContainer<FunctionSignature> &parameters) {
return parameters.Parameter4;
}
@ -311,7 +350,7 @@ struct ParameterContainerAccess<4> {
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
void Set(ParameterContainer<FunctionSignature> &parameters,
const typename AtType<FunctionSignature, 4>::type &value) {
const typename AtType<4, FunctionSignature>::type &value) {
parameters.Parameter4 = value;
}
};
@ -322,7 +361,7 @@ struct ParameterContainerAccess<5> {
VTKM_SUPPRESS_EXEC_WARNINGS
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
const typename AtType<FunctionSignature, 5>::type &
const typename AtType<5, FunctionSignature>::type &
Get(const ParameterContainer<FunctionSignature> &parameters) {
return parameters.Parameter5;
}
@ -331,7 +370,7 @@ struct ParameterContainerAccess<5> {
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
void Set(ParameterContainer<FunctionSignature> &parameters,
const typename AtType<FunctionSignature, 5>::type &value) {
const typename AtType<5, FunctionSignature>::type &value) {
parameters.Parameter5 = value;
}
};
@ -342,7 +381,7 @@ struct ParameterContainerAccess<6> {
VTKM_SUPPRESS_EXEC_WARNINGS
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
const typename AtType<FunctionSignature, 6>::type &
const typename AtType<6, FunctionSignature>::type &
Get(const ParameterContainer<FunctionSignature> &parameters) {
return parameters.Parameter6;
}
@ -351,7 +390,7 @@ struct ParameterContainerAccess<6> {
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
void Set(ParameterContainer<FunctionSignature> &parameters,
const typename AtType<FunctionSignature, 6>::type &value) {
const typename AtType<6, FunctionSignature>::type &value) {
parameters.Parameter6 = value;
}
};
@ -362,7 +401,7 @@ struct ParameterContainerAccess<7> {
VTKM_SUPPRESS_EXEC_WARNINGS
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
const typename AtType<FunctionSignature, 7>::type &
const typename AtType<7, FunctionSignature>::type &
Get(const ParameterContainer<FunctionSignature> &parameters) {
return parameters.Parameter7;
}
@ -371,7 +410,7 @@ struct ParameterContainerAccess<7> {
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
void Set(ParameterContainer<FunctionSignature> &parameters,
const typename AtType<FunctionSignature, 7>::type &value) {
const typename AtType<7, FunctionSignature>::type &value) {
parameters.Parameter7 = value;
}
};
@ -382,7 +421,7 @@ struct ParameterContainerAccess<8> {
VTKM_SUPPRESS_EXEC_WARNINGS
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
const typename AtType<FunctionSignature, 8>::type &
const typename AtType<8, FunctionSignature>::type &
Get(const ParameterContainer<FunctionSignature> &parameters) {
return parameters.Parameter8;
}
@ -391,7 +430,7 @@ struct ParameterContainerAccess<8> {
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
void Set(ParameterContainer<FunctionSignature> &parameters,
const typename AtType<FunctionSignature, 8>::type &value) {
const typename AtType<8, FunctionSignature>::type &value) {
parameters.Parameter8 = value;
}
};
@ -402,7 +441,7 @@ struct ParameterContainerAccess<9> {
VTKM_SUPPRESS_EXEC_WARNINGS
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
const typename AtType<FunctionSignature, 9>::type &
const typename AtType<9, FunctionSignature>::type &
Get(const ParameterContainer<FunctionSignature> &parameters) {
return parameters.Parameter9;
}
@ -411,7 +450,7 @@ struct ParameterContainerAccess<9> {
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
void Set(ParameterContainer<FunctionSignature> &parameters,
const typename AtType<FunctionSignature, 9>::type &value) {
const typename AtType<9, FunctionSignature>::type &value) {
parameters.Parameter9 = value;
}
};
@ -422,7 +461,7 @@ struct ParameterContainerAccess<10> {
VTKM_SUPPRESS_EXEC_WARNINGS
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
const typename AtType<FunctionSignature, 10>::type &
const typename AtType<10, FunctionSignature>::type &
Get(const ParameterContainer<FunctionSignature> &parameters) {
return parameters.Parameter10;
}
@ -431,7 +470,7 @@ struct ParameterContainerAccess<10> {
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
void Set(ParameterContainer<FunctionSignature> &parameters,
const typename AtType<FunctionSignature, 10>::type &value) {
const typename AtType<10, FunctionSignature>::type &value) {
parameters.Parameter10 = value;
}
};

@ -42,10 +42,9 @@ $# Ignore the following comment. It is meant for the generated file.
#include <vtkm/Types.h>
#include <vtkm/internal/IndexTag.h>
VTKM_THIRDPARTY_PRE_INCLUDE
#include <boost/function_types/function_type.hpp>
#include <boost/mpl/at.hpp>
VTKM_THIRDPARTY_POST_INCLUDE
#include <type_traits>
#include <vtkm/internal/brigand.hpp>
$py(max_parameters=10)\
#define VTKM_MAX_FUNCTION_PARAMETERS $(max_parameters)
@ -94,13 +93,13 @@ namespace internal {
template<typename T>
struct FunctionInterfaceReturnContainer {
T Value;
static const bool VALID = true;
static VTKM_CONSTEXPR bool VALID = true;
};
template<>
struct FunctionInterfaceReturnContainer<void> {
// Nothing to store for void return.
static const bool VALID = false;
static VTKM_CONSTEXPR bool VALID = false;
};
namespace detail {
@ -124,11 +123,51 @@ $endfor\
$endfor\
//============================================================================
template< typename FS, int Index>
struct AtType
template<typename> struct FunctionSigInfo;
template<typename R, typename... ArgTypes>
struct FunctionSigInfo<R(ArgTypes...)>
{
typedef boost::function_types::components<FS> ParamterTypes;
typedef typename boost::mpl::at_c<ParamterTypes, Index>::type type;
static VTKM_CONSTEXPR std::size_t Arity = sizeof...(ArgTypes);
using ArityType = std::integral_constant<int, Arity>;
using ResultType = R;
using Components = brigand::list<R,ArgTypes...>;
using Parameters = brigand::list<ArgTypes...>;
};
template<int, typename> struct AtType;
template<int Index, typename R, typename... ArgTypes>
struct AtType<Index, R(ArgTypes...)>
{
using type = brigand::at_c< brigand::list<R,ArgTypes...>, Index>;
};
template<typename Collection, typename NewType> struct AppendType;
template<template<typename...> class L, typename T, typename NT, typename... U>
struct AppendType<L<T, U...>, NT>
{
typedef T type(U...,NT);
};
template<typename Collection> struct AsSigType;
template<template<typename...> class L, typename T, typename... U>
struct AsSigType< L<T, U...> >
{
typedef T type(U...);
};
template< typename Components,
vtkm::IdComponent ParameterIndex,
typename NewType >
class ReplaceType {
typedef std::integral_constant<std::size_t, (std::size_t)ParameterIndex> Index;
using split = brigand::split_at<Components, Index>;
using front = brigand::push_back< brigand::front<split>, NewType >;
using back = brigand::pop_front< brigand::back<split> >;
using replaced = brigand::append< front, back >;
public:
using type = typename AsSigType< replaced >::type;
};
@ -144,7 +183,7 @@ struct ParameterContainerAccess<$(param_index)> {
VTKM_SUPPRESS_EXEC_WARNINGS
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
const typename AtType<FunctionSignature, $(param_index)>::type &
const typename AtType<$(param_index), FunctionSignature>::type &
Get(const ParameterContainer<FunctionSignature> &parameters) {
return parameters.Parameter$(param_index);
}
@ -153,7 +192,7 @@ struct ParameterContainerAccess<$(param_index)> {
template<typename FunctionSignature>
VTKM_EXEC_CONT_EXPORT
void Set(ParameterContainer<FunctionSignature> &parameters,
const typename AtType<FunctionSignature, $(param_index)>::type &value) {
const typename AtType<$(param_index), FunctionSignature>::type &value) {
parameters.Parameter$(param_index) = value;
}
};

@ -0,0 +1,81 @@
//============================================================================
// 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_internal_IntegerSequence_h
#define vtk_m_internal_IntegerSequence_h
#include <cstdlib>
namespace vtkm {
namespace internal {
/// \brief A container of unsigned integers
///
/// C++11 Doesn't provide an IntegerSequence class and helper constructor
// So we need to roll our own. This class has been tested up to 512 elements.
//
template<int...> struct IntegerSequence{};
namespace detail {
template<int N, int... Is> //unroll in blocks of 4
struct MakeSeq : MakeSeq<N-4, N-3, N-2, N-1, N, Is...> {};
template<int... Is>
struct MakeSeq<0,1,2,3,Is...> //termination case
{ using type = IntegerSequence<0,1,2,3,Is...>; };
template<int Mod, int N>
struct PreMakeSeq : MakeSeq<N-3, N-2, N-1, N> {};
template<int N> //specialization for value +1 to divisible by 4
struct PreMakeSeq<1,N> : MakeSeq<N> {};
template<int N> //specialization for value +2 to divisible by 4
struct PreMakeSeq<2,N> : MakeSeq<N-1,N> {};
template<int N> //specialization for value +3 to divisible by 4
struct PreMakeSeq<3,N> : MakeSeq<N-2,N-1,N> {};
template<> //specialization for 4
struct PreMakeSeq<4,3> { using type = IntegerSequence<0,1,2,3>; };
template<> //specialization for 3
struct PreMakeSeq<3,2> { using type = IntegerSequence<0,1,2>; };
template<> //specialization for 2
struct PreMakeSeq<2,1> { using type = IntegerSequence<0,1>; };
template<> //specialization for 1
struct PreMakeSeq<1,0> { using type = IntegerSequence<0>; };
template<> //specialization for 0
struct PreMakeSeq<0,-1> { using type = IntegerSequence<>; };
} //namespace detail
/// \brief A helper method to create an Integer sequence of 0...N-1.
template<int N>
struct MakeIntegerSequence : detail::PreMakeSeq<N%4,N-1> {};
}
}
#endif //vtk_m_internal_IntegerSequence_h

File diff suppressed because it is too large Load Diff

@ -1,197 +0,0 @@
//============================================================================
// 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.
//============================================================================
$# This file uses the pyexpander macro processing utility to build the
$# FunctionInterface facilities that use a variable number of arguments.
$# Information, documentation, and downloads for pyexpander can be found at:
$#
$# http://pyexpander.sourceforge.net/
$#
$# To build the source code, execute the following (after installing
$# pyexpander, of course):
$#
$# expander.py ListTagDetail.h.in > ListTagDetail.h
$#
$# Ignore the following comment. It is meant for the generated file.
// **** DO NOT EDIT THIS FILE!!! ****
// This file is automatically generated by FunctionInterfaceDetailPre.h.in
#ifndef vtk_m_internal_ListTagDetail_h
#define vtk_m_internal_ListTagDetail_h
#if !defined(vtk_m_ListTag_h) && !defined(VTKM_TEST_HEADER_BUILD)
#error ListTagDetail.h must be included from ListTag.h
#endif
#include <vtkm/Types.h>
$py(max_base_list=15)\
#define VTKM_MAX_BASE_LIST $(max_base_list)
$# Python commands used in template expansion.
$py(
def comma_if(flag):
if flag:
return ','
else:
return '';
def template_params(num_params, name='T', start=1, default=''):
if num_params < start:
return ''
result = 'typename %s%d%s' % (name, start, default)
for param in xrange(start+1, num_params+1):
result += ',\n typename %s%d%s' % (name, param, default)
return result
def param_list(num_params, name='T', start=1):
if num_params < start:
return ''
result = '%s%d' % (name, start)
for param in xrange(start+1, num_params+1):
result += ',%s%d' % (name, param)
return result
def signature(num_params, name='T', return_type='void', start=1):
result = '%s(' % return_type
if num_params >= start:
result += '%s%d' % (name, start)
for param in xrange(start+1, num_params+1):
result += ',%s%d' % (name, param)
result += ')'
return result
)\
$#
$extend(comma_if, param_list, template_params, signature)\
namespace vtkm {
namespace detail {
//-----------------------------------------------------------------------------
/// Base class that all ListTag classes inherit from. Helps identify lists
/// in macros like VTKM_IS_LIST_TAG.
///
struct ListRoot { };
template<typename signature>
struct ListBase { };
//-----------------------------------------------------------------------------
template<typename Functor>
VTKM_CONT_EXPORT
void ListForEachImpl(const Functor &, ListBase<void()>) { }
$for(num_params in xrange(1, max_base_list+1))\
template<typename Functor,
$template_params(num_params)>
VTKM_CONT_EXPORT
void ListForEachImpl(Functor &f, ListBase<void($param_list(num_params))>)
{
$for(param_index in range(1, num_params+1))\
f(T$(param_index)());
$endfor\
}
template<typename Functor,
$template_params(num_params)>
VTKM_CONT_EXPORT
void ListForEachImpl(const Functor &f, ListBase<void($param_list(num_params))>)
{
$for(param_index in range(1, num_params+1))\
f(T$(param_index)());
$endfor\
}
$endfor\
//-----------------------------------------------------------------------------
template<typename List, typename Type>
struct ListContainsImpl;
template<typename Type>
struct ListContainsImpl<ListBase<void()>, Type>
{
static const bool value = false;
};
template<typename Type>
struct ListContainsImpl<ListBase<void(Type)>, Type>
{
static const bool value = true;
};
template<typename Type, typename T1>
struct ListContainsImpl<ListBase<void(T1)>, Type>
{
static const bool value = false;
};
$for(num_params in xrange(2, max_base_list+1))\
template<typename Type,
$template_params(num_params, start=2)>
struct ListContainsImpl<ListBase<void(Type,$param_list(num_params, start=2))>, Type>
{
static const bool value = true;
};
template<typename Type,
$template_params(num_params)>
struct ListContainsImpl<ListBase<$signature(num_params)>, Type>
{
static const bool value =
ListContainsImpl<ListBase<$signature(num_params, start=2)>, Type>::value;
};
$endfor\
} // namespace detail
//-----------------------------------------------------------------------------
/// A basic tag for a list of typenames. This struct can be subclassed
/// and still behave like a list tag.
#if defined(VTKM_HAVE_CXX_11)
template<typename... ArgTypes>
struct ListTagBase : detail::ListRoot
{
typedef detail::ListBase<void(ArgTypes...)> List;
};
#else
template<$template_params(max_base_list, default=' = vtkm::internal::NullType')>
struct ListTagBase : detail::ListRoot
{
typedef detail::ListBase<void($param_list(max_base_list))> List;
};
$for(num_params in xrange(0, (max_base_list+1)-1))\
template<$template_params(num_params)>
struct ListTagBase<$param_list(num_params)> : detail::ListRoot
{
typedef detail::ListBase<void($param_list(num_params))> List;
};
$endfor\
#endif
} // namespace vtkm
#endif //vtk_m_internal_ListTagDetail_h

2555
vtkm/internal/brigand.hpp Normal file

File diff suppressed because it is too large Load Diff

@ -22,5 +22,6 @@ set(unit_tests
UnitTestConfigureFor32.cxx
UnitTestConfigureFor64.cxx
UnitTestFunctionInterface.cxx
UnitTestIntegerSequence.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})

@ -0,0 +1,73 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/internal/IntegerSequence.h>
#include <vtkm/testing/Testing.h>
#include <vector>
namespace
{
template<std::size_t Len, int... Ts>
void verify_correct_length(vtkm::internal::IntegerSequence<Ts...>)
{
static_assert( Len == sizeof...(Ts), "Incorrect length");
//use a runtime time to verify the contents of the integer sequence
//are 0...N-1
std::vector<int> container= {Ts...};
for(std::size_t i=0; i < Len; ++i)
{
VTKM_TEST_ASSERT(container[i]==static_cast<int>(i), "Incorrect value");
}
}
void IntegerSequenceSizes()
{
using zero = vtkm::internal::MakeIntegerSequence<0>::type;
using one = vtkm::internal::MakeIntegerSequence<1>::type;
using two = vtkm::internal::MakeIntegerSequence<2>::type;
using four = vtkm::internal::MakeIntegerSequence<4>::type;
using thirty_two = vtkm::internal::MakeIntegerSequence<32>::type;
using thirty_three = vtkm::internal::MakeIntegerSequence<33>::type;
using thirty_four = vtkm::internal::MakeIntegerSequence<34>::type;
using thirty_five = vtkm::internal::MakeIntegerSequence<35>::type;
using two_fifty_six = vtkm::internal::MakeIntegerSequence<256>::type;
using five_twelve = vtkm::internal::MakeIntegerSequence<512>::type;
verify_correct_length<0>(zero());
verify_correct_length<1>(one());
verify_correct_length<2>(two());
verify_correct_length<4>(four());
verify_correct_length<32>(thirty_two());
verify_correct_length<33>(thirty_three());
verify_correct_length<34>(thirty_four());
verify_correct_length<35>(thirty_five());
verify_correct_length<256>(two_fifty_six());
verify_correct_length<512>(five_twelve());
}
}
int UnitTestIntegerSequence(int, char *[])
{
return vtkm::testing::Testing::Run(IntegerSequenceSizes);
}

@ -136,11 +136,11 @@ void TryList(const vtkm::Vec<int,N> &expected, ListTag)
void TestLists()
{
std::cout << "Valid List Tag Checks" << std::endl;
VTKM_TEST_ASSERT(vtkm::internal::ListTagCheck<TestListTag1>::Valid,
VTKM_TEST_ASSERT(vtkm::internal::ListTagCheck<TestListTag1>::value,
"Failed list tag check");
VTKM_TEST_ASSERT(vtkm::internal::ListTagCheck<TestListTagJoin>::Valid,
VTKM_TEST_ASSERT(vtkm::internal::ListTagCheck<TestListTagJoin>::value,
"Failed list tag check");
VTKM_TEST_ASSERT(!vtkm::internal::ListTagCheck<TestClass<1> >::Valid,
VTKM_TEST_ASSERT(!vtkm::internal::ListTagCheck<TestClass<1> >::value,
"Failed list tag check");
std::cout << "ListTagEmpty" << std::endl;

@ -31,20 +31,13 @@
#include <vtkm/cont/arg/ControlSignatureTagBase.h>
#include <vtkm/cont/arg/Transport.h>
#include <vtkm/cont/arg/TypeCheck.h>
#include <vtkm/cont/internal/DynamicTransform.h>
#include <vtkm/exec/arg/ExecutionSignatureTagBase.h>
#include <vtkm/exec/internal/WorkletInvokeFunctor.h>
VTKM_THIRDPARTY_PRE_INCLUDE
#include <boost/mpl/at.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/find.hpp>
#include <boost/mpl/zip_view.hpp>
#include <boost/mpl/vector.hpp>
VTKM_THIRDPARTY_POST_INCLUDE
#include <vtkm/internal/IntegerSequence.h>
#include <vtkm/internal/brigand.hpp>
#include <sstream>
@ -72,60 +65,32 @@ inline void PrintFailureMessage(int index, std::false_type)
throw vtkm::cont::ErrorControlBadType(message.str());
}
// Is designed as a boost mpl binary metafunction.
// Is designed as a brigand fold operation.
template<typename T, typename State>
struct DetermineIfHasDynamicParameter
{
template<typename T, typename U>
struct apply
{
typedef typename vtkm::cont::internal::DynamicTransformTraits<U>::DynamicTag DynamicTag;
typedef typename std::is_same<
using DynamicTag = typename vtkm::cont::internal::DynamicTransformTraits<T>::DynamicTag;
using isDynamic = typename std::is_same<
DynamicTag,
vtkm::cont::internal::DynamicTransformTagCastAndCall>::type UType;
vtkm::cont::internal::DynamicTransformTagCastAndCall>::type;
typedef std::integral_constant<bool,
(T::value || UType::value) > type;
};
using type = std::integral_constant<bool,
(State::value || isDynamic::value) >;
};
template<typename ValueType, typename TagList>
void NiceInCorrectParameterErrorMessage()
{
VTKM_STATIC_ASSERT_MSG(ValueType() == TagList(),
"Unable to match 'ValueType' to the signature tag 'ControlSignatureTag'" );
}
template<typename T>
void ShowInCorrectParameter(std::true_type, T) {}
template<typename T>
void ShowInCorrectParameter(std::false_type, T)
{
typedef typename boost::mpl::deref<T>::type ZipType;
typedef typename boost::mpl::at_c<ZipType,0>::type ValueType;
typedef typename boost::mpl::at_c<ZipType,1>::type ControlSignatureTag;
NiceInCorrectParameterErrorMessage<ValueType,ControlSignatureTag>();
};
// Is designed as a boost mpl unary metafunction.
// Is designed as a brigand fold operation.
template <typename Index, typename Params, typename SigTypes>
struct DetermineHasInCorrectParameters
{
//When we find parameters that don't match, we set our 'type' to true_
//otherwise we are false_
template<typename T>
struct apply
{
using ValueType = typename boost::mpl::at_c<T,0>::type;
using ControlSignatureTag = typename boost::mpl::at_c<T,1>::type;
using T = typename brigand::at_c<Params,Index::value>;
using ControlSignatureTag = typename brigand::at_c<SigTypes,Index::value>;
using TypeCheckTag = typename ControlSignatureTag::TypeCheckTag;
//We need to not the result of CanContinueTagType, because we want to return
//true when we have the first parameter that DOES NOT match the control
//signature requirements
using type = std::integral_constant< bool,
!vtkm::cont::arg::TypeCheck<TypeCheckTag,ValueType>::value>;
};
vtkm::cont::arg::TypeCheck<TypeCheckTag,T>::value >;
static_assert( type::value,
"Unable to match 'ValueType' to the signature tag 'ControlSignatureTag'");
};
// Checks that an argument in a ControlSignature is a valid control signature
@ -327,7 +292,7 @@ private:
void StartInvoke(
const vtkm::internal::FunctionInterface<Signature> &parameters) const
{
typedef vtkm::internal::FunctionInterface<Signature> ParameterInterface;
using ParameterInterface = vtkm::internal::FunctionInterface<Signature>;
VTKM_STATIC_ASSERT_MSG(ParameterInterface::ARITY == NUM_INVOKE_PARAMS,
"Dispatcher Invoke called with wrong number of arguments.");
@ -341,11 +306,14 @@ private:
//proper dynamic trait. Doing this, allows us to generate zero dynamic
//check & convert code when we already know all the types. This results
//in smaller executables and libraries.
typedef boost::function_types::parameter_types<Signature> MPLSignatureForm;
typedef typename boost::mpl::fold<
MPLSignatureForm,
std::false_type,
detail::DetermineIfHasDynamicParameter>::type HasDynamicTypes;
using ParamTypes = typename ParameterInterface::ParameterSig;
using HasDynamicTypes =
brigand::fold< ParamTypes,
std::false_type,
detail::DetermineIfHasDynamicParameter< brigand::_element,
brigand::_state
>
>;
this->StartInvokeDynamic(parameters, HasDynamicTypes() );
}
@ -377,30 +345,29 @@ private:
const vtkm::internal::FunctionInterface<Signature> &parameters,
std::false_type) const
{
using ParameterInterface = vtkm::internal::FunctionInterface<Signature>;
//Nothing requires a conversion from dynamic to static types, so
//next we need to verify that each argument's type is correct. If not
//we need to throw a nice compile time error
typedef boost::function_types::parameter_types<Signature> MPLSignatureForm;
typedef typename boost::function_types::parameter_types<
typename WorkletType::ControlSignature > WorkletContSignature;
using ParamTypes = typename ParameterInterface::ParameterSig;
using ContSigTypes = typename vtkm::internal::detail::FunctionSigInfo<
typename WorkletType::ControlSignature>::Parameters;
using NumParams = vtkm::internal::MakeIntegerSequence< ParameterInterface::ARITY >;
typedef boost::mpl::vector< MPLSignatureForm, WorkletContSignature > ZippedSignatures;
typedef boost::mpl::zip_view<ZippedSignatures> ZippedView;
using isAllValid =
brigand::fold< NumParams,
std::true_type,
detail::DetermineHasInCorrectParameters< brigand::_element,
ParamTypes,
ContSigTypes
>
>;
//When isAllValid is false we produce a second static_assert
//stating that the static transform is not possible
static_assert( isAllValid::value, "Unable to match all parameter types" );
typedef typename boost::mpl::find_if<
ZippedView,
detail::DetermineHasInCorrectParameters>::type LocationOfIncorrectParameter;
typedef typename std::is_same< LocationOfIncorrectParameter,
typename boost::mpl::end< ZippedView>::type >::type HasOnlyCorrectTypes;
//When HasOnlyCorrectTypes is false we produce an error
//message which should state what the parameter type and tag type is
//that failed to match.
detail::ShowInCorrectParameter(HasOnlyCorrectTypes(),
LocationOfIncorrectParameter());
this->DynamicTransformInvoke(parameters, HasOnlyCorrectTypes());
this->DynamicTransformInvoke(parameters, isAllValid());
}
template<typename Signature>