You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
7.4 KiB
C
139 lines
7.4 KiB
C
3 weeks ago
|
/*=========================================================================
|
||
|
|
||
|
Program: Visualization Toolkit
|
||
|
Module: vtkDataArrayIteratorMacro.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.
|
||
|
|
||
|
=========================================================================*/
|
||
|
/**
|
||
|
* @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:
|
||
|
*
|
||
|
* 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, ...));
|
||
|
* }
|
||
|
*
|
||
|
* @sa
|
||
|
* vtkArrayDispatch vtkGenericDataArray
|
||
|
* vtkTemplateMacro vtkTypedDataArrayIterator
|
||
|
*/
|
||
|
|
||
|
#ifndef vtkDataArrayIteratorMacro_h
|
||
|
#define vtkDataArrayIteratorMacro_h
|
||
|
|
||
|
#ifndef VTK_LEGACY_REMOVE
|
||
|
|
||
|
#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 // legacy remove
|
||
|
|
||
|
#endif // vtkDataArrayIteratorMacro_h
|
||
|
|
||
|
// VTK-HeaderTest-Exclude: vtkDataArrayIteratorMacro.h
|