29 #if defined(FunctorHolder_RECURSES)
30 #error Recursive header files inclusion detected in FunctorHolder.h
33 #define FunctorHolder_RECURSES
35 #if !defined FunctorHolder_h
37 #define FunctorHolder_h
42 #include <type_traits>
61 template <
typename F,
typename... T>
63 auto apply(F && fn, T &&... args)
64 -> decltype((std::forward<F>(fn))(std::forward<T>(args)...))
66 return (std::forward<F>(fn))(std::forward<T>(args)...);
74 template <
typename F,
typename... T>
76 auto apply(F && fn, T &&... args)
77 -> decltype((*std::forward<F>(fn))(std::forward<T>(args)...))
79 return (*std::forward<F>(fn))(std::forward<T>(args)...);
87 static constexpr std::true_type apply(std::shared_ptr<T>
const&) {
return {}; }
90 static constexpr std::false_type apply(T
const&) {
return {}; }
94 struct ReferenceWrapperTrait
97 static constexpr std::true_type apply(std::reference_wrapper<T>
const&) {
return {}; }
100 static constexpr std::false_type apply(T
const&) {
return {}; }
149 typename FunctorStorage,
170 typename std::enable_if<!std::is_base_of<FunctorHolder, typename std::decay<Function>::type>::value,
int>::type = 0
185 template <
typename... T>
187 -> decltype(Invoker<NeedDereference>::apply(this->myFunctor, std::forward<T>(args)...))
189 return Invoker<NeedDereference>::apply(
myFunctor, std::forward<T>(args)...);
197 template <
typename... T>
199 -> decltype(Invoker<NeedDereference>::apply(this->myFunctor, std::forward<T>(args)...))
201 return Invoker<NeedDereference>::apply(
myFunctor, std::forward<T>(args)...);
211 out <<
"[FunctorHolder]";
213 out <<
" using std::shared_ptr storage (rvalue)";
214 else if ( ReferenceWrapperTrait::apply(
myFunctor) )
215 out <<
" using std::reference_wrapper storage (lvalue)";
217 out <<
" using custom storage";
237 template <
typename FunctorStorage,
bool NeedDereference>
241 object.selfDisplay( out );
250 template <
typename Function>
251 inline auto holdFunctorImpl(Function && fn, std::true_type)
252 -> FunctorHolder<decltype(std::ref(std::forward<Function>(fn))),
false>
254 return FunctorHolder<decltype(std::ref(std::forward<Function>(fn))),
false>{ std::forward<Function>(fn) };
258 template <
typename Function>
259 inline auto holdFunctorImpl(Function && fn, std::false_type)
260 -> FunctorHolder<std::shared_ptr<Function>,
true>
262 return FunctorHolder<std::shared_ptr<Function>,
true>{ std::make_shared<Function>(std::forward<Function>(fn)) };
278 template <
typename Function>
280 -> decltype(holdFunctorImpl(std::forward<Function>(fn),
typename std::is_lvalue_reference<Function>{}))
282 return holdFunctorImpl(std::forward<Function>(fn),
typename std::is_lvalue_reference<Function>{});
290 #undef FunctorHolder_RECURSES
Aim: hold any callable object (function, functor, lambda, ...) as a C(Unary)Functor model.
FunctorHolder(Function &&fn)
Constructor.
void selfDisplay(std::ostream &out) const
Writes/Displays the object on an output stream.
constexpr bool isValid() const
Checks the validity/consistency of the object.
auto operator()(T &&... args) const -> decltype(Invoker< NeedDereference >::apply(this->myFunctor, std::forward< T >(args)...))
Invokes the stored callable object in a constant context.
FunctorStorage myFunctor
The callable object.
std::ostream & operator<<(std::ostream &out, const FunctorHolder< FunctorStorage, NeedDereference > &object)
Overloads 'operator<<' for displaying objects of class FunctorHolder.
auto holdFunctor(Function &&fn) -> decltype(holdFunctorImpl(std::forward< Function >(fn), typename std::is_lvalue_reference< Function >{}))
Hold any callable object (function, functor, lambda, ...) as a C(Unary)Functor model.
DGtal is the top-level namespace which contains all DGtal functions and types.