mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-19 18:45:43 +00:00
Merge topic 'variant-trivial-copy'
7518d0675 Try to fix uninitialized anonymous variable warning 5b18ffd77 Register Variant as trivially copyable if possible 16305bd83 Add tests of ArrayHandleMultiplexer on multiple devices Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Robert Maynard <robert.maynard@kitware.com> Merge-request: !1898
This commit is contained in:
commit
291f3527b1
@ -22,6 +22,7 @@
|
|||||||
#include <vtkm/cont/ArrayHandleGroupVecVariable.h>
|
#include <vtkm/cont/ArrayHandleGroupVecVariable.h>
|
||||||
#include <vtkm/cont/ArrayHandleImplicit.h>
|
#include <vtkm/cont/ArrayHandleImplicit.h>
|
||||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleMultiplexer.h>
|
||||||
#include <vtkm/cont/ArrayHandlePermutation.h>
|
#include <vtkm/cont/ArrayHandlePermutation.h>
|
||||||
#include <vtkm/cont/ArrayHandleSOA.h>
|
#include <vtkm/cont/ArrayHandleSOA.h>
|
||||||
#include <vtkm/cont/ArrayHandleTransform.h>
|
#include <vtkm/cont/ArrayHandleTransform.h>
|
||||||
@ -891,6 +892,64 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TestMultiplexerAsInput
|
||||||
|
{
|
||||||
|
vtkm::cont::Invoker Invoke;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
VTKM_CONT void operator()(T vtkmNotUsed(type)) const
|
||||||
|
{
|
||||||
|
using InputArrayType = vtkm::cont::ArrayHandleCounting<T>;
|
||||||
|
|
||||||
|
InputArrayType input(T(1), T(2), ARRAY_SIZE);
|
||||||
|
vtkm::cont::ArrayHandleMultiplexer<
|
||||||
|
vtkm::cont::ArrayHandle<T>,
|
||||||
|
InputArrayType,
|
||||||
|
vtkm::cont::ArrayHandleCast<T, vtkm::cont::ArrayHandleIndex>>
|
||||||
|
multiplexArray(input);
|
||||||
|
vtkm::cont::ArrayHandle<T> result;
|
||||||
|
|
||||||
|
this->Invoke(PassThrough{}, multiplexArray, result);
|
||||||
|
|
||||||
|
vtkm::cont::printSummary_ArrayHandle(multiplexArray, std::cout);
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
// verify results
|
||||||
|
VTKM_TEST_ASSERT(
|
||||||
|
test_equal_portals(result.GetPortalConstControl(), input.GetPortalConstControl()),
|
||||||
|
"CastingArrayHandle failed");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TestMultiplexerAsOutput
|
||||||
|
{
|
||||||
|
vtkm::cont::Invoker Invoke;
|
||||||
|
|
||||||
|
template <typename CastFromType>
|
||||||
|
VTKM_CONT void operator()(CastFromType vtkmNotUsed(type)) const
|
||||||
|
{
|
||||||
|
using InputArrayType = vtkm::cont::ArrayHandleIndex;
|
||||||
|
using ResultArrayType = vtkm::cont::ArrayHandle<CastFromType>;
|
||||||
|
|
||||||
|
InputArrayType input(ARRAY_SIZE);
|
||||||
|
|
||||||
|
ResultArrayType result;
|
||||||
|
vtkm::cont::ArrayHandleMultiplexer<vtkm::cont::ArrayHandle<vtkm::Id>,
|
||||||
|
vtkm::cont::ArrayHandleCast<vtkm::Id, ResultArrayType>>
|
||||||
|
multiplexerArray = vtkm::cont::make_ArrayHandleCast<vtkm::Id>(result);
|
||||||
|
|
||||||
|
this->Invoke(PassThrough{}, input, multiplexerArray);
|
||||||
|
|
||||||
|
vtkm::cont::printSummary_ArrayHandle(multiplexerArray, std::cout);
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
// verify results
|
||||||
|
VTKM_TEST_ASSERT(
|
||||||
|
test_equal_portals(input.GetPortalConstControl(), result.GetPortalConstControl()),
|
||||||
|
"Multiplexing ArrayHandle failed");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <vtkm::IdComponent NUM_COMPONENTS>
|
template <vtkm::IdComponent NUM_COMPONENTS>
|
||||||
struct TestGroupVecAsInput
|
struct TestGroupVecAsInput
|
||||||
{
|
{
|
||||||
@ -1511,6 +1570,16 @@ private:
|
|||||||
vtkm::testing::Testing::TryTypes(
|
vtkm::testing::Testing::TryTypes(
|
||||||
TestingFancyArrayHandles<DeviceAdapterTag>::TestCastAsOutput(), CastTypesToTest());
|
TestingFancyArrayHandles<DeviceAdapterTag>::TestCastAsOutput(), CastTypesToTest());
|
||||||
|
|
||||||
|
std::cout << "-------------------------------------------" << std::endl;
|
||||||
|
std::cout << "Testing ArrayHandleMultiplexer as Input" << std::endl;
|
||||||
|
vtkm::testing::Testing::TryTypes(
|
||||||
|
TestingFancyArrayHandles<DeviceAdapterTag>::TestMultiplexerAsInput(), CastTypesToTest());
|
||||||
|
|
||||||
|
std::cout << "-------------------------------------------" << std::endl;
|
||||||
|
std::cout << "Testing ArrayHandleMultiplexer as Output" << std::endl;
|
||||||
|
vtkm::testing::Testing::TryTypes(
|
||||||
|
TestingFancyArrayHandles<DeviceAdapterTag>::TestMultiplexerAsOutput(), CastTypesToTest());
|
||||||
|
|
||||||
std::cout << "-------------------------------------------" << std::endl;
|
std::cout << "-------------------------------------------" << std::endl;
|
||||||
std::cout << "Testing ArrayHandleGroupVec<3> as Input" << std::endl;
|
std::cout << "Testing ArrayHandleGroupVec<3> as Input" << std::endl;
|
||||||
vtkm::testing::Testing::TryTypes(
|
vtkm::testing::Testing::TryTypes(
|
||||||
|
@ -72,6 +72,10 @@ namespace vtkm
|
|||||||
namespace internal
|
namespace internal
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Forward declaration
|
||||||
|
template <typename... Ts>
|
||||||
|
class Variant;
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -95,40 +99,206 @@ struct VariantDestroyFunctor
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
template <typename... Ts>
|
||||||
|
struct AllTriviallyCopyable;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct AllTriviallyCopyable<> : std::true_type
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T0>
|
||||||
|
struct AllTriviallyCopyable<T0>
|
||||||
|
: std::integral_constant<bool, (std::is_trivially_copyable<T0>::value)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T0, typename T1>
|
||||||
|
struct AllTriviallyCopyable<T0, T1>
|
||||||
|
: std::integral_constant<bool,
|
||||||
|
(std::is_trivially_copyable<T0>::value &&
|
||||||
|
std::is_trivially_copyable<T1>::value)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T0, typename T1, typename T2>
|
||||||
|
struct AllTriviallyCopyable<T0, T1, T2>
|
||||||
|
: std::integral_constant<bool,
|
||||||
|
(std::is_trivially_copyable<T0>::value &&
|
||||||
|
std::is_trivially_copyable<T1>::value &&
|
||||||
|
std::is_trivially_copyable<T2>::value)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T0, typename T1, typename T2, typename T3>
|
||||||
|
struct AllTriviallyCopyable<T0, T1, T2, T3>
|
||||||
|
: std::integral_constant<bool,
|
||||||
|
(std::is_trivially_copyable<T0>::value &&
|
||||||
|
std::is_trivially_copyable<T1>::value &&
|
||||||
|
std::is_trivially_copyable<T2>::value &&
|
||||||
|
std::is_trivially_copyable<T3>::value)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T0, typename T1, typename T2, typename T3, typename T4, typename... Ts>
|
||||||
|
struct AllTriviallyCopyable<T0, T1, T2, T3, T4, Ts...>
|
||||||
|
: std::integral_constant<bool,
|
||||||
|
(std::is_trivially_copyable<T0>::value &&
|
||||||
|
std::is_trivially_copyable<T1>::value &&
|
||||||
|
std::is_trivially_copyable<T2>::value &&
|
||||||
|
std::is_trivially_copyable<T3>::value &&
|
||||||
|
std::is_trivially_copyable<T4>::value &&
|
||||||
|
AllTriviallyCopyable<Ts...>::value)>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename VariantType>
|
||||||
|
struct VariantTriviallyCopyable;
|
||||||
|
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
class Variant
|
struct VariantTriviallyCopyable<vtkm::internal::Variant<Ts...>> : AllTriviallyCopyable<Ts...>
|
||||||
{
|
{
|
||||||
struct ListTag : vtkm::ListTagBase<Ts...>
|
};
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
struct VariantStorageImpl
|
||||||
|
{
|
||||||
typename vtkmstd::aligned_union<0, Ts...>::type Storage;
|
typename vtkmstd::aligned_union<0, Ts...>::type Storage;
|
||||||
|
|
||||||
|
vtkm::IdComponent Index = -1;
|
||||||
|
|
||||||
|
template <vtkm::IdComponent Index>
|
||||||
|
using TypeAt = typename vtkm::ListTypeAt<vtkm::ListTagBase<Ts...>, Index>::type;
|
||||||
|
|
||||||
VTKM_EXEC_CONT void* GetPointer() { return reinterpret_cast<void*>(&this->Storage); }
|
VTKM_EXEC_CONT void* GetPointer() { return reinterpret_cast<void*>(&this->Storage); }
|
||||||
VTKM_EXEC_CONT const void* GetPointer() const
|
VTKM_EXEC_CONT const void* GetPointer() const
|
||||||
{
|
{
|
||||||
return reinterpret_cast<const void*>(&this->Storage);
|
return reinterpret_cast<const void*>(&this->Storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkm::IdComponent Index = -1;
|
VTKM_EXEC_CONT vtkm::IdComponent GetIndex() const noexcept { return this->Index; }
|
||||||
|
VTKM_EXEC_CONT bool IsValid() const noexcept { return this->GetIndex() >= 0; }
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT void Reset() noexcept
|
||||||
|
{
|
||||||
|
if (this->IsValid())
|
||||||
|
{
|
||||||
|
this->CastAndCall(detail::VariantDestroyFunctor{});
|
||||||
|
this->Index = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Functor, typename... Args>
|
||||||
|
VTKM_EXEC_CONT auto CastAndCall(Functor&& f, Args&&... args) const
|
||||||
|
noexcept(noexcept(f(std::declval<const TypeAt<0>&>(), args...)))
|
||||||
|
-> decltype(f(std::declval<const TypeAt<0>&>(), args...))
|
||||||
|
{
|
||||||
|
VTKM_ASSERT(this->IsValid());
|
||||||
|
return detail::VariantCastAndCallImpl<decltype(f(std::declval<const TypeAt<0>&>(), args...))>(
|
||||||
|
brigand::list<Ts...>{},
|
||||||
|
this->GetIndex(),
|
||||||
|
std::forward<Functor>(f),
|
||||||
|
this->GetPointer(),
|
||||||
|
std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Functor, typename... Args>
|
||||||
|
VTKM_EXEC_CONT auto CastAndCall(Functor&& f, Args&&... args) noexcept(
|
||||||
|
noexcept(f(std::declval<const TypeAt<0>&>(), args...)))
|
||||||
|
-> decltype(f(std::declval<TypeAt<0>&>(), args...))
|
||||||
|
{
|
||||||
|
VTKM_ASSERT(this->IsValid());
|
||||||
|
return detail::VariantCastAndCallImpl<decltype(f(std::declval<TypeAt<0>&>(), args...))>(
|
||||||
|
brigand::list<Ts...>{},
|
||||||
|
this->GetIndex(),
|
||||||
|
std::forward<Functor>(f),
|
||||||
|
this->GetPointer(),
|
||||||
|
std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename VariantType,
|
||||||
|
typename TriviallyCopyable = typename VariantTriviallyCopyable<VariantType>::type>
|
||||||
|
struct VariantConstructorImpl;
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
struct VariantConstructorImpl<vtkm::internal::Variant<Ts...>, std::true_type>
|
||||||
|
: VariantStorageImpl<Ts...>
|
||||||
|
{
|
||||||
|
VariantConstructorImpl() = default;
|
||||||
|
~VariantConstructorImpl() = default;
|
||||||
|
|
||||||
|
VariantConstructorImpl(const VariantConstructorImpl&) = default;
|
||||||
|
VariantConstructorImpl(VariantConstructorImpl&&) = default;
|
||||||
|
VariantConstructorImpl& operator=(const VariantConstructorImpl&) = default;
|
||||||
|
VariantConstructorImpl& operator=(VariantConstructorImpl&&) = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
struct VariantConstructorImpl<vtkm::internal::Variant<Ts...>, std::false_type>
|
||||||
|
: VariantStorageImpl<Ts...>
|
||||||
|
{
|
||||||
|
VariantConstructorImpl() = default;
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT ~VariantConstructorImpl() { this->Reset(); }
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT VariantConstructorImpl(const VariantConstructorImpl& src) noexcept
|
||||||
|
{
|
||||||
|
src.CastAndCall(VariantCopyFunctor{}, this->GetPointer());
|
||||||
|
this->Index = src.Index;
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT VariantConstructorImpl(VariantConstructorImpl&& rhs) noexcept
|
||||||
|
{
|
||||||
|
this->Storage = std::move(rhs.Storage);
|
||||||
|
this->Index = std::move(rhs.Index);
|
||||||
|
rhs.Index = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT VariantConstructorImpl& operator=(const VariantConstructorImpl& src) noexcept
|
||||||
|
{
|
||||||
|
this->Reset();
|
||||||
|
src.CastAndCall(detail::VariantCopyFunctor{}, this->GetPointer());
|
||||||
|
this->Index = src.Index;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT VariantConstructorImpl& operator=(VariantConstructorImpl&& rhs) noexcept
|
||||||
|
{
|
||||||
|
this->Reset();
|
||||||
|
this->Storage = std::move(rhs.Storage);
|
||||||
|
this->Index = std::move(rhs.Index);
|
||||||
|
rhs.Index = -1;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <typename... Ts>
|
||||||
|
class Variant : detail::VariantConstructorImpl<Variant<Ts...>>
|
||||||
|
{
|
||||||
|
using Superclass = detail::VariantConstructorImpl<Variant<Ts...>>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Returns the index of the type of object this variant is storing. If no object is currently
|
/// Returns the index of the type of object this variant is storing. If no object is currently
|
||||||
/// stored (i.e. the Variant is invalid), -1 is returned.
|
/// stored (i.e. the Variant is invalid), -1 is returned.
|
||||||
///
|
///
|
||||||
VTKM_EXEC_CONT vtkm::IdComponent GetIndex() const noexcept { return this->Index; }
|
VTKM_EXEC_CONT vtkm::IdComponent GetIndex() const noexcept
|
||||||
|
{
|
||||||
|
return this->Superclass::GetIndex();
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if this Variant is storing an object from one of the types in the template
|
/// Returns true if this Variant is storing an object from one of the types in the template
|
||||||
/// list, false otherwise.
|
/// list, false otherwise.
|
||||||
///
|
///
|
||||||
VTKM_EXEC_CONT bool IsValid() const noexcept { return this->GetIndex() >= 0; }
|
VTKM_EXEC_CONT bool IsValid() const noexcept { return this->Superclass::IsValid(); }
|
||||||
|
|
||||||
/// Type that converts to a std::integral_constant containing the index of the given type (or
|
/// Type that converts to a std::integral_constant containing the index of the given type (or
|
||||||
/// -1 if that type is not in the list).
|
/// -1 if that type is not in the list).
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using IndexOf = std::integral_constant<vtkm::IdComponent, vtkm::ListIndexOf<ListTag, T>::value>;
|
using IndexOf = std::integral_constant<vtkm::IdComponent,
|
||||||
|
vtkm::ListIndexOf<vtkm::ListTagBase<Ts...>, T>::value>;
|
||||||
|
|
||||||
/// Returns the index for the given type (or -1 if that type is not in the list).
|
/// Returns the index for the given type (or -1 if that type is not in the list).
|
||||||
///
|
///
|
||||||
@ -141,13 +311,18 @@ public:
|
|||||||
/// Type that converts to the type at the given index.
|
/// Type that converts to the type at the given index.
|
||||||
///
|
///
|
||||||
template <vtkm::IdComponent Index>
|
template <vtkm::IdComponent Index>
|
||||||
using TypeAt = typename vtkm::ListTypeAt<ListTag, Index>::type;
|
using TypeAt = typename Superclass::template TypeAt<Index>;
|
||||||
|
|
||||||
/// The number of types representable by this Variant.
|
/// The number of types representable by this Variant.
|
||||||
///
|
///
|
||||||
static constexpr vtkm::IdComponent NumberOfTypes = vtkm::IdComponent{ sizeof...(Ts) };
|
static constexpr vtkm::IdComponent NumberOfTypes = vtkm::IdComponent{ sizeof...(Ts) };
|
||||||
|
|
||||||
Variant() = default;
|
Variant() = default;
|
||||||
|
~Variant() = default;
|
||||||
|
Variant(const Variant&) = default;
|
||||||
|
Variant(Variant&&) = default;
|
||||||
|
Variant& operator=(const Variant&) = default;
|
||||||
|
Variant& operator=(Variant&&) = default;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
VTKM_EXEC_CONT Variant(const T& src) noexcept
|
VTKM_EXEC_CONT Variant(const T& src) noexcept
|
||||||
@ -171,38 +346,6 @@ public:
|
|||||||
this->Index = index;
|
this->Index = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
VTKM_EXEC_CONT Variant(Variant&& rhs) noexcept
|
|
||||||
{
|
|
||||||
this->Storage = std::move(rhs.Storage);
|
|
||||||
this->Index = std::move(rhs.Index);
|
|
||||||
rhs.Index = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC_CONT Variant(const Variant& src) noexcept
|
|
||||||
{
|
|
||||||
src.CastAndCall(detail::VariantCopyFunctor{}, this->GetPointer());
|
|
||||||
this->Index = src.GetIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC_CONT ~Variant() { this->Reset(); }
|
|
||||||
|
|
||||||
VTKM_EXEC_CONT Variant& operator=(Variant&& rhs) noexcept
|
|
||||||
{
|
|
||||||
this->Reset();
|
|
||||||
this->Storage = std::move(rhs.Storage);
|
|
||||||
this->Index = std::move(rhs.Index);
|
|
||||||
rhs.Index = -1;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_EXEC_CONT Variant& operator=(const Variant& src) noexcept
|
|
||||||
{
|
|
||||||
this->Reset();
|
|
||||||
src.CastAndCall(detail::VariantCopyFunctor{}, this->GetPointer());
|
|
||||||
this->Index = src.GetIndex();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
VTKM_EXEC_CONT T& Emplace(Args&&... args)
|
VTKM_EXEC_CONT T& Emplace(Args&&... args)
|
||||||
{
|
{
|
||||||
@ -305,13 +448,7 @@ public:
|
|||||||
noexcept(noexcept(f(std::declval<const TypeAt<0>&>(), args...)))
|
noexcept(noexcept(f(std::declval<const TypeAt<0>&>(), args...)))
|
||||||
-> decltype(f(std::declval<const TypeAt<0>&>(), args...))
|
-> decltype(f(std::declval<const TypeAt<0>&>(), args...))
|
||||||
{
|
{
|
||||||
VTKM_ASSERT(this->IsValid());
|
return this->Superclass::CastAndCall(std::forward<Functor>(f), std::forward<Args>(args)...);
|
||||||
return detail::VariantCastAndCallImpl<decltype(f(std::declval<const TypeAt<0>&>(), args...))>(
|
|
||||||
vtkm::internal::ListTagAsBrigandList<ListTag>(),
|
|
||||||
this->GetIndex(),
|
|
||||||
std::forward<Functor>(f),
|
|
||||||
this->GetPointer(),
|
|
||||||
std::forward<Args>(args)...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Functor, typename... Args>
|
template <typename Functor, typename... Args>
|
||||||
@ -319,26 +456,13 @@ public:
|
|||||||
noexcept(f(std::declval<const TypeAt<0>&>(), args...)))
|
noexcept(f(std::declval<const TypeAt<0>&>(), args...)))
|
||||||
-> decltype(f(std::declval<TypeAt<0>&>(), args...))
|
-> decltype(f(std::declval<TypeAt<0>&>(), args...))
|
||||||
{
|
{
|
||||||
VTKM_ASSERT(this->IsValid());
|
return this->Superclass::CastAndCall(std::forward<Functor>(f), std::forward<Args>(args)...);
|
||||||
return detail::VariantCastAndCallImpl<decltype(f(std::declval<TypeAt<0>&>(), args...))>(
|
|
||||||
vtkm::internal::ListTagAsBrigandList<ListTag>(),
|
|
||||||
this->GetIndex(),
|
|
||||||
std::forward<Functor>(f),
|
|
||||||
this->GetPointer(),
|
|
||||||
std::forward<Args>(args)...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destroys any object the Variant is holding and sets the Variant to an invalid state. This
|
/// Destroys any object the Variant is holding and sets the Variant to an invalid state. This
|
||||||
/// method is not thread safe.
|
/// method is not thread safe.
|
||||||
///
|
///
|
||||||
VTKM_EXEC_CONT void Reset() noexcept
|
VTKM_EXEC_CONT void Reset() noexcept { this->Superclass::Reset(); }
|
||||||
{
|
|
||||||
if (this->IsValid())
|
|
||||||
{
|
|
||||||
this->CastAndCall(detail::VariantDestroyFunctor{});
|
|
||||||
this->Index = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Convert a ListTag to a Variant.
|
/// \brief Convert a ListTag to a Variant.
|
||||||
|
@ -12,9 +12,10 @@
|
|||||||
|
|
||||||
#include <vtkm/testing/Testing.h>
|
#include <vtkm/testing/Testing.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace
|
namespace test_variant
|
||||||
{
|
{
|
||||||
|
|
||||||
template <vtkm::IdComponent Index>
|
template <vtkm::IdComponent Index>
|
||||||
@ -60,6 +61,32 @@ void TestIndexing()
|
|||||||
VTKM_STATIC_ASSERT((std::is_same<VariantType::TypeAt<3>, TypePlaceholder<3>>::value));
|
VTKM_STATIC_ASSERT((std::is_same<VariantType::TypeAt<3>, TypePlaceholder<3>>::value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestTriviallyCopyable()
|
||||||
|
{
|
||||||
|
// Make sure base types are behaving as expected
|
||||||
|
VTKM_STATIC_ASSERT(std::is_trivially_copyable<float>::value);
|
||||||
|
VTKM_STATIC_ASSERT(std::is_trivially_copyable<int>::value);
|
||||||
|
VTKM_STATIC_ASSERT(!std::is_trivially_copyable<std::shared_ptr<float>>::value);
|
||||||
|
|
||||||
|
// A variant of trivially copyable things should be trivially copyable
|
||||||
|
VTKM_STATIC_ASSERT((vtkm::internal::detail::AllTriviallyCopyable<float, int>::value));
|
||||||
|
VTKM_STATIC_ASSERT((std::is_trivially_copyable<vtkm::internal::Variant<float, int>>::value));
|
||||||
|
|
||||||
|
// A variant of any non-trivially copyable things is not trivially copyable
|
||||||
|
VTKM_STATIC_ASSERT(
|
||||||
|
(!vtkm::internal::detail::AllTriviallyCopyable<std::shared_ptr<float>, float, int>::value));
|
||||||
|
VTKM_STATIC_ASSERT(
|
||||||
|
(!vtkm::internal::detail::AllTriviallyCopyable<float, std::shared_ptr<float>, int>::value));
|
||||||
|
VTKM_STATIC_ASSERT(
|
||||||
|
(!vtkm::internal::detail::AllTriviallyCopyable<float, int, std::shared_ptr<float>>::value));
|
||||||
|
VTKM_STATIC_ASSERT((!std::is_trivially_copyable<
|
||||||
|
vtkm::internal::Variant<std::shared_ptr<float>, float, int>>::value));
|
||||||
|
VTKM_STATIC_ASSERT((!std::is_trivially_copyable<
|
||||||
|
vtkm::internal::Variant<float, std::shared_ptr<float>, int>>::value));
|
||||||
|
VTKM_STATIC_ASSERT((!std::is_trivially_copyable<
|
||||||
|
vtkm::internal::Variant<float, int, std::shared_ptr<float>>>::value));
|
||||||
|
}
|
||||||
|
|
||||||
struct TestFunctor
|
struct TestFunctor
|
||||||
{
|
{
|
||||||
template <vtkm::IdComponent Index>
|
template <vtkm::IdComponent Index>
|
||||||
@ -114,12 +141,8 @@ void TestCastAndCall()
|
|||||||
VTKM_TEST_ASSERT(test_equal(result, TestValue(3, vtkm::FloatDefault{})));
|
VTKM_TEST_ASSERT(test_equal(result, TestValue(3, vtkm::FloatDefault{})));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestCopyDestroy()
|
struct CountConstructDestruct
|
||||||
{
|
{
|
||||||
std::cout << "Test copy destroy" << std::endl;
|
|
||||||
|
|
||||||
struct CountConstructDestruct
|
|
||||||
{
|
|
||||||
vtkm::Id* Count;
|
vtkm::Id* Count;
|
||||||
CountConstructDestruct(vtkm::Id* count)
|
CountConstructDestruct(vtkm::Id* count)
|
||||||
: Count(count)
|
: Count(count)
|
||||||
@ -132,13 +155,18 @@ void TestCopyDestroy()
|
|||||||
++(*this->Count);
|
++(*this->Count);
|
||||||
}
|
}
|
||||||
~CountConstructDestruct() { --(*this->Count); }
|
~CountConstructDestruct() { --(*this->Count); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void TestCopyDestroy()
|
||||||
|
{
|
||||||
|
std::cout << "Test copy destroy" << std::endl;
|
||||||
|
|
||||||
using VariantType = vtkm::internal::Variant<TypePlaceholder<0>,
|
using VariantType = vtkm::internal::Variant<TypePlaceholder<0>,
|
||||||
TypePlaceholder<1>,
|
TypePlaceholder<1>,
|
||||||
CountConstructDestruct,
|
CountConstructDestruct,
|
||||||
TypePlaceholder<2>,
|
TypePlaceholder<2>,
|
||||||
TypePlaceholder<3>>;
|
TypePlaceholder<3>>;
|
||||||
|
VTKM_STATIC_ASSERT(!std::is_trivially_copyable<VariantType>::value);
|
||||||
vtkm::Id count = 0;
|
vtkm::Id count = 0;
|
||||||
|
|
||||||
VariantType variant1 = CountConstructDestruct(&count);
|
VariantType variant1 = CountConstructDestruct(&count);
|
||||||
@ -218,15 +246,16 @@ void RunTest()
|
|||||||
{
|
{
|
||||||
TestSize();
|
TestSize();
|
||||||
TestIndexing();
|
TestIndexing();
|
||||||
|
TestTriviallyCopyable();
|
||||||
TestGet();
|
TestGet();
|
||||||
TestCastAndCall();
|
TestCastAndCall();
|
||||||
TestCopyDestroy();
|
TestCopyDestroy();
|
||||||
TestEmplace();
|
TestEmplace();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // namespace test_variant
|
||||||
|
|
||||||
int UnitTestVariant(int argc, char* argv[])
|
int UnitTestVariant(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
return vtkm::testing::Testing::Run(RunTest, argc, argv);
|
return vtkm::testing::Testing::Run(test_variant::RunTest, argc, argv);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user