OTB  6.7.0
Orfeo Toolbox
otbVariadicConcatenateFunctor.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otb_VariadicConcatenateFunctor_h
22 #define otb_VariadicConcatenateFunctor_h
23 
25 #include <vector>
26 #include <numeric>
27 #include <array>
28 
29 namespace otb
30 {
31 
32 namespace Functor
33 {
34 
35 
36 namespace variadic_concatenate_details
37 {
38 
39 template <typename T> size_t NumberOfElements(const T &)
40 {
41  static_assert(std::is_scalar<T>::value,"variadic_concatenate_details::NumberOfElements<T> only works for T and itk::VariableLengthVector<T> where T is a scalar type.");
42  return 1;
43 }
44 
45 template <typename T> size_t NumberOfElements(const itk::VariableLengthVector<T> & v)
46 {
47  static_assert(std::is_scalar<T>::value,"variadic_concatenate_details::NumberOfElements<T> only works for T and itk::VariableLengthVector<T> where T is a scalar type.");
48  return v.GetSize();
49 }
50 
51 template <typename ...T> size_t NumberOfElements(const T&...t)
52 {
53  std::array<size_t,sizeof...(T)> sizes = {{NumberOfElements(t)...}};
54  return std::accumulate(sizes.begin(),sizes.end(),0);
55 }
56 
57 template <typename Out, typename T> size_t fillVector(itk::VariableLengthVector<Out> & out, size_t idx, const T & t)
58 {
59  assert(idx<out.GetSize());
60  out[idx] = static_cast<Out>(t);
61  return idx+1;
62 }
63 
64 template <typename Out, typename T> size_t fillVector(itk::VariableLengthVector<Out> & out, size_t idx, const itk::VariableLengthVector<T> & t)
65 {
66  assert(idx+t.GetSize()<=out.GetSize());
67  for(auto it = 0UL; it<t.GetSize(); ++it)
68  out[idx+it] = static_cast<Out>(t[it]);
69  return idx+t.GetSize();
70 }
71 
72 template <typename Out, typename Current, typename ...T> size_t fillVector(itk::VariableLengthVector<Out> & out, size_t idx, const Current& current, const T&...t)
73 {
74  size_t newIdx = fillVector(out,idx,current);
75  return fillVector(out,newIdx,t...);
76 }
77 } // end namespace variadic_concatenate_details
78 
79 // N images (all types) -> vector image
80 // This functor concatenates N images (N = variadic) of type
81 // VectorImage and or Image, into a single VectorImage
82 
89 template<typename TOut, typename ...TIns> struct VariadicConcatenate
90 {
91  auto operator()(const TIns &... ins) const
92  {
93  const size_t numberOfElements = variadic_concatenate_details::NumberOfElements(ins...);
94  itk::VariableLengthVector<TOut> out(numberOfElements);
96 
98 
99  return out;
100  }
101 
102  // Must define OutputSize because output pixel is vector
103  constexpr size_t OutputSize(const std::array<size_t, sizeof...(TIns)> inputsNbBands) const
104  {
105  return std::accumulate(inputsNbBands.begin(),inputsNbBands.end(),0);
106  }
107 };
108 
109 } // end namespace Functor
110 
111 } // end namespace otb
112 
113 #endif
constexpr vcl_size_t OutputSize(const std::array< vcl_size_t, sizeof...(TIns)> inputsNbBands) const
auto operator()(const TIns &...ins) const
vcl_size_t fillVector(itk::VariableLengthVector< Out > &out, vcl_size_t idx, const T &t)
This functor concatenates any number of input of scalar type or VariableLengthVector.
unsigned int GetSize(void) const noexcept