File: vtkDataArrayIteratorMacro.h

package info (click to toggle)
vtk9 9.5.2%2Bdfsg3-4
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 205,916 kB
  • sloc: cpp: 2,336,565; ansic: 327,116; python: 111,200; yacc: 4,104; java: 3,977; sh: 3,032; xml: 2,771; perl: 2,189; lex: 1,787; makefile: 178; javascript: 165; objc: 153; tcl: 59
file content (124 lines) | stat: -rw-r--r-- 7,107 bytes parent folder | download | duplicates (7)
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
// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
// SPDX-License-Identifier: BSD-3-Clause
/**
 * @def   vtkDataArrayIteratorMacro
 * @brief   (deprecated) A macro for obtaining iterators to
 * vtkDataArray data when the array implementation and type are unknown.
 *
 * @deprecated This macro is deprecated and should not be used any longer. See
 * vtkArrayDispatch.h and vtkDataArrayRange.h for replacements.
 *
 * See vtkTemplateMacro.
 * This macro is similar, but defines several additional typedefs and variables
 * for safely iterating through data in a vtkAbstractArray container:
 *  - vtkDAValueType is typedef'd to the array's element value type.
 *  - vtkDAContainerType is typedef'd to the most derived class of
 *    vtkAbstractArray for which a suitable iterator has been found.
 *  - vtkDAIteratorType is typedef'd to the most suitable iterator type found.
 *  - vtkDABegin is an object of vtkDAIteratorType that points to the first
 *    component of the first tuple in the array.
 *  - vtkDAEnd is an object of vtkDAIteratorType that points to the element
 *    *after* the last component of the last tuple in the array.
 * The primary advantage to using this macro is that arrays with non-standard
 * memory layouts will be safely handled, and dangerous calls to GetVoidPointer
 * are avoided.
 * For arrays with > 1 component, the iterator will proceed through all
 * components of a tuple before moving on to the next tuple.
 * This matches the memory layout of the standard vtkDataArray subclasses such
 * as vtkFloatArray.
 *
 * For the standard vtkDataArray implementations (which are subclasses of
 * vtkAOSDataArrayTemplate), the iterators will simply be pointers to the raw
 * memory of the array.
 * This allows very fast iteration when possible, and permits compiler
 * optimizations in the standard template library to occur (such as reducing
 * std::copy to memmove).
 *
 * For arrays that are subclasses of vtkTypedDataArray, a
 * vtkTypedDataArrayIterator is used.
 * Such iterators safely traverse the array using API calls and have
 * pointer-like semantics, but add about a 35% performance overhead compared
 * with iterating over the raw memory (measured by summing a vtkFloatArray
 * containing 10M values on GCC 4.8.1 with -O3 optimization using both iterator
 * types -- see TestDataArrayIterators).
 *
 * For arrays that are not subclasses of vtkTypedDataArray, there is no reliably
 * safe way to iterate over the array elements.
 * In such cases, this macro performs the legacy behavior of casting
 * vtkAbstractArray::GetVoidPointer(...) to vtkDAValueType* to create the
 * iterators.
 *
 * To use this macro, create a templated worker function:
 *
 * @code
 * template <class Iterator>
 * void myFunc(Iterator begin, Iterator end, ...) {...}
 *
 * and then call the vtkDataArrayIteratorMacro inside of a switch statement
 * using the above objects and typedefs as needed:
 *
 * vtkAbstractArray *someArray = ...;
 * switch (someArray->GetDataType())
 * {
 *   vtkDataArrayIteratorMacro(someArray, myFunc(vtkDABegin, vtkDAEnd, ...));
 * }
 * @endcode
 *
 * @sa
 * vtkArrayDispatch vtkGenericDataArray
 * vtkTemplateMacro vtkTypedDataArrayIterator
 */

#ifndef vtkDataArrayIteratorMacro_h
#define vtkDataArrayIteratorMacro_h

#include "vtkAOSDataArrayTemplate.h" // For classes referred to in the macro
#include "vtkSetGet.h"               // For vtkTemplateMacro
#include "vtkTypedDataArray.h"       // For classes referred to in the macro

// Silence 'unused typedef' warnings on GCC.
// use of the typedef in question depends on the macro
// argument _call and thus should not be removed.
#if defined(__GNUC__)
#define _vtkDAIMUnused __attribute__((unused))
#else
#define _vtkDAIMUnused
#endif

#define vtkDataArrayIteratorMacro(_array, _call)                                                   \
  vtkTemplateMacro(                                                                                \
    vtkAbstractArray* _aa(_array); if (vtkAOSDataArrayTemplate<VTK_TT>* _dat =                     \
                                         vtkAOSDataArrayTemplate<VTK_TT>::FastDownCast(_aa)) {     \
      typedef VTK_TT vtkDAValueType;                                                               \
      typedef vtkAOSDataArrayTemplate<vtkDAValueType> vtkDAContainerType;                          \
      typedef vtkDAContainerType::Iterator vtkDAIteratorType;                                      \
      vtkDAIteratorType vtkDABegin(_dat->Begin());                                                 \
      vtkDAIteratorType vtkDAEnd(_dat->End());                                                     \
      (void)vtkDABegin; /* Prevent warnings when unused */                                         \
      (void)vtkDAEnd;                                                                              \
      _call;                                                                                       \
    } else if (vtkTypedDataArray<VTK_TT>* _tda = vtkTypedDataArray<VTK_TT>::FastDownCast(_aa)) {   \
      typedef VTK_TT vtkDAValueType;                                                               \
      typedef vtkTypedDataArray<vtkDAValueType> vtkDAContainerType;                                \
      typedef vtkDAContainerType::Iterator vtkDAIteratorType;                                      \
      vtkDAIteratorType vtkDABegin(_tda->Begin());                                                 \
      vtkDAIteratorType vtkDAEnd(_tda->End());                                                     \
      (void)vtkDABegin;                                                                            \
      (void)vtkDAEnd;                                                                              \
      _call;                                                                                       \
    } else {                                                                                       \
      /* This is not ideal, as no explicit iterator has been declared. */                          \
      /* Cast the void pointer and hope for the best!                  */                          \
      typedef VTK_TT vtkDAValueType;                                                               \
      typedef vtkAbstractArray vtkDAContainerType _vtkDAIMUnused;                                  \
      typedef vtkDAValueType* vtkDAIteratorType;                                                   \
      vtkDAIteratorType vtkDABegin = static_cast<vtkDAIteratorType>(_aa->GetVoidPointer(0));       \
      vtkDAIteratorType vtkDAEnd = vtkDABegin + _aa->GetMaxId() + 1;                               \
      (void)vtkDABegin;                                                                            \
      (void)vtkDAEnd;                                                                              \
      _call;                                                                                       \
    })

#endif // vtkDataArrayIteratorMacro_h

// VTK-HeaderTest-Exclude: vtkDataArrayIteratorMacro.h