/*========================================================================= 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 "vtkConfigure.h" #include "vtkDataArray.h" #include "vtkMeta.h" #include "vtkSetGet.h" #include "vtkType.h" #include #include /** * @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 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 struct IsVtkDataArray : std::is_base_of { }; template using EnableIfVtkDataArray = typename std::enable_if::value>::type; //------------------------------------------------------------------------------ // If a value is a valid tuple size template struct IsValidTupleSize : std::integral_constant 0 || Size == DynamicTupleSize)> { }; template using EnableIfValidTupleSize = typename std::enable_if::value>::type; //------------------------------------------------------------------------------ // If a value is a non-dynamic tuple size template struct IsStaticTupleSize : std::integral_constant 0)> { }; template using EnableIfStaticTupleSize = typename std::enable_if::value>::type; //------------------------------------------------------------------------------ // If two values are valid non-dynamic tuple sizes: template struct AreStaticTupleSizes : std::integral_constant::value && IsStaticTupleSize::value)> { }; template using EnableIfStaticTupleSizes = typename std::enable_if::value, T>::type; //------------------------------------------------------------------------------ // If either of the tuple sizes is not statically defined template struct IsEitherTupleSizeDynamic : std::integral_constant::value || !IsStaticTupleSize::value)> { }; template using EnableIfEitherTupleSizeIsDynamic = typename std::enable_if::value, T>::type; //------------------------------------------------------------------------------ // Helper that switches between a storageless integral constant for known // sizes, and a runtime variable for variable sizes. template struct GenericTupleSize : public std::integral_constant { static_assert(IsValidTupleSize::value, "Invalid tuple size."); private: using Superclass = std::integral_constant; 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 { 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 struct GetAPITypeImpl { using APIType = typename ArrayType::ValueType; }; template <> struct GetAPITypeImpl { using APIType = double; }; } // end namespace detail //------------------------------------------------------------------------------ // Typedef for double if vtkDataArray, or the array's ValueType for subclasses. template > using GetAPIType = typename detail::GetAPITypeImpl::APIType; //------------------------------------------------------------------------------ namespace detail { template struct IsAOSDataArrayImpl { using APIType = GetAPIType; static constexpr bool value = std::is_base_of, ArrayType>::value; }; } // end namespace detail //------------------------------------------------------------------------------ // True if ArrayType inherits some specialization of vtkAOSDataArrayTemplate template using IsAOSDataArray = std::integral_constant::value>; } // end namespace vtk VTK_ITER_OPTIMIZE_END #endif // vtkDataArrayMeta_h // VTK-HeaderTest-Exclude: vtkDataArrayMeta.h