|
| 1 | +/* |
| 2 | + * 4. FOLD EXPRESSIONS |
| 3 | + * |
| 4 | + * Fold expressions provide the tools to apply BINARY OPERATORS to all elements in a |
| 5 | + * parameter pack without having of recursive template unpacking or intitializer tricks |
| 6 | + * |
| 7 | + * There are 4 forms of a fold expression: |
| 8 | + * (... OP pack) // Unary right fold => ((arg1 [+] arg2) [+] ...) |
| 9 | + * (pack OP ...) // Unary left fold => (... [+] (arg2 [+] arg3)) |
| 10 | + * (init OP ... OP pack) // Binary left fold => ((init [+] arg1) [+] arg2) [+] ...) |
| 11 | + * (pack OP ... OP init) // Binary right fold => (... [+] (arg2 [+] (arg3 [+] init))) |
| 12 | + */ |
1 | 13 | #include <iostream> |
2 | 14 | #include <vector> |
3 | 15 | #include <set> |
4 | 16 | #include <string> |
5 | | -//#include <print> // Needs to be included if we are using C++23 print function |
| 17 | +#include <cassert> |
| 18 | +#include <sstream> |
6 | 19 |
|
7 | | -//size_t... I is a std::integer_sequence whose values are specified by a non-type template |
| 20 | +//(size_t... I) is a std::integer_sequence whose values are specified by a non-type template |
8 | 21 | template<typename TupleT, size_t... IdxT> |
9 | | -void print(const TupleT& tupl, std::index_sequence<IdxT...>){ |
| 22 | +std::string print(const TupleT& tupl, std::index_sequence<IdxT...>){ |
10 | 23 | //This experssion (..., operator) folds the tuple by applying operator to |
11 | 24 | // each of its elements going from left to right |
12 | | - std::cout << "("; |
13 | | - (..., (std::cout << (IdxT == 0 ? "" : ", ") << std::get<IdxT>(tupl))); |
14 | | - std::cout << ")\n"; |
| 25 | + std::ostringstream oss; |
| 26 | + oss << "("; |
| 27 | + (..., (oss << (IdxT == 0 ? "" : ", ") << std::get<IdxT>(tupl))); |
| 28 | + oss << ")\n"; |
| 29 | + return oss.str(); |
15 | 30 | } |
16 | 31 |
|
17 | 32 | // This is a non-type template that takes a tuple with multiple arguments of some type T |
18 | 33 | template<typename... T> |
19 | | -void printTuple(const std::tuple<T...>& tupl){ |
20 | | - //std::make_integer_sequence creates a sequence of integers of size equal to the number of arguments of T |
21 | | - print(tupl, std::make_index_sequence<sizeof...(T)>()); |
| 34 | +std::string printTuple(const std::tuple<T...>& tupl){ |
| 35 | + // std::make_integer_sequence creates a sequence of integers of size equal to the number of arguments of T |
| 36 | + return print(tupl, std::make_index_sequence<sizeof...(T)>()); |
22 | 37 | } |
23 | 38 |
|
24 | 39 | int main(){ |
25 | | - std::vector<std::tuple<std::string>> my_list = {("5","3","1"),("1","3","2"),("3","5","A"),("6","4","5")}; |
| 40 | + std::cout << "===== Test : Fold expressions applied to tuple printing =====\n"; |
26 | 41 |
|
27 | | - auto a = std::make_index_sequence<4>(); |
28 | | - for(auto tupl_ : my_list){ |
29 | | - //std::cout << std::fmt("{}", my_list[i]) << std::endl; //For C++20 use format |
30 | | - //print("{}", my_list[i]); // For C++23 use print |
31 | | - printTuple(tupl_); |
| 42 | + std::vector<std::tuple<std::string, std::string, std::string>> my_list = { |
| 43 | + {"5","3","1"}, |
| 44 | + {"1","3","2"}, |
| 45 | + {"3","5","A"}, |
| 46 | + {"6","4","5"} |
| 47 | + }; |
| 48 | + |
| 49 | + std::vector<std::string> expected_output = {"(5, 3, 1)\n", |
| 50 | + "(1, 3, 2)\n", |
| 51 | + "(3, 5, A)\n", |
| 52 | + "(6, 4, 5)\n"}; |
| 53 | + for(size_t i = 0; i < my_list.size(); i++) |
| 54 | + { |
| 55 | + const auto& tupl_ = my_list[i]; |
| 56 | + std::string result = printTuple(tupl_); |
| 57 | + if (result != expected_output[i]) |
| 58 | + { |
| 59 | + std::cerr << "Failed on tuple " << i << ": got " << result |
| 60 | + << " expected " << expected_output[i] << "\n"; |
| 61 | + assert(false); |
| 62 | + } |
| 63 | + // In C++20 use std::fmt as follows: |
| 64 | + // std::cout << std::fmt("{}", my_list[i]) << std::endl; |
| 65 | + // In C++23 use std::print |
| 66 | + // print("{}", my_list[i]); |
32 | 67 | } |
| 68 | + std::cout << "All tuples verified successfully\n"; |
33 | 69 | return 0; |
34 | 70 | } |
| 71 | + |
0 commit comments