VTK-m  2.0
UnknownArrayHandle.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_cont_UnknownArrayHandle_h
11 #define vtk_m_cont_UnknownArrayHandle_h
12 
13 #include <vtkm/cont/vtkm_cont_export.h>
14 
16 #include <vtkm/cont/ArrayHandle.h>
21 #include <vtkm/cont/StorageList.h>
22 
23 #include <vtkm/Deprecated.h>
24 #include <vtkm/TypeList.h>
25 
26 #include <memory>
27 #include <typeindex>
28 
29 namespace vtkm
30 {
31 namespace cont
32 {
33 
34 namespace detail
35 {
36 
37 template <typename T, typename S>
38 void UnknownAHDelete(void* mem)
39 {
41  AH* arrayHandle = reinterpret_cast<AH*>(mem);
42  delete arrayHandle;
43 }
44 
45 template <typename T, typename S>
46 void* UnknownAHNewInstance()
47 {
49 }
50 
51 template <typename T, typename S>
52 vtkm::Id UnknownAHNumberOfValues(void* mem)
53 {
55  AH* arrayHandle = reinterpret_cast<AH*>(mem);
56  return arrayHandle->GetNumberOfValues();
57 }
58 
59 template <typename T, typename StaticSize = typename vtkm::internal::SafeVecTraits<T>::IsSizeStatic>
60 struct UnknownAHNumberOfComponentsImpl;
61 template <typename T>
62 struct UnknownAHNumberOfComponentsImpl<T, vtkm::VecTraitsTagSizeStatic>
63 {
64  static constexpr vtkm::IdComponent Value = vtkm::internal::SafeVecTraits<T>::NUM_COMPONENTS;
65 };
66 template <typename T>
67 struct UnknownAHNumberOfComponentsImpl<T, vtkm::VecTraitsTagSizeVariable>
68 {
69  static constexpr vtkm::IdComponent Value = 0;
70 };
71 
72 template <typename T>
73 vtkm::IdComponent UnknownAHNumberOfComponents()
74 {
75  return UnknownAHNumberOfComponentsImpl<T>::Value;
76 }
77 
78 template <typename T,
79  typename = typename vtkm::internal::SafeVecTraits<T>::IsSizeStatic,
80  typename = vtkm::HasVecTraits<T>>
81 struct UnknownAHNumberOfComponentsFlatImpl;
82 template <typename T>
83 struct UnknownAHNumberOfComponentsFlatImpl<T, vtkm::VecTraitsTagSizeStatic, std::true_type>
84 {
85  static constexpr vtkm::IdComponent Value = vtkm::VecFlat<T>::NUM_COMPONENTS;
86 };
87 template <typename T>
88 struct UnknownAHNumberOfComponentsFlatImpl<T, vtkm::VecTraitsTagSizeVariable, std::true_type>
89 {
90  static constexpr vtkm::IdComponent Value = 0;
91 };
92 template <typename T>
93 struct UnknownAHNumberOfComponentsFlatImpl<T, vtkm::VecTraitsTagSizeStatic, std::false_type>
94 {
95  static constexpr vtkm::IdComponent Value = 1;
96 };
97 
98 template <typename T>
99 vtkm::IdComponent UnknownAHNumberOfComponentsFlat()
100 {
101  return UnknownAHNumberOfComponentsFlatImpl<T>::Value;
102 }
103 
104 template <typename T, typename S>
105 void UnknownAHAllocate(void* mem,
106  vtkm::Id numValues,
107  vtkm::CopyFlag preserve,
108  vtkm::cont::Token& token)
109 {
111  AH* arrayHandle = reinterpret_cast<AH*>(mem);
112  arrayHandle->Allocate(numValues, preserve, token);
113 }
114 
115 template <typename T, typename S>
116 void UnknownAHShallowCopy(const void* sourceMem, void* destinationMem)
117 {
119  const AH* source = reinterpret_cast<const AH*>(sourceMem);
120  AH* destination = reinterpret_cast<AH*>(destinationMem);
121  *destination = *source;
122 }
123 
124 template <typename T, typename S>
125 void UnknownAHDeepCopy(const void* sourceMem, void* destinationMem)
126 {
128  const AH* source = reinterpret_cast<const AH*>(sourceMem);
129  AH* destination = reinterpret_cast<AH*>(destinationMem);
130  destination->DeepCopyFrom(*source);
131 }
132 
133 template <typename T, typename S>
134 std::vector<vtkm::cont::internal::Buffer>
135 UnknownAHExtractComponent(void* mem, vtkm::IdComponent componentIndex, vtkm::CopyFlag allowCopy)
136 {
138  AH* arrayHandle = reinterpret_cast<AH*>(mem);
139  auto componentArray = vtkm::cont::ArrayExtractComponent(*arrayHandle, componentIndex, allowCopy);
140  return componentArray.GetBuffers();
141 }
142 
143 template <typename T, typename S>
144 void UnknownAHReleaseResources(void* mem)
145 {
147  AH* arrayHandle = reinterpret_cast<AH*>(mem);
148  arrayHandle->ReleaseResources();
149 }
150 
151 template <typename T, typename S>
152 void UnknownAHReleaseResourcesExecution(void* mem)
153 {
155  AH* arrayHandle = reinterpret_cast<AH*>(mem);
156  arrayHandle->ReleaseResourcesExecution();
157 }
158 
159 template <typename T, typename S>
160 void UnknownAHPrintSummary(void* mem, std::ostream& out, bool full)
161 {
163  AH* arrayHandle = reinterpret_cast<AH*>(mem);
164  vtkm::cont::printSummary_ArrayHandle(*arrayHandle, out, full);
165 }
166 
167 struct VTKM_CONT_EXPORT UnknownAHContainer;
168 
169 struct MakeUnknownAHContainerFunctor
170 {
171  template <typename T, typename S>
172  std::shared_ptr<UnknownAHContainer> operator()(const vtkm::cont::ArrayHandle<T, S>& array) const;
173 };
174 
175 struct VTKM_CONT_EXPORT UnknownAHComponentInfo
176 {
177  std::type_index Type;
178  bool IsIntegral;
179  bool IsFloat;
180  bool IsSigned;
181  std::size_t Size;
182 
183  UnknownAHComponentInfo() = delete;
184 
185  bool operator==(const UnknownAHComponentInfo& rhs);
186 
187  template <typename T>
188  static UnknownAHComponentInfo Make()
189  {
190  return UnknownAHComponentInfo{ typeid(T),
191  std::is_integral<T>::value,
192  std::is_floating_point<T>::value,
193  std::is_signed<T>::value,
194  sizeof(T) };
195  }
196 
197 private:
198  UnknownAHComponentInfo(std::type_index&& type,
199  bool isIntegral,
200  bool isFloat,
201  bool isSigned,
202  std::size_t size)
203  : Type(std::move(type))
204  , IsIntegral(isIntegral)
205  , IsFloat(isFloat)
206  , IsSigned(isSigned)
207  , Size(size)
208  {
209  }
210 };
211 
212 struct VTKM_CONT_EXPORT UnknownAHContainer
213 {
214  void* ArrayHandlePointer;
215 
216  std::type_index ValueType;
217  std::type_index StorageType;
218  UnknownAHComponentInfo BaseComponentType;
219 
220  using DeleteType = void(void*);
221  DeleteType* DeleteFunction;
222 
223  using NewInstanceType = void*();
224  NewInstanceType* NewInstance;
225 
226  using NewInstanceBasicType = std::shared_ptr<UnknownAHContainer>();
227  NewInstanceBasicType* NewInstanceBasic;
228  NewInstanceBasicType* NewInstanceFloatBasic;
229 
230  using NumberOfValuesType = vtkm::Id(void*);
231  NumberOfValuesType* NumberOfValues;
232 
233  using NumberOfComponentsType = vtkm::IdComponent();
234  NumberOfComponentsType* NumberOfComponents;
235  NumberOfComponentsType* NumberOfComponentsFlat;
236 
237  using AllocateType = void(void*, vtkm::Id, vtkm::CopyFlag, vtkm::cont::Token&);
238  AllocateType* Allocate;
239 
240  using ShallowCopyType = void(const void*, void*);
241  ShallowCopyType* ShallowCopy;
242 
243  using DeepCopyType = void(const void*, void*);
244  DeepCopyType* DeepCopy;
245 
246  using ExtractComponentType = std::vector<vtkm::cont::internal::Buffer>(void*,
249  ExtractComponentType* ExtractComponent;
250 
251  using ReleaseResourcesType = void(void*);
252  ReleaseResourcesType* ReleaseResources;
253  ReleaseResourcesType* ReleaseResourcesExecution;
254 
255  using PrintSummaryType = void(void*, std::ostream&, bool);
256  PrintSummaryType* PrintSummary;
257 
258  void operator=(const UnknownAHContainer&) = delete;
259 
260  ~UnknownAHContainer() { this->DeleteFunction(this->ArrayHandlePointer); }
261 
262  std::shared_ptr<UnknownAHContainer> MakeNewInstance() const;
263 
264  template <typename T, typename S>
265  static std::shared_ptr<UnknownAHContainer> Make(const vtkm::cont::ArrayHandle<T, S>& array)
266  {
267  return std::shared_ptr<UnknownAHContainer>(new UnknownAHContainer(array));
268  }
269 
270  template <typename TargetT, typename SourceT, typename SourceS>
271  static std::shared_ptr<UnknownAHContainer> Make(
273  {
275  array;
276  return Make(castArray.GetSourceArray());
277  }
278 
279  template <typename T, typename... Ss>
280  static std::shared_ptr<UnknownAHContainer> Make(
282  {
284  .GetArrayHandleVariant();
285  if (variant.IsValid())
286  {
287  return variant.CastAndCall(MakeUnknownAHContainerFunctor{});
288  }
289  else
290  {
291  return std::shared_ptr<UnknownAHContainer>{};
292  }
293  }
294 
295 private:
296  UnknownAHContainer(const UnknownAHContainer&) = default;
297 
298  template <typename T, typename S>
299  explicit UnknownAHContainer(const vtkm::cont::ArrayHandle<T, S>& array);
300 };
301 
302 template <typename T>
303 std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic(vtkm::VecTraitsTagSizeStatic)
304 {
305  return UnknownAHContainer::Make(vtkm::cont::ArrayHandleBasic<T>{});
306 }
307 template <typename T>
308 std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic(vtkm::VecTraitsTagSizeVariable)
309 {
310  throw vtkm::cont::ErrorBadType("Cannot create a basic array container from with ValueType of " +
311  vtkm::cont::TypeToString<T>());
312 }
313 template <typename T>
314 std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceBasic()
315 {
316  return UnknownAHNewInstanceBasic<T>(typename vtkm::internal::SafeVecTraits<T>::IsSizeStatic{});
317 }
318 
319 template <typename T>
320 std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic(vtkm::VecTraitsTagSizeStatic)
321 {
322  using FloatT = typename vtkm::internal::SafeVecTraits<T>::template ReplaceBaseComponentType<
324  return UnknownAHContainer::Make(vtkm::cont::ArrayHandleBasic<FloatT>{});
325 }
326 template <typename T>
327 std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic(vtkm::VecTraitsTagSizeVariable)
328 {
329  throw vtkm::cont::ErrorBadType("Cannot create a basic array container from with ValueType of " +
330  vtkm::cont::TypeToString<T>());
331 }
332 template <typename T>
333 std::shared_ptr<UnknownAHContainer> UnknownAHNewInstanceFloatBasic()
334 {
335  return UnknownAHNewInstanceFloatBasic<T>(
336  typename vtkm::internal::SafeVecTraits<T>::IsSizeStatic{});
337 }
338 
339 template <typename T, typename S>
340 inline UnknownAHContainer::UnknownAHContainer(const vtkm::cont::ArrayHandle<T, S>& array)
341  : ArrayHandlePointer(new vtkm::cont::ArrayHandle<T, S>(array))
342  , ValueType(typeid(T))
343  , StorageType(typeid(S))
344  , BaseComponentType(
345  UnknownAHComponentInfo::Make<typename vtkm::internal::SafeVecTraits<T>::BaseComponentType>())
346  , DeleteFunction(detail::UnknownAHDelete<T, S>)
347  , NewInstance(detail::UnknownAHNewInstance<T, S>)
348  , NewInstanceBasic(detail::UnknownAHNewInstanceBasic<T>)
349  , NewInstanceFloatBasic(detail::UnknownAHNewInstanceFloatBasic<T>)
350  , NumberOfValues(detail::UnknownAHNumberOfValues<T, S>)
351  , NumberOfComponents(detail::UnknownAHNumberOfComponents<T>)
352  , NumberOfComponentsFlat(detail::UnknownAHNumberOfComponentsFlat<T>)
353  , Allocate(detail::UnknownAHAllocate<T, S>)
354  , ShallowCopy(detail::UnknownAHShallowCopy<T, S>)
355  , DeepCopy(detail::UnknownAHDeepCopy<T, S>)
356  , ExtractComponent(detail::UnknownAHExtractComponent<T, S>)
357  , ReleaseResources(detail::UnknownAHReleaseResources<T, S>)
358  , ReleaseResourcesExecution(detail::UnknownAHReleaseResourcesExecution<T, S>)
359  , PrintSummary(detail::UnknownAHPrintSummary<T, S>)
360 {
361 }
362 
363 template <typename T, typename S>
364 inline std::shared_ptr<UnknownAHContainer> MakeUnknownAHContainerFunctor::operator()(
365  const vtkm::cont::ArrayHandle<T, S>& array) const
366 {
367  return UnknownAHContainer::Make(array);
368 };
369 
370 } // namespace detail
371 
372 // Forward declaration. Include UncertainArrayHandle.h if using this.
373 template <typename ValueTypeList, typename StorageTypeList>
374 class UncertainArrayHandle;
375 
406 class VTKM_CONT_EXPORT UnknownArrayHandle
407 {
408  std::shared_ptr<detail::UnknownAHContainer> Container;
409 
410  VTKM_CONT bool IsValueTypeImpl(std::type_index type) const;
411  VTKM_CONT bool IsStorageTypeImpl(std::type_index type) const;
412  VTKM_CONT bool IsBaseComponentTypeImpl(const detail::UnknownAHComponentInfo& type) const;
413 
414 public:
415  VTKM_CONT UnknownArrayHandle() = default;
416 
417  template <typename T, typename S>
419  : Container(detail::UnknownAHContainer::Make(array))
420  {
421  }
422 
429  VTKM_CONT bool IsValid() const;
430 
437  VTKM_CONT UnknownArrayHandle NewInstance() const;
438 
446  VTKM_CONT UnknownArrayHandle NewInstanceBasic() const;
447 
464  VTKM_CONT UnknownArrayHandle NewInstanceFloatBasic() const;
465 
469  VTKM_CONT std::string GetValueTypeName() const;
470 
474  VTKM_CONT std::string GetBaseComponentTypeName() const;
475 
479  VTKM_CONT std::string GetStorageTypeName() const;
480 
486  VTKM_CONT std::string GetArrayTypeName() const;
487 
490  template <typename ValueType>
491  VTKM_CONT bool IsValueType() const
492  {
493  return this->IsValueTypeImpl(typeid(ValueType));
494  }
495 
498  template <typename StorageType>
500  {
501  return this->IsStorageTypeImpl(typeid(StorageType));
502  }
503 
515  template <typename BaseComponentType>
517  {
518  return this->IsBaseComponentTypeImpl(detail::UnknownAHComponentInfo::Make<BaseComponentType>());
519  }
520 
533  template <typename ArrayHandleType>
534  VTKM_CONT bool IsType() const
535  {
536  VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
537  return (this->IsValueType<typename ArrayHandleType::ValueType>() &&
538  this->IsStorageType<typename ArrayHandleType::StorageTag>());
539  }
540 
548  // Defined in UncertainArrayHandle.h
549  template <typename NewValueTypeList, typename NewStorageTypeList>
551  NewValueTypeList = NewValueTypeList{},
552  NewStorageTypeList = NewStorageTypeList{}) const;
553 
556  VTKM_CONT vtkm::Id GetNumberOfValues() const;
557 
565  VTKM_CONT vtkm::IdComponent GetNumberOfComponents() const;
566 
579  VTKM_CONT vtkm::IdComponent GetNumberOfComponentsFlat() const;
580 
586  VTKM_CONT void Allocate(vtkm::Id numValues,
587  vtkm::CopyFlag preserve,
588  vtkm::cont::Token& token) const;
589  VTKM_CONT void Allocate(vtkm::Id numValues, vtkm::CopyFlag preserve = vtkm::CopyFlag::Off) const;
591 
599  template <typename ArrayHandleType>
600  VTKM_CONT bool CanConvert() const;
601 
602  // MSVC will issue deprecation warnings here if this template is instantiated with
603  // a deprecated class even if the template is used from a section of code where
604  // deprecation warnings are suppressed. This is annoying behavior since this template
605  // has no control over what class it is used with. To get around it, we have to
606  // suppress all deprecation warnings here.
607 #ifdef VTKM_MSVC
609 #endif
610  template <typename T, typename S>
617  {
618  using ArrayType = vtkm::cont::ArrayHandle<T, S>;
619  if (!this->IsType<ArrayType>())
620  {
621  VTKM_LOG_CAST_FAIL(*this, decltype(array));
622  throwFailedDynamicCast(this->GetArrayTypeName(), vtkm::cont::TypeToString(array));
623  }
624 
625  array = *reinterpret_cast<ArrayType*>(this->Container->ArrayHandlePointer);
626  }
627 
628  template <typename T, typename... Ss>
629  VTKM_CONT void AsArrayHandle(
631 
632  template <typename TargetT, typename SourceT, typename SourceS>
635  {
636  using ContainedArrayType = vtkm::cont::ArrayHandle<SourceT, SourceS>;
638  this->AsArrayHandle<ContainedArrayType>());
639  }
640 
641  template <typename ArrayType>
642  VTKM_CONT ArrayType AsArrayHandle() const
643  {
644  VTKM_IS_ARRAY_HANDLE(ArrayType);
645  ArrayType array;
646  this->AsArrayHandle(array);
647  return array;
648  }
650 #ifdef VTKM_MSVC
652 #endif
653 
661  void DeepCopyFrom(const vtkm::cont::UnknownArrayHandle& source);
662 
670  void DeepCopyFrom(const vtkm::cont::UnknownArrayHandle& source) const;
671 
684  void CopyShallowIfPossible(const vtkm::cont::UnknownArrayHandle& source);
685 
700  void CopyShallowIfPossible(const vtkm::cont::UnknownArrayHandle& source) const;
701 
729  template <typename BaseComponentType>
731  vtkm::IdComponent componentIndex,
732  vtkm::CopyFlag allowCopy = vtkm::CopyFlag::On) const
733  {
734  using ComponentArrayType = vtkm::cont::ArrayHandleStride<BaseComponentType>;
735  if (!this->IsBaseComponentType<BaseComponentType>())
736  {
737  VTKM_LOG_CAST_FAIL(*this, ComponentArrayType);
738  throwFailedDynamicCast("UnknownArrayHandle with " + this->GetArrayTypeName(),
739  "component array of " + vtkm::cont::TypeToString<BaseComponentType>());
740  }
741 
742  auto buffers = this->Container->ExtractComponent(
743  this->Container->ArrayHandlePointer, componentIndex, allowCopy);
744  return ComponentArrayType(buffers);
745  }
746 
788  template <typename BaseComponentType>
790  vtkm::CopyFlag allowCopy = vtkm::CopyFlag::On) const
791  {
793  vtkm::IdComponent numComponents = this->GetNumberOfComponentsFlat();
794  for (vtkm::IdComponent cIndex = 0; cIndex < numComponents; ++cIndex)
795  {
796  result.AppendComponentArray(this->ExtractComponent<BaseComponentType>(cIndex, allowCopy));
797  }
798  return result;
799  }
800 
810  template <typename TypeList, typename StorageList, typename Functor, typename... Args>
811  VTKM_CONT void CastAndCallForTypes(Functor&& functor, Args&&... args) const;
812 
826  template <typename TypeList, typename StorageList, typename Functor, typename... Args>
827  VTKM_CONT void CastAndCallForTypesWithFloatFallback(Functor&& functor, Args&&... args) const;
828 
850  template <typename Functor, typename... Args>
851  VTKM_CONT void CastAndCallWithExtractedArray(Functor&& functor, Args&&... args) const;
852 
856  VTKM_CONT void ReleaseResourcesExecution() const;
857 
860  VTKM_CONT void ReleaseResources() const;
861 
862  VTKM_CONT void PrintSummary(std::ostream& out, bool full = false) const;
863 };
864 
865 //=============================================================================
866 // Out of class implementations
867 
868 namespace detail
869 {
870 
871 template <typename T, typename S>
872 struct UnknownArrayHandleCanConvert
873 {
874  VTKM_CONT bool operator()(const vtkm::cont::UnknownArrayHandle& array) const
875  {
876  return array.IsType<vtkm::cont::ArrayHandle<T, S>>();
877  }
878 };
879 
880 template <typename TargetT, typename SourceT, typename SourceS>
881 struct UnknownArrayHandleCanConvert<TargetT, vtkm::cont::StorageTagCast<SourceT, SourceS>>
882 {
883  VTKM_CONT bool operator()(const vtkm::cont::UnknownArrayHandle& array) const
884  {
885  return UnknownArrayHandleCanConvert<SourceT, SourceS>{}(array);
886  }
887 };
888 
889 template <typename T>
890 struct UnknownArrayHandleCanConvertTry
891 {
892  template <typename S>
893  VTKM_CONT void operator()(S, const vtkm::cont::UnknownArrayHandle& array, bool& canConvert) const
894  {
895  canConvert |= UnknownArrayHandleCanConvert<T, S>{}(array);
896  }
897 };
898 
899 template <typename T, typename... Ss>
900 struct UnknownArrayHandleCanConvert<T, vtkm::cont::StorageTagMultiplexer<Ss...>>
901 {
902  VTKM_CONT bool operator()(const vtkm::cont::UnknownArrayHandle& array) const
903  {
904  bool canConvert = false;
905  vtkm::ListForEach(UnknownArrayHandleCanConvertTry<T>{}, vtkm::List<Ss...>{}, array, canConvert);
906  return canConvert;
907  }
908 };
909 
910 } // namespace detail
911 
912 template <typename ArrayHandleType>
913 VTKM_CONT bool UnknownArrayHandle::CanConvert() const
914 {
915  VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
916 
917  return detail::UnknownArrayHandleCanConvert<typename ArrayHandleType::ValueType,
918  typename ArrayHandleType::StorageTag>{}(*this);
919 }
920 
921 namespace detail
922 {
923 
924 struct UnknownArrayHandleMultiplexerCastTry
925 {
926  template <typename T, typename S, typename... Ss>
927  VTKM_CONT void operator()(
928  S,
929  const vtkm::cont::UnknownArrayHandle& unknownArray,
931  bool& converted) const
932  {
933  using ArrayType = vtkm::cont::ArrayHandle<T, S>;
934  if (unknownArray.CanConvert<ArrayType>())
935  {
936  if (converted && !unknownArray.IsType<ArrayType>())
937  {
938  // The array has already been converted and pushed in the multiplexer. It is
939  // possible that multiple array types can be put in the ArrayHandleMultiplexer
940  // (for example, and ArrayHandle or an ArrayHandle that has been cast). Exact
941  // matches will override other matches (hence, the second part of the condition),
942  // but at this point we have already found a better array to put inside.
943  return;
944  }
946  unknownArray.AsArrayHandle<ArrayType>());
947  converted = true;
948  }
949  }
950 };
951 
952 } // namespace detail
953 
954 template <typename T, typename... Ss>
955 void UnknownArrayHandle::AsArrayHandle(
957 {
958  bool converted = false;
960  detail::UnknownArrayHandleMultiplexerCastTry{}, vtkm::List<Ss...>{}, *this, array, converted);
961 
962  if (!converted)
963  {
964  VTKM_LOG_CAST_FAIL(*this, decltype(array));
966  }
967 }
968 
969 namespace detail
970 {
971 
972 struct UnknownArrayHandleTry
973 {
974  template <typename T, typename S, typename Functor, typename... Args>
975  void operator()(vtkm::List<T, S>,
976  Functor&& f,
977  bool& called,
978  const vtkm::cont::UnknownArrayHandle& unknownArray,
979  Args&&... args) const
980  {
981  using DerivedArrayType = vtkm::cont::ArrayHandle<T, S>;
982  if (!called && unknownArray.CanConvert<DerivedArrayType>())
983  {
984  called = true;
985  DerivedArrayType derivedArray;
986  unknownArray.AsArrayHandle(derivedArray);
987  VTKM_LOG_CAST_SUCC(unknownArray, derivedArray);
988 
989  // If you get a compile error here, it means that you have called CastAndCall for a
990  // vtkm::cont::UnknownArrayHandle and the arguments of the functor do not match those
991  // being passed. This is often because it is calling the functor with an ArrayHandle
992  // type that was not expected. Either add overloads to the functor to accept all
993  // possible array types or constrain the types tried for the CastAndCall. Note that
994  // the functor will be called with an array of type vtkm::cont::ArrayHandle<T, S>.
995  // Directly using a subclass of ArrayHandle (e.g. vtkm::cont::ArrayHandleConstant<T>)
996  // might not work.
997  f(derivedArray, std::forward<Args>(args)...);
998  }
999  }
1000 };
1001 
1002 } // namespace detail
1003 
1004 namespace internal
1005 {
1006 
1007 namespace detail
1008 {
1009 
1010 template <typename T>
1011 struct IsUndefinedArrayType
1012 {
1013 };
1014 template <typename T, typename S>
1015 struct IsUndefinedArrayType<vtkm::List<T, S>> : vtkm::cont::internal::IsInvalidArrayHandle<T, S>
1016 {
1017 };
1018 
1019 } // namespace detail
1020 
1021 template <typename ValueTypeList, typename StorageTypeList>
1022 using ListAllArrayTypes =
1024 
1025 VTKM_CONT_EXPORT void ThrowCastAndCallException(const vtkm::cont::UnknownArrayHandle&,
1026  const std::type_info&);
1027 
1028 } // namespace internal
1029 
1030 template <typename TypeList, typename StorageTagList, typename Functor, typename... Args>
1031 inline void UnknownArrayHandle::CastAndCallForTypes(Functor&& f, Args&&... args) const
1032 {
1033  using crossProduct = internal::ListAllArrayTypes<TypeList, StorageTagList>;
1034 
1035  bool called = false;
1036  vtkm::ListForEach(detail::UnknownArrayHandleTry{},
1037  crossProduct{},
1038  std::forward<Functor>(f),
1039  called,
1040  *this,
1041  std::forward<Args>(args)...);
1042  if (!called)
1043  {
1044  // throw an exception
1045  VTKM_LOG_CAST_FAIL(*this, TypeList);
1046  internal::ThrowCastAndCallException(*this, typeid(TypeList));
1047  }
1048 }
1049 
1050 template <typename TypeList, typename StorageTagList, typename Functor, typename... Args>
1051 VTKM_CONT void UnknownArrayHandle::CastAndCallForTypesWithFloatFallback(Functor&& functor,
1052  Args&&... args) const
1053 {
1054  using crossProduct = internal::ListAllArrayTypes<TypeList, StorageTagList>;
1055 
1056  bool called = false;
1057  vtkm::ListForEach(detail::UnknownArrayHandleTry{},
1058  crossProduct{},
1059  std::forward<Functor>(functor),
1060  called,
1061  *this,
1062  std::forward<Args>(args)...);
1063  if (!called)
1064  {
1065  // Copy to a float array and try again
1066  vtkm::cont::UnknownArrayHandle floatArray = this->NewInstanceFloatBasic();
1067  floatArray.DeepCopyFrom(*this);
1068  vtkm::ListForEach(detail::UnknownArrayHandleTry{},
1069  crossProduct{},
1070  std::forward<Functor>(functor),
1071  called,
1072  floatArray,
1073  std::forward<Args>(args)...);
1074  }
1075  if (!called)
1076  {
1077  // throw an exception
1078  VTKM_LOG_CAST_FAIL(*this, TypeList);
1079  internal::ThrowCastAndCallException(*this, typeid(TypeList));
1080  }
1081 }
1082 
1083 //=============================================================================
1084 // Free function casting helpers
1085 
1088 template <typename ArrayHandleType>
1090 {
1091  return array.template IsType<ArrayHandleType>();
1092 }
1093 
1098 template <typename ArrayHandleType>
1099 VTKM_CONT inline ArrayHandleType Cast(const vtkm::cont::UnknownArrayHandle& array)
1100 {
1101  return array.template AsArrayHandle<ArrayHandleType>();
1102 }
1103 
1104 namespace detail
1105 {
1106 
1107 struct UnknownArrayHandleTryExtract
1108 {
1109  template <typename T, typename Functor, typename... Args>
1110  void operator()(T,
1111  Functor&& f,
1112  bool& called,
1113  const vtkm::cont::UnknownArrayHandle& unknownArray,
1114  Args&&... args) const
1115  {
1116  if (!called && unknownArray.IsBaseComponentType<T>())
1117  {
1118  called = true;
1119  auto extractedArray = unknownArray.ExtractArrayFromComponents<T>();
1120  VTKM_LOG_CAST_SUCC(unknownArray, extractedArray);
1121 
1122  // If you get a compile error here, it means that you have called
1123  // CastAndCallWithExtractedArray for a vtkm::cont::UnknownArrayHandle and the arguments of
1124  // the functor do not match those being passed. This is often because it is calling the
1125  // functor with an ArrayHandle type that was not expected. Add overloads to the functor to
1126  // accept all possible array types or constrain the types tried for the CastAndCall. Note
1127  // that the functor will be called with an array of type that is different than the actual
1128  // type of the `ArrayHandle` stored in the `UnknownArrayHandle`.
1129  f(extractedArray, std::forward<Args>(args)...);
1130  }
1131  }
1132 };
1133 
1134 } // namespace detail
1135 
1136 template <typename Functor, typename... Args>
1137 inline void UnknownArrayHandle::CastAndCallWithExtractedArray(Functor&& functor,
1138  Args&&... args) const
1139 {
1140  bool called = false;
1141  vtkm::ListForEach(detail::UnknownArrayHandleTryExtract{},
1143  std::forward<Functor>(functor),
1144  called,
1145  *this,
1146  std::forward<Args>(args)...);
1147  if (!called)
1148  {
1149  // Throw an exception.
1150  // The message will be a little wonky because the types are just the value types, not the
1151  // full type to cast to.
1153  internal::ThrowCastAndCallException(*this, typeid(vtkm::TypeListScalarAll));
1154  }
1155 }
1156 
1157 }
1158 } // namespace vtkm::cont
1159 
1160 //=============================================================================
1161 // Specializations of serialization related classes
1163 
1164 namespace vtkm
1165 {
1166 namespace cont
1167 {
1168 
1169 template <>
1170 struct VTKM_CONT_EXPORT SerializableTypeString<vtkm::cont::UnknownArrayHandle>
1171 {
1172  static VTKM_CONT std::string Get();
1173 };
1174 }
1175 } // namespace vtkm::cont
1176 
1177 namespace mangled_diy_namespace
1178 {
1179 
1180 template <>
1181 struct VTKM_CONT_EXPORT Serialization<vtkm::cont::UnknownArrayHandle>
1182 {
1183 public:
1184  static VTKM_CONT void save(BinaryBuffer& bb, const vtkm::cont::UnknownArrayHandle& obj);
1185  static VTKM_CONT void load(BinaryBuffer& bb, vtkm::cont::UnknownArrayHandle& obj);
1186 };
1187 
1188 } // namespace mangled_diy_namespace
1189 
1191 
1192 #endif //vtk_m_cont_UnknownArrayHandle_h
vtkm::cont::UnknownArrayHandle::IsBaseComponentType
VTKM_CONT bool IsBaseComponentType() const
Returns true if this array's ValueType has the provided base component type.
Definition: UnknownArrayHandle.h:516
vtkm::cont::ArrayHandle::GetNumberOfValues
VTKM_CONT vtkm::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:448
vtkm::cont::ArrayHandle< T, S >
ArrayHandle.h
ArrayExtractComponent.h
vtkm::cont::ArrayHandleRecombineVec
A grouping of ArrayHandleStrides into an ArrayHandle of Vecs.
Definition: ArrayHandleRecombineVec.h:557
ArrayHandleStride.h
vtkm::cont::UnknownArrayHandle::AsArrayHandle
VTKM_CONT void AsArrayHandle(vtkm::cont::ArrayHandle< T, S > &array) const
Definition: UnknownArrayHandle.h:616
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
ArrayHandleCast.h
vtkm::cont::UnknownArrayHandle::ExtractComponent
VTKM_CONT vtkm::cont::ArrayHandleStride< BaseComponentType > ExtractComponent(vtkm::IdComponent componentIndex, vtkm::CopyFlag allowCopy=vtkm::CopyFlag::On) const
Extract a component of the array.
Definition: UnknownArrayHandle.h:730
vtkm::cont::ArrayHandle::Allocate
VTKM_CONT void Allocate(vtkm::Id numberOfValues, vtkm::CopyFlag preserve, vtkm::cont::Token &token) const
Allocates an array large enough to hold the given number of values.
Definition: ArrayHandle.h:465
VTKM_LOG_CAST_FAIL
#define VTKM_LOG_CAST_FAIL(inObj, outType)
Convenience macro for logging a failed cast of dynamic object.
Definition: Logging.h:269
vtkm::Get
VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT auto Get(const vtkm::Tuple< Ts... > &tuple) -> decltype(tuple.template Get< Index >())
Retrieve the object from a vtkm::Tuple at the given index.
Definition: Tuple.h:83
ArrayHandleRecombineVec.h
vtkm::IdComponent
vtkm::Int32 IdComponent
Represents a component ID (index of component in a vector).
Definition: Types.h:168
vtkm::cont::printSummary_ArrayHandle
VTKM_NEVER_EXPORT VTKM_CONT void printSummary_ArrayHandle(const vtkm::cont::ArrayHandle< T, StorageT > &array, std::ostream &out, bool full=false)
Definition: ArrayHandle.h:789
vtkm::cont::UnknownArrayHandle::CanConvert
VTKM_CONT bool CanConvert() const
Determine if the contained array can be passed to the given array type.
Definition: UnknownArrayHandle.h:913
vtkm::cont::UnknownArrayHandle
An ArrayHandle of an unknown value type and storage.
Definition: UnknownArrayHandle.h:406
vtkm::HasVecTraits
typename detail::HasVecTraitsImpl< T >::Type HasVecTraits
Determines whether the given type has VecTraits defined.
Definition: VecTraits.h:176
vtkm::cont::ArrayHandleRecombineVec::AppendComponentArray
void AppendComponentArray(const vtkm::cont::ArrayHandle< ComponentType, vtkm::cont::StorageTagStride > &array)
Definition: ArrayHandleRecombineVec.h:583
vtkm::cont::operator==
VTKM_CONT bool operator==(const vtkm::cont::Token &token, vtkm::cont::Token::Reference ref)
Definition: Token.h:174
vtkm::cont::ArrayHandle::ReleaseResourcesExecution
VTKM_CONT void ReleaseResourcesExecution() const
Releases any resources being used in the execution environment (that are not being shared by the cont...
Definition: ArrayHandle.h:552
vtkm::cont::ArrayHandleMultiplexer
An ArrayHandle that can behave like several other handles.
Definition: ArrayHandleMultiplexer.h:398
vtkm::ListRemoveIf
typename detail::ListRemoveIfImpl< List, Predicate >::type ListRemoveIf
Takes an existing List and a predicate template that is applied to each type in the List.
Definition: List.h:674
vtkm::ListForEach
VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT void ListForEach(Functor &&f, vtkm::List< Ts... >, Args &&... args)
Definition: List.h:720
vtkm::cont::ErrorBadType
This class is thrown when VTK-m encounters data of a type that is incompatible with the current opera...
Definition: ErrorBadType.h:25
mangled_diy_namespace
Definition: Particle.h:331
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
vtkm::exec::arg::load
VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC T load(const U &u, vtkm::Id v)
Definition: FetchTagArrayDirectIn.h:36
vtkm::cont::UnknownArrayHandle::DeepCopyFrom
void DeepCopyFrom(const vtkm::cont::UnknownArrayHandle &source)
Deep copies data from another UnknownArrayHandle.
VTKM_DEPRECATED_SUPPRESS_END
#define VTKM_DEPRECATED_SUPPRESS_END
Definition: Deprecated.h:123
vtkm::cont::throwFailedDynamicCast
VTKM_SILENCE_WEAK_VTABLE_WARNING_END VTKM_CONT_EXPORT void throwFailedDynamicCast(const std::string &baseType, const std::string &derivedType)
Throws an ErrorBadType exception with the following message: Cast failed: baseType --> derivedType".
vtkm::cont::ArrayHandleStride
An ArrayHandle that accesses a basic array with strides and offsets.
Definition: ArrayHandleStride.h:251
vtkm::cont::Cast
VTKM_CONT ArrayHandleType Cast(const vtkm::cont::UnknownArrayHandle &array)
Returns variant cast to the given ArrayHandle type.
Definition: UnknownArrayHandle.h:1099
vtkm::cont::StorageTagCast
Definition: ArrayHandleCast.h:28
vtkm::cont::Token
A token to hold the scope of an ArrayHandle or other object.
Definition: Token.h:35
vtkm::VecTraitsTagSizeVariable
A tag for vectors where the number of components are not determined until run time.
Definition: VecTraits.h:41
vtkm::cont::ArrayHandleCast::GetSourceArray
ArrayHandleType GetSourceArray() const
Returns the ArrayHandle that is being transformed.
Definition: ArrayHandleCast.h:169
VTKM_IS_ARRAY_HANDLE
#define VTKM_IS_ARRAY_HANDLE(T)
Definition: ArrayHandle.h:132
VTKM_LOG_CAST_SUCC
#define VTKM_LOG_CAST_SUCC(inObj, outObj)
Convenience macro for logging the successful cast of dynamic object.
Definition: Logging.h:268
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
TypeList.h
vtkm::VecFlat
Treat a Vec or Vec-like object as a flat Vec.
Definition: VecFlat.h:224
vtkm::CopyFlag::On
@ On
VTKM_DEPRECATED_SUPPRESS_BEGIN
#define VTKM_DEPRECATED_SUPPRESS_BEGIN
Definition: Deprecated.h:122
vtkm::cont::ArrayHandle::DeepCopyFrom
VTKM_CONT void DeepCopyFrom(const vtkm::cont::ArrayHandle< ValueType, StorageTag > &source) const
Deep copies the data in the array.
Definition: ArrayHandle.h:682
vtkm::CopyFlag::Off
@ Off
vtkm::FloatDefault
vtkm::Float32 FloatDefault
The floating point type to use when no other precision is specified.
Definition: Types.h:198
vtkm::cont::UncertainArrayHandle
An ArrayHandle of an uncertain value type and storage.
Definition: UncertainArrayHandle.h:39
vtkm::cont::UnknownArrayHandle::ExtractArrayFromComponents
VTKM_CONT vtkm::cont::ArrayHandleRecombineVec< BaseComponentType > ExtractArrayFromComponents(vtkm::CopyFlag allowCopy=vtkm::CopyFlag::On) const
Extract the array knowing only the component type of the array.
Definition: UnknownArrayHandle.h:789
vtkm::VecTraitsTagSizeStatic
A tag for vectors where the number of components are known at compile time.
Definition: VecTraits.h:34
ArrayHandleMultiplexer.h
vtkm::cont::ArrayHandleCast
Cast the values of an array to the specified type, on demand.
Definition: ArrayHandleCast.h:141
Deprecated.h
vtkm::cont::UnknownArrayHandle::IsStorageType
VTKM_CONT bool IsStorageType() const
Returns true if this array matches the StorageType template argument.
Definition: UnknownArrayHandle.h:499
vtkm::cont::ArrayExtractComponent
vtkm::cont::ArrayHandleStride< typename vtkm::internal::SafeVecTraits< T >::BaseComponentType > ArrayExtractComponent(const vtkm::cont::ArrayHandle< T, S > &src, vtkm::IdComponent componentIndex, vtkm::CopyFlag allowCopy=vtkm::CopyFlag::On)
Pulls a component out of an ArrayHandle.
Definition: ArrayExtractComponent.h:258
vtkm::List
Definition: List.h:34
vtkm::CopyFlag
CopyFlag
Definition: Flags.h:16
vtkm::cont::UnknownArrayHandle::IsType
VTKM_CONT bool IsType() const
Returns true if this array matches the ArrayHandleType template argument.
Definition: UnknownArrayHandle.h:534
vtkm::cont::IsType
VTKM_CONT bool IsType(const vtkm::cont::UnknownArrayHandle &array)
Returns true if variant matches the type of ArrayHandleType.
Definition: UnknownArrayHandle.h:1089
StorageList.h
vtkm::cont::ArrayHandleBasic
Definition: ArrayHandleBasic.h:97
vtkm::cont::UnknownArrayHandle::IsValueType
VTKM_CONT bool IsValueType() const
Returns true if this array matches the ValueType template argument.
Definition: UnknownArrayHandle.h:491
vtkm::cont::ArrayHandle::ReleaseResources
VTKM_CONT void ReleaseResources() const
Releases all resources in both the control and execution environments.
Definition: ArrayHandle.h:559
vtkm::cont::TypeToString
VTKM_CONT_EXPORT VTKM_CONT std::string TypeToString(const std::type_info &t)
Use RTTI information to retrieve the name of the type T.
vtkm::cont::UnknownArrayHandle::AsArrayHandle
VTKM_CONT void AsArrayHandle(vtkm::cont::ArrayHandle< TargetT, vtkm::cont::StorageTagCast< SourceT, SourceS >> &array) const
Definition: UnknownArrayHandle.h:633
vtkm::cont::UnknownArrayHandle::Container
std::shared_ptr< detail::UnknownAHContainer > Container
Definition: UnknownArrayHandle.h:408
vtkm::cont::UnknownArrayHandle::UnknownArrayHandle
VTKM_CONT UnknownArrayHandle(const vtkm::cont::ArrayHandle< T, S > &array)
Definition: UnknownArrayHandle.h:418
vtkm::cont::StorageTagMultiplexer
Definition: ArrayHandleMultiplexer.h:141