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