1 /*
2 * Copyright 2005, The libsigc++ Development Team
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 #ifndef _SIGC_BOUND_ARGUMENT_H_
20 #define _SIGC_BOUND_ARGUMENT_H_
21
22
23 #include <sigc++/limit_reference.h>
24 #include <sigc++/reference_wrapper.h>
25
26
27 namespace sigc {
28
29 /** A bound_argument<Foo> object stores a bound (for instance, with sigc::bind(), or sigc::bind_return()) argument.
30 *
31 * If Foo is a wrapped reference to a class Bar (reference_wrapper<Bar>) then this
32 * object is implemented on top of a limit_reference. When the slot is
33 * invoked, the limit_reference::invoke() method provides the argument (a Bar&).
34 * When the slot is visited (e.g. visit_each<>()), we simply visit the limit_reference,
35 * which will visit the derived type, or a sigc::trackable base if necessary.
36 *
37 * Likewise, If Foo is a wrapped const reference to a class Bar (const_reference_wrapper<Bar>)
38 * then this object is implemented on top of a const_limit_reference.
39 *
40 * If Foo is something else (such as an argument that is bound by value) bound_argument just
41 * stores a cop of that value, and both invoke() and visit() simply return it.
42 *
43 * This object is used by the bind_functor<> and bind_return_functor<> objects,
44 * depending on whether the argument is bound as a parameter or as a return value.
45 *
46 * The general template implementation is used for parameters that are passed by value.
47 * @e T_type The type of the bound argument.
48 */
49 template <class T_type>
50 class bound_argument
51 {
52 public:
53 /** Constructor.
54 * @param _A_argument The argument to bind.
55 */
bound_argument(const T_type & _A_argument)56 bound_argument(const T_type& _A_argument)
57 : visited_(_A_argument)
58 {}
59
60 /** Retrieve the entity to visit in visit_each().
61 * @return The bound argument.
62 */
visit()63 inline const T_type& visit() const
64 { return visited_; }
65
66 /** Retrieve the entity to pass to the bound functor or return.
67 * @return The bound argument.
68 */
invoke()69 inline T_type& invoke()
70 { return visited_; }
71
72 private:
73 /** The value of the argument.
74 */
75 T_type visited_;
76 };
77
78 //Template specialization:
79 /** bound_argument object for a bound argument that is passed by bind() or
80 * returned by bind_return() by reference, specialized for reference_wrapper<> types.
81 * @e T_wrapped The type of the bound argument.
82 */
83 template <class T_wrapped>
84 class bound_argument< reference_wrapper<T_wrapped> >
85 {
86 public:
87 /** Constructor.
88 * @param _A_argument The argument to bind.
89 */
bound_argument(const reference_wrapper<T_wrapped> & _A_argument)90 bound_argument(const reference_wrapper<T_wrapped>& _A_argument)
91 : visited_(unwrap(_A_argument))
92 {}
93
94 /** Retrieve the entity to visit in visit_each().
95 * @return The limited_reference to the bound argument.
96 */
visit()97 inline const limit_reference<T_wrapped>& visit() const
98 { return visited_; }
99
100 /** Retrieve the entity to pass to the bound functor or return.
101 * @return The bound argument.
102 */
invoke()103 inline T_wrapped& invoke()
104 { return visited_.invoke(); }
105
106 private:
107 /** The limited_reference to the bound argument.
108 */
109 limit_reference<T_wrapped> visited_;
110 };
111
112 /** bound_argument object for a bound argument that is passed by bind() or
113 * returned by bind_return() by const reference, specialized for const reference_wrapper<> types.
114 * - @e T_wrapped The type of the bound argument.
115 */
116 template <class T_wrapped>
117 class bound_argument< const_reference_wrapper<T_wrapped> >
118 {
119 public:
120 /** Constructor.
121 * @param _A_argument The argument to bind.
122 */
bound_argument(const const_reference_wrapper<T_wrapped> & _A_argument)123 bound_argument(const const_reference_wrapper<T_wrapped>& _A_argument)
124 : visited_(unwrap(_A_argument))
125 {}
126
127 /** Retrieve the entity to visit in visit_each().
128 * @return The const_limited_reference to the bound argument.
129 */
visit()130 inline const const_limit_reference<T_wrapped>& visit() const
131 { return visited_; }
132
133 /** Retrieve the entity to pass to the bound functor or return.
134 * @return The bound argument.
135 */
invoke()136 inline const T_wrapped& invoke()
137 { return visited_.invoke(); }
138
139 private:
140 /** The const_limited_reference to the bound argument.
141 */
142 const_limit_reference<T_wrapped> visited_;
143 };
144
145 /** Implementation of visit_each() specialized for the bound_argument class.
146 * Call visit_each() on the entity returned by the bound_argument's visit()
147 * method.
148 * @e T_action The type of functor to invoke.
149 * @e T_type The type of bound_argument.
150 * @param _A_action The functor to invoke.
151 * @param _A_argument The visited instance.
152 */
153 template <class T_action, class T_type>
154 void
visit_each(const T_action & _A_action,const bound_argument<T_type> & _A_argument)155 visit_each(const T_action& _A_action,
156 const bound_argument<T_type>& _A_argument)
157 {
158 visit_each(_A_action, _A_argument.visit());
159 }
160
161
162 } /* namespace sigc */
163
164
165 #endif /* _SIGC_BOUND_ARGUMENT_H_ */
166