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++/trackable.h>
8 #include <sigc++/signal.h>
9 #include <sigc++/functors/ptr_fun.h>
10 #include <sigc++/functors/mem_fun.h>
11 #include <sstream>
12 #include <iomanip>
13 #include <vector>
14 #include <cstdlib>
15
16 namespace
17 {
18
19 TestUtilities* util = nullptr;
20 std::ostringstream result_stream;
21
22 struct arithmetic_mean_accumulator
23 {
24 typedef double result_type;
25 template<typename T_iterator>
operator ()__anon00c3ac1c0111::arithmetic_mean_accumulator26 double operator()(T_iterator first, T_iterator last) const
27 {
28 double value_ = 0;
29 int n_ = 0;
30 for (; first != last; ++first, ++n_)
31 value_ += *first;
32 return (n_ ? value_ / n_ : -1); // empty slot list <=> n_==0
33 }
34 };
35
36 template<class Ret>
37 struct vector_accumulator
38 {
39 typedef std::vector<Ret> result_type;
40 template<typename T_iterator>
operator ()__anon00c3ac1c0111::vector_accumulator41 result_type operator()(T_iterator first, T_iterator last) const
42 {
43 result_type vec;
44 for (; first != last; ++first)
45 vec.push_back(*first);
46 return vec;
47 }
48 };
49
foo(int i)50 int foo(int i)
51 {
52 const int result = 3 * i + 1;
53 result_stream << "foo: " << result << ", ";
54 return result;
55 }
56
bar(double i)57 int bar(double i)
58 {
59 const int result = 5 * int(i) - 3;
60 result_stream << "bar: " << result << ", ";
61 return result;
62 }
63
64 struct A : public sigc::trackable
65 {
foo__anon00c3ac1c0111::A66 int foo(int i)
67 {
68 const int result = 20 * i - 14;
69 result_stream << "A::foo: " << result << ", ";
70 return result;
71 }
72 };
73
test_empty_signal()74 void test_empty_signal()
75 {
76 sigc::signal<int,int>::accumulated<arithmetic_mean_accumulator> sig;
77 sigc::signal<int,int>::accumulated<vector_accumulator<int> > sig_vec;
78
79 result_stream << "Result (empty slot list): " << sig(0);
80 util->check_result(result_stream, "Result (empty slot list): -1");
81 result_stream << "Vector result (empty slot list): "
82 << (sig_vec(0).empty() ? "empty" : "not empty");
83 util->check_result(result_stream, "Vector result (empty slot list): empty");
84 }
85
test_mean()86 void test_mean()
87 {
88 sigc::signal<int,int>::accumulated<arithmetic_mean_accumulator> sig;
89
90 A a;
91 sig.connect(sigc::ptr_fun1(&foo));
92 sig.connect(sigc::mem_fun1(a, &A::foo));
93 sig.connect(sigc::ptr_fun1(&bar));
94
95 double dres = sig(1);
96 result_stream << "Mean accumulator: Result (i=1): "
97 << std::fixed << std::setprecision(3) << dres;
98 util->check_result(result_stream,
99 "foo: 4, A::foo: 6, bar: 2, Mean accumulator: Result (i=1): 4.000");
100
101 dres = sig(11);
102 result_stream << "Mean accumulator: Plain Result (i=11): "
103 << std::fixed << std::setprecision(3) << dres;
104 util->check_result(result_stream,
105 "foo: 34, A::foo: 206, bar: 52, Mean accumulator: Plain Result (i=11): 97.333");
106 }
107
test_vector_accumulator()108 void test_vector_accumulator()
109 {
110 sigc::signal<int,int>::accumulated<vector_accumulator<int> > sig_vec;
111
112 A a;
113 sig_vec.connect(sigc::ptr_fun(&foo));
114 sig_vec.connect(sigc::mem_fun(a, &A::foo));
115 sig_vec.connect(sigc::ptr_fun(&bar));
116
117 auto res1 = sig_vec(1);
118 result_stream << "Vector accumulator: Result (i=1): ";
119 for (auto num : res1)
120 result_stream << num << " ";
121 util->check_result(result_stream,
122 "foo: 4, A::foo: 6, bar: 2, Vector accumulator: Result (i=1): 4 6 2 ");
123
124 auto res3 = sig_vec(3);
125 result_stream << "Vector accumulator: Result (i=3): ";
126 for (auto num : res3)
127 result_stream << num << " ";
128 util->check_result(result_stream,
129 "foo: 10, A::foo: 46, bar: 12, Vector accumulator: Result (i=3): 10 46 12 ");
130 }
131
132 } // end anonymous namespace
133
main(int argc,char * argv[])134 int main(int argc, char* argv[])
135 {
136 util = TestUtilities::get_instance();
137
138 if (!util->check_command_args(argc, argv))
139 return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE;
140
141 test_empty_signal();
142 test_mean();
143 test_vector_accumulator();
144
145 return util->get_result_and_delete_instance() ? EXIT_SUCCESS : EXIT_FAILURE;
146 }
147