1 /* Copyright (C) 2016 Murray Cumming
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/
19 #include <sigc++/tuple-utils/tuple_for_each.h>
25 template <class T_element_from>
26 class for_each_simple {
29 visit(const T_element_from& from) {
30 std::cout << "for_each_simple(): " << std::to_string(from) << std::endl;
35 test_tuple_for_each_same_types() {
37 auto t_original = std::make_tuple(1, 2, 3);
38 sigc::internal::tuple_for_each<for_each_simple>(t_original);
42 auto t_original = std::make_tuple(1, (double)2.1f, 3);
43 sigc::internal::tuple_for_each<for_each_simple>(t_original);
47 template <class T_element_from>
48 class for_each_simple_with_extras {
51 visit(const T_element_from& from, int extra1, const std::string& extra2) {
52 std::cout << "for_each_simple_with_extras(): from=" << std::to_string(from)
53 << ", extra1: " << extra1 << ", extra2: " << extra2 << std::endl;
58 test_tuple_for_each_same_types_with_extras() {
60 auto t_original = std::make_tuple(1, (double)2.1f, 3);
61 sigc::internal::tuple_for_each<for_each_simple_with_extras>(
62 t_original, 89, "eightynine");
66 template <class T_element_from>
67 class for_each_simple_with_nonconst_extras {
70 visit(const T_element_from& from, int& extra) {
76 test_tuple_for_each_same_types_with_nonconst_extras() {
78 auto t_original = std::make_tuple(1, (double)2.1f, 3);
81 sigc::internal::tuple_for_each<for_each_simple_with_nonconst_extras>(t_original, extra);
82 // std::cout << "extra: " << extra << std::endl;
87 // The general template declaration.
88 // We then provide specializations for each type,
89 // so we can test having a different return value for each T_element_from type.
90 template <class T_element_from>
91 class visitor_with_specializations;
93 // An int will be converted to a std::string:
95 class visitor_with_specializations<int> {
98 visit(const int& from) {
99 std::cout << "visitor_with_specializations::visit(): "
100 << std::to_string(from) << std::endl;
104 // A double will be converted to a char:
106 class visitor_with_specializations<double> {
109 visit(const double& from) {
110 std::cout << "visitor_with_specializations::visit(): "
111 << std::to_string(from)[0] << std::endl;
115 // A std::string will be converted to an int:
117 class visitor_with_specializations<std::string> {
120 visit(const std::string& from) {
121 std::cout << "visitor_with_specializations::visit(): " << std::stoi(from)
126 // A const char* will be converted to an int:
128 class visitor_with_specializations<const char*> {
131 visit(const char* from) {
132 std::cout << "visitor_with_specializations::visit(): " << std::stoi(from)
138 test_tuple_for_each_multiple_types() {
139 auto t_original = std::make_tuple(1, (double)2.1f, std::string("3"));
140 sigc::internal::tuple_for_each<visitor_with_specializations>(t_original);
143 template <class T_element_from>
144 class for_each_nonconst {
147 visit(T_element_from& from) {
149 // Or, for instance, call a non-const method on from.
154 test_tuple_for_each_nonconst() {
155 auto t = std::make_tuple(1, 2, 3);
156 sigc::internal::tuple_for_each<for_each_nonconst, decltype(t)&>(t);
157 std::cout << std::get<0>(t) << std::endl;
158 assert(std::get<0>(t) == 2);
159 assert(std::get<1>(t) == 4);
160 assert(std::get<2>(t) == 6);
164 test_tuple_for_each_stdref() {
169 auto t_original = std::make_tuple(std::ref(a), std::ref(b), std::ref(c));
170 sigc::internal::tuple_for_each<for_each_simple>(t_original);
177 auto t_original = std::make_tuple(std::ref(a), std::ref(b), std::ref(c));
178 sigc::internal::tuple_for_each<for_each_nonconst>(t_original);
185 static std::string correct_sequence_output;
187 template <class T_element_from>
188 class for_each_correct_sequence {
191 visit(const T_element_from& from) {
192 //std::cout << "from: " << from << std::endl;
193 correct_sequence_output += std::to_string(from);
198 test_tuple_for_each_correct_sequence() {
199 correct_sequence_output.clear();
200 auto t = std::make_tuple(1, 2, 3);
201 sigc::internal::tuple_for_each<for_each_correct_sequence>(t);
202 //std::cout << "correct_sequence_output: " << correct_sequence_output << std::endl;
203 assert(correct_sequence_output == "123");
207 test_tuple_for_each_empty_tuple() {
208 auto t = std::tuple<>();
209 sigc::internal::tuple_for_each<for_each_simple>(t);
214 test_tuple_for_each_constexpr() {
215 constexpr auto t_original = std::make_tuple(1, (double)2.1f, "3");
216 sigc::internal::tuple_for_each<visitor_with_specializations>(t_original);
221 test_tuple_for_each_same_types();
222 test_tuple_for_each_same_types_with_extras();
223 test_tuple_for_each_same_types_with_nonconst_extras();
225 test_tuple_for_each_multiple_types();
227 test_tuple_for_each_nonconst();
229 test_tuple_for_each_stdref();
231 test_tuple_for_each_correct_sequence();
233 test_tuple_for_each_empty_tuple();
235 test_tuple_for_each_constexpr();