otbVariadicInputsImageFilter.h 3.64 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 36 37 38 39 40
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>;

  using InputTypesTupleType = std::tuple<TInputs...>;

  itkNewMacro(Self);
  
41
  template <std::size_t I> void SetVInput(const typename std::tuple_element<I,InputTypesTupleType>::type * inputPtr)
42
  {
43
    this->SetNthInput(I,const_cast<typename std::tuple_element<I,InputTypesTupleType>::type *>(inputPtr));
44 45
  }

46
#define DefineLegacySetInputMacro(n)                                                                               \
47 48
  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)                                           \
49
  {                                                                                                                \
50
    this->template SetVInput<n-1>(img); // template keyword to avoid C++ parsing ambiguity                          \
51 52 53 54 55 56 57 58 59 60 61 62 63 64
  }

  // 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);
65 66

#undef DefineLegacySetInputMacro
67
  
68 69 70 71 72 73 74 75 76 77 78 79
  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)>{});
  }

80 81 82 83 84
  auto GetVInputs()
  {
    return GetInputsImpl(std::make_index_sequence<sizeof...(TInputs)>{});
  }

85 86 87 88 89 90 91 92 93 94 95 96 97
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)...};
  }
98 99 100 101 102

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

}

#endif