]> git.tdb.fi Git - ext/sigc++-2.0.git/blob - tests/test_visit_each.cc
Adjust the name of the library to match upstream
[ext/sigc++-2.0.git] / tests / test_visit_each.cc
1 /* Copyright (C) 2014 The libsigc++ Development Team
2  *
3  * This file is part of libsigc++.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include "testutilities.h"
20 #include <string>
21 #include <iostream>
22 #include <sstream>
23 #include <cstdlib>
24 #include <sigc++/signal.h>
25
26 // SIGCTEST_CASE 1  Assume that class sigc::visitor has not been implemented.
27 //                  Don't test with MyClass2, which is expected to fail in this case.
28 // SIGCTEST_CASE 2  Assume that class sigc::visitor has not been implemented.
29 //                  Test with MyClass2, although it is expected to fail in this case.
30 // SIGCTEST_CASE 3  Assume that class sigc::visitor has been implemented.
31 //                  Test with MyClass2, which is expected to succeed in this case.
32 // See also https://bugzilla.gnome.org/show_bug.cgi?id=724496
33 #define SIGCTEST_CASE 3
34
35 namespace
36 {
37 std::ostringstream result_stream;
38 }
39
40 // namespace assumed to belong to an external package.
41 namespace ns_ext
42 {
43 class NsExtClass
44 {
45 };
46
47 template <class T_action, class T_functor>
48 void visit_each(T_action&, const T_functor&)
49 {
50   result_stream << "ns_ext::visit_each() ";
51 }
52
53 } // end namespace ns_ext
54
55 namespace
56 {
57 class MyClass1 : public sigc::trackable
58 {
59 public:
60   MyClass1(const std::string& str) : s(str) {}
61
62   void execute(int i)
63   {
64     result_stream << s << i;
65   }
66 private:
67   std::string s;
68 };
69
70 class MyClass2 : public ns_ext::NsExtClass, public sigc::trackable
71 {
72 public:
73   MyClass2(const std::string& str) : s(str) {}
74
75   void execute(int i)
76   {
77     result_stream << s << i;
78   }
79 private:
80   std::string s;
81 };
82
83 } // end anonymous namespace
84
85 namespace ns1
86 {
87 // User-defined adaptor, as decribed in adaptor_trait.h.
88 template <class T_functor>
89 struct MyAdaptor1 : public sigc::adapts<T_functor>
90 {
91   template <class T_arg1=void, class T_arg2=void>
92   struct deduce_result_type
93   { typedef sigc::deduce_result_t<T_functor, T_arg1, T_arg2> type; };
94   typedef typename sigc::functor_trait<T_functor>::result_type result_type;
95
96   result_type
97   operator()() const
98   {
99     result_stream << "MyAdaptor1()() ";
100     return this->functor_();
101   }
102
103   template <class T_arg1>
104   typename deduce_result_type<T_arg1>::type
105   operator()(T_arg1 _A_arg1) const
106   {
107     result_stream << "MyAdaptor1()(_A_arg1) ";
108     return this->functor_(_A_arg1);
109   }
110
111   template <class T_arg1, class T_arg2>
112   typename deduce_result_type<T_arg1, T_arg2>::type
113   operator()(T_arg1 _A_arg1, T_arg2 _A_arg2) const
114   {
115     result_stream << "MyAdaptor1()(_A_arg1, _A_arg2) ";
116     return this->functor_(_A_arg1, _A_arg2);
117   }
118
119   // Constructs a MyAdaptor1 object that wraps the passed functor.
120   // Initializes adapts<T_functor>::functor_, which is invoked from operator()().
121   explicit MyAdaptor1(const T_functor& _A_functor)
122     : sigc::adapts<T_functor>(_A_functor) {}
123 };
124
125 template <class T_action, class T_functor>
126 void visit_each(const T_action& _A_action,
127                 const MyAdaptor1<T_functor>& _A_target)
128 {
129   visit_each(_A_action, _A_target.functor_);
130 }
131
132 template <typename T_functor>
133 inline MyAdaptor1<T_functor>
134 my_adaptor1(const T_functor& _A_func)
135 {
136   return MyAdaptor1<T_functor>(_A_func);
137 }
138
139 } // end namespace ns1
140
141 #if SIGCTEST_CASE >= 3
142 // Specialization of sigc::visitor for MyAdaptor1.
143 namespace sigc
144 {
145 template <class T_functor>
146 struct visitor<ns1::MyAdaptor1<T_functor> >
147 {
148   template <class T_action>
149   static void do_visit_each(const T_action& _A_action,
150                             const ns1::MyAdaptor1<T_functor>& _A_target)
151   {
152     sigc::visit_each(_A_action, _A_target.functor_);
153   }
154 };
155 } // end namespace sigc
156 #endif // SIGCTEST_CASE >= 3
157
158
159 int main(int argc, char* argv[])
160 {
161   auto util = TestUtilities::get_instance();
162
163   if (!util->check_command_args(argc, argv))
164     return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE;
165
166   sigc::slot<void, int> sl1;
167
168   {
169     MyClass1 my_class1("x=");
170     sl1 = sigc::mem_fun(my_class1, &MyClass1::execute);
171     sl1(-2);
172     util->check_result(result_stream, "x=-2");
173
174   } // auto-disconnect sl1
175
176   sl1(-2);
177   util->check_result(result_stream, "");
178
179 #if SIGCTEST_CASE >= 2
180   {
181     MyClass2 my_class2("y=");
182     sl1 = sigc::mem_fun(my_class2, &MyClass2::execute);
183     sl1(2);
184     util->check_result(result_stream, "y=2");
185
186   } // auto-disconnect sl1
187
188   sl1(2);
189   util->check_result(result_stream, "");
190 #endif // SIGCTEST_CASE >= 2
191
192   {
193     MyClass1 my_class3("a=");
194     sl1 = ns1::my_adaptor1(sigc::mem_fun(my_class3, &MyClass1::execute));
195     sl1(42);
196     util->check_result(result_stream, "MyAdaptor1()(_A_arg1) a=42");
197
198   } // auto-disconnect sl1
199
200   sl1(42);
201   util->check_result(result_stream, "");
202
203   return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE;
204 }