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_VecFromPortalPermute_h
11 #define vtk_m_VecFromPortalPermute_h
12 
13 #include <vtkm/Math.h>
14 #include <vtkm/TypeTraits.h>
15 #include <vtkm/Types.h>
16 #include <vtkm/VecTraits.h>
17 
18 namespace vtkm
19 {
20 
21 /// \brief A short vector from an ArrayPortal and a vector of indices.
22 ///
23 /// The \c VecFromPortalPermute class is a Vec-like class that holds an array
24 /// portal and a second Vec-like containing indices into the array. Each value
25 /// of this vector is the value from the array with the respective index.
26 ///
27 template <typename IndexVecType, typename PortalType>
28 class VecFromPortalPermute
29 {
30 public:
31   using ComponentType = typename std::remove_const<typename PortalType::ValueType>::type;
32 
33   VTKM_SUPPRESS_EXEC_WARNINGS
34   VTKM_EXEC_CONT
VecFromPortalPermute()35   VecFromPortalPermute() {}
36 
37   VTKM_SUPPRESS_EXEC_WARNINGS
38   VTKM_EXEC_CONT
VecFromPortalPermute(const IndexVecType * indices,const PortalType & portal)39   VecFromPortalPermute(const IndexVecType* indices, const PortalType& portal)
40     : Indices(indices)
41     , Portal(portal)
42   {
43   }
44 
45   VTKM_SUPPRESS_EXEC_WARNINGS
46   VTKM_EXEC_CONT
GetNumberOfComponents()47   vtkm::IdComponent GetNumberOfComponents() const { return this->Indices->GetNumberOfComponents(); }
48 
49   VTKM_SUPPRESS_EXEC_WARNINGS
50   template <vtkm::IdComponent DestSize>
CopyInto(vtkm::Vec<ComponentType,DestSize> & dest)51   VTKM_EXEC_CONT void CopyInto(vtkm::Vec<ComponentType, DestSize>& dest) const
52   {
53     vtkm::IdComponent numComponents = vtkm::Min(DestSize, this->GetNumberOfComponents());
54     for (vtkm::IdComponent index = 0; index < numComponents; index++)
55     {
56       dest[index] = (*this)[index];
57     }
58   }
59 
60   VTKM_SUPPRESS_EXEC_WARNINGS
61   VTKM_EXEC_CONT
62   ComponentType operator[](vtkm::IdComponent index) const
63   {
64     return this->Portal.Get((*this->Indices)[index]);
65   }
66 
67 private:
68   const IndexVecType* const Indices;
69   PortalType Portal;
70 };
71 
72 template <typename IndexVecType, typename PortalType>
73 class VecFromPortalPermute<IndexVecType, const PortalType*>
74 {
75 public:
76   using ComponentType = typename std::remove_const<typename PortalType::ValueType>::type;
77 
78   VTKM_SUPPRESS_EXEC_WARNINGS
79   VTKM_EXEC_CONT
VecFromPortalPermute()80   VecFromPortalPermute() {}
81 
82   VTKM_SUPPRESS_EXEC_WARNINGS
83   VTKM_EXEC_CONT
VecFromPortalPermute(const IndexVecType * indices,const PortalType * const portal)84   VecFromPortalPermute(const IndexVecType* indices, const PortalType* const portal)
85     : Indices(indices)
86     , Portal(portal)
87   {
88   }
89 
90   VTKM_SUPPRESS_EXEC_WARNINGS
91   VTKM_EXEC_CONT
GetNumberOfComponents()92   vtkm::IdComponent GetNumberOfComponents() const { return this->Indices->GetNumberOfComponents(); }
93 
94   VTKM_SUPPRESS_EXEC_WARNINGS
95   template <vtkm::IdComponent DestSize>
CopyInto(vtkm::Vec<ComponentType,DestSize> & dest)96   VTKM_EXEC_CONT void CopyInto(vtkm::Vec<ComponentType, DestSize>& dest) const
97   {
98     vtkm::IdComponent numComponents = vtkm::Min(DestSize, this->GetNumberOfComponents());
99     for (vtkm::IdComponent index = 0; index < numComponents; index++)
100     {
101       dest[index] = (*this)[index];
102     }
103   }
104 
105   VTKM_SUPPRESS_EXEC_WARNINGS
106   VTKM_EXEC_CONT
107   ComponentType operator[](vtkm::IdComponent index) const
108   {
109     return this->Portal->Get((*this->Indices)[index]);
110   }
111 
112 private:
113   const IndexVecType* const Indices;
114   const PortalType* const Portal;
115 };
116 
117 template <typename IndexVecType, typename PortalType>
118 struct TypeTraits<vtkm::VecFromPortalPermute<IndexVecType, PortalType>>
119 {
120 private:
121   using VecType = vtkm::VecFromPortalPermute<IndexVecType, PortalType>;
122   using ComponentType = typename PortalType::ValueType;
123 
124 public:
125   using NumericTag = typename vtkm::TypeTraits<ComponentType>::NumericTag;
126   using DimensionalityTag = TypeTraitsVectorTag;
127 
128   VTKM_SUPPRESS_EXEC_WARNINGS
129   VTKM_EXEC_CONT
130   static VecType ZeroInitialization() { return VecType(); }
131 };
132 
133 template <typename IndexVecType, typename PortalType>
134 struct VecTraits<vtkm::VecFromPortalPermute<IndexVecType, PortalType>>
135 {
136   using VecType = vtkm::VecFromPortalPermute<IndexVecType, PortalType>;
137 
138   using ComponentType = typename VecType::ComponentType;
139   using BaseComponentType = typename vtkm::VecTraits<ComponentType>::BaseComponentType;
140   using HasMultipleComponents = vtkm::VecTraitsTagMultipleComponents;
141   using IsSizeStatic = vtkm::VecTraitsTagSizeVariable;
142 
143   VTKM_SUPPRESS_EXEC_WARNINGS
144   VTKM_EXEC_CONT
145   static vtkm::IdComponent GetNumberOfComponents(const VecType& vector)
146   {
147     return vector.GetNumberOfComponents();
148   }
149 
150   VTKM_SUPPRESS_EXEC_WARNINGS
151   VTKM_EXEC_CONT
152   static ComponentType GetComponent(const VecType& vector, vtkm::IdComponent componentIndex)
153   {
154     return vector[componentIndex];
155   }
156 
157   VTKM_SUPPRESS_EXEC_WARNINGS
158   template <vtkm::IdComponent destSize>
159   VTKM_EXEC_CONT static void CopyInto(const VecType& src, vtkm::Vec<ComponentType, destSize>& dest)
160   {
161     src.CopyInto(dest);
162   }
163 };
164 
165 template <typename IndexVecType, typename PortalType>
166 inline VTKM_EXEC VecFromPortalPermute<IndexVecType, PortalType> make_VecFromPortalPermute(
167   const IndexVecType* index,
168   const PortalType& portal)
169 {
170   return VecFromPortalPermute<IndexVecType, PortalType>(index, portal);
171 }
172 
173 template <typename IndexVecType, typename PortalType>
174 inline VTKM_EXEC VecFromPortalPermute<IndexVecType, const PortalType*> make_VecFromPortalPermute(
175   const IndexVecType* index,
176   const PortalType* const portal)
177 {
178   return VecFromPortalPermute<IndexVecType, const PortalType*>(index, portal);
179 }
180 
181 } // namespace vtkm
182 
183 #endif //vtk_m_VecFromPortalPermute_h
184