diff --git a/Modules/Core/Functor/include/otbFunctorImageFilter.h b/Modules/Core/Functor/include/otbFunctorImageFilter.h index d52b4fa36db6e5231af91e59882572d7dac93047..5bb3f5012e05ef56eedc63a55feca46c68fecc2e 100644 --- a/Modules/Core/Functor/include/otbFunctorImageFilter.h +++ b/Modules/Core/Functor/include/otbFunctorImageFilter.h @@ -293,21 +293,24 @@ public: /** Run-time type information (and related methods). */ itkTypeMacro(FunctorImageFilter, ImageToImageFilter); - - /** Get the functor object. The functor is returned by reference. - * (Functors do not have to derive from itk::LightObject, so they do - * not necessarily have a reference count. So we cannot return a - * SmartPointer.) */ - FunctorType& GetFunctor() + /** Get the functor object. + * + * \return A non-const reference to the Functor in use. Note that + * this call will call the Modified() function of the filter, which + * will trigger a full output computation upon Update(). For + * inspection only, prefer using GetFunctor() + */ + FunctorType& GetModifiableFunctor() { this->Modified(); return m_Functor; } - /** Get the functor object. The functor is returned by reference. - * (Functors do not have to derive from itk::LightObject, so they do - * not necessarily have a reference count. So we cannot return a - * SmartPointer.) */ + /** Get the functor object. + * + * \return A const reference to the Functor in use. For a + * modifiable version of the functor, see GetModifiableFunctor(). + */ const FunctorType& GetFunctor() const { return m_Functor; diff --git a/Modules/Core/Functor/include/otbFunctorImageFilter.hxx b/Modules/Core/Functor/include/otbFunctorImageFilter.hxx index cbc94cb7625490ef8424800e073a3c04f2f44fe9..eff6074b92f8da67b12678cca4d89a628447cc9b 100644 --- a/Modules/Core/Functor/include/otbFunctorImageFilter.hxx +++ b/Modules/Core/Functor/include/otbFunctorImageFilter.hxx @@ -190,13 +190,13 @@ template<class C, class Out, class ... In> struct OperProxy<void(C::*)(Out&, In. // Will be easier to write in c++17 with std::apply and fold expressions -template <class Tuple, class Out, class Oper, size_t...Is> auto CallOperatorImpl(Tuple& t, Out & out, const Oper & oper,std::index_sequence<Is...>) +template <class Tuple, class Out, class Oper, size_t...Is> auto CallOperatorImpl(Tuple& t, Out & out, Oper & oper,std::index_sequence<Is...>) { OperProxy<Oper>::Compute(oper,out,GetProxy<typename std::remove_reference<decltype(std::get<Is>(t))>::type>::Get(std::get<Is>(t))...); } // Will be easier to write in c++17 with std::apply and fold expressions -template <class Out, class Oper, typename ... Args> auto CallOperator(Out & out, const Oper& oper, std::tuple<Args...> & t) +template <class Out, class Oper, typename ... Args> auto CallOperator(Out & out, Oper& oper, std::tuple<Args...> & t) { CallOperatorImpl(t,out,oper,std::make_index_sequence<sizeof...(Args)>{}); } diff --git a/Modules/Core/Functor/test/otbFunctorImageFilter.cxx b/Modules/Core/Functor/test/otbFunctorImageFilter.cxx index b662d724827d5343a5e12444efb333c7f966c1de..a8323f2fd23082d54c71f410105827d325fbc1e3 100644 --- a/Modules/Core/Functor/test/otbFunctorImageFilter.cxx +++ b/Modules/Core/Functor/test/otbFunctorImageFilter.cxx @@ -103,6 +103,21 @@ template <typename TOut,typename TIn> struct TestOperatorVoidReturn } }; + // Fake test operator non const + template <typename TOut,typename TIn> struct TestOperatorNonConst + { + auto operator()(const TIn&) + { + TOut res(OutputSize()); + return res; + } + + constexpr size_t OutputSize(...) const + { + return 1; + } + }; + template <typename TOut, typename TIn> void TestFilter() { @@ -122,11 +137,10 @@ template <typename TOut,typename TIn> struct TestOperatorVoidReturn // Build and run filter auto functor = TestOperator<TOut,TIn>{}; auto filter = NewFunctorFilter(functor); - + using FilterType = typename decltype(filter)::ObjectType; static_assert(FilterType::NumberOfInputs == 1,""); static_assert(std::is_same<typename FilterType::template InputImageType<0>, InputImageType>::value, ""); - filter->SetVariadicInputs(in); filter->SetInput1(in); filter->template SetVariadicInput<0>(in); // template keyword to avoid C++ parse ambiguity @@ -139,6 +153,12 @@ template <typename TOut,typename TIn> struct TestOperatorVoidReturn using FilterWithVoidReturnType = typename decltype(filter)::ObjectType; static_assert(FilterWithVoidReturnType::NumberOfInputs == 1,""); static_assert(std::is_same<typename FilterWithVoidReturnType::template InputImageType<0>, InputImageType>::value, ""); + + // Test with non const operator + auto functorNonConstOperator = TestOperatorNonConst<TOut,TIn>{}; + auto filterWithNonConstOperator = NewFunctorFilter(functorNonConstOperator); + filterWithNonConstOperator->SetInput1(in); + filterWithNonConstOperator->Update(); filterWithVoidReturn->SetVariadicInputs(in); filterWithVoidReturn->SetInput1(in); @@ -154,6 +174,10 @@ template <typename TOut,typename TIn> struct TestOperatorVoidReturn auto filterWithLambda = NewFunctorFilter(lambda,1, {{0,0}}); filterWithLambda->SetVariadicInputs(in); filterWithLambda->Update(); + + // Test with standard filter use + using FullFilterType = otb::FunctorImageFilter<TestOperator<TOut,TIn>>; + auto filter2 = FullFilterType::New(); } TypesCheck()