SimpleITK  
sitkTemplateFunctions.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18#ifndef sitkTemplateFunctions_h
19#define sitkTemplateFunctions_h
20
21#include "sitkMacro.h"
22#include "sitkCommon.h"
23#include "sitkExceptionObject.h"
24
25#include <vector>
26#include <ostream>
27#include <iterator>
28#include <utility>
29
30namespace itk
31{
32
33template <unsigned int VImageDimension>
34class ImageRegion;
35template <typename T>
36class Versor;
37
38namespace simple
39{
40
46template <typename T>
48Unused(const T &) {};
49
57template <typename T>
58SITKCommon_HIDDEN std::ostream &
59 operator<<(std::ostream & os, const std::vector<T> & v)
60{
61 if (v.empty())
62 {
63 return os << "[ ]";
64 }
65
66 os << "[ ";
67 std::copy(v.begin(), v.end() - 1, std::ostream_iterator<T>(os, ", "));
68 return os << v.back() << " ]";
69}
70
71template <typename TITKPointVector, typename TType>
72TITKPointVector SITKCommon_HIDDEN
73sitkSTLVectorToITKPointVector(const std::vector<TType> & in)
74{
75
76 using itkPointVectorType = TITKPointVector;
77 itkPointVectorType out;
78
79 unsigned int Dimension = itkPointVectorType::value_type::GetPointDimension();
80
81 for (unsigned int i = 0; i + Dimension <= in.size(); i += Dimension)
82 {
83 typename itkPointVectorType::value_type pt(&in[i]);
84 out.push_back(pt);
85 }
86 return out;
87}
88
95template <typename TITKVector, typename TType>
96TITKVector SITKCommon_HIDDEN
97sitkSTLVectorToITK(const std::vector<TType> & in)
98{
99 using itkVectorType = TITKVector;
100 if (in.size() < itkVectorType::Dimension)
101 {
102 sitkExceptionMacro(<< "Unable to convert vector to ITK type\n"
103 << "Expected vector of length " << itkVectorType::Dimension << " but only got " << in.size()
104 << " elements.");
105 }
106 itkVectorType out;
107 for (unsigned int i = 0; i < itkVectorType::Dimension; ++i)
108 {
109 out[i] = in[i];
110 }
111 return out;
112}
113
116template <typename TType, typename TITKVector>
117std::vector<TType> SITKCommon_HIDDEN
118sitkITKVectorToSTL(const TITKVector & in)
119{
120 std::vector<TType> out(TITKVector::Dimension);
121 for (unsigned int i = 0; i < TITKVector::Dimension; ++i)
122 {
123 out[i] = static_cast<TType>(in[i]);
124 }
125 return out;
126}
127
132template <typename TType, typename TVectorOfITKVector>
133std::vector<TType> SITKCommon_HIDDEN
134sitkVectorOfITKVectorToSTL(const TVectorOfITKVector & in)
135{
136 using ITKVectorType = typename std::iterator_traits<decltype(std::begin(in))>::value_type;
137 std::vector<TType> out;
138 out.reserve(in.Size() * ITKVectorType::Dimension);
139 for (const auto & v : in)
140 {
141 out.insert(out.end(), v.begin(), v.end());
142 }
143 return out;
144}
145
146
147template <typename TType, typename TITKVector>
148std::vector<TType> SITKCommon_HIDDEN
149sitkITKVectorToSTL(const std::vector<TITKVector> & in)
150{
151 std::vector<TType> out;
152 out.reserve(in.size() * TITKVector::Dimension);
153 typename std::vector<TITKVector>::const_iterator iter = in.begin();
154 while (iter != in.end())
155 {
156 for (unsigned int i = 0; i < TITKVector::Dimension; ++i)
157 {
158 out.push_back(static_cast<TType>((*iter)[i]));
159 }
160 ++iter;
161 }
162
163 return out;
164}
165
169template <unsigned int VImageDimension>
170std::vector<unsigned int> SITKCommon_HIDDEN
172{
173 std::vector<unsigned int> out(VImageDimension * 2);
174 for (unsigned int i = 0; i < VImageDimension; ++i)
175 {
176 out[i] = static_cast<unsigned int>(in.GetIndex(i));
177 out[VImageDimension + i] = static_cast<unsigned int>(in.GetSize(i));
178 }
179 return out;
180}
181
182
183/* \brief Convert to an itk::Matrix type, where the vector is in row
184 * major form. If the vector is of 0-size then an identity matrix will
185 * be constructed.
186 */
187template <typename TDirectionType>
188TDirectionType SITKCommon_HIDDEN
189sitkSTLToITKDirection(const std::vector<double> & direction)
190{
191 TDirectionType itkDirection;
192
193 if (direction.empty())
194 {
195 itkDirection.SetIdentity();
196 }
197 else if (direction.size() == TDirectionType::RowDimensions * TDirectionType::ColumnDimensions)
198 {
199 std::copy(direction.begin(), direction.end(), itkDirection.GetVnlMatrix().begin());
200 }
201 else
202 {
203 sitkExceptionMacro(<< "Length of input (" << direction.size() << ") does not match matrix dimensions ("
204 << TDirectionType::RowDimensions << ", " << TDirectionType::ColumnDimensions << ").\n");
205 }
206 return itkDirection;
207}
208
209
210template <typename TDirectionType>
211std::vector<double> SITKCommon_HIDDEN
212sitkITKDirectionToSTL(const TDirectionType & d)
213{
214 return std::vector<double>(d.GetVnlMatrix().begin(), d.GetVnlMatrix().end());
215}
216
217
218template <typename T, typename TType>
220sitkSTLVectorToITKVersor(const std::vector<TType> & in)
221{
222 using itkVectorType = itk::Versor<T>;
223 if (in.size() != 4)
224 {
225 sitkExceptionMacro(<< "Unable to convert vector to ITK Versor type\n"
226 << "Expected vector of length " << 4 << " but got " << in.size() << " elements.");
227 }
228 itkVectorType out;
229 out.Set(in[0], in[1], in[2], in[3]);
230 return out;
231}
232
233
234template <typename TType, typename T>
235std::vector<TType> SITKCommon_HIDDEN
237{
238 std::vector<TType> out(4);
239 out[0] = in.GetX();
240 out[1] = in.GetY();
241 out[2] = in.GetZ();
242 out[3] = in.GetW();
243 return out;
244}
245
246// Based on p0052r8 : Generic Scope Guard and RAII Wrapper for the
247// Standard Library
248// by Peter Sommerlad and Andrew L. Sandoval
249template <typename F>
251{
252 F f_;
253 bool run_;
254 explicit scope_exit(F f) noexcept
255 : f_(std::move(f))
256 , run_(true)
257 {}
258 scope_exit(scope_exit && rhs) noexcept
259 : f_((rhs.run_ = false, std::move(rhs.f_)))
260 , run_(true)
261 {}
263 {
264 if (run_)
265 f_();
266 }
267
268 scope_exit &
269 operator=(scope_exit && rhs) = delete;
270 scope_exit(const scope_exit &) = delete;
271 scope_exit &
272 operator=(const scope_exit &) = delete;
273};
274
275template <typename F>
277make_scope_exit(F && f) noexcept
278{
279 return scope_exit<F>{ std::forward<F>(f) };
280}
281
282namespace detail
283{
284
285template <typename T, T Offset, T... Is>
287{
288 using type = std::integer_sequence<T, Offset + Is...>;
289};
290} // namespace detail
291
292template <unsigned int Start, unsigned int Stop>
295 Start,
296 std::make_integer_sequence<unsigned int, Stop - Start + 1>::type>;
297
298} // namespace simple
299} // namespace itk
300
301#endif
const IndexType & GetIndex() const
const SizeType & GetSize() const
ValueType GetZ() const
ValueType GetY() const
void Set(const MatrixType &mat)
ValueType GetW() const
ValueType GetX() const
std::vector< TType > SITKCommon_HIDDEN sitkVectorOfITKVectorToSTL(const TVectorOfITKVector &in)
Convert an ITK style array of ITK fixed width vector to std::vector.
std::vector< TType > SITKCommon_HIDDEN sitkITKVectorToSTL(const TITKVector &in)
Convert an ITK fixed width vector to a std::vector.
SITKCommon_EXPORT std::ostream & operator<<(std::ostream &os, const EventEnum k)
TITKVector SITKCommon_HIDDEN sitkSTLVectorToITK(const std::vector< TType > &in)
Copy the elements of an std::vector into an ITK fixed width vector.
detail::make_offset_integer_sequence_helper< unsigned int, Start, std::make_integer_sequence< unsigned int, Stop - Start+1 >::type > make_dimension_sequence
scope_exit< F > make_scope_exit(F &&f) noexcept
std::vector< unsigned int > SITKCommon_HIDDEN sitkITKImageRegionToSTL(const ImageRegion< VImageDimension > &in)
Convert an ITK ImageRegion to and std::vector with the first part being the start index followed by t...
std::vector< TType > SITKCommon_HIDDEN sitkITKVersorToSTL(const itk::Versor< T > &in)
void SITKCommon_HIDDEN Unused(const T &)
A function which does nothing.
std::vector< double > SITKCommon_HIDDEN sitkITKDirectionToSTL(const TDirectionType &d)
TDirectionType SITKCommon_HIDDEN sitkSTLToITKDirection(const std::vector< double > &direction)
itk::Versor< T > SITKCommon_HIDDEN sitkSTLVectorToITKVersor(const std::vector< TType > &in)
TITKPointVector SITKCommon_HIDDEN sitkSTLVectorToITKPointVector(const std::vector< TType > &in)
#define SITKCommon_HIDDEN
Definition sitkCommon.h:44
#define sitkExceptionMacro(x)
Definition sitkMacro.h:65
scope_exit & operator=(scope_exit &&rhs)=delete
scope_exit(const scope_exit &)=delete
scope_exit & operator=(const scope_exit &)=delete
scope_exit(scope_exit &&rhs) noexcept