Imported Upstream version 2.99.2
[platform/upstream/libsigc++.git] / sigc++ / adaptors / hide.h
1 #ifndef _SIGC_ADAPTORS_HIDE_H_
2 #define _SIGC_ADAPTORS_HIDE_H_
3
4 #include <sigc++/adaptors/adaptor_trait.h>
5 #include <sigc++/tuple-utils/tuple_end.h>
6 #include <sigc++/tuple-utils/tuple_start.h>
7
8 namespace sigc {
9
10 /** @defgroup hide hide(), hide_return()
11  * sigc::hide() alters an arbitrary functor in that it adds a parameter
12  * whose value is ignored on invocation of the returned functor.
13  * Thus you can discard one argument of a signal.
14  *
15  * You may optionally specify the zero-based position of the parameter
16  * to ignore as a template argument. The default is to ignore the last
17  * parameter.
18  * (A value of @p -1 adds a parameter at the end so sigc::hide<-1>() gives the same result as sigc::hide().)
19  *
20  * The type of the parameter can optionally be specified if not deduced.
21  *
22  * @par Examples:
23  * @code
24  * void foo(int, int);
25  * // single argument hiding ...
26  * sigc::hide(&foo)(1,2,3);     // adds a dummy parameter at the back and calls foo(1,2)
27  * sigc::hide<-1>(&foo)(1,2,3); // same as sigc::hide(&foo)(1,2,3) (calls foo(1,2))
28  * sigc::hide<0>(&foo)(1,2,3);  // adds a dummy parameter at the beginning and calls foo(2,3)
29  * sigc::hide<1>(&foo)(1,2,3);  // adds a dummy parameter in the middle and calls foo(1,3)
30  * sigc::hide<2>(&foo)(1,2,3);  // adds a dummy parameter at the back and calls foo(1,2)
31  * @endcode
32  *
33  * The functor sigc::hide() returns can be directly passed into
34  * sigc::signal::connect().
35  *
36  * @par Example:
37  * @code
38  * sigc::signal<void(int)> some_signal;
39  * void foo();
40  * some_signal.connect(sigc::hide(&foo));
41  * @endcode
42  *
43  * sigc::hide() can be nested in order to discard multiple arguments.
44  * @par Example:
45  * @code
46  * // multiple argument hiding ...
47  * sigc::hide(sigc::hide(&foo))(1,2,3,4); // adds two dummy parameters at the back and calls foo(1,2)
48  * @endcode
49
50  * sigc::hide_return() alters an arbitrary functor by
51  * dropping its return value, thus converting it to a void functor.
52  *
53  * @ingroup adaptors
54  */
55
56
57 /** Adaptor that adds a dummy parameter to the wrapped functor.
58  * Use the convenience function sigc::hide() to create an instance of sigc::hide_functor.
59  *
60  * The following template arguments are used:
61  * - @e I_location Zero-based position of the dummy parameter (@p -1 for the last parameter).
62  * - @e T_type Type of the dummy parameter.
63  * - @e T_functor Type of the functor to wrap.
64  *
65  * @ingroup hide
66  */
67 template <int I_location, class T_functor>
68 struct hide_functor : public adapts<T_functor>
69 {
70   using adaptor_type = typename adapts<T_functor>::adaptor_type;
71   using result_type = typename adaptor_type::result_type;
72
73   /** Invokes the wrapped functor, ignoring the argument at index @e I_location (0-indexed).
74    * @param _A_a Arguments to be passed on to the functor, apart from the ignored argument.
75    * @return The return value of the functor invocation.
76    */
77   template <class... T_arg>
78   decltype(auto)
79   operator()(T_arg&&... _A_a)
80     {
81        constexpr auto size = sizeof...(T_arg);
82        constexpr auto index_ignore = (I_location == -1 ? size - 1 : I_location);
83        const auto t = std::tuple<T_arg...>(std::forward<T_arg>(_A_a)...);
84
85        const auto t_start = internal::tuple_start<index_ignore>(t);
86        const auto t_end = internal::tuple_end<size - index_ignore - 1>(t);
87        const auto t_used = std::tuple_cat(t_start, t_end);
88
89        constexpr auto size_used = size - 1;
90
91        //TODO: Remove these? They are just here as a sanity check.
92        static_assert(std::tuple_size<decltype(t_used)>::value == size_used, "Unexpected t_used size.");
93
94        const auto seq = std::make_index_sequence<size_used>();
95        return call_functor_operator_parentheses(t_used, seq);
96     }
97
98   /** Constructs a hide_functor object that adds a dummy parameter to the passed functor.
99    * @param _A_func Functor to invoke from operator()().
100    */
101   explicit hide_functor(const T_functor& _A_func)
102     : adapts<T_functor>(_A_func)
103     {}
104
105 private:
106   //TODO_variadic: Replace this with std::experimental::apply() if that becomes standard
107   //C++, or add our own implementation, to avoid code duplication.
108   template<class T_tuple, std::size_t... Is>
109   decltype(auto)
110   call_functor_operator_parentheses(T_tuple& tuple,
111     std::index_sequence<Is...>)
112   {
113     return this->functor_.template operator()(std::get<Is>(tuple)...);
114   }
115 };
116
117
118 #ifndef DOXYGEN_SHOULD_SKIP_THIS
119 //template specialization of visitor<>::do_visit_each<>(action, functor):
120 /** Performs a functor on each of the targets of a functor.
121  * The function overload for sigc::hide_functor performs a functor on the
122  * functor stored in the sigc::hide_functor object.
123  *
124  * @ingroup hide
125  */
126 template <int I_location, class T_functor>
127 struct visitor<hide_functor<I_location, T_functor> >
128 {
129   template <typename T_action>
130   static void do_visit_each(const T_action& _A_action,
131                             const hide_functor<I_location, T_functor>& _A_target)
132   {
133     sigc::visit_each(_A_action, _A_target.functor_);
134   }
135 };
136 #endif // DOXYGEN_SHOULD_SKIP_THIS
137
138 /** Creates an adaptor of type sigc::hide_functor which adds a dummy parameter to the passed functor.
139  * The optional template argument @e I_location specifies the zero-based
140  * position of the dummy parameter in the returned functor (@p -1 stands for the last parameter).
141  *
142  * @param _A_func Functor that should be wrapped.
143  * @return Adaptor that executes @e _A_func, ignoring the value of the dummy parameter.
144  *
145  * @ingroup hide
146  */
147 template <int I_location, class T_functor>
148 inline decltype(auto)
149 hide(const T_functor& _A_func)
150   { return hide_functor<I_location, T_functor>(_A_func); }
151
152 /** Creates an adaptor of type sigc::hide_functor which adds a dummy parameter to the passed functor.
153  * This overload adds a dummy parameter at the back of the functor's parameter list.
154  *
155  * @param _A_func Functor that should be wrapped.
156  * @return Adaptor that executes @e _A_func, ignoring the value of the last parameter.
157  *
158  * @ingroup hide
159  */
160 template <class T_functor>
161 inline decltype(auto)
162 hide(const T_functor& _A_func)
163   { return hide_functor<-1, T_functor> (_A_func); }
164
165 } /* namespace sigc */
166
167 #endif /* _SIGC_ADAPTORS_HIDE_H_ */