otbVariadicInputsImageFilter.h 3.84 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef otb_VariadicInputsImageFilter_h
#define otb_VariadicInputsImageFilter_h

Julien Michel's avatar
Julien Michel committed
23 24
#include "itkImageSource.h"

25 26
namespace otb {

Julien Michel's avatar
Julien Michel committed
27 28
/// TODO: Documentation

29 30 31 32 33 34 35
template<class TOuptut, class ... TInputs> class VariadicInputsImageFilter : public itk::ImageSource<TOuptut>
{
public:
  using Self = VariadicInputsImageFilter<TOuptut, TInputs...>;
  using Pointer =  itk::SmartPointer<Self>;
  using ConstPointer = itk::SmartPointer<const Self>;
  using Superclass = itk::ImageSource<TOuptut>;
36
  
37
  using InputTypesTupleType = std::tuple<TInputs...>;
38 39
  
  template <size_t I> using InputImageType = typename std::tuple_element<I,InputTypesTupleType>::type;
40 41
  static constexpr size_t NumberOfInputs = std::tuple_size<InputTypesTupleType>::value; 

42
  
43 44
  itkNewMacro(Self);
  
45
  template <std::size_t I> void SetVInput(const typename std::tuple_element<I,InputTypesTupleType>::type * inputPtr)
46
  {
47
    this->SetNthInput(I,const_cast<typename std::tuple_element<I,InputTypesTupleType>::type *>(inputPtr));
48
  }
49
  
50
#define DefineLegacySetInputMacro(n)                                                                               \
51 52
  template<typename Tuple = InputTypesTupleType, typename Check = typename std::enable_if<n<=std::tuple_size<Tuple>::value >::type> \
  void SetInput ## n(const typename std::tuple_element<n-1,Tuple>::type * img)                                           \
53
  {                                                                                                                \
54
    this->template SetVInput<n-1>(img);                                                                             \
55 56 57 58 59 60 61 62 63 64 65 66 67 68
  }

  // The following defines legacy setters SetInput1()
  // ... SetInput10(), only if the number of input type is sufficient
  DefineLegacySetInputMacro(1);
  DefineLegacySetInputMacro(2);
  DefineLegacySetInputMacro(3);
  DefineLegacySetInputMacro(4);
  DefineLegacySetInputMacro(5);
  DefineLegacySetInputMacro(6);
  DefineLegacySetInputMacro(7);
  DefineLegacySetInputMacro(8);
  DefineLegacySetInputMacro(9);
  DefineLegacySetInputMacro(10);
Julien Michel's avatar
Julien Michel committed
69 70

#undef DefineLegacySetInputMacro
71
  
72 73 74 75 76 77 78 79 80 81 82 83
  template <std::size_t I> const typename std::tuple_element<I,InputTypesTupleType>::type * GetVInput()
  {
    using ImageType = typename std::tuple_element<I,InputTypesTupleType>::type;
    return dynamic_cast<const ImageType *>(this->GetInput(I));
  }

  void SetVInputs(TInputs*... inputs)
  {
    auto inTuple = std::make_tuple(inputs...);
    SetInputsImpl(inTuple,std::make_index_sequence<sizeof...(inputs)>{});
  }

84 85 86 87 88
  auto GetVInputs()
  {
    return GetInputsImpl(std::make_index_sequence<sizeof...(TInputs)>{});
  }

89 90 91 92 93 94 95 96 97 98 99 100 101
protected:
  VariadicInputsImageFilter()
  {
    this->SetNumberOfRequiredInputs(sizeof...(TInputs));
  };
  
  ~VariadicInputsImageFilter() = default;
  
private:
  template<class Tuple, size_t...Is> auto SetInputsImpl(Tuple& t, std::index_sequence<Is...>)
  {
    return std::initializer_list<int>{(this->SetVInput<Is>(std::get<Is>(t)),0)...};
  }
102 103 104 105 106

  template <size_t...Is> auto GetInputsImpl(std::index_sequence<Is...>)
  {
    return std::make_tuple(this->GetVInput<Is>()...);
  }
107 108 109 110 111 112 113 114
  
  VariadicInputsImageFilter(const Self&) = delete;
  void operator=(const Self&) = delete;
};

}

#endif