/* * Copyright 2003 - 2016, The libsigc++ Development Team * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SIGC_ADAPTORS_HIDE_H #define SIGC_ADAPTORS_HIDE_H #include #include #include namespace sigc { /** @defgroup hide hide(), hide_return() * sigc::hide() alters an arbitrary functor in that it adds a parameter * whose value is ignored on invocation of the returned functor. * Thus you can discard one argument of a signal. * * You may optionally specify the zero-based position of the parameter * to ignore as a template argument. The default is to ignore the last * parameter. * (A value of @p -1 adds a parameter at the end so sigc::hide<-1>() gives the same result as sigc::hide().) * * The type of the parameter can optionally be specified if not deduced. * * @par Examples: * @code * void foo(int, int); * // single argument hiding ... * sigc::hide(&foo)(1,2,3); // adds a dummy parameter at the back and calls foo(1,2) * sigc::hide<-1>(&foo)(1,2,3); // same as sigc::hide(&foo)(1,2,3) (calls foo(1,2)) * sigc::hide<0>(&foo)(1,2,3); // adds a dummy parameter at the beginning and calls foo(2,3) * sigc::hide<1>(&foo)(1,2,3); // adds a dummy parameter in the middle and calls foo(1,3) * sigc::hide<2>(&foo)(1,2,3); // adds a dummy parameter at the back and calls foo(1,2) * @endcode * * The functor sigc::hide() returns can be directly passed into * @ref sigc::signal_with_accumulator::connect() "sigc::signal::connect()". * * @par Example: * @code * sigc::signal some_signal; * void foo(); * some_signal.connect(sigc::hide(&foo)); * @endcode * * sigc::hide() can be nested in order to discard multiple arguments. * @par Example: * @code * // multiple argument hiding ... * // adds two dummy parameters at the back and calls foo(1,2) * sigc::hide(sigc::hide(&foo))(1,2,3,4); * @endcode * sigc::hide_return() alters an arbitrary functor by * dropping its return value, thus converting it to a void functor. * * @ingroup adaptors */ /** Adaptor that adds a dummy parameter to the wrapped functor. * Use the convenience function sigc::hide() to create an instance of sigc::hide_functor. * * The following template arguments are used: * - @e I_location Zero-based position of the dummy parameter (@p -1 for the last parameter). * - @e T_functor Type of the functor to wrap. * * @ingroup hide */ template struct hide_functor : public adapts { /** Invokes the wrapped functor, ignoring the argument at index @e I_location (0-indexed). * @param a Arguments to be passed on to the functor, apart from the ignored argument. * @return The return value of the functor invocation. */ template decltype(auto) operator()(T_arg&&... a) { constexpr auto size = sizeof...(T_arg); constexpr auto index_ignore = (I_location == -1 ? size - 1 : I_location); const auto t = std::tuple(std::forward(a)...); const auto t_start = internal::tuple_start(t); const auto t_end = internal::tuple_end(t); const auto t_used = std::tuple_cat(t_start, t_end); return std::apply(this->functor_, t_used); } /** Constructs a hide_functor object that adds a dummy parameter to the passed functor. * @param func Functor to invoke from operator()(). */ explicit hide_functor(const T_functor& func) : adapts(func) {} }; #ifndef DOXYGEN_SHOULD_SKIP_THIS // template specialization of visitor<>::do_visit_each<>(action, functor): /** Performs a functor on each of the targets of a functor. * The function overload for sigc::hide_functor performs a functor on the * functor stored in the sigc::hide_functor object. * * @ingroup hide */ template struct visitor> { template static void do_visit_each(const T_action& action, const hide_functor& target) { sigc::visit_each(action, target.functor_); } }; #endif // DOXYGEN_SHOULD_SKIP_THIS /** Creates an adaptor of type sigc::hide_functor which adds a dummy parameter to the passed * functor. * The optional template argument @e I_location specifies the zero-based * position of the dummy parameter in the returned functor (@p -1 stands for the last parameter). * * @param func Functor that should be wrapped. * @return Adaptor that executes @e func, ignoring the value of the dummy parameter. * * @ingroup hide */ template inline decltype(auto) hide(const T_functor& func) { return hide_functor(func); } /** Creates an adaptor of type sigc::hide_functor which adds a dummy parameter to the passed * functor. * This overload adds a dummy parameter at the back of the functor's parameter list. * * @param func Functor that should be wrapped. * @return Adaptor that executes @e func, ignoring the value of the last parameter. * * @ingroup hide */ template inline decltype(auto) hide(const T_functor& func) { return hide_functor<-1, T_functor>(func); } } /* namespace sigc */ #endif /* SIGC_ADAPTORS_HIDE_H */