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 215 216 217 218 219 220 221 222 223 224 225 226 227 228
|
/*=========================================================================
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:
VTK_ABI_NAMESPACE_BEGIN
template <typename ValueType>
class vtkAOSDataArrayTemplate;
VTK_ABI_NAMESPACE_END
namespace vtk
{
VTK_ABI_NAMESPACE_BEGIN
// Typedef for data array indices:
using ComponentIdType = int;
using TupleIdType = vtkIdType;
using ValueIdType = vtkIdType;
VTK_ABI_NAMESPACE_END
namespace detail
{
VTK_ABI_NAMESPACE_BEGIN
//------------------------------------------------------------------------------
// 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;
};
VTK_ABI_NAMESPACE_END
} // end namespace detail
VTK_ABI_NAMESPACE_BEGIN
//------------------------------------------------------------------------------
// 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;
VTK_ABI_NAMESPACE_END
//------------------------------------------------------------------------------
namespace detail
{
VTK_ABI_NAMESPACE_BEGIN
template <typename ArrayType>
struct IsAOSDataArrayImpl
{
using APIType = GetAPIType<ArrayType>;
static constexpr bool value = std::is_base_of<vtkAOSDataArrayTemplate<APIType>, ArrayType>::value;
};
VTK_ABI_NAMESPACE_END
} // end namespace detail
VTK_ABI_NAMESPACE_BEGIN
//------------------------------------------------------------------------------
// True if ArrayType inherits some specialization of vtkAOSDataArrayTemplate
template <typename ArrayType>
using IsAOSDataArray = std::integral_constant<bool, detail::IsAOSDataArrayImpl<ArrayType>::value>;
VTK_ABI_NAMESPACE_END
} // end namespace vtk
VTK_ITER_OPTIMIZE_END
#endif // vtkDataArrayMeta_h
// VTK-HeaderTest-Exclude: vtkDataArrayMeta.h
|