1 //============================================================================
2 //  Copyright (c) Kitware, Inc.
3 //  All rights reserved.
4 //  See LICENSE.txt for details.
5 //  This software is distributed WITHOUT ANY WARRANTY; without even
6 //  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
7 //  PURPOSE.  See the above copyright notice for more information.
8 //
9 //  Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
10 //  Copyright 2015 UT-Battelle, LLC.
11 //  Copyright 2015 Los Alamos National Security.
12 //
13 //  Under the terms of Contract DE-NA0003525 with NTESS,
14 //  the U.S. Government retains certain rights in this software.
15 //
16 //  Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
17 //  Laboratory (LANL), the U.S. Government retains certain rights in
18 //  this software.
19 //============================================================================
20 #ifndef vtk_m_VecFromPortalPermute_h
21 #define vtk_m_VecFromPortalPermute_h
22 
23 #include <vtkm/Math.h>
24 #include <vtkm/TypeTraits.h>
25 #include <vtkm/Types.h>
26 #include <vtkm/VecTraits.h>
27 
28 namespace vtkm
29 {
30 
31 /// \brief A short vector from an ArrayPortal and a vector of indices.
32 ///
33 /// The \c VecFromPortalPermute class is a Vec-like class that holds an array
34 /// portal and a second Vec-like containing indices into the array. Each value
35 /// of this vector is the value from the array with the respective index.
36 ///
37 template <typename IndexVecType, typename PortalType>
38 class VecFromPortalPermute
39 {
40 public:
41   using ComponentType = typename std::remove_const<typename PortalType::ValueType>::type;
42 
43   VTKM_SUPPRESS_EXEC_WARNINGS
44   VTKM_EXEC_CONT
VecFromPortalPermute()45   VecFromPortalPermute() {}
46 
47   VTKM_SUPPRESS_EXEC_WARNINGS
48   VTKM_EXEC_CONT
VecFromPortalPermute(const IndexVecType * indices,const PortalType & portal)49   VecFromPortalPermute(const IndexVecType* indices, const PortalType& portal)
50     : Indices(indices)
51     , Portal(portal)
52   {
53   }
54 
55   VTKM_SUPPRESS_EXEC_WARNINGS
56   VTKM_EXEC_CONT
GetNumberOfComponents()57   vtkm::IdComponent GetNumberOfComponents() const { return this->Indices->GetNumberOfComponents(); }
58 
59   VTKM_SUPPRESS_EXEC_WARNINGS
60   template <vtkm::IdComponent DestSize>
CopyInto(vtkm::Vec<ComponentType,DestSize> & dest)61   VTKM_EXEC_CONT void CopyInto(vtkm::Vec<ComponentType, DestSize>& dest) const
62   {
63     vtkm::IdComponent numComponents = vtkm::Min(DestSize, this->GetNumberOfComponents());
64     for (vtkm::IdComponent index = 0; index < numComponents; index++)
65     {
66       dest[index] = (*this)[index];
67     }
68   }
69 
70   VTKM_SUPPRESS_EXEC_WARNINGS
71   VTKM_EXEC_CONT
72   ComponentType operator[](vtkm::IdComponent index) const
73   {
74     return this->Portal.Get((*this->Indices)[index]);
75   }
76 
77 private:
78   const IndexVecType* Indices;
79   PortalType Portal;
80 };
81 
82 template <typename IndexVecType, typename PortalType>
83 struct TypeTraits<vtkm::VecFromPortalPermute<IndexVecType, PortalType>>
84 {
85 private:
86   using VecType = vtkm::VecFromPortalPermute<IndexVecType, PortalType>;
87   using ComponentType = typename PortalType::ValueType;
88 
89 public:
90   using NumericTag = typename vtkm::TypeTraits<ComponentType>::NumericTag;
91   using DimensionalityTag = TypeTraitsVectorTag;
92 
93   VTKM_SUPPRESS_EXEC_WARNINGS
94   VTKM_EXEC_CONT
95   static VecType ZeroInitialization() { return VecType(); }
96 };
97 
98 template <typename IndexVecType, typename PortalType>
99 struct VecTraits<vtkm::VecFromPortalPermute<IndexVecType, PortalType>>
100 {
101   using VecType = vtkm::VecFromPortalPermute<IndexVecType, PortalType>;
102 
103   using ComponentType = typename VecType::ComponentType;
104   using HasMultipleComponents = vtkm::VecTraitsTagMultipleComponents;
105   using IsSizeStatic = vtkm::VecTraitsTagSizeVariable;
106 
107   VTKM_SUPPRESS_EXEC_WARNINGS
108   VTKM_EXEC_CONT
109   static vtkm::IdComponent GetNumberOfComponents(const VecType& vector)
110   {
111     return vector.GetNumberOfComponents();
112   }
113 
114   VTKM_SUPPRESS_EXEC_WARNINGS
115   VTKM_EXEC_CONT
116   static ComponentType GetComponent(const VecType& vector, vtkm::IdComponent componentIndex)
117   {
118     return vector[componentIndex];
119   }
120 
121   VTKM_SUPPRESS_EXEC_WARNINGS
122   template <vtkm::IdComponent destSize>
123   VTKM_EXEC_CONT static void CopyInto(const VecType& src, vtkm::Vec<ComponentType, destSize>& dest)
124   {
125     src.CopyInto(dest);
126   }
127 };
128 
129 template <typename IndexVecType, typename PortalType>
130 inline VTKM_EXEC VecFromPortalPermute<IndexVecType, PortalType> make_VecFromPortalPermute(
131   const IndexVecType* index,
132   const PortalType& portal)
133 {
134   return VecFromPortalPermute<IndexVecType, PortalType>(index, portal);
135 }
136 
137 } // namespace vtkm
138 
139 #endif //vtk_m_VecFromPortalPermute_h
140