Skip to content

Commit 0b88479

Browse files
committed
Add another variadic exercise
1 parent 9cbc035 commit 0b88479

File tree

1 file changed

+78
-4
lines changed

1 file changed

+78
-4
lines changed

cpp11training/cpp11training/7.variadic_templates.cpp

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,81 @@ TEST(variadic_tuple_iteration, DISABLED_we_can_transform_an_indexed_tuple) {
144144
EXPECT_EQ(3, std::get<1>(result));
145145
EXPECT_NEAR(4.5, std::get<2>(result), .0001);
146146
}
147-
auto product = [](auto... functions)
147+
148+
using Amount = int;
149+
struct Account {
150+
Amount balance;
151+
};
152+
auto consult(const Account &a) {
153+
return a.balance;
154+
}
155+
auto transaction(Account& from, Account& to, Amount amount)
156+
{
157+
if (from.balance <= amount) return false;
158+
from.balance -= amount;
159+
to.balance += amount;
160+
return true;
161+
}
162+
163+
164+
// TODO:
165+
// uncomment next line
166+
// #define I_CAN_WRAP_FUNCTIONS
167+
//
168+
// And now...
169+
//
170+
// create the `writer` meta-function so that it
171+
// returns a function that
172+
// * accepts an existing M _and_ all the arguments for `f`
173+
// * appends `m` to an existing M
174+
// * returns the tuple { m, f(args) }
175+
//
176+
// GOAL:
177+
// Learn to work with functions as first class citizens
178+
// allows you to write more orthogonal code: the code
179+
// concerned with the logging does not need to have anything to
180+
// do with the code performing the action.
181+
//
182+
// HINT:
183+
// use generic lambdas
184+
// mind reference arguments! They need to be perfect-forwarded!
185+
//
186+
#ifdef I_CAN_WRAP_FUNCTIONS
187+
template<typename M, typename F>
188+
auto writer(M m, F f) {
189+
}
190+
#endif
191+
192+
TEST(variadic_templates, DISABLED_can_be_used_to_wrap_existing_functions) {
193+
Account mine{1000};
194+
Account yours{50};
195+
196+
ASSERT_TRUE(transaction(mine, yours, 50));
197+
ASSERT_EQ(950, mine.balance);
198+
ASSERT_EQ(100, yours.balance);
199+
200+
#ifdef I_CAN_WRAP_FUNCTIONS
201+
using namespace std::string_literals;
202+
auto v_consult = writer("consult\n"s, consult);
203+
auto v_transaction = writer("transaction\n"s, transaction);
204+
205+
std::string logs0;
206+
{
207+
auto [logs1, balance] = v_consult(logs0, mine);
208+
EXPECT_EQ("consult\n", logs1);
209+
EXPECT_EQ(950, balance);
210+
EXPECT_EQ(100, yours.balance);
211+
auto [logs2, u] = v_transaction(logs1, yours, mine, 50);
212+
EXPECT_EQ("consult\ntransaction\n", logs2);
213+
EXPECT_EQ(true, u);
214+
EXPECT_EQ(1000, mine.balance);
215+
EXPECT_EQ(50, yours.balance);
216+
}
217+
#endif
218+
}
219+
220+
221+
auto tabulate = [](auto... functions)
148222
{
149223
return [](auto ...arguments) {
150224
return std::string{ "not implemented" };
@@ -156,11 +230,11 @@ TEST(composition, DISABLED_print_a_matrix)
156230

157231
// this exercise will take some more time...
158232
//
159-
// TODO: fill in the `product` function so that it prints a table
233+
// TODO: fill in the `tabulate` function so that it prints a table
160234
// of the functions applied to the arguments
161235
// GOAL: learn to deal with multiple packs and expansions
162236
// GRADE: HARD
163-
const auto table = product(
237+
const auto table = tabulate(
164238
[](auto i) { return i; },
165239
[](auto i) { return i * i; },
166240
[](auto i) { return i * i*i - 1; }
@@ -172,7 +246,7 @@ TEST(composition, DISABLED_print_a_matrix)
172246

173247
EXPECT_EQ(R"(1, 4, 9, 100
174248
1, 8, 27, 1000)",
175-
product([](auto i) { return i*i; },
249+
tabulate([](auto i) { return i*i; },
176250
[](auto i) { return i*i*i; })
177251
(1, 2, 3, 10));
178252
}

0 commit comments

Comments
 (0)