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_VecFromPortal_h
11 #define vtk_m_VecFromPortal_h
12 
13 #include <vtkm/Math.h>
14 #include <vtkm/TypeTraits.h>
15 #include <vtkm/Types.h>
16 #include <vtkm/VecTraits.h>
17 
18 #include <vtkm/internal/ArrayPortalValueReference.h>
19 
20 namespace vtkm
21 {
22 
23 /// \brief A short variable-length array from a window in an ArrayPortal.
24 ///
25 /// The \c VecFromPortal class is a Vec-like class that holds an array portal
26 /// and exposes a small window of that portal as if it were a \c Vec.
27 ///
28 template <typename PortalType>
29 class VecFromPortal
30 {
31 public:
32   using ComponentType = typename std::remove_const<typename PortalType::ValueType>::type;
33 
34   VTKM_SUPPRESS_EXEC_WARNINGS
35   VTKM_EXEC_CONT
VecFromPortal()36   VecFromPortal()
37     : NumComponents(0)
38     , Offset(0)
39   {
40   }
41 
42   VTKM_SUPPRESS_EXEC_WARNINGS
43   VTKM_EXEC_CONT
44   VecFromPortal(const PortalType& portal, vtkm::IdComponent numComponents = 0, vtkm::Id offset = 0)
Portal(portal)45     : Portal(portal)
46     , NumComponents(numComponents)
47     , Offset(offset)
48   {
49   }
50 
51   VTKM_EXEC_CONT
GetNumberOfComponents()52   vtkm::IdComponent GetNumberOfComponents() const { return this->NumComponents; }
53 
54   template <typename T, vtkm::IdComponent DestSize>
CopyInto(vtkm::Vec<T,DestSize> & dest)55   VTKM_EXEC_CONT void CopyInto(vtkm::Vec<T, DestSize>& dest) const
56   {
57     vtkm::IdComponent numComponents = vtkm::Min(DestSize, this->NumComponents);
58     for (vtkm::IdComponent index = 0; index < numComponents; index++)
59     {
60       dest[index] = this->Portal.Get(index + this->Offset);
61     }
62   }
63 
64   VTKM_SUPPRESS_EXEC_WARNINGS
65   VTKM_EXEC_CONT
66   vtkm::internal::ArrayPortalValueReference<PortalType> operator[](vtkm::IdComponent index) const
67   {
68     return vtkm::internal::ArrayPortalValueReference<PortalType>(this->Portal,
69                                                                  index + this->Offset);
70   }
71 
72 private:
73   PortalType Portal;
74   vtkm::IdComponent NumComponents;
75   vtkm::Id Offset;
76 };
77 
78 template <typename PortalType>
79 struct TypeTraits<vtkm::VecFromPortal<PortalType>>
80 {
81 private:
82   using ComponentType = typename PortalType::ValueType;
83 
84 public:
85   using NumericTag = typename vtkm::TypeTraits<ComponentType>::NumericTag;
86   using DimensionalityTag = TypeTraitsVectorTag;
87 
88   VTKM_SUPPRESS_EXEC_WARNINGS
89   VTKM_EXEC_CONT
90   static vtkm::VecFromPortal<PortalType> ZeroInitialization()
91   {
92     return vtkm::VecFromPortal<PortalType>();
93   }
94 };
95 
96 template <typename PortalType>
97 struct VecTraits<vtkm::VecFromPortal<PortalType>>
98 {
99   using VecType = vtkm::VecFromPortal<PortalType>;
100 
101   using ComponentType = typename VecType::ComponentType;
102   using BaseComponentType = typename vtkm::VecTraits<ComponentType>::BaseComponentType;
103   using HasMultipleComponents = vtkm::VecTraitsTagMultipleComponents;
104   using IsSizeStatic = vtkm::VecTraitsTagSizeVariable;
105 
106   VTKM_SUPPRESS_EXEC_WARNINGS
107   VTKM_EXEC_CONT
108   static vtkm::IdComponent GetNumberOfComponents(const VecType& vector)
109   {
110     return vector.GetNumberOfComponents();
111   }
112 
113   VTKM_SUPPRESS_EXEC_WARNINGS
114   VTKM_EXEC_CONT
115   static ComponentType GetComponent(const VecType& vector, vtkm::IdComponent componentIndex)
116   {
117     return vector[componentIndex];
118   }
119 
120   VTKM_SUPPRESS_EXEC_WARNINGS
121   template <vtkm::IdComponent destSize>
122   VTKM_EXEC_CONT static void CopyInto(const VecType& src, vtkm::Vec<ComponentType, destSize>& dest)
123   {
124     src.CopyInto(dest);
125   }
126 };
127 
128 } // namespace vtkm
129 
130 #endif //vtk_m_VecFromPortal_h
131