]> git.tdb.fi Git - ext/sigc++-2.0.git/blob - sigc++/adaptors/bound_argument.h
Import libsigc++ 2.10.8 sources
[ext/sigc++-2.0.git] / sigc++ / adaptors / bound_argument.h
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    */
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    */
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    */
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 #ifndef SIGCXX_DISABLE_DEPRECATED
79
80 //Template specialization:
81 /** bound_argument object for a bound argument that is passed by bind() or
82  * returned by bind_return() by reference, specialized for reference_wrapper<> types.
83  * @e T_wrapped The type of the bound argument.
84  */
85 template <class T_wrapped>
86 class bound_argument< reference_wrapper<T_wrapped> >
87 {
88 public:
89   /** Constructor.
90    * @param _A_argument The argument to bind.
91    */
92   bound_argument(const reference_wrapper<T_wrapped>& _A_argument)
93     : visited_(unwrap(_A_argument))
94     {}
95
96   /** Retrieve the entity to visit in visit_each().
97    * @return The limited_reference to the bound argument.
98    */
99   inline const limit_reference<T_wrapped>& visit() const
100     { return visited_; }
101
102   /** Retrieve the entity to pass to the bound functor or return.
103    * @return The bound argument.
104    */
105   inline T_wrapped& invoke()
106     { return visited_.invoke(); }
107
108 private:
109   /** The limited_reference to the bound argument.
110    */
111   limit_reference<T_wrapped> visited_;
112 };
113
114 /** bound_argument object for a bound argument that is passed by bind() or
115  * returned by bind_return() by const reference, specialized for const reference_wrapper<> types.
116  * - @e T_wrapped The type of the bound argument.
117  */
118 template <class T_wrapped>
119 class bound_argument< const_reference_wrapper<T_wrapped> >
120 {
121 public:
122   /** Constructor.
123    * @param _A_argument The argument to bind.
124    */
125   bound_argument(const const_reference_wrapper<T_wrapped>& _A_argument)
126     : visited_(unwrap(_A_argument))
127     {}
128
129   /** Retrieve the entity to visit in visit_each().
130    * @return The const_limited_reference to the bound argument.
131    */
132   inline const const_limit_reference<T_wrapped>& visit() const
133     { return visited_; }
134
135   /** Retrieve the entity to pass to the bound functor or return.
136    * @return The bound argument.
137    */
138   inline const T_wrapped& invoke()
139     { return visited_.invoke(); }
140
141 private:
142   /** The const_limited_reference to the bound argument.
143    */
144   const_limit_reference<T_wrapped> visited_;
145 };
146
147 #endif // SIGCXX_DISABLE_DEPRECATED
148
149 //Template specialization:
150 /** bound_argument object for a bound argument that is passed by bind() or
151  * returned by bind_return() by reference, specialized for std::reference_wrapper<> types.
152  * @e T_wrapped The type of the bound argument.
153  */
154 template <class T_wrapped>
155 class bound_argument< std::reference_wrapper<T_wrapped> >
156 {
157 public:
158   /** Constructor.
159    * @param _A_argument The argument to bind.
160    */
161   bound_argument(const std::reference_wrapper<T_wrapped>& _A_argument)
162     : visited_(unwrap(_A_argument))
163     {}
164
165   /** Retrieve the entity to visit in visit_each().
166    * @return The limited_reference to the bound argument.
167    */
168   inline const limit_reference<T_wrapped>& visit() const
169     { return visited_; }
170
171   /** Retrieve the entity to pass to the bound functor or return.
172    * @return The bound argument.
173    */
174   inline T_wrapped& invoke()
175     { return visited_.invoke(); }
176
177 private:
178   /** The limited_reference to the bound argument.
179    */
180   limit_reference<T_wrapped> visited_;
181 };
182
183
184
185 #ifndef DOXYGEN_SHOULD_SKIP_THIS
186 /** Implementation of visitor<>::do_visit_each<>() specialized for the bound_argument class.
187  * Call visit_each() on the entity returned by the bound_argument's visit()
188  * method.
189  * @tparam T_type The type of bound_argument.
190  * @tparam T_action The type of functor to invoke.
191  * @param _A_action The functor to invoke.
192  * @param _A_argument The visited instance.
193  */
194 template <class T_type>
195 struct visitor<bound_argument<T_type> >
196 {
197   template <class T_action>
198   static void do_visit_each(const T_action& _A_action,
199                             const bound_argument<T_type>& _A_argument)
200   {
201     sigc::visit_each(_A_action, _A_argument.visit());
202   }
203 };
204 #endif // DOXYGEN_SHOULD_SKIP_THIS
205
206 } /* namespace sigc */
207
208
209 #endif /* _SIGC_BOUND_ARGUMENT_H_ */