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_ArrayHandleIndex_h
11 #define vtk_m_cont_ArrayHandleIndex_h
12 
13 #include <vtkm/cont/ArrayHandleImplicit.h>
14 
15 namespace vtkm
16 {
17 
18 namespace internal
19 {
20 
21 struct VTKM_ALWAYS_EXPORT IndexFunctor
22 {
operatorIndexFunctor23   VTKM_EXEC_CONT vtkm::Id operator()(vtkm::Id index) const { return index; }
24 };
25 
26 } // namespace internal
27 
28 namespace cont
29 {
30 
31 struct VTKM_ALWAYS_EXPORT StorageTagIndex
32 {
33 };
34 
35 namespace internal
36 {
37 
38 using StorageTagIndexSuperclass =
39   typename vtkm::cont::ArrayHandleImplicit<vtkm::internal::IndexFunctor>::StorageTag;
40 
41 template <>
42 struct Storage<vtkm::Id, vtkm::cont::StorageTagIndex> : Storage<vtkm::Id, StorageTagIndexSuperclass>
43 {
44 };
45 
46 } // namespace internal
47 
48 /// \brief An implicit array handle containing the its own indices.
49 ///
50 /// \c ArrayHandleIndex is an implicit array handle containing the values
51 /// 0, 1, 2, 3,... to a specified size. Every value in the array is the same
52 /// as the index to that value.
53 ///
54 class ArrayHandleIndex : public vtkm::cont::ArrayHandle<vtkm::Id, StorageTagIndex>
55 {
56 public:
57   VTKM_ARRAY_HANDLE_SUBCLASS_NT(ArrayHandleIndex,
58                                 (vtkm::cont::ArrayHandle<vtkm::Id, StorageTagIndex>));
59 
60   VTKM_CONT
61   ArrayHandleIndex(vtkm::Id length)
62     : Superclass(
63         internal::FunctorToArrayHandleImplicitBuffers(vtkm::internal::IndexFunctor{}, length))
64   {
65   }
66 };
67 
68 /// A convenience function for creating an ArrayHandleIndex. It takes the
69 /// size of the array and generates an array holding vtkm::Id from [0, size - 1]
70 VTKM_CONT inline vtkm::cont::ArrayHandleIndex make_ArrayHandleIndex(vtkm::Id length)
71 {
72   return vtkm::cont::ArrayHandleIndex(length);
73 }
74 }
75 } // namespace vtkm::cont
76 
77 //=============================================================================
78 // Specializations of serialization related classes
79 /// @cond SERIALIZATION
80 
81 namespace vtkm
82 {
83 namespace cont
84 {
85 
86 template <>
87 struct SerializableTypeString<vtkm::cont::ArrayHandleIndex>
88 {
89   static VTKM_CONT const std::string Get() { return "AH_Index"; }
90 };
91 
92 template <>
93 struct SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::Id, vtkm::cont::StorageTagIndex>>
94   : SerializableTypeString<vtkm::cont::ArrayHandleIndex>
95 {
96 };
97 }
98 } // vtkm::cont
99 
100 namespace mangled_diy_namespace
101 {
102 
103 template <>
104 struct Serialization<vtkm::cont::ArrayHandleIndex>
105 {
106 private:
107   using BaseType = vtkm::cont::ArrayHandle<vtkm::Id, vtkm::cont::StorageTagIndex>;
108 
109 public:
110   static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
111   {
112     vtkmdiy::save(bb, obj.GetNumberOfValues());
113   }
114 
115   static VTKM_CONT void load(BinaryBuffer& bb, BaseType& obj)
116   {
117     vtkm::Id length = 0;
118     vtkmdiy::load(bb, length);
119 
120     obj = vtkm::cont::ArrayHandleIndex(length);
121   }
122 };
123 
124 template <>
125 struct Serialization<vtkm::cont::ArrayHandle<vtkm::Id, vtkm::cont::StorageTagIndex>>
126   : Serialization<vtkm::cont::ArrayHandleIndex>
127 {
128 };
129 } // diy
130 /// @endcond SERIALIZATION
131 
132 #endif //vtk_m_cont_ArrayHandleIndex_h
133