1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkGenericDataArray.h
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 /**
16  * @class   vtkGenericDataArray
17  * @brief   Base interface for all typed vtkDataArray
18  * subclasses.
19  *
20  *
21  *
22  * A more detailed description of this class and related tools can be found
23  * \ref VTK-7-1-ArrayDispatch "here".
24  *
25  * The vtkGenericDataArray class provides a generic implementation of the
26  * vtkDataArray API. It relies on subclasses providing access to data
27  * via 8 "concept methods", which should be implemented as non-virtual
28  * methods of the subclass. These methods are:
29  *
30  * - ValueType GetValue(vtkIdType valueIdx) const
31  * - [public] void SetValue(vtkIdType valueIdx, ValueType value)
32  * - [public] void GetTypedTuple(vtkIdType tupleIdx, ValueType* tuple) const
33  * - [public] void SetTypedTuple(vtkIdType tupleIdx, const ValueType* tuple)
34  * - [public] ValueType GetTypedComponent(vtkIdType tupleIdx, int compIdx) const
35  * - [public] void SetTypedComponent(vtkIdType tupleIdx, int compIdx,
36  *                                   ValueType value)
37  * - [protected] bool AllocateTuples(vtkIdType numTuples)
38  * - [protected] bool ReallocateTuples(vtkIdType numTuples)
39  *
40  * Note that these methods use the CRTP idiom, which provides static binding to
41  * avoid virtual calls. This allows the compiler to optimize away layers of
42  * indirection when these methods are used. Well-designed implementations
43  * of these methods will reduce to raw memory accesses, providing efficient
44  * performance comparable to working with the pointer data.
45  *
46  * See vtkAOSDataArrayTemplate and vtkSOADataArrayTemplate for example
47  * implementations.
48  *
49  * In practice, code should not be written to use vtkGenericDataArray objects.
50  * Doing so is rather unweildy due to the CRTP pattern requiring the derived
51  * class be provided as a template argument. Instead, the vtkArrayDispatch
52  * framework can be used to detect a vtkDataArray's implementation type and
53  * instantiate appropriate templated worker code.
54  *
55  * vtkArrayDispatch is also intended to replace code that currently relies on
56  * the encapsulation-breaking GetVoidPointer method. Not all subclasses of
57  * vtkDataArray use the memory layout assumed by GetVoidPointer; calling this
58  * method on, e.g. a vtkSOADataArrayTemplate will trigger a deep copy of the
59  * array data into an AOS buffer. This is very inefficient and should be
60  * avoided.
61  *
62  * @sa
63  * vtkArrayDispatcher vtkDataArrayRange
64  */
65 
66 #ifndef vtkGenericDataArray_h
67 #define vtkGenericDataArray_h
68 
69 #include "vtkDataArray.h"
70 
71 #include "vtkCompiler.h" // for VTK_USE_EXTERN_TEMPLATE
72 #include "vtkGenericDataArrayLookupHelper.h"
73 #include "vtkSmartPointer.h"
74 #include "vtkTypeTraits.h"
75 
76 #include <cassert>
77 
78 template <class DerivedT, class ValueTypeT>
79 class vtkGenericDataArray : public vtkDataArray
80 {
81   typedef vtkGenericDataArray<DerivedT, ValueTypeT> SelfType;
82 
83 public:
84   typedef ValueTypeT ValueType;
85   vtkTemplateTypeMacro(SelfType, vtkDataArray);
86 
87   /**
88    * Compile time access to the VTK type identifier.
89    */
90   enum
91   {
92     VTK_DATA_TYPE = vtkTypeTraits<ValueType>::VTK_TYPE_ID
93   };
94 
95   /// @defgroup vtkGDAConceptMethods vtkGenericDataArray Concept Methods
96   /// These signatures must be reimplemented in subclasses as public,
97   /// non-virtual methods. Ideally, they should be inlined and as efficient as
98   /// possible to ensure the best performance possible.
99 
100   /**
101    * Get the value at @a valueIdx. @a valueIdx assumes AOS ordering.
102    * @note GetTypedComponent is preferred over this method. It is faster for
103    * SOA arrays, and shows equivalent performance for AOS arrays when
104    * NumberOfComponents is known to the compiler (See vtkAssume.h).
105    * @ingroup vtkGDAConceptMethods
106    */
GetValue(vtkIdType valueIdx)107   inline ValueType GetValue(vtkIdType valueIdx) const
108   {
109     return static_cast<const DerivedT*>(this)->GetValue(valueIdx);
110   }
111 
112   /**
113    * Set the value at @a valueIdx to @a value. @a valueIdx assumes AOS ordering.
114    * @note SetTypedComponent is preferred over this method. It is faster for
115    * SOA arrays, and shows equivalent performance for AOS arrays when
116    * NumberOfComponents is known to the compiler (See vtkAssume.h).
117    * @ingroup vtkGDAConceptMethods
118    */
SetValue(vtkIdType valueIdx,ValueType value)119   void SetValue(vtkIdType valueIdx, ValueType value)
120     VTK_EXPECTS(0 <= valueIdx && valueIdx < GetNumberOfValues())
121   {
122     static_cast<DerivedT*>(this)->SetValue(valueIdx, value);
123   }
124 
125   /**
126    * Copy the tuple at @a tupleIdx into @a tuple.
127    * @note GetTypedComponent is preferred over this method. The overhead of
128    * copying the tuple is significant compared to the more performant
129    * component-wise access methods, which typically optimize to raw memory
130    * access.
131    * @ingroup vtkGDAConceptMethods
132    */
GetTypedTuple(vtkIdType tupleIdx,ValueType * tuple)133   void GetTypedTuple(vtkIdType tupleIdx, ValueType* tuple) const
134     VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples())
135   {
136     static_cast<const DerivedT*>(this)->GetTypedTuple(tupleIdx, tuple);
137   }
138 
139   /**
140    * Set this array's tuple at @a tupleIdx to the values in @a tuple.
141    * @note SetTypedComponent is preferred over this method. The overhead of
142    * copying the tuple is significant compared to the more performant
143    * component-wise access methods, which typically optimize to raw memory
144    * access.
145    * @ingroup vtkGDAConceptMethods
146    */
SetTypedTuple(vtkIdType tupleIdx,const ValueType * tuple)147   void SetTypedTuple(vtkIdType tupleIdx, const ValueType* tuple)
148     VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples())
149   {
150     static_cast<DerivedT*>(this)->SetTypedTuple(tupleIdx, tuple);
151   }
152 
153   /**
154    * Get component @a compIdx of the tuple at @a tupleIdx. This is typically
155    * the fastest way to access array data.
156    * @ingroup vtkGDAConceptMethods
157    */
GetTypedComponent(vtkIdType tupleIdx,int compIdx)158   ValueType GetTypedComponent(vtkIdType tupleIdx, int compIdx) const VTK_EXPECTS(0 <= tupleIdx &&
159     tupleIdx < GetNumberOfTuples()) VTK_EXPECTS(0 <= compIdx && compIdx < GetNumberOfComponents())
160   {
161     return static_cast<const DerivedT*>(this)->GetTypedComponent(tupleIdx, compIdx);
162   }
163 
164   /**
165    * Set component @a compIdx of the tuple at @a tupleIdx to @a value. This is
166    * typically the fastest way to set array data.
167    * @ingroup vtkGDAConceptMethods
168    */
SetTypedComponent(vtkIdType tupleIdx,int compIdx,ValueType value)169   void SetTypedComponent(vtkIdType tupleIdx, int compIdx, ValueType value)
170     VTK_EXPECTS(0 <= tupleIdx && tupleIdx < GetNumberOfTuples())
171       VTK_EXPECTS(0 <= compIdx && compIdx < GetNumberOfComponents())
172   {
173     static_cast<DerivedT*>(this)->SetTypedComponent(tupleIdx, compIdx, value);
174   }
175 
176   ///@{
177   /**
178    * Default implementation raises a runtime error. If subclasses keep on
179    * supporting this API, they should override this method.
180    */
181   void* GetVoidPointer(vtkIdType valueIdx) override;
182   ValueType* GetPointer(vtkIdType valueIdx);
183   void SetVoidArray(void*, vtkIdType, int) override;
184   void SetVoidArray(void*, vtkIdType, int, int) override;
185   void SetArrayFreeFunction(void (*callback)(void*)) override;
186   void* WriteVoidPointer(vtkIdType valueIdx, vtkIdType numValues) override;
187   ValueType* WritePointer(vtkIdType valueIdx, vtkIdType numValues);
188   ///@}
189 
190   /**
191    * Removes a tuple at the given index. Default implementation
192    * iterates over tuples to move elements. Subclasses are
193    * encouraged to reimplemented this method to support faster implementations,
194    * if needed.
195    */
196   void RemoveTuple(vtkIdType tupleIdx) override;
197 
198   /**
199    * Insert data at the end of the array. Return its location in the array.
200    */
201   vtkIdType InsertNextValue(ValueType value);
202 
203   /**
204    * Insert data at a specified position in the array.
205    */
206   void InsertValue(vtkIdType valueIdx, ValueType value);
207 
208   /**
209    * Insert (memory allocation performed) the tuple t at tupleIdx.
210    */
211   void InsertTypedTuple(vtkIdType tupleIdx, const ValueType* t);
212 
213   /**
214    * Insert (memory allocation performed) the tuple onto the end of the array.
215    */
216   vtkIdType InsertNextTypedTuple(const ValueType* t);
217 
218   /**
219    * Insert (memory allocation performed) the value at the specified tuple and
220    * component location.
221    */
222   void InsertTypedComponent(vtkIdType tupleIdx, int compIdx, ValueType val);
223 
224   ///@{
225   /**
226    * Get the range of array values for the given component in the
227    * native data type.
228    */
229   void GetValueRange(ValueType range[2], int comp);
230   ValueType* GetValueRange(int comp) VTK_SIZEHINT(2);
231   ///@}
232 
233   /**
234    * Get the range of array values for the 0th component in the
235    * native data type.
236    */
GetValueRange()237   ValueType* GetValueRange() VTK_SIZEHINT(2) { return this->GetValueRange(0); }
GetValueRange(ValueType range[2])238   void GetValueRange(ValueType range[2]) { this->GetValueRange(range, 0); }
239 
240   /**
241    * These methods are analogous to the GetValueRange methods, except that the
242    * only consider finite values.
243    * @{
244    */
245   void GetFiniteValueRange(ValueType range[2], int comp);
246   ValueType* GetFiniteValueRange(int comp) VTK_SIZEHINT(2);
GetFiniteValueRange()247   ValueType* GetFiniteValueRange() VTK_SIZEHINT(2) { return this->GetFiniteValueRange(0); }
GetFiniteValueRange(ValueType range[2])248   void GetFiniteValueRange(ValueType range[2]) { this->GetFiniteValueRange(range, 0); }
249   /**@}*/
250 
251   /**
252    * Return the capacity in typeof T units of the current array.
253    * TODO Leftover from vtkDataArrayTemplate, redundant with GetSize. Deprecate?
254    */
Capacity()255   vtkIdType Capacity() { return this->Size; }
256 
257   /**
258    * Set component @a comp of all tuples to @a value.
259    */
260   virtual void FillTypedComponent(int compIdx, ValueType value);
261 
262   /**
263    * Set all the values in array to @a value.
264    */
265   virtual void FillValue(ValueType value);
266 
267   int GetDataType() const override;
268   int GetDataTypeSize() const override;
269   bool HasStandardMemoryLayout() const override;
270   vtkTypeBool Allocate(vtkIdType size, vtkIdType ext = 1000) override;
271   vtkTypeBool Resize(vtkIdType numTuples) override;
272   void SetNumberOfComponents(int num) override;
273   void SetNumberOfTuples(vtkIdType number) override;
274   void Initialize() override;
275   void Squeeze() override;
276   void SetTuple(vtkIdType dstTupleIdx, vtkIdType srcTupleIdx, vtkAbstractArray* source) override;
277   // MSVC doesn't like 'using' here (error C2487). Just forward instead:
278   // using Superclass::SetTuple;
SetTuple(vtkIdType tupleIdx,const float * tuple)279   void SetTuple(vtkIdType tupleIdx, const float* tuple) override
280   {
281     this->Superclass::SetTuple(tupleIdx, tuple);
282   }
SetTuple(vtkIdType tupleIdx,const double * tuple)283   void SetTuple(vtkIdType tupleIdx, const double* tuple) override
284   {
285     this->Superclass::SetTuple(tupleIdx, tuple);
286   }
287 
288   void InsertTuples(vtkIdList* dstIds, vtkIdList* srcIds, vtkAbstractArray* source) override;
289   // MSVC doesn't like 'using' here (error C2487). Just forward instead:
290   // using Superclass::InsertTuples;
InsertTuples(vtkIdType dstStart,vtkIdType n,vtkIdType srcStart,vtkAbstractArray * source)291   void InsertTuples(
292     vtkIdType dstStart, vtkIdType n, vtkIdType srcStart, vtkAbstractArray* source) override
293   {
294     this->Superclass::InsertTuples(dstStart, n, srcStart, source);
295   }
296 
297   void InsertTuple(vtkIdType dstTupleIdx, vtkIdType srcTupleIdx, vtkAbstractArray* source) override;
298   void InsertTuple(vtkIdType tupleIdx, const float* source) override;
299   void InsertTuple(vtkIdType tupleIdx, const double* source) override;
300   void InsertComponent(vtkIdType tupleIdx, int compIdx, double value) override;
301   vtkIdType InsertNextTuple(vtkIdType srcTupleIdx, vtkAbstractArray* source) override;
302   vtkIdType InsertNextTuple(const float* tuple) override;
303   vtkIdType InsertNextTuple(const double* tuple) override;
304   void GetTuples(vtkIdList* tupleIds, vtkAbstractArray* output) override;
305   void GetTuples(vtkIdType p1, vtkIdType p2, vtkAbstractArray* output) override;
306   double* GetTuple(vtkIdType tupleIdx) override;
307   void GetTuple(vtkIdType tupleIdx, double* tuple) override;
308   void InterpolateTuple(vtkIdType dstTupleIdx, vtkIdList* ptIndices, vtkAbstractArray* source,
309     double* weights) override;
310   void InterpolateTuple(vtkIdType dstTupleIdx, vtkIdType srcTupleIdx1, vtkAbstractArray* source1,
311     vtkIdType srcTupleIdx2, vtkAbstractArray* source2, double t) override;
312   void SetComponent(vtkIdType tupleIdx, int compIdx, double value) override;
313   double GetComponent(vtkIdType tupleIdx, int compIdx) override;
314   void SetVariantValue(vtkIdType valueIdx, vtkVariant value) override;
315   vtkVariant GetVariantValue(vtkIdType valueIdx) override;
316   void InsertVariantValue(vtkIdType valueIdx, vtkVariant value) override;
317   vtkIdType LookupValue(vtkVariant value) override;
318   virtual vtkIdType LookupTypedValue(ValueType value);
319   void LookupValue(vtkVariant value, vtkIdList* valueIds) override;
320   virtual void LookupTypedValue(ValueType value, vtkIdList* valueIds);
321   void ClearLookup() override;
322   void DataChanged() override;
323   void FillComponent(int compIdx, double value) override;
324   VTK_NEWINSTANCE vtkArrayIterator* NewIterator() override;
325 
326 protected:
327   vtkGenericDataArray();
328   ~vtkGenericDataArray() override;
329 
330   /**
331    * Allocate space for numTuples. Old data is not preserved. If numTuples == 0,
332    * all data is freed.
333    * @ingroup vtkGDAConceptMethods
334    */
AllocateTuples(vtkIdType numTuples)335   inline bool AllocateTuples(vtkIdType numTuples)
336   {
337     return static_cast<DerivedT*>(this)->AllocateTuples(numTuples);
338   }
339 
340   /**
341    * Allocate space for numTuples. Old data is preserved. If numTuples == 0,
342    * all data is freed.
343    * @ingroup vtkGDAConceptMethods
344    */
ReallocateTuples(vtkIdType numTuples)345   inline bool ReallocateTuples(vtkIdType numTuples)
346   {
347     return static_cast<DerivedT*>(this)->ReallocateTuples(numTuples);
348   }
349 
350   // This method resizes the array if needed so that the given tuple index is
351   // valid/accessible.
352   bool EnsureAccessToTuple(vtkIdType tupleIdx);
353 
354   /**
355    * Compute the range for a specific component. If comp is set -1
356    * then L2 norm is computed on all components. Call ClearRange
357    * to force a recomputation if it is needed. The range is copied
358    * to the range argument.
359    * THIS METHOD IS NOT THREAD SAFE.
360    */
361   void ComputeValueRange(ValueType range[2], int comp);
362 
363   /**
364    * Compute the range for a specific component. If comp is set -1
365    * then L2 norm is computed on all components. Call ClearRange
366    * to force a recomputation if it is needed. The range is copied
367    * to the range argument.
368    * THIS METHOD IS NOT THREAD SAFE.
369    */
370   void ComputeFiniteValueRange(ValueType range[2], int comp);
371 
372   /**
373    * Computes the range for each component of an array, the length
374    * of \a ranges must be two times the number of components.
375    * Returns true if the range was computed. Will return false
376    * if you try to compute the range of an array of length zero.
377    */
378   bool ComputeScalarValueRange(ValueType* ranges);
379 
380   /**
381    * Returns true if the range was computed. Will return false
382    * if you try to compute the range of an array of length zero.
383    */
384   bool ComputeVectorValueRange(ValueType range[2]);
385 
386   /**
387    * Computes the range for each component of an array, the length
388    * of \a ranges must be two times the number of components.
389    * Returns true if the range was computed. Will return false
390    * if you try to compute the range of an array of length zero.
391    */
392   bool ComputeFiniteScalarValueRange(ValueType* ranges);
393 
394   /**
395    * Returns true if the range was computed. Will return false
396    * if you try to compute the range of an array of length zero.
397    */
398   bool ComputeFiniteVectorValueRange(ValueType range[2]);
399 
400   std::vector<double> LegacyTuple;
401   std::vector<ValueType> LegacyValueRange;
402   std::vector<ValueType> LegacyValueRangeFull;
403 
404   vtkGenericDataArrayLookupHelper<SelfType> Lookup;
405 
406 private:
407   vtkGenericDataArray(const vtkGenericDataArray&) = delete;
408   void operator=(const vtkGenericDataArray&) = delete;
409 };
410 
411 // these predeclarations are needed before the .txx include for MinGW
412 namespace vtkDataArrayPrivate
413 {
414 template <typename A, typename R, typename T>
415 bool DoComputeScalarRange(A*, R*, T);
416 template <typename A, typename R>
417 bool DoComputeVectorRange(A*, R[2], AllValues);
418 template <typename A, typename R>
419 bool DoComputeVectorRange(A*, R[2], FiniteValues);
420 } // namespace vtkDataArrayPrivate
421 
422 #include "vtkGenericDataArray.txx"
423 
424 // Adds an implementation of NewInstanceInternal() that returns an AoS
425 // (unmapped) VTK array, if possible. This allows the pipeline to copy and
426 // propagate the array when the array data is not modifiable. Use this in
427 // combination with vtkAbstractTypeMacro or vtkAbstractTemplateTypeMacro
428 // (instead of vtkTypeMacro) to avoid adding the default NewInstance
429 // implementation.
430 #define vtkAOSArrayNewInstanceMacro(thisClass)                                                     \
431 protected:                                                                                         \
432   vtkObjectBase* NewInstanceInternal() const override                                              \
433   {                                                                                                \
434     if (vtkDataArray* da = vtkDataArray::CreateDataArray(thisClass::VTK_DATA_TYPE))                \
435     {                                                                                              \
436       return da;                                                                                   \
437     }                                                                                              \
438     return thisClass::New();                                                                       \
439   }                                                                                                \
440                                                                                                    \
441 public:
442 
443 #endif
444 
445 // This portion must be OUTSIDE the include blockers. This is used to tell
446 // libraries other than vtkCommonCore that instantiations of
447 // the GetValueRange lookups can be found externally. This prevents each library
448 // from instantiating these on their own.
449 // Additionally it helps hide implementation details that pull in system
450 // headers.
451 // We only provide these specializations for the 64-bit integer types, since
452 // other types can reuse the double-precision mechanism in
453 // vtkDataArray::GetRange without losing precision.
454 #ifdef VTK_GDA_VALUERANGE_INSTANTIATING
455 
456 // Forward declare necessary stuffs:
457 template <typename ValueType>
458 class vtkAOSDataArrayTemplate;
459 template <typename ValueType>
460 class vtkSOADataArrayTemplate;
461 
462 #ifdef VTK_USE_SCALED_SOA_ARRAYS
463 template <typename ValueType>
464 class vtkScaledSOADataArrayTemplate;
465 #endif
466 
467 #define VTK_INSTANTIATE_VALUERANGE_ARRAYTYPE(ArrayType, ValueType)                                 \
468   template VTKCOMMONCORE_EXPORT bool DoComputeScalarRange(                                         \
469     ArrayType*, ValueType*, vtkDataArrayPrivate::AllValues);                                       \
470   template VTKCOMMONCORE_EXPORT bool DoComputeScalarRange(                                         \
471     ArrayType*, ValueType*, vtkDataArrayPrivate::FiniteValues);                                    \
472   template VTKCOMMONCORE_EXPORT bool DoComputeVectorRange(                                         \
473     ArrayType*, ValueType[2], vtkDataArrayPrivate::AllValues);                                     \
474   template VTKCOMMONCORE_EXPORT bool DoComputeVectorRange(                                         \
475     ArrayType*, ValueType[2], vtkDataArrayPrivate::FiniteValues);
476 
477 #ifdef VTK_USE_SCALED_SOA_ARRAYS
478 
479 #define VTK_INSTANTIATE_VALUERANGE_VALUETYPE(ValueType)                                            \
480   VTK_INSTANTIATE_VALUERANGE_ARRAYTYPE(vtkAOSDataArrayTemplate<ValueType>, ValueType)              \
481   VTK_INSTANTIATE_VALUERANGE_ARRAYTYPE(vtkSOADataArrayTemplate<ValueType>, ValueType)              \
482   VTK_INSTANTIATE_VALUERANGE_ARRAYTYPE(vtkScaledSOADataArrayTemplate<ValueType>, ValueType)
483 
484 #else // VTK_USE_SCALED_SOA_ARRAYS
485 
486 #define VTK_INSTANTIATE_VALUERANGE_VALUETYPE(ValueType)                                            \
487   VTK_INSTANTIATE_VALUERANGE_ARRAYTYPE(vtkAOSDataArrayTemplate<ValueType>, ValueType)              \
488   VTK_INSTANTIATE_VALUERANGE_ARRAYTYPE(vtkSOADataArrayTemplate<ValueType>, ValueType)
489 
490 #endif
491 
492 #elif defined(VTK_USE_EXTERN_TEMPLATE) // VTK_GDA_VALUERANGE_INSTANTIATING
493 
494 #ifndef VTK_GDA_TEMPLATE_EXTERN
495 #define VTK_GDA_TEMPLATE_EXTERN
496 #ifdef _MSC_VER
497 #pragma warning(push)
498 // The following is needed when the following is declared
499 // dllexport and is used from another class in vtkCommonCore
500 #pragma warning(disable : 4910) // extern and dllexport incompatible
501 #endif
502 
503 // Forward declare necessary stuffs:
504 template <typename ValueType>
505 class vtkAOSDataArrayTemplate;
506 template <typename ValueType>
507 class vtkSOADataArrayTemplate;
508 
509 #ifdef VTK_USE_SCALED_SOA_ARRAYS
510 template <typename ValueType>
511 class vtkScaledSOADataArrayTemplate;
512 #endif
513 
514 namespace vtkDataArrayPrivate
515 {
516 template <typename A, typename R, typename T>
517 bool DoComputeScalarRange(A*, R*, T);
518 template <typename A, typename R>
519 bool DoComputeVectorRange(A*, R[2], AllValues);
520 template <typename A, typename R>
521 bool DoComputeVectorRange(A*, R[2], FiniteValues);
522 } // namespace vtkDataArrayPrivate
523 
524 #define VTK_DECLARE_VALUERANGE_ARRAYTYPE(ArrayType, ValueType)                                     \
525   extern template VTKCOMMONCORE_EXPORT bool DoComputeScalarRange(                                  \
526     ArrayType*, ValueType*, vtkDataArrayPrivate::AllValues);                                       \
527   extern template VTKCOMMONCORE_EXPORT bool DoComputeScalarRange(                                  \
528     ArrayType*, ValueType*, vtkDataArrayPrivate::FiniteValues);                                    \
529   extern template VTKCOMMONCORE_EXPORT bool DoComputeVectorRange(                                  \
530     ArrayType*, ValueType[2], vtkDataArrayPrivate::AllValues);                                     \
531   extern template VTKCOMMONCORE_EXPORT bool DoComputeVectorRange(                                  \
532     ArrayType*, ValueType[2], vtkDataArrayPrivate::FiniteValues);
533 
534 #ifdef VTK_USE_SCALED_SOA_ARRAYS
535 
536 #define VTK_DECLARE_VALUERANGE_VALUETYPE(ValueType)                                                \
537   VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkAOSDataArrayTemplate<ValueType>, ValueType)                  \
538   VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkSOADataArrayTemplate<ValueType>, ValueType)                  \
539   VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkScaledSOADataArrayTemplate<ValueType>, ValueType)
540 
541 #else // VTK_USE_SCALED_SOA_ARRAYS
542 
543 #define VTK_DECLARE_VALUERANGE_VALUETYPE(ValueType)                                                \
544   VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkAOSDataArrayTemplate<ValueType>, ValueType)                  \
545   VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkSOADataArrayTemplate<ValueType>, ValueType)
546 
547 #endif
548 
549 namespace vtkDataArrayPrivate
550 {
551 // These are instantiated in vtkGenericDataArrayValueRange${i}.cxx
552 VTK_DECLARE_VALUERANGE_VALUETYPE(long)
553 VTK_DECLARE_VALUERANGE_VALUETYPE(unsigned long)
554 VTK_DECLARE_VALUERANGE_VALUETYPE(long long)
555 VTK_DECLARE_VALUERANGE_VALUETYPE(unsigned long long)
556 
557 // This is instantiated in vtkGenericDataArray.cxx
558 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkDataArray, double)
559 
560 // These are instantiated in vtkFloatArray.cxx, vtkDoubleArray.cxx, etc
561 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkAOSDataArrayTemplate<float>, double)
562 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkAOSDataArrayTemplate<double>, double)
563 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkAOSDataArrayTemplate<char>, double)
564 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkAOSDataArrayTemplate<signed char>, double)
565 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkAOSDataArrayTemplate<unsigned char>, double)
566 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkAOSDataArrayTemplate<short>, double)
567 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkAOSDataArrayTemplate<unsigned short>, double)
568 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkAOSDataArrayTemplate<int>, double)
569 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkAOSDataArrayTemplate<unsigned int>, double)
570 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkAOSDataArrayTemplate<long>, double)
571 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkAOSDataArrayTemplate<unsigned long>, double)
572 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkAOSDataArrayTemplate<long long>, double)
573 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkAOSDataArrayTemplate<unsigned long long>, double)
574 
575 // These are instantiated in vtkSOADataArrayTemplateInstantiate${i}.cxx
576 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkSOADataArrayTemplate<float>, double)
577 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkSOADataArrayTemplate<double>, double)
578 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkSOADataArrayTemplate<char>, double)
579 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkSOADataArrayTemplate<signed char>, double)
580 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkSOADataArrayTemplate<unsigned char>, double)
581 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkSOADataArrayTemplate<short>, double)
582 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkSOADataArrayTemplate<unsigned short>, double)
583 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkSOADataArrayTemplate<int>, double)
584 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkSOADataArrayTemplate<unsigned int>, double)
585 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkSOADataArrayTemplate<long>, double)
586 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkSOADataArrayTemplate<unsigned long>, double)
587 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkSOADataArrayTemplate<long long>, double)
588 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkSOADataArrayTemplate<unsigned long long>, double)
589 
590 // These are instantiated in vtkScaledSOADataArrayTemplateInstantiate${i}.cxx
591 #ifdef VTK_USE_SCALED_SOA_ARRAYS
592 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkScaledSOADataArrayTemplate<float>, double)
593 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkScaledSOADataArrayTemplate<double>, double)
594 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkScaledSOADataArrayTemplate<char>, double)
595 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkScaledSOADataArrayTemplate<signed char>, double)
596 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkScaledSOADataArrayTemplate<unsigned char>, double)
597 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkScaledSOADataArrayTemplate<short>, double)
598 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkScaledSOADataArrayTemplate<unsigned short>, double)
599 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkScaledSOADataArrayTemplate<int>, double)
600 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkScaledSOADataArrayTemplate<unsigned int>, double)
601 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkScaledSOADataArrayTemplate<long>, double)
602 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkScaledSOADataArrayTemplate<unsigned long>, double)
603 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkScaledSOADataArrayTemplate<long long>, double)
604 VTK_DECLARE_VALUERANGE_ARRAYTYPE(vtkScaledSOADataArrayTemplate<unsigned long long>, double)
605 #endif // VTK_USE_SCALED_SOA_ARRAYS
606 
607 } // namespace vtkDataArrayPrivate
608 
609 #undef VTK_DECLARE_VALUERANGE_ARRAYTYPE
610 #undef VTK_DECLARE_VALUERANGE_VALUETYPE
611 
612 #ifdef _MSC_VER
613 #pragma warning(pop)
614 #endif
615 #endif // VTK_SOA_DATA_ARRAY_TEMPLATE_EXTERN
616 
617 #endif // VTK_GDA_VALUERANGE_INSTANTIATING
618 
619 // VTK-HeaderTest-Exclude: vtkGenericDataArray.h
620