1 /* Copyright (C) 2014 The libsigc++ Development Team
3 * This file is part of libsigc++.
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.
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.
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/>.
19 #include "testutilities.h"
24 #include <sigc++/signal.h>
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
37 std::ostringstream result_stream;
40 // namespace assumed to belong to an external package.
47 template <class T_action, class T_functor>
48 void visit_each(T_action&, const T_functor&)
50 result_stream << "ns_ext::visit_each() ";
53 } // end namespace ns_ext
57 class MyClass1 : public sigc::trackable
60 MyClass1(const std::string& str) : s(str) {}
64 result_stream << s << i;
70 class MyClass2 : public ns_ext::NsExtClass, public sigc::trackable
73 MyClass2(const std::string& str) : s(str) {}
77 result_stream << s << i;
83 } // end anonymous namespace
87 // User-defined adaptor, as decribed in adaptor_trait.h.
88 template <class T_functor>
89 struct MyAdaptor1 : public sigc::adapts<T_functor>
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;
99 result_stream << "MyAdaptor1()() ";
100 return this->functor_();
103 template <class T_arg1>
104 typename deduce_result_type<T_arg1>::type
105 operator()(T_arg1 _A_arg1) const
107 result_stream << "MyAdaptor1()(_A_arg1) ";
108 return this->functor_(_A_arg1);
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
115 result_stream << "MyAdaptor1()(_A_arg1, _A_arg2) ";
116 return this->functor_(_A_arg1, _A_arg2);
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) {}
125 template <class T_action, class T_functor>
126 void visit_each(const T_action& _A_action,
127 const MyAdaptor1<T_functor>& _A_target)
129 visit_each(_A_action, _A_target.functor_);
132 template <typename T_functor>
133 inline MyAdaptor1<T_functor>
134 my_adaptor1(const T_functor& _A_func)
136 return MyAdaptor1<T_functor>(_A_func);
139 } // end namespace ns1
141 #if SIGCTEST_CASE >= 3
142 // Specialization of sigc::visitor for MyAdaptor1.
145 template <class T_functor>
146 struct visitor<ns1::MyAdaptor1<T_functor> >
148 template <class T_action>
149 static void do_visit_each(const T_action& _A_action,
150 const ns1::MyAdaptor1<T_functor>& _A_target)
152 sigc::visit_each(_A_action, _A_target.functor_);
155 } // end namespace sigc
156 #endif // SIGCTEST_CASE >= 3
159 int main(int argc, char* argv[])
161 auto util = TestUtilities::get_instance();
163 if (!util->check_command_args(argc, argv))
164 return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE;
166 sigc::slot<void, int> sl1;
169 MyClass1 my_class1("x=");
170 sl1 = sigc::mem_fun(my_class1, &MyClass1::execute);
172 util->check_result(result_stream, "x=-2");
174 } // auto-disconnect sl1
177 util->check_result(result_stream, "");
179 #if SIGCTEST_CASE >= 2
181 MyClass2 my_class2("y=");
182 sl1 = sigc::mem_fun(my_class2, &MyClass2::execute);
184 util->check_result(result_stream, "y=2");
186 } // auto-disconnect sl1
189 util->check_result(result_stream, "");
190 #endif // SIGCTEST_CASE >= 2
193 MyClass1 my_class3("a=");
194 sl1 = ns1::my_adaptor1(sigc::mem_fun(my_class3, &MyClass1::execute));
196 util->check_result(result_stream, "MyAdaptor1()(_A_arg1) a=42");
198 } // auto-disconnect sl1
201 util->check_result(result_stream, "");
203 return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE;