Imported Upstream version 2.99.2
[platform/upstream/libsigc++.git] / tests / test_bind_return.cc
1 // -*- c++ -*-
2 /* Copyright 2002, The libsigc++ Development Team
3  *  Assigned to public domain.  Use as you wish without restriction.
4  */
5
6 #include "testutilities.h"
7 #include <sigc++/adaptors/bind_return.h>
8 #include <sigc++/functors/slot.h>
9 #include <sstream>
10 #include <string>
11 #include <functional> //For std::ref().
12 #include <cstdlib>
13
14 namespace
15 {
16 std::ostringstream result_stream;
17
18 struct foo
19 {
20   void operator()(int i)
21   {
22     result_stream << "foo(int " << i << ") ";
23   }
24
25   float operator()(float i)
26   {
27     result_stream << "foo(float " << i << ") ";
28     return i*5;
29   }
30 };
31
32 struct bar : public sigc::trackable
33 {
34   bar(int i = 0) : i_(i) {}
35   operator int() { return i_; }
36   int i_;
37 };
38
39 } // end anonymous namespace
40
41 int main(int argc, char* argv[])
42 {
43   auto util = TestUtilities::get_instance();
44
45   if (!util->check_command_args(argc, argv))
46     return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE;
47
48   result_stream << sigc::bind_return(foo(), -12345)(5);
49   util->check_result(result_stream, "foo(int 5) -12345");
50
51   // Here we just build a functor, not a slot. There is no such thing as a
52   // default functor, or an invalidated functor. As such, functors can return
53   // references.
54   std::string str("guest book");
55   // A convoluted way to do
56   // sigc::bind_return(foo(), std::ref(str))(6) = "main";
57   sigc::bind_return<std::reference_wrapper<std::string> >(foo(), std::ref(str))(6) = "main";
58   result_stream << str;
59   util->check_result(result_stream, "foo(int 6) main");
60
61   // Here we build a slot (constructed from a functor). Slots cannot return
62   // references: if they could, then what would be the return value of the
63   // default slot or of an invalidated slot? On the other hand, slots are
64   // guaranteed to be able to construct and return a valid default instance as
65   // long as there exists a default constructor for it.
66   //
67   // Therefore, we use 'bar', and not 'bar&' for this slot signature.
68   sigc::slot<bar(int)> sl;
69   {
70     bar choco(-1);
71     sl = sigc::bind_return(foo(), std::ref(choco));
72     result_stream << sl(7);
73     util->check_result(result_stream, "foo(int 7) -1");
74   } // auto-disconnect
75
76   result_stream << sl(8);
77   util->check_result(result_stream, "0");
78
79   return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE;
80 }