18 #ifndef viskores_cont_ArrayHandleTransform_h
19 #define viskores_cont_ArrayHandleTransform_h
37 struct NullFunctorType
43 template <
typename ValueType_,
45 typename FunctorType_,
46 typename InverseFunctorType_ = NullFunctorType>
47 class VISKORES_ALWAYS_EXPORT ArrayPortalTransform;
49 template <
typename ValueType_,
typename PortalType_,
typename FunctorType_>
50 class VISKORES_ALWAYS_EXPORT
51 ArrayPortalTransform<ValueType_, PortalType_, FunctorType_, NullFunctorType>
54 using PortalType = PortalType_;
55 using ValueType = ValueType_;
56 using FunctorType = FunctorType_;
59 ArrayPortalTransform(
const PortalType& portal = PortalType(),
60 const FunctorType& functor = FunctorType())
70 template <
class OtherV,
class OtherP,
class OtherF>
71 VISKORES_EXEC_CONT ArrayPortalTransform(
const ArrayPortalTransform<OtherV, OtherP, OtherF>& src)
72 : Portal(src.GetPortal())
73 , Functor(src.GetFunctor())
78 viskores::Id GetNumberOfValues()
const {
return this->Portal.GetNumberOfValues(); }
81 ValueType
Get(
viskores::Id index)
const {
return this->Functor(this->Portal.Get(index)); }
84 const PortalType& GetPortal()
const {
return this->Portal; }
87 const FunctorType& GetFunctor()
const {
return this->Functor; }
94 template <
typename ValueType_,
96 typename FunctorType_,
97 typename InverseFunctorType_>
98 class VISKORES_ALWAYS_EXPORT ArrayPortalTransform
99 :
public ArrayPortalTransform<ValueType_, PortalType_, FunctorType_, NullFunctorType>
101 using Writable = viskores::internal::PortalSupportsSets<PortalType_>;
104 using Superclass = ArrayPortalTransform<ValueType_, PortalType_, FunctorType_, NullFunctorType>;
105 using PortalType = PortalType_;
106 using ValueType = ValueType_;
107 using FunctorType = FunctorType_;
108 using InverseFunctorType = InverseFunctorType_;
111 ArrayPortalTransform(
const PortalType& portal = PortalType(),
112 const FunctorType& functor = FunctorType(),
113 const InverseFunctorType& inverseFunctor = InverseFunctorType())
114 : Superclass(portal, functor)
115 , InverseFunctor(inverseFunctor)
119 template <
class OtherV,
class OtherP,
class OtherF,
class OtherInvF>
121 const ArrayPortalTransform<OtherV, OtherP, OtherF, OtherInvF>& src)
123 , InverseFunctor(src.GetInverseFunctor())
127 template <
typename Writable_ = Writable,
128 typename =
typename std::enable_if<Writable_::value>::type>
131 this->Portal.Set(index, this->InverseFunctor(value));
135 const InverseFunctorType& GetInverseFunctor()
const {
return this->InverseFunctor; }
138 InverseFunctorType InverseFunctor;
151 using NullFunctorType = viskores::internal::NullFunctorType;
153 template <
typename Prov
idedFunctorType,
typename FunctorIsExecContObject>
154 struct TransformFunctorManagerImpl;
156 template <
typename Prov
idedFunctorType>
157 struct TransformFunctorManagerImpl<ProvidedFunctorType, std::false_type>
160 !viskores::cont::internal::IsExecutionObjectBase<ProvidedFunctorType>::value,
161 "Must use an ExecutionAndControlObject instead of an ExecutionObject.");
163 ProvidedFunctorType Functor;
164 using FunctorType = ProvidedFunctorType;
166 TransformFunctorManagerImpl() =
default;
169 TransformFunctorManagerImpl(
const ProvidedFunctorType& functor)
175 ProvidedFunctorType PrepareForControl()
const {
return this->Functor; }
180 return this->Functor;
184 template <
typename Prov
idedFunctorType>
185 struct TransformFunctorManagerImpl<ProvidedFunctorType, std::true_type>
189 ProvidedFunctorType Functor;
192 using FunctorType = viskores::cont::internal::ControlObjectType<ProvidedFunctorType>;
194 TransformFunctorManagerImpl() =
default;
197 TransformFunctorManagerImpl(
const ProvidedFunctorType& functor)
203 auto PrepareForControl() const
204 -> decltype(
viskores::cont::internal::CallPrepareForControl(this->Functor))
206 return viskores::cont::internal::CallPrepareForControl(this->Functor);
211 -> decltype(viskores::cont::internal::CallPrepareForExecution(this->Functor, device, token))
213 return viskores::cont::internal::CallPrepareForExecution(this->Functor, device, token);
217 template <
typename Prov
idedFunctorType>
218 struct TransformFunctorManager
219 : TransformFunctorManagerImpl<
221 typename viskores::cont::internal::IsExecutionAndControlObjectBase<ProvidedFunctorType>::type>
223 using Superclass = TransformFunctorManagerImpl<
225 typename viskores::cont::internal::IsExecutionAndControlObjectBase<ProvidedFunctorType>::type>;
226 using FunctorType =
typename Superclass::FunctorType;
230 VISKORES_CONT TransformFunctorManager(
const TransformFunctorManager&) =
default;
232 VISKORES_CONT TransformFunctorManager(
const ProvidedFunctorType& functor)
233 : Superclass(functor)
237 template <
typename ValueType>
238 using TransformedValueType = decltype(std::declval<FunctorType>()(std::declval<ValueType>()));
241 template <
typename ArrayHandleType,
242 typename FunctorType,
243 typename InverseFunctorType = NullFunctorType>
244 struct VISKORES_ALWAYS_EXPORT StorageTagTransform
246 using FunctorManager = TransformFunctorManager<FunctorType>;
248 typename FunctorManager::template TransformedValueType<typename ArrayHandleType::ValueType>;
251 template <
typename ArrayHandleType,
typename FunctorType>
252 class Storage<typename StorageTagTransform<ArrayHandleType, FunctorType>::ValueType,
253 StorageTagTransform<ArrayHandleType, FunctorType>>
255 using FunctorManager = TransformFunctorManager<FunctorType>;
256 using ValueType =
typename StorageTagTransform<ArrayHandleType, FunctorType>::ValueType;
258 using SourceStorage =
typename ArrayHandleType::StorageType;
260 static std::vector<viskores::cont::internal::Buffer> SourceBuffers(
261 const std::vector<viskores::cont::internal::Buffer>& buffers)
263 return std::vector<viskores::cont::internal::Buffer>(buffers.begin() + 1, buffers.end());
270 using ReadPortalType =
271 viskores::internal::ArrayPortalTransform<ValueType,
272 typename ArrayHandleType::ReadPortalType,
273 typename FunctorManager::FunctorType>;
276 const std::vector<viskores::cont::internal::Buffer>&)
282 const std::vector<viskores::cont::internal::Buffer>& buffers)
284 return SourceStorage::GetNumberOfValues(SourceBuffers(buffers));
288 const std::vector<viskores::cont::internal::Buffer>& buffers,
294 return ReadPortalType(SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
295 buffers[0].GetMetaData<FunctorManager>().PrepareForControl());
299 return ReadPortalType(
300 SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
301 buffers[0].GetMetaData<FunctorManager>().PrepareForExecution(device, token));
305 VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> CreateBuffers(
306 const ArrayHandleType& handle = ArrayHandleType{},
307 const FunctorType& functor = FunctorType())
309 return viskores::cont::internal::CreateBuffers(FunctorManager(functor), handle);
313 const std::vector<viskores::cont::internal::Buffer>& buffers)
316 typename ArrayHandleType::StorageTag>(
317 SourceBuffers(buffers));
321 const std::vector<viskores::cont::internal::Buffer>& buffers)
323 return buffers[0].GetMetaData<FunctorManager>().Functor;
327 const std::vector<viskores::cont::internal::Buffer>&)
329 return NullFunctorType{};
333 template <
typename ArrayHandleType,
typename FunctorType,
typename InverseFunctorType>
335 typename StorageTagTransform<ArrayHandleType, FunctorType, InverseFunctorType>::ValueType,
336 StorageTagTransform<ArrayHandleType, FunctorType, InverseFunctorType>>
338 using FunctorManager = TransformFunctorManager<FunctorType>;
339 using InverseFunctorManager = TransformFunctorManager<InverseFunctorType>;
340 using ValueType =
typename StorageTagTransform<ArrayHandleType, FunctorType>::ValueType;
342 using SourceStorage =
typename ArrayHandleType::StorageType;
344 static std::vector<viskores::cont::internal::Buffer> SourceBuffers(
345 const std::vector<viskores::cont::internal::Buffer>& buffers)
347 return std::vector<viskores::cont::internal::Buffer>(buffers.begin() + 2, buffers.end());
351 using ReadPortalType =
352 viskores::internal::ArrayPortalTransform<ValueType,
353 typename ArrayHandleType::ReadPortalType,
354 typename FunctorManager::FunctorType,
355 typename InverseFunctorManager::FunctorType>;
356 using WritePortalType =
357 viskores::internal::ArrayPortalTransform<ValueType,
358 typename ArrayHandleType::WritePortalType,
359 typename FunctorManager::FunctorType,
360 typename InverseFunctorManager::FunctorType>;
363 const std::vector<viskores::cont::internal::Buffer>&)
369 const std::vector<viskores::cont::internal::Buffer>& buffers)
371 return SourceStorage::GetNumberOfValues(SourceBuffers(buffers));
376 const std::vector<viskores::cont::internal::Buffer>& buffers,
380 std::vector<viskores::cont::internal::Buffer> sourceBuffers = SourceBuffers(buffers);
381 SourceStorage::ResizeBuffers(numValues, sourceBuffers, preserve, token);
385 const std::vector<viskores::cont::internal::Buffer>& buffers,
391 return ReadPortalType(SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
392 buffers[0].GetMetaData<FunctorManager>().PrepareForControl(),
393 buffers[1].GetMetaData<InverseFunctorManager>().PrepareForControl());
397 return ReadPortalType(
398 SourceStorage::CreateReadPortal(SourceBuffers(buffers), device, token),
399 buffers[0].GetMetaData<FunctorManager>().PrepareForExecution(device, token),
400 buffers[1].GetMetaData<InverseFunctorManager>().PrepareForExecution(device, token));
405 const std::vector<viskores::cont::internal::Buffer>& buffers,
409 return WritePortalType(
410 SourceStorage::CreateWritePortal(SourceBuffers(buffers), device, token),
411 buffers[0].GetMetaData<FunctorManager>().PrepareForExecution(device, token),
412 buffers[1].GetMetaData<InverseFunctorManager>().PrepareForExecution(device, token));
415 VISKORES_CONT static std::vector<viskores::cont::internal::Buffer> CreateBuffers(
416 const ArrayHandleType& handle = ArrayHandleType{},
417 const FunctorType& functor = FunctorType(),
418 const InverseFunctorType& inverseFunctor = InverseFunctorType())
420 return viskores::cont::internal::CreateBuffers(
421 FunctorManager(functor), InverseFunctorManager(inverseFunctor), handle);
425 const std::vector<viskores::cont::internal::Buffer>& buffers)
428 typename ArrayHandleType::StorageTag>(
429 SourceBuffers(buffers));
433 const std::vector<viskores::cont::internal::Buffer>& buffers)
435 return buffers[0].GetMetaData<FunctorManager>().Functor;
439 const std::vector<viskores::cont::internal::Buffer>& buffers)
441 return buffers[1].GetMetaData<InverseFunctorManager>().Functor;
458 template <
typename ArrayHandleType,
459 typename FunctorType,
460 typename InverseFunctorType = internal::NullFunctorType>
463 template <
typename ArrayHandleType,
typename FunctorType>
466 typename internal::StorageTagTransform<ArrayHandleType, FunctorType>::ValueType,
467 internal::StorageTagTransform<ArrayHandleType, FunctorType>>
478 typename internal::StorageTagTransform<ArrayHandleType, FunctorType>::ValueType,
479 internal::StorageTagTransform<ArrayHandleType, FunctorType>>));
483 const FunctorType& functor = FunctorType{},
484 internal::NullFunctorType = internal::NullFunctorType{})
485 :
Superclass(StorageType::CreateBuffers(handle, functor))
493 template <
typename HandleType,
typename FunctorType>
502 template <
typename ArrayHandleType,
typename FunctorType,
typename InverseFunctorType>
503 class ArrayHandleTransform
505 typename internal::StorageTagTransform<ArrayHandleType, FunctorType, InverseFunctorType>::
507 internal::StorageTagTransform<ArrayHandleType, FunctorType, InverseFunctorType>>
514 (ArrayHandleTransform<ArrayHandleType, FunctorType, InverseFunctorType>),
516 typename internal::StorageTagTransform<ArrayHandleType, FunctorType, InverseFunctorType>::
518 internal::StorageTagTransform<ArrayHandleType, FunctorType, InverseFunctorType>>));
521 const FunctorType& functor = FunctorType(),
522 const InverseFunctorType& inverseFunctor = InverseFunctorType())
540 FunctorType
GetFunctor()
const {
return StorageType::GetFunctor(this->GetBuffers()); }
546 return StorageType::GetInverseFunctor(this->GetBuffers());
550 template <
typename HandleType,
typename FunctorType,
typename InverseFunctorType>
555 handle, functor, inverseFunctor);
569 template <
typename AH,
typename Functor,
typename InvFunctor>
570 struct SerializableTypeString<
viskores::cont::ArrayHandleTransform<AH, Functor, InvFunctor>>
581 template <
typename AH,
typename Functor>
582 struct SerializableTypeString<
viskores::cont::ArrayHandleTransform<AH, Functor>>
592 template <
typename AH,
typename Functor,
typename InvFunctor>
593 struct SerializableTypeString<
viskores::cont::ArrayHandle<
594 typename viskores::cont::internal::StorageTagTransform<AH, Functor, InvFunctor>::ValueType,
595 viskores::cont::internal::StorageTagTransform<AH, Functor, InvFunctor>>>
596 : SerializableTypeString<viskores::cont::ArrayHandleTransform<AH, Functor, InvFunctor>>
605 template <
typename AH,
typename Functor>
606 struct Serialization<
viskores::cont::ArrayHandleTransform<AH, Functor>>
613 static VISKORES_CONT void save(BinaryBuffer& bb,
const BaseType& obj)
615 Type transformedArray = obj;
616 viskoresdiy::save(bb, obj.GetArray());
617 viskoresdiy::save(bb, obj.GetFunctor());
630 template <
typename AH,
typename Functor,
typename InvFunctor>
631 struct Serialization<
viskores::cont::ArrayHandleTransform<AH, Functor, InvFunctor>>
638 static VISKORES_CONT void save(BinaryBuffer& bb,
const BaseType& obj)
640 Type transformedArray = obj;
641 viskoresdiy::save(bb, transformedArray.GetTransformedArray());
642 viskoresdiy::save(bb, transformedArray.GetFunctor());
643 viskoresdiy::save(bb, transformedArray.GetInverseFunctor());
652 InvFunctor invFunctor;
658 template <
typename AH,
typename Functor,
typename InvFunctor>
659 struct Serialization<
viskores::cont::ArrayHandle<
660 typename viskores::cont::internal::StorageTagTransform<AH, Functor, InvFunctor>::ValueType,
661 viskores::cont::internal::StorageTagTransform<AH, Functor, InvFunctor>>>
662 : Serialization<viskores::cont::ArrayHandleTransform<AH, Functor, InvFunctor>>
669 #endif //viskores_cont_ArrayHandleTransform_h