Commit 6758821e authored by Victor Poughon's avatar Victor Poughon

Merge branch 'remove_variadic_fom_getset' into 'develop'

Rename Get/Set Variadic[Named]Input[s]() by Get/SetInput() for easier reading in FunctorImageFilter

See merge request !328
parents 6fcc483c 2d6a3c08
......@@ -328,11 +328,11 @@ private:
fftShiftFilter->Update();
toComplexFilter->SetVariadicInputs( fftShiftFilter->GetOutput() );
toComplexFilter->SetInputs( fftShiftFilter->GetOutput() );
}
else
{
toComplexFilter->SetVariadicInputs( inImage );
toComplexFilter->SetInputs( inImage );
}
toComplexFilter->Update();
......
......@@ -273,7 +273,7 @@ private:
// save a reference to the functor
m_Filters.push_back(transferLogFilter.GetPointer());
transferLogFilter->SetVariadicInputs(tempImage);
transferLogFilter->SetInputs(tempImage);
transferLogFilter->UpdateOutputInformation();
shrinkFilter->SetInput(transferLogFilter->GetOutput());
......
......@@ -271,10 +271,10 @@ private:
classificationFilter = MultiScaleClassificationFilterType::New();
using namespace Functor::MultiScaleConvexOrConcaveDecisionRule_tags;
classificationFilter->SetVariadicNamedInput<max_opening_profile_derivative>( omsCharFilter->GetOutput() );
classificationFilter->SetVariadicNamedInput<opening_profile_characteristics>( omsCharFilter->GetOutputCharacteristics() );
classificationFilter->SetVariadicNamedInput<max_closing_profile_derivative>( cmsCharFilter->GetOutput() );
classificationFilter->SetVariadicNamedInput<closing_profile_characteristics>( cmsCharFilter->GetOutputCharacteristics() );
classificationFilter->SetInput<max_opening_profile_derivative>( omsCharFilter->GetOutput() );
classificationFilter->SetInput<opening_profile_characteristics>( omsCharFilter->GetOutputCharacteristics() );
classificationFilter->SetInput<max_closing_profile_derivative>( cmsCharFilter->GetOutput() );
classificationFilter->SetInput<closing_profile_characteristics>( cmsCharFilter->GetOutputCharacteristics() );
classificationFilter->GetModifiableFunctor().SetSigma( sigma );
classificationFilter->GetModifiableFunctor().SetLabelSeparator( static_cast<unsigned short>(initValue + profileSize * step) );
AddProcess(classificationFilter, "Classification");
......
......@@ -179,18 +179,18 @@ private:
case 0: // H-alpha-A
if (inhv)
m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
m_SRFilter->SetInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
else if (invh)
m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
m_SRFilter->SetInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_SRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
m_SRFilter->SetInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_SRFilter->SetInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
radius.Fill(GetParameterInt("inco.kernelsize"));
m_MeanFilter->GetFilter()->SetRadius(radius);
m_MeanFilter->SetInput(m_SRFilter->GetOutput());
m_HAFilter->SetVariadicInput<0>(m_MeanFilter->GetOutput());
m_HAFilter->SetInput<0>(m_MeanFilter->GetOutput());
SetParameterOutputImage("out", m_HAFilter->GetOutput());
break;
......@@ -198,18 +198,18 @@ private:
case 1: // Barnes
if (inhv)
m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
m_SRFilter->SetInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
else if (invh)
m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
m_SRFilter->SetInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_SRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
m_SRFilter->SetInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_SRFilter->SetInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
radius.Fill(GetParameterInt("inco.kernelsize"));
m_MeanFilter->GetFilter()->SetRadius(radius);
m_MeanFilter->SetInput(m_SRFilter->GetOutput());
m_BarnesFilter->SetVariadicInput<0>(m_MeanFilter->GetOutput());
m_BarnesFilter->SetInput<0>(m_MeanFilter->GetOutput());
SetParameterOutputImage("out", m_BarnesFilter->GetOutput());
break;
......@@ -217,18 +217,18 @@ private:
case 2: // Huynen
if (inhv)
m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
m_SRFilter->SetInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
else if (invh)
m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
m_SRFilter->SetInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
m_SRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_SRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
m_SRFilter->SetInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_SRFilter->SetInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
radius.Fill(GetParameterInt("inco.kernelsize"));
m_MeanFilter->GetFilter()->SetRadius(radius);
m_MeanFilter->SetInput(m_SRFilter->GetOutput());
m_HuynenFilter->SetVariadicInput<0>(m_MeanFilter->GetOutput());
m_HuynenFilter->SetInput<0>(m_MeanFilter->GetOutput());
SetParameterOutputImage("out", m_HuynenFilter->GetOutput());
break;
......@@ -245,7 +245,7 @@ private:
m_ImageList->PushBack(GetParameterComplexDoubleImage("invv"));
m_Concatener->SetInput(m_ImageList);
m_PauliFilter->SetVariadicInput<0>(m_Concatener->GetOutput());
m_PauliFilter->SetInput<0>(m_Concatener->GetOutput());
SetParameterOutputImage("out", m_PauliFilter->GetOutput() );
......
......@@ -395,12 +395,12 @@ private:
m_RCohSRFilter = RCohSRFilterType::New();
if (inhv)
m_RCohSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
m_RCohSRFilter->SetInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
else if (invh)
m_RCohSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
m_RCohSRFilter->SetInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
m_RCohSRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_RCohSRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
m_RCohSRFilter->SetInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_RCohSRFilter->SetInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
SetParameterOutputImage("outc", m_RCohSRFilter->GetOutput()); // input: 3 x 1 complex channel | output : 6 complex channels
......@@ -412,12 +412,12 @@ private:
m_RCovSRFilter = RCovSRFilterType::New();
if (inhv)
m_RCovSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
m_RCovSRFilter->SetInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
else if (invh)
m_RCovSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
m_RCovSRFilter->SetInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
m_RCovSRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_RCovSRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
m_RCovSRFilter->SetInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_RCovSRFilter->SetInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
SetParameterOutputImage("outc", m_RCovSRFilter->GetOutput()); // input: 3 x 1 complex channel | output : 6 complex channels
......@@ -429,12 +429,12 @@ private:
m_RCCSRFilter = RCCSRFilterType::New();
if (inhv)
m_RCCSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
m_RCCSRFilter->SetInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("inhv"));
else if (invh)
m_RCCSRFilter->SetVariadicNamedInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
m_RCCSRFilter->SetInput<polarimetry_tags::hv_or_vh>(GetParameterComplexDoubleImage("invh"));
m_RCCSRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_RCCSRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
m_RCCSRFilter->SetInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_RCCSRFilter->SetInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
SetParameterOutputImage("outc", m_RCCSRFilter->GetOutput()); // input: 3 x 1 complex channel | output : 6 complex channels
......@@ -444,7 +444,7 @@ private:
case 3: // ReciprocalCoherencyToReciprocalMuellerImageFilter
m_RCRMFilter = RCRMFilterType::New();
m_RCRMFilter->SetVariadicInput<0>(GetParameterComplexDoubleVectorImage("inc"));
m_RCRMFilter->SetInput<0>(GetParameterComplexDoubleVectorImage("inc"));
SetParameterOutputImage("outf", m_RCRMFilter->GetOutput()); // input: 6 complex channels | 16 real channels
......@@ -454,7 +454,7 @@ private:
case 4: // ReciprocalCovarianceToCoherencyDegreeImageFilter
m_RCCDFilter = RCCDFilterType::New();
m_RCCDFilter->SetVariadicInput<0>(GetParameterComplexDoubleVectorImage("inc"));
m_RCCDFilter->SetInput<0>(GetParameterComplexDoubleVectorImage("inc"));
SetParameterOutputImage("outc", m_RCCDFilter->GetOutput()); // input: 6 complex channels | 3 complex channels
......@@ -464,7 +464,7 @@ private:
case 5: // ReciprocalCovarianceToReciprocalCoherencyImageFilter
m_RCRCFilter = RCRCFilterType::New();
m_RCRCFilter->SetVariadicInput<0>(GetParameterComplexDoubleVectorImage("inc"));
m_RCRCFilter->SetInput<0>(GetParameterComplexDoubleVectorImage("inc"));
SetParameterOutputImage("outc", m_RCRCFilter->GetOutput()); // input: 6 complex channels | 6 complex channels
......@@ -474,7 +474,7 @@ private:
case 6: // ReciprocalLinearCovarianceToReciprocalCircularCovarianceImageFilter
m_RLCRCCFilter = RLCRCCFilterType::New();
m_RLCRCCFilter->SetVariadicInput<0>(GetParameterComplexDoubleVectorImage("inc"));
m_RLCRCCFilter->SetInput<0>(GetParameterComplexDoubleVectorImage("inc"));
SetParameterOutputImage("outc", m_RLCRCCFilter->GetOutput()); // input: 6 complex channels | output : 6 complex channels
......@@ -485,7 +485,7 @@ private:
m_MRCFilter = MRCFilterType::New();
m_MRCFilter->SetVariadicInput<0>(GetParameterDoubleVectorImage("inf"));
m_MRCFilter->SetInput<0>(GetParameterDoubleVectorImage("inf"));
SetParameterOutputImage("outc", m_MRCFilter->GetOutput()); // input: 16 real channels | output : 6 complex channels
......@@ -499,10 +499,10 @@ private:
case 8: // SinclairToCoherency
m_CohSRFilter = CohSRFilterType::New();
m_CohSRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_CohSRFilter->SetVariadicNamedInput<polarimetry_tags::hv>(GetParameterComplexDoubleImage("inhv"));
m_CohSRFilter->SetVariadicNamedInput<polarimetry_tags::vh>(GetParameterComplexDoubleImage("invh"));
m_CohSRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
m_CohSRFilter->SetInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_CohSRFilter->SetInput<polarimetry_tags::hv>(GetParameterComplexDoubleImage("inhv"));
m_CohSRFilter->SetInput<polarimetry_tags::vh>(GetParameterComplexDoubleImage("invh"));
m_CohSRFilter->SetInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
SetParameterOutputImage("outc", m_CohSRFilter->GetOutput()); // input: 4 x 1 complex channel | 10 complex channels
......@@ -512,10 +512,10 @@ private:
case 9: // SinclairToCovariance
m_CovSRFilter = CovSRFilterType::New();
m_CovSRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_CovSRFilter->SetVariadicNamedInput<polarimetry_tags::hv>(GetParameterComplexDoubleImage("inhv"));
m_CovSRFilter->SetVariadicNamedInput<polarimetry_tags::vh>(GetParameterComplexDoubleImage("invh"));
m_CovSRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
m_CovSRFilter->SetInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_CovSRFilter->SetInput<polarimetry_tags::hv>(GetParameterComplexDoubleImage("inhv"));
m_CovSRFilter->SetInput<polarimetry_tags::vh>(GetParameterComplexDoubleImage("invh"));
m_CovSRFilter->SetInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
SetParameterOutputImage("outc", m_CovSRFilter->GetOutput()); // input: 4 x 1 complex channel | output : 10 complex channels
......@@ -525,10 +525,10 @@ private:
case 10: // SinclairToCircularCovariance
m_CCSRFilter = CCSRFilterType::New();
m_CCSRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_CCSRFilter->SetVariadicNamedInput<polarimetry_tags::hv>(GetParameterComplexDoubleImage("inhv"));
m_CCSRFilter->SetVariadicNamedInput<polarimetry_tags::vh>(GetParameterComplexDoubleImage("invh"));
m_CCSRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
m_CCSRFilter->SetInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_CCSRFilter->SetInput<polarimetry_tags::hv>(GetParameterComplexDoubleImage("inhv"));
m_CCSRFilter->SetInput<polarimetry_tags::vh>(GetParameterComplexDoubleImage("invh"));
m_CCSRFilter->SetInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
SetParameterOutputImage("outc", m_CCSRFilter->GetOutput()); // input: 4 x 1 complex channel | output : 10 complex channels
......@@ -543,10 +543,10 @@ private:
case 11: // SinclairToMueller
m_MSRFilter = MSRFilterType::New();
m_MSRFilter->SetVariadicNamedInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_MSRFilter->SetVariadicNamedInput<polarimetry_tags::hv>(GetParameterComplexDoubleImage("inhv"));
m_MSRFilter->SetVariadicNamedInput<polarimetry_tags::vh>(GetParameterComplexDoubleImage("invh"));
m_MSRFilter->SetVariadicNamedInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
m_MSRFilter->SetInput<polarimetry_tags::hh>(GetParameterComplexDoubleImage("inhh"));
m_MSRFilter->SetInput<polarimetry_tags::hv>(GetParameterComplexDoubleImage("inhv"));
m_MSRFilter->SetInput<polarimetry_tags::vh>(GetParameterComplexDoubleImage("invh"));
m_MSRFilter->SetInput<polarimetry_tags::vv>(GetParameterComplexDoubleImage("invv"));
SetParameterOutputImage("outf", m_MSRFilter->GetOutput()); // input: 4 x 1 complex channel | output : 16 real channels
......@@ -556,7 +556,7 @@ private:
case 12: // MuellerToPolarisationDegreeAndPowerImageFilter
m_MPDPFilter = MPDPFilterType::New();
m_MPDPFilter->SetVariadicInput<0>(GetParameterDoubleVectorImage("inf"));
m_MPDPFilter->SetInput<0>(GetParameterDoubleVectorImage("inf"));
SetParameterOutputImage("outf", m_MPDPFilter->GetOutput()); // input: 16 real channels | output : 4 real channels
......
......@@ -234,7 +234,7 @@ template <typename C, typename R, typename... T, typename TNameMap> struct Funct
* or returns void and has first parameter as output (i.e. T& or itk::VariableLengthVector<T>&)
*
* The returned filter is ready to use. Inputs can be set through the
* SetVariadicInputs() method (see VariadicInputsImageFilter class for
* SetInputs() method (see VariadicInputsImageFilter class for
* details)
*
* \param[in] the Functor to build the filter from
......
......@@ -253,7 +253,7 @@ FunctorImageFilter<TFunction, TNameMap>
// Propagate to each variadic inputs, including possible radius
// TODO: For now all inputs are padded with the radius, even if they
// are not neighborhood based
functor_filter_details::SetInputRequestedRegions<InputHasNeighborhood>(this->GetVariadicInputs(),requestedRegion, m_Radius);
functor_filter_details::SetInputRequestedRegions<InputHasNeighborhood>(this->GetInputs(),requestedRegion, m_Radius);
}
template <class TFunction, class TNameMap>
......@@ -264,7 +264,7 @@ FunctorImageFilter<TFunction, TNameMap>::GenerateOutputInformation()
Superclass::GenerateOutputInformation();
// Get All variadic inputs
auto inputs = this->GetVariadicInputs();
auto inputs = this->GetInputs();
// Retrieve an array of number of components per input
auto inputNbComps = functor_filter_details::GetNumberOfComponentsPerInput(inputs);
......@@ -286,7 +286,7 @@ FunctorImageFilter<TFunction, TNameMap>
itk::ProgressReporter p(this,threadId,outputRegionForThread.GetNumberOfPixels());
// This will build a tuple of iterators to be used
auto inputIterators = functor_filter_details::MakeIterators(this->GetVariadicInputs(),outputRegionForThread, m_Radius,InputHasNeighborhood{});
auto inputIterators = functor_filter_details::MakeIterators(this->GetInputs(),outputRegionForThread, m_Radius,InputHasNeighborhood{});
// Build a default value
typename OutputImageType::PixelType outputValueHolder;
......
......@@ -25,28 +25,33 @@
namespace otb {
/**
* \class VariadicInputsImageFilter
* \brief Base class for image filter with variadic inputs.
*
* This filter act as a base class for all filters that will take
* several input images with different types and produce an output
* image.
*
*
* Type for each input is taken from the variadic template parameter
* TInputs.
*
* Inputs get be set/get with SetVariadicInput<N>() and
* GetVariadicInput<N>(), when N is the index (first input is 0) of
* the input. This is resolved at compile time: you can not call
* SetVariadicInput<N>() with an argument not matching the Nth input
*
* Inputs get be set/get with SetInput<N>() and
* GetInput<N>(), when N is the index (first input is 0) of
* the input. This is resolved at compile time: you can not call
* SetInput<N>() with an argument not matching the Nth input
* type (it will lead to type mismatch compilation error).
*
* Alternatively, you can call SetVariadicInputs() with all the input
*
* Note that you can also call SetInput() and GetInput() which will
* automatically fetch the first input.
*
* Alternatively, you can call SetInputs() with all the input
* image in the same order as in the template parameters.
*
* Last, there is a macro that generates SetInput1() ... SetInput10()
* (iff the number of varidic input types is large enough) for
* backward compatibility.
*
*
* \ingroup OTBFunctor
*/
template<class TOuptut, class ... TInputs> class VariadicInputsImageFilter : public itk::ImageSource<TOuptut>
{
......@@ -64,20 +69,26 @@ public:
// Good old new macro
itkNewMacro(Self);
// Import definitions for SetInput and GetInput to avoid shadowing
// by SetInput<> and GetIntput<> defined in this method
using Superclass::GetInput;
using Superclass::SetInput;
/**
* \param Set the Ith input
*/
template <std::size_t I> void SetVariadicInput(const typename std::tuple_element<I,InputTypesTupleType>::type * inputPtr)
template <std::size_t I = 0>
void SetInput(const InputImageType<I>* inputPtr)
{
static_assert(std::tuple_size<InputTypesTupleType>::value>I,"Template value I is out of range.");
this->SetNthInput(I,const_cast<typename std::tuple_element<I,InputTypesTupleType>::type *>(inputPtr));
static_assert(NumberOfInputs > I, "Template value I is out of range.");
this->SetNthInput(I, const_cast<InputImageType<I>*>(inputPtr));
}
#define DefineLegacySetInputMacro(n) \
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) \
{ \
this->template SetVariadicInput<n-1>(img); \
#define DefineLegacySetInputMacro(n) \
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) \
{ \
this->template SetInput<n - 1>(img); \
}
// The following defines legacy setters SetInput1()
......@@ -95,20 +106,17 @@ public:
#undef DefineLegacySetInputMacro
/**
* \return the Ith variadic input
*/
template <std::size_t I> const typename std::tuple_element<I,InputTypesTupleType>::type * GetVariadicInput()
template <std::size_t I = 0>
const InputImageType<I>* GetInput()
{
static_assert(std::tuple_size<InputTypesTupleType>::value>I,"Template value I is out of range.");
using ImageType = typename std::tuple_element<I,InputTypesTupleType>::type;
return dynamic_cast<const ImageType *>(this->GetInput(I));
static_assert(NumberOfInputs > I, "Template value I is out of range.");
return dynamic_cast<const InputImageType<I>*>(this->GetInput(I));
}
/**
* \param inputs A vararg list of inputs
*/
void SetVariadicInputs(TInputs*... inputs)
void SetInputs(TInputs*... inputs)
{
auto inTuple = std::make_tuple(inputs...);
SetInputsImpl(inTuple,std::make_index_sequence<sizeof...(inputs)>{});
......@@ -117,7 +125,7 @@ public:
/**
* \return A tuple with all inputs
*/
auto GetVariadicInputs()
auto GetInputs()
{
return GetInputsImpl(std::make_index_sequence<sizeof...(TInputs)>{});
}
......@@ -133,12 +141,12 @@ protected:
private:
template<class Tuple, size_t...Is> auto SetInputsImpl(Tuple& t, std::index_sequence<Is...>)
{
return std::initializer_list<int>{(this->SetVariadicInput<Is>(std::get<Is>(t)),0)...};
return std::initializer_list<int>{(this->SetInput<Is>(std::get<Is>(t)), 0)...};
}
template <size_t...Is> auto GetInputsImpl(std::index_sequence<Is...>)
{
return std::make_tuple(this->GetVariadicInput<Is>()...);
return std::make_tuple(this->GetInput<Is>()...);
}
VariadicInputsImageFilter(const Self&) = delete;
......
......@@ -28,6 +28,16 @@ namespace otb {
namespace internal
{
/**
* \struct tuple_index
* \brief retrieve index of a type in tuple if exists
*
* This struct allows to retrieve the index of the first occurence of type
* Arg in tuple Tuple. If type Arg can not be found, compilation will
* end with a static_assert failing.
*
* ::value holds the index of type Arg in tuple Tuple.
*/
template<typename Arg, typename Tuple> struct tuple_index;
template<typename Arg, typename...Args> struct tuple_index<Arg, std::tuple<Arg,Args...> >
{
......@@ -41,6 +51,43 @@ template<typename Arg, typename NotMatching, typename...Args> struct tuple_index
};
}
/**
* \class VariadicNamedInputsImageFilter
* \brief Adds tagged versions for Get/SetInput to otb::VariadicInputsImageFilter
*
* This class extends otb::VariadicInputsImageFilter with SetInput<>()
* and GetInput<>() with tags.
*
* Template parameter TInputNameMap should be a tuple of same size as
* variadic template parameter TInputs. Each type in the tuple will be
* used as a tag to set/get the corresponding input and thus should be
* unique in tuple.
*
* This allows to add semantic to inputs and remove the need for the
* user to know input orders and set them by their index.
*
* Example of use:
* \code
* struct Foo {};
* struct Bar {};
* using Names = std::tuple<<Foo,Bar>;
*
* using Filter = VariadicNamedInputsImageFilter<OutputType, Names,
* InputType1, InputType2>;
*
* // Set the input corresponding to Foo tag:
* filter->SetInput<Foo>(in);
*
* // Get the input corresponding to Bar tag:
* auto in = filter->GetInput<Bar>();
*
* \endcode
*
* \sa otb::VariadicNamedInputsImageFilter
* \sa otb::FunctorImageFilter
*
* \ingroup OTBFunctor
*/
template<class TOuptut, class TInputNameMap, class ... TInputs> class VariadicNamedInputsImageFilter : public VariadicInputsImageFilter<TOuptut,TInputs...>
{
public:
......@@ -53,30 +100,61 @@ public:
template <size_t I> using InputImageType = typename Superclass::template InputImageType<I>;
static constexpr size_t NumberOfInputs = Superclass::NumberOfInputs;
// This checks that TInputNameMap has the correct size
static_assert(std::tuple_size<TInputNameMap>::value == NumberOfInputs,"Tuple for input name does not match the size of ... TInputs");
// Good old new macro
itkNewMacro(Self);
template <typename Tag> void SetVariadicNamedInput(const InputImageType<internal::tuple_index<Tag, TInputNameMap>::value> * inputPtr)
// Import definitions for SetInput and GetInput to avoid shadowing
// by SetInput<> and GetIntput<> defined in this method
using Superclass::GetInput;
using Superclass::SetInput;
/**
* Set the input corresponding to tag Tag
* \tparam Tag tag of the input
* \param inputPtr the pointer to the input image
*/
template <typename Tag>
void SetInput(const InputImageType<internal::tuple_index<Tag, TInputNameMap>::value>* inputPtr)
{
constexpr size_t idx = internal::tuple_index<Tag, TInputNameMap>::value;
this->SetNthInput(idx,const_cast<InputImageType<idx> *>(inputPtr));
}
template <typename Tag> void SetVariadicNamedInput(Tag,const InputImageType<internal::tuple_index<Tag, TInputNameMap>::value> * inputPtr)
/**
* Set the input corresponding to tag Tag
* \param tag tag of the input
* \param inputPtr the pointer to the input image
*/
template <typename Tag>
void SetInput(Tag, const InputImageType<internal::tuple_index<Tag, TInputNameMap>::value>* inputPtr)
{
SetVariadicNamedInput<Tag>(inputPtr);
SetInput<Tag>(inputPtr);
}
template <typename Tag> const InputImageType<internal::tuple_index<Tag,TInputNameMap>::value> * GetVariadicNamedInput()
/**
* Get the input corresponding to tag Tag
* \tparam Tag tag of the input
* \return the pointer to the input image
*/
template <typename Tag>
const InputImageType<internal::tuple_index<Tag, TInputNameMap>::value>* GetInput()
{
constexpr size_t idx = internal::tuple_index<Tag, TInputNameMap>::value;
return dynamic_cast<const InputImageType<idx> *>(this->GetInput(idx));
return dynamic_cast<const InputImageType<idx>*>(this->Superclass::GetInput(idx));
}
template <typename Tag> const InputImageType<internal::tuple_index<Tag,TInputNameMap>::value> * GetVariadicNamedInput(Tag)
/**
* Get the input corresponding to tag Tag
* \param tag tag of the input
* \return the pointer to the input image
*/
template <typename Tag>
const InputImageType<internal::tuple_index<Tag, TInputNameMap>::value>* GetInput(Tag)
{
return GetVariadicNamedInput<Tag>();
return GetInput<Tag>();
}
protected:
......
......@@ -192,7 +192,7 @@ private:
*
* Set inputs with:
* \code
* SetVariadicInput<0>(inputPtr);
* SetInput<0>(inputPtr);
* \endcode
*
* \ingroup OTBPolarimetry
......
......@@ -118,7 +118,7 @@ public:
*
* Set inputs with:
* \code
* SetVariadicInput<0>(inputPtr);
* SetInput<0>(inputPtr);
* \endcode
*
* \ingroup OTBPolarimetry
......
......@@ -118,7 +118,7 @@ private:
*
* Set inputs with:
* \code
* SetVariadicInput<0>(inputPtr);
* SetInput<0>(inputPtr);
* \endcode
*
* \ingroup OTBPolarimetry
......
......@@ -124,7 +124,7 @@ public:
*
* Set inputs with:
* \code
* SetVariadicInput<0>(inputPtr);
* SetInput<0>(inputPtr);
* \endcode
*
* \ingroup OTBPolarimetry
......
......@@ -107,7 +107,7 @@ public:
*
* Set inputs with:
* \code
* SetVariadicInput<0>(inputPtr);
* SetInput<0>(inputPtr);
* \endcode
*
* \ingroup OTBPolarimetry
......
......@@ -99,7 +99,7 @@ public:
*
* Set inputs with:
* \code
* SetVariadicInput<0>(inputPtr);
* SetInput<0>(inputPtr);
* \endcode
*
*
......
......@@ -187,7 +187,7 @@ public:
*
* Set inputs with:
* \code
* SetVariadicInput<0>(inputPtr);
* SetInput<0>(inputPtr);
* \endcode
*
* \ingroup OTBPolarimetry
......
......@@ -84,7 +84,7 @@ public:
*
* Set inputs with:
* \code
* SetVariadicInput<0>(inputPtr);
* SetInput<0>(inputPtr);
* \endcode
*
* \ingroup OTBPolarimetry
......