forked from Kitware/VTK
-
Notifications
You must be signed in to change notification settings - Fork 0
/
vtkDataArrayMeta.h
214 lines (170 loc) · 6.74 KB
/
vtkDataArrayMeta.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/*=========================================================================
Program: Visualization Toolkit
Module: vtkDataArrayMeta.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#ifndef vtkDataArrayMeta_h
#define vtkDataArrayMeta_h
#include "vtkAssume.h"
#include "vtkDataArray.h"
#include "vtkDebugRangeIterators.h"
#include "vtkMeta.h"
#include "vtkSetGet.h"
#include "vtkType.h"
#include <type_traits>
#include <utility>
/**
* @file vtkDataArrayMeta.h
* This file contains a variety of metaprogramming constructs for working
* with vtkDataArrays.
*/
// When enabled, extra debugging checks are enabled for the iterators.
// Specifically:
// - Specializations are disabled (All code uses the generic implementation).
// - Additional assertions are inserted to ensure correct runtime usage.
// - Performance-related annotations (e.g. force inlining) are disabled.
#if defined(VTK_DEBUG_RANGE_ITERATORS)
#define VTK_ITER_ASSERT(x, msg) assert((x) && msg)
#else
#define VTK_ITER_ASSERT(x, msg)
#endif
#if defined(VTK_ALWAYS_OPTIMIZE_ARRAY_ITERATORS) && !defined(VTK_DEBUG_RANGE_ITERATORS)
#define VTK_ITER_INLINE VTK_ALWAYS_INLINE
#define VTK_ITER_ASSUME VTK_ASSUME_NO_ASSERT
#define VTK_ITER_OPTIMIZE_START VTK_ALWAYS_OPTIMIZE_START
#define VTK_ITER_OPTIMIZE_END VTK_ALWAYS_OPTIMIZE_START
#else
#define VTK_ITER_INLINE inline
#define VTK_ITER_ASSUME VTK_ASSUME
#define VTK_ITER_OPTIMIZE_START
#define VTK_ITER_OPTIMIZE_END
#endif
VTK_ITER_OPTIMIZE_START
// For IsAOSDataArray:
template <typename ValueType>
class vtkAOSDataArrayTemplate;
namespace vtk
{
// Typedef for data array indices:
using ComponentIdType = int;
using TupleIdType = vtkIdType;
using ValueIdType = vtkIdType;
namespace detail
{
//------------------------------------------------------------------------------
// Used by ranges/iterators when tuple size is unknown at compile time
static constexpr ComponentIdType DynamicTupleSize = 0;
//------------------------------------------------------------------------------
// Detect data array value types
template <typename T>
struct IsVtkDataArray : std::is_base_of<vtkDataArray, T>
{
};
template <typename T>
using EnableIfVtkDataArray = typename std::enable_if<IsVtkDataArray<T>::value>::type;
//------------------------------------------------------------------------------
// If a value is a valid tuple size
template <ComponentIdType Size>
struct IsValidTupleSize : std::integral_constant<bool, (Size > 0 || Size == DynamicTupleSize)>
{
};
template <ComponentIdType TupleSize>
using EnableIfValidTupleSize = typename std::enable_if<IsValidTupleSize<TupleSize>::value>::type;
//------------------------------------------------------------------------------
// If a value is a non-dynamic tuple size
template <ComponentIdType Size>
struct IsStaticTupleSize : std::integral_constant<bool, (Size > 0)>
{
};
template <ComponentIdType TupleSize>
using EnableIfStaticTupleSize = typename std::enable_if<IsStaticTupleSize<TupleSize>::value>::type;
//------------------------------------------------------------------------------
// If two values are valid non-dynamic tuple sizes:
template <ComponentIdType S1, ComponentIdType S2>
struct AreStaticTupleSizes
: std::integral_constant<bool, (IsStaticTupleSize<S1>::value && IsStaticTupleSize<S2>::value)>
{
};
template <ComponentIdType S1, ComponentIdType S2, typename T = void>
using EnableIfStaticTupleSizes =
typename std::enable_if<AreStaticTupleSizes<S1, S2>::value, T>::type;
//------------------------------------------------------------------------------
// If either of the tuple sizes is not statically defined
template <ComponentIdType S1, ComponentIdType S2>
struct IsEitherTupleSizeDynamic
: std::integral_constant<bool, (!IsStaticTupleSize<S1>::value || !IsStaticTupleSize<S2>::value)>
{
};
template <ComponentIdType S1, ComponentIdType S2, typename T = void>
using EnableIfEitherTupleSizeIsDynamic =
typename std::enable_if<IsEitherTupleSizeDynamic<S1, S2>::value, T>::type;
//------------------------------------------------------------------------------
// Helper that switches between a storageless integral constant for known
// sizes, and a runtime variable for variable sizes.
template <ComponentIdType TupleSize>
struct GenericTupleSize : public std::integral_constant<ComponentIdType, TupleSize>
{
static_assert(IsValidTupleSize<TupleSize>::value, "Invalid tuple size.");
private:
using Superclass = std::integral_constant<ComponentIdType, TupleSize>;
public:
// Need to construct from array for specialization.
using Superclass::Superclass;
VTK_ITER_INLINE GenericTupleSize() noexcept = default;
VTK_ITER_INLINE GenericTupleSize(vtkDataArray*) noexcept {}
};
// Specialize for dynamic types, mimicking integral_constant API:
template <>
struct GenericTupleSize<DynamicTupleSize>
{
using value_type = ComponentIdType;
VTK_ITER_INLINE GenericTupleSize() noexcept
: value(0)
{
}
VTK_ITER_INLINE explicit GenericTupleSize(vtkDataArray* array)
: value(array->GetNumberOfComponents())
{
}
VTK_ITER_INLINE operator value_type() const noexcept { return value; }
VTK_ITER_INLINE value_type operator()() const noexcept { return value; }
ComponentIdType value;
};
template <typename ArrayType>
struct GetAPITypeImpl
{
using APIType = typename ArrayType::ValueType;
};
template <>
struct GetAPITypeImpl<vtkDataArray>
{
using APIType = double;
};
} // end namespace detail
//------------------------------------------------------------------------------
// Typedef for double if vtkDataArray, or the array's ValueType for subclasses.
template <typename ArrayType, typename = detail::EnableIfVtkDataArray<ArrayType>>
using GetAPIType = typename detail::GetAPITypeImpl<ArrayType>::APIType;
//------------------------------------------------------------------------------
namespace detail
{
template <typename ArrayType>
struct IsAOSDataArrayImpl
{
using APIType = GetAPIType<ArrayType>;
static constexpr bool value = std::is_base_of<vtkAOSDataArrayTemplate<APIType>, ArrayType>::value;
};
} // end namespace detail
//------------------------------------------------------------------------------
// True if ArrayType inherits some specialization of vtkAOSDataArrayTemplate
template <typename ArrayType>
using IsAOSDataArray = std::integral_constant<bool, detail::IsAOSDataArrayImpl<ArrayType>::value>;
} // end namespace vtk
VTK_ITER_OPTIMIZE_END
#endif // vtkDataArrayMeta_h
// VTK-HeaderTest-Exclude: vtkDataArrayMeta.h