MeVisLab Toolbox Reference
mlTSubImageVariant.h
Go to the documentation of this file.
1 /*************************************************************************************
2 **
3 ** Copyright 2022, MeVis Medical Solutions AG
4 **
5 ** The user may use this file in accordance with the license agreement provided with
6 ** the Software or, alternatively, in accordance with the terms contained in a
7 ** written agreement between the user and MeVis Medical Solutions AG.
8 **
9 ** For further information use the contact form at https://www.mevislab.de/contact
10 **
11 **************************************************************************************/
12 
13 #pragma once
14 
15 #include "mlInitSystemML.h"
16 #include "mlTSubImage.h"
17 
18 #include <variant>
19 #include <array>
20 
21 namespace ml
22 {
23 #ifndef DOXYGEN_SHOULD_SKIP_THIS
24  /*
25  * This logs to the MeVisLab console a fatal error that the input- and output types are different
26  */
27  void MLEXPORT logFatalErrorMessageNotEqualTypes(const char *function, const MLDataType &inputType,
28  const MLDataType &outputType);
29 
30  /*
31  * This logs to the MeVisLab console a fatal error that the given type is not supported
32  */
33  void MLEXPORT logFatalErrorMessageNotSupportedType(const char *function,
34  const MLDataType &inputType);
35 
36 
37  template <typename... T>
38  using TSubImageVariant = std::variant<TSubImage<T>...>;
39 
40  template <typename T> struct TSubImagePair
41  {
42  TSubImage<T> output;
43  TSubImage<T> input;
44  };
45 
46  template <typename... T>
47  using TSubImageVariantPair = std::variant<TSubImagePair<T>...>;
48 
49 
50  template <std::size_t N, typename T>
51  using TSubImageArray = std::array<TSubImage<T>, N>;
52 
53  template <std::size_t N, typename ...T>
54  using TSubImageVariantArray = std::variant<TSubImageArray<N, T>...>;
55 
56 
57  template <std::size_t N, typename T>
58  struct TSubImageArrayPair
59  {
60  TSubImage<T> output;
61  std::array<TSubImage<T>, N> inputs;
62  };
63 
64  template <std::size_t N, typename... T>
65  using TSubImageVariantArrayPair = std::variant<TSubImageArrayPair<N, T>...>;
66 
67 
68 
69  /*
70  * A set of internal helper function to generate different kind of TSubImageVariants
71  */
72 
73  namespace detail
74  {
75  // -----------------------------------------------------------------------------------------
76 
77  template <typename T>
78  auto createTSubImageVariantImpl(const SubImage* subImage)
79  {
80  logFatalErrorMessageNotSupportedType(__FUNCTION__, subImage->getDataType());
81  return T{};
82  }
83 
84  template <typename T, typename U, typename... V>
85  auto createTSubImageVariantImpl(const SubImage* subImage)
86  {
87  static_assert(!std::is_same_v<std::int8_t, U>, "The type std::int8_t/signed char is not supported by the "
88  "ML type system. Please use MLint8 instead!");
89  if (subImage->getDataType() == TypeTraits<U>::getDataType())
90  {
91  return T{TSubImage<U>(*subImage)};
92  }
93  return createTSubImageVariantImpl<T, V...>(subImage);
94  }
95 
96  // -----------------------------------------------------------------------------------------
97 
98  template <typename T, std::size_t... N>
99  auto createTSubImageArrayImpl(const SubImage *subImages, std::index_sequence<N...>)
100  {
101  return std::array<TSubImage<T>, sizeof...(N)>{TSubImage<T>(subImages[N])...};
102  }
103 
104  template <std::size_t N, typename T>
105  auto createTSubImageArray(const SubImage *inputs)
106  {
107  return TSubImageArray<N, T>{createTSubImageArrayImpl<T>(inputs, std::make_index_sequence<N>())};
108  }
109 
110  // -----------------------------------------------------------------------------------------
111 
112  template <std::size_t N, typename T>
113  auto createTSubImageArrayPair(SubImage &output, const SubImage *inputs)
114  {
115  return TSubImageArrayPair<N, T>{TSubImage<T>(output),
116  createTSubImageArrayImpl<T>(inputs, std::make_index_sequence<N>())};
117  }
118 
119  // -----------------------------------------------------------------------------------------
120 
121  template <typename T, std::size_t N>
122  auto createTSubImageVariantArrayImpl(const SubImage *inputs)
123  {
124  logFatalErrorMessageNotSupportedType(__FUNCTION__, inputs[0].getDataType());
125  return T{};
126  }
127 
128  template <typename T, std::size_t N, typename U, typename... V>
129  auto createTSubImageVariantArrayImpl(const SubImage *inputs)
130  {
131  static_assert(!std::is_same_v<std::int8_t, U>,
132  "The type std::int8_t/signed char is not supported by the "
133  "ML type system. Please use MLint8 instead!");
134 
135  if (inputs[0].getDataType() == TypeTraits<U>::getDataType())
136  {
137  return T{createTSubImageArray<N, U>(inputs)};
138  }
139  return createTSubImageVariantArrayImpl<T, N, V...>(inputs);
140  }
141 
142  // -----------------------------------------------------------------------------------------
143 
144  template <typename T, std::size_t N>
145  auto createTSubImageVariantArrayPairImpl(SubImage &output, const SubImage *inputs)
146  {
147  logFatalErrorMessageNotSupportedType(__FUNCTION__, output.getDataType());
148  return T{};
149  }
150 
151  template <typename T, std::size_t N, typename U, typename... V>
152  auto createTSubImageVariantArrayPairImpl(SubImage &output, const SubImage *inputs)
153  {
154  static_assert(!std::is_same_v<std::int8_t, U>, "The type std::int8_t/signed char is not supported by the "
155  "ML type system. Please use MLint8 instead!");
156 
157  if (output.getDataType() == TypeTraits<U>::getDataType())
158  {
159  return T{createTSubImageArrayPair<N, U>(output, inputs)};
160  }
161  return createTSubImageVariantArrayPairImpl<T, N, V...>(output, inputs);
162  }
163 
164  // -----------------------------------------------------------------------------------------
165 
166  template <typename T>
167  auto createTSubImageVariantPairImpl(SubImage &output, const SubImage*)
168  {
169  logFatalErrorMessageNotSupportedType(__FUNCTION__, output.getDataType());
170  return T{};
171  }
172 
173  template <typename T, typename U, typename... V>
174  auto createTSubImageVariantPairImpl(SubImage &output, const SubImage* input)
175  {
176  static_assert(!std::is_same_v<std::int8_t, U>,
177  "The type std::int8_t/signed char is not supported by the "
178  "ML type system. Please use MLint8 instead!");
179 
180  if (output.getDataType() == TypeTraits<U>::getDataType())
181  {
182  return T{TSubImagePair<U>{output, *input}};
183  }
184  return createTSubImageVariantPairImpl<T, V...>(output, input);
185  }
186  // -----------------------------------------------------------------------------------------
187  } // namespace detail
188 
189 
190  /* The following comprises a list of commonly used types.
191 
192  Don't make a preprocessor macros out of them, because many refactoring tools
193  cannot look through macros!
194 
195  List of supported integral types:
196  MLuint8, MLint8, MLuint16, MLint16, MLuint32, MLint32, MLuint64, MLint64
197 
198  List of supported scalar types.
199  MLuint8, MLint8, MLuint16, MLint16, MLuint32, MLint32, MLuint64, MLint64, MLfloat, MLdouble
200 
201  List of supported standard types
202  MLuint8, MLint8, MLuint16, MLint16, MLuint32, MLint32, MLuint64, MLint64,
203  MLfloat, MLdouble, std::complex<MLfloat>, std::complex<double>, Vector2f,
204  Vector2d, Vector3f, Vector3d, Vector6f, Vector6d, Matrix2f, Matrix2d, Matrix3f, Matrix3d
205 
206  */
207 
208 #endif // DOXYGEN_SHOULD_SKIP_THIS
209 
241  template <typename... T>
242  TSubImageVariant<T...> createTSubImageVariant(const SubImage* subImage)
243  {
244  return detail::createTSubImageVariantImpl<TSubImageVariant<T...>, T...>(subImage);
245  }
246 
247 
275  template <typename... T>
276  TSubImageVariantPair<T...> createTSubImageVariantPair(SubImage &output, const SubImage* input)
277  {
278  return detail::createTSubImageVariantPairImpl<TSubImageVariantPair<T...>, T...>(output, input);
279  }
280 
281 
315  template <std::size_t N, typename... T>
316  TSubImageVariantArray<N, T...> createTSubImageVariantArray(const SubImage* inputs)
317  {
318  return detail::createTSubImageVariantArrayImpl<TSubImageVariantArray<N, T...>, N, T...>(inputs);
319  }
320 
321 
354  template <std::size_t N, typename... T>
355  TSubImageVariantArrayPair<N, T...> createTSubImageVariantArrayPair(SubImage &output,
356  const SubImage *inputs)
357  {
358  TSubImageVariantArrayPair<N, T...> result;
359 
360  for (std::size_t i = 0; i < N; ++i)
361  {
362  if (output.getDataType() != inputs[i].getDataType())
363  {
364  logFatalErrorMessageNotEqualTypes(__FUNCTION__, inputs[0].getDataType(),
365  output.getDataType());
366  return result;
367  }
368  }
369 
370  result = detail::createTSubImageVariantArrayPairImpl<TSubImageVariantArrayPair<N, T...>, N, T...>(
371  output, inputs);
372 
373  return result;
374  }
375 
376 
377 } // namespace ml
@ T
Definition: SoKeyGrabber.h:71
@ V
Definition: SoKeyGrabber.h:73
@ N
Definition: SoKeyGrabber.h:65
@ U
Definition: SoKeyGrabber.h:72
This class manages/represents a rectangular 6d image region which is organized linearly in memory.
Definition: mlSubImage.h:75
MLDataType getDataType() const
Return type of image data.
Definition: mlSubImage.h:288
MLint32 MLDataType
MLDataType.
Definition: mlTypeDefs.h:684
#define MLEXPORT
To export symbols from a dll/shared object, we need to mark them with the MLEXPORT symbol.
Main documentation file for ML users and developers.
Definition: SoSFMLImage.h:51
TSubImageVariant< T... > createTSubImageVariant(const SubImage *subImage)
TSubImageVariantArrayPair< N, T... > createTSubImageVariantArrayPair(SubImage &output, const SubImage *inputs)
TSubImageVariantPair< T... > createTSubImageVariantPair(SubImage &output, const SubImage *input)
TSubImageVariantArray< N, T... > createTSubImageVariantArray(const SubImage *inputs)
static MLDataType getDataType()
Return the data type.
Definition: mlTypeTraits.h:75