From a6399f2c25b7c94216862ef488f53676dcfc99be Mon Sep 17 00:00:00 2001 From: Julien Michel Date: Tue, 2 Oct 2018 13:28:29 +0200 Subject: [PATCH] ENH: experiment with variadic types (WIP) --- Modules/Core/ImageBase/test/CMakeLists.txt | 2 +- .../ImageBase/test/otbFunctorImageFilter.cxx | 203 ++++++++++++++++++ .../ImageBase/test/otbImageBaseTestDriver.cxx | 1 + 3 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 Modules/Core/ImageBase/test/otbFunctorImageFilter.cxx diff --git a/Modules/Core/ImageBase/test/CMakeLists.txt b/Modules/Core/ImageBase/test/CMakeLists.txt index b2ac501075..ad4522d2e0 100644 --- a/Modules/Core/ImageBase/test/CMakeLists.txt +++ b/Modules/Core/ImageBase/test/CMakeLists.txt @@ -40,7 +40,7 @@ set(OTBImageBaseTests otbImageTest.cxx otbImageFunctionAdaptor.cxx otbMetaImageFunction.cxx - + otbFunctorImageFilter.cxx ) add_executable(otbImageBaseTestDriver ${OTBImageBaseTests}) diff --git a/Modules/Core/ImageBase/test/otbFunctorImageFilter.cxx b/Modules/Core/ImageBase/test/otbFunctorImageFilter.cxx new file mode 100644 index 0000000000..9867264535 --- /dev/null +++ b/Modules/Core/ImageBase/test/otbFunctorImageFilter.cxx @@ -0,0 +1,203 @@ +/* + * 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. + */ + +//#include "otbFunctor.h" +//#include "otbFunctorImageFilter.h" + +#include "otbImage.h" +#include "otbVectorImage.h" +#include "itkNeighborhood.h" +#include "itkImageRegionIterator.h" +#include "itkImageSource.h" +#include + + +// Proxy to switch image type from T (Jordi has better code for that) +template struct ImageTypeProxy +{ + using ImageType = otb::Image; +}; + +template struct ImageTypeProxy > +{ + using ImageType = otb::VectorImage; +}; + + +// Variadic creation of iterator tuple +template auto MakeIterator(itk::SmartPointer img) +{ + itk::ImageRegionConstIterator it(img,img->GetLargestPossibleRegion()); + return it; +} + + +template auto MakeIterators(itk::SmartPointer... args) + { + return std::make_tuple(MakeIterator(args)...); + } + +// Variadic call of operator from iterator tuple +template auto CallOperatorImpl(Tuple& t, const Oper & oper,std::index_sequence) +{ + return oper(std::get(t).Get()...); +} + +template auto CallOperator(const Oper& oper, std::tuple & t) +{ + return CallOperatorImpl(t,oper,std::make_index_sequence{}); +} + +// Variadic move of iterators +template auto MoveIteratorsImpl(Tuple & t, std::index_sequence) +{ + return std::make_tuple(++(std::get(t) )...); +} + +template void MoveIterators(std::tuple & t) +{ + MoveIteratorsImpl(t,std::make_index_sequence{}); +} + + +// Variadic functor class (will disapear) +template class VariadicFunctor +{ +public: + Out operator()(const T&...) const + { + return Out(); + } + + unsigned int GetNumberOfVariadicArgs() const + { + const unsigned int nbArgs = sizeof...(T); + return nbArgs; + } +}; + +// Example of functor +template class AddFunctor : public VariadicFunctor +{ +public: + Out operator()(const In1 & in1, const In2 & in2) + { + return static_cast(in1+in2); + } +}; + + +template void Ignore(Args ...) +{} + +template class VariadicInputsImageFilter : public itk::ImageSource +{ +public: + using Self = VariadicInputsImageFilter; + using Pointer = itk::SmartPointer; + using ConstPointer = itk::SmartPointer; + using Superclass = itk::ImageSource; + + using InputTypesTupleType = std::tuple; + + itkNewMacro(Self); + + template void SetVInput(typename std::tuple_element::type * inputPtr) + { + this->SetNthInput(I,inputPtr); + } + + template const typename std::tuple_element::type * GetVInput() + { + using ImageType = typename std::tuple_element::type; + return dynamic_cast(this->GetInput(I)); + } + + void SetVInputs(TInputs*... inputs) + { + auto inTuple = std::make_tuple(inputs...); + SetInputsImpl(inTuple,std::make_index_sequence{}); + } + +protected: + VariadicInputsImageFilter() + { + this->SetNumberOfRequiredInputs(sizeof...(TInputs)); + }; + + ~VariadicInputsImageFilter() = default; + +private: + template auto SetInputsImpl(Tuple& t, std::index_sequence) + { + return std::initializer_list{(this->SetVInput(std::get(t)),0)...}; + } + + VariadicInputsImageFilter(const Self&) = delete; + void operator=(const Self&) = delete; +}; + + +using namespace otb; + +int otbFunctorImageFilter(int, char ** ) +{ + using VectorImageType = VectorImage; + using ImageType = Image; + using RegionType = typename ImageType::RegionType; + using SizeType = typename RegionType::SizeType; + using IndexType = typename RegionType::IndexType; + + using NeighborhoodType = itk::Neighborhood; + using VectorPixelType = typename VectorImageType::PixelType; + + auto vimage = VectorImageType::New(); + auto image = ImageType::New(); + + SizeType size({200,200}); + + vimage->SetRegions(size); + image->SetRegions(size); + + auto f1 = VariadicFunctor,double>(); + std::cout<<"Nb variadic args: "<GetLargestPossibleRegion(),3, no_radius_tag()); + // auto vit = MakeIterator(vimage,vimage->GetLargestPossibleRegion(),3,radius_tag()); + + + auto filter = VariadicInputsImageFilter::New(); + + filter->SetVInput<0>(vimage); + filter->SetVInput<1>(image); + + filter->SetVInputs(vimage,image); + + std::cout<GetVInput<0>()<< filter->GetVInput<1>()<